verilator-3.874/0000775000177100017500000000000012534632371013531 5ustar wsnyderwsnyderverilator-3.874/TODO0000775000177100017500000001375112525171733014233 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: List of To Do issues. // // Copyright 2004-2015 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. Language support: * Fix ordering of each bit separately in a signal (mips) assign b[3:0] = b[7:4]; assign b[7:4] = in; * Support UDP gate primitives/ cell libraries (have code for combos - problem is sequential udps) * Function to eval combo logic after /*verilator public*/ functions [gwaters] * Support generated clocks (correctness) * Real numbers * Recursive functions * Verilog configuration files * Structs/unions (have starting point) * DPI to define C/C++ calls from Verilog * Expression coverage (see notes) * Better tristate support Long-term Features * Assertions * Tristate support * Multithreaded execution Configure/Make/Install * Full MSVC++ compilation (does scons support this?) (4.000?) * Distribute with flex/bison already expanded? Flex library not needed. Probably too difficult to be worth it. Testing: * Move test_c/sp/v/verilated into test_regress format (4.000?) * Capture all inputs into global "rerun it" file * Code to make wrapper that sets signals, so can do comparison checks * New random program generator * Better graph viewer with search and zoom * Port and test against opencores.org code * // verilator debug in code so can see only tree affecting those nodes Usability: * Detect and pre-remove most UNOPTFLATs (4.000) * Better reporting of unopt problems, including what lines of code * Report more errors (all of them?) before exiting [Eugene Weber] * Auto-create scons config files * Print version/etc message at runtime. (4.000?) Include number of lines of code, percent comments, code complexity measurement <-80chars-------------------------------------------------------------------> Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2013. Verilated #### modules, #### instances, ##### sigs, #### non-comment lines, ##### ops, ### KB model size * Default the --l2name to remove extra "v" level of hierarchy (flag to make "top") Lint: * CDCRSTLOGIC should allow filtering with paths "waive CDCRSTLOGIC --from a.b.sig --to a.c.sig --via OR" Internal Code: * Eliminate the AstNUser* passed to all visitors; its only needed in V3Width, and removing it will speed up and simplify all the other code. * V3Graph should be templated container type, taking in Vertex + Edge types * Rename V3PreLex etc to match VerilogPerl filenames * Instead of string, have an VEncodedString/VIdString which contains __DOT__ish things, to reduce bugs. Also add _20 trailing space to \ encoded names. (4.000) Runtime: * New evalulation loop ~/src/verilator/notes/event_loop.txt (4.000?) * Remove all private internal functions from top level wrapper header, move to new level (4.000?) * Completely standalone simulation (4.000) main() records arguments for $test$plusvars instantiates top, does tracing (support $dump?) calls top->simulateForever() exits Performance: * Latch optimizations * Constant propagation Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF)) Extra shift (perhaps due to clean): if (1 & CAST (VARREF >> #)) * Gated clock and latch conversion to flops. [JeanPaul Vanitegem] Could propagate the AND into pos/negedges and let domaining optimize. * Negedge reset Switch to remove negedges that don't matter Can't remove async resets from control flops (like in syncronizers) * If all references to array have a constant index, blow up into separate signals-per-index * Bit-multiply for faster bit swapping and a=b[1,3,2] random bit reorderings. * Move _last sets and all other combo logic inside master if() that triggers on all possible sense items * Rewrite and combine V3Life, V3Subst If block temp only ever set in one place to constant, propagate it Used in t_mem for array delayed assignments Replace variables if set later in same cfunc branch See for example duplicate sets of _narrow in cycle 90/91 of t_select_plusloop * Same assignment on both if branches "if (a) { ... b=2; } else { ... b=2;}" -> "b=2; if ..." Careful though, as b could appear in the statement or multiple times in statement (Could just require exatly two 'b's in statement) * Simplify XOR/XNOR/AND/OR bit selection trees Foo = A[1] ^ A[2] ^ A[3] etc are better as ^ ( A & 32'b...1110 ) * Combine variables into wider elements Parallel statements on different bits should become single signal Variables that are always consumed in "parallel" can be joined * Duplicate assignments in gate optimization Common to have many separate posedge blocks, each with identical reset_r <= rst_in * If signal is used only once (not counting trace), always gate substitute Don't merge if any combining would form circ logic (out goes back to in) * Multiple assignments each bit can become single assign with concat Make sure a SEL of a CONCAT can get the single bit back. * Usually blocks/values Enable only after certain time, so VL_TIME_I(32) > 0x1e gets eliminated out * Better ordering of a<=b, b<=c, put all refs to 'b' next to each other to optimize caching * Allow Split of case statements without a $display/$stop * I-cache packing improvements (what/how?) * Data cache organization (order of vars in class) First have clocks, then bools instead of uint32_t's then based on what sense list they come from, all outputs, then all inputs finally have any signals part of a "usually" block, or constant. * Rather then tracking widths, have a MSB...LSB of this expression (or better, a bitmask of bits relevant in this expression) * Track recirculation and convert into clock-enables * Clock enables should become new clocking domains for speed * If floped(a) & flopped(b) and no other a&b, then instead flop(a&b). * Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal) verilator-3.874/bin/0000775000177100017500000000000012534632370014300 5ustar wsnyderwsnyderverilator-3.874/bin/verilator_difftree0000775000177100017500000001532512525171733020114 0ustar wsnyderwsnyder: # -*-Mode: perl;-*- use perl, wherever it is eval 'exec perl -wS $0 ${1+"$@"}' if 0; # See copyright, etc in below POD section. ###################################################################### require 5.006_001; use warnings; use Getopt::Long; use IO::File; use Pod::Usage; use strict; use vars qw ($Debug); #====================================================================== # Old version 1 dump nodes with no dtypep's our %Ver1_Non_Dtyped = map {$_ => 1} qw( ACTIVE ALWAYS ALWAYSPOST ALWAYSPUBLIC ATTROF BEGIN BREAK CASE CASEITEM CCALL CELL CELLINLINE CFILE CFUNC CHANGEDET CLOCKING COMMENT CONTINUE COVERDECL COVERINC COVERTOGGLE CRETURN CSTMT DEFPARAM DISABLE DISPLAY DOT DPIEXPORT FCLOSE FFLUSH FINAL FINISH FOPEN GENCASE GENERATE GENFOR GENIF IF IMPLICIT INITARRAY INITIAL JUMPGO JUMPLABEL MODULE NETLIST NOTFOUNDMODULE PACKAGE PACKAGEIMPORT PARSEREF PIN PORT PRAGMA PRIMITIVE PSLASSERT PSLCOVER PSLDEFCLOCK PULL RANGE READMEM REPEAT RETURN SCCTOR SCDTOR SCHDR SCIMP SCIMPHDR SCINT SCOPE SELBIT SELEXTRACT SELMINUS SELPLUS SENGATE SENITEM SENTREE SFORMAT SFORMATF STOP SYSIGNORE SYSTEMT TASK TASKREF TEXT TOPSCOPE TYPEDEFFWD TYPETABLE UCSTMT UDPTABLE UDPTABLELINE UNTILSTABLE VASSERT WHILE ); #====================================================================== # main $Debug = 0; my $Opt_A; my $Opt_B; my $Opt_Lineno = 1; autoflush STDOUT 1; autoflush STDERR 1; Getopt::Long::config ("no_auto_abbrev"); if (! GetOptions ( "help" => \&usage, "debug" => \&debug, "<>" => \¶meter, "lineno!" => \$Opt_Lineno, )) { die "%Error: Bad usage, try 'verilator_difftree --help'\n"; } defined $Opt_A or die "%Error: No old diff filename\n"; defined $Opt_B or die "%Error: No new diff filename\n"; -e $Opt_A or die "%Error: No old diff filename found: $Opt_A\n"; -e $Opt_B or die "%Error: No new diff filename found: $Opt_B\n"; if (-d $Opt_A && -d $Opt_B) { diff_dir ($Opt_A, $Opt_B); } elsif (-f $Opt_A && -f $Opt_B) { diff_file ($Opt_A, $Opt_B); } else { die "%Error: Mix of files and dirs\n"; } sub diff_dir { my $a = shift; my $b = shift; # Diff all files under two directories my %files; foreach my $fn (glob("$a/*.tree")) { (my $base = $fn) =~ s!.*/!!; $files{$base}{a} = $fn; } foreach my $fn (glob("$b/*.tree")) { (my $base = $fn) =~ s!.*/!!; $files{$base}{b} = $fn; } my $any; foreach my $base (sort (keys %files)) { my $a = $files{$base}{a}; my $b = $files{$base}{b}; next if !$a || !$b; print "="x70,"\n"; print "= $a <-> $b\n"; diff_file($a,$b); $any = 1; } $any or warn "%Warning: No .tree files found\n"; } sub diff_file { my $a = shift; my $b = shift; # Compare the two tree files (my $short_a = $a) =~ s/[^a-zA-Z0-9.]+/_/g; (my $short_b = $b) =~ s/[^a-zA-Z0-9.]+/_/g; my $tmp_a = "/tmp/${$}_${short_a}.a"; my $tmp_b = "/tmp/${$}_${short_b}.b"; my $vera = version_from($a); my $verb = version_from($b); my $verCvt = (($vera < 0x3900 && $verb >= 0x3900) || ($vera >= 0x3900 && $verb < 0x3900)); filter ($a, $tmp_a, $verCvt); filter ($b, $tmp_b, $verCvt); system("diff -u $tmp_a $tmp_b"); unlink $tmp_a; unlink $tmp_b; } sub version_from { my $fn = shift; # Return dump format my $f1 = IO::File->new ($fn) or die "%Error: $! $fn,"; while (defined (my $line=$f1->getline())) { last if $. > 10; return hex $1 if $line =~ /\(format (0x[0-9.]+)\)/; } return 1.0; } sub filter { my $fn1 = shift; my $fn2 = shift; my $verCvt = shift; # Remove hex numbers before diffing my $f1 = IO::File->new ($fn1) or die "%Error: $! $fn1,"; my $f2 = IO::File->new ($fn2,"w") or die "%Error: $! $fn2,"; while (defined (my $line=$f1->getline())) { same_line: next if $line =~ / This=/; $line =~ s/0x[a-f0-9]+/0x/g; $line =~ s///g; $line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno; if ($verCvt) { next if $line =~ /^ NETLIST/; $line =~ s!\@dt=0x\(G?/?([^)]+)\)!$1!g; # NEW: @dt -> OLD: non @dt format # # Below Ver1_Non_Dtyped may replace above further if ($line =~ /: ([A-Z]+) /) { my $type = $1; next if $type =~ 'DTYPE'; if ($type eq 'TYPETABLE' || $type eq 'RANGE') { $line =~ /^(\s+\S+:) /; my $prefix = $1; while (defined ($line=$f1->getline())) { next if $line =~ /^\s+[a-z]/; # Table body next if $line =~ /^${prefix}[0-9]:/; goto same_line; } next; } if ($Ver1_Non_Dtyped{$type}) { $line =~ s! w[0-9]+!!g; } } $line =~ s!\@dt=0$!NoW!g; # NEW: dt=null -> common format $line =~ s!\@dt=0 !NoW !g; # NEW: dt=null -> common format $line =~ s! s?w0$! NoW!g; # OLD: no width -> common format $line =~ s! s?w0 ! NoW !g; # OLD: no width -> common format } print $f2 $line; } $f1->close; $f2->close; } #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } sub debug { $Debug = 1; } sub parameter { my $param = shift; if (!defined $Opt_A) { $Opt_A = $param; } elsif (!defined $Opt_B) { $Opt_B = $param; } else { die "%Error: Unknown parameter: $param\n"; } } ####################################################################### sub run { # Run a system command, check errors my $command = shift; print "\t$command\n"; system "$command"; my $status = $?; ($status == 0) or die "%Error: Command Failed $command, $status, stopped"; } ####################################################################### __END__ =pod =head1 NAME verilator_difftree - Compare two Verilator debugging trees =head1 SYNOPSIS verilator_difftree .../a/a.tree .../b/a.tree verilator_difftree .../a .../b =head1 DESCRIPTION Verilator_difftree is used for debugging Verilator tree output files. It performs a diff between two files, or all files common between two directories, ignoring irrelevant pointer differences. =head1 ARGUMENTS =over 4 =item --help Displays this message and program version and exits. =item --nolineno Do not show differences in line numbering. =back =head1 DISTRIBUTION The latest version is available from L. Copyright 2005-2015 by Wilson Snyder. This package 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. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO C =cut ###################################################################### ### Local Variables: ### compile-command: "$V4/bin/verilator_difftree {$V4D,$V4}/test_regress/obj_dir/t_EXAMPLE/V*_03_*.tree" ### End: verilator-3.874/bin/verilator_coverage0000775000177100017500000002026212525171733020113 0ustar wsnyderwsnyder: # -*-Mode: perl;-*- use perl, wherever it is eval 'exec perl -wS $0 ${1+"$@"}' if 0; ###################################################################### # # Copyright 2003-2015 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ###################################################################### require 5.006_001; use warnings; BEGIN { if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) { # Magic to allow author testing of perl packages in local directory require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT}; } } use Getopt::Long; use FindBin qw($RealBin $RealScript); use IO::File; use Pod::Usage; use Cwd qw(abs_path getcwd); use strict; use vars qw ($Debug @Opt_Verilator_Sw); ####################################################################### ####################################################################### # main autoflush STDOUT 1; autoflush STDERR 1; $Debug = 0; # No arguments can't do anything useful. Give help if ($#ARGV < 0) { pod2usage(-exitstatus=>2, -verbose=>0); } # We sneak a look at the flags so we can do some pre-environment checks # All flags will hit verilator... foreach my $sw (@ARGV) { $sw = "'$sw'" if $sw =~ m![^---a-zA-Z0-9_/\\:.+]!; push @Opt_Verilator_Sw, $sw; } Getopt::Long::config ("no_auto_abbrev","pass_through"); if (! GetOptions ( # Major operating modes "help" => \&usage, "debug:s" => \&debug, # "version!" => \&version, # Also passthru'ed # Additional parameters "<>" => sub {}, # Ignored )) { pod2usage(-exitstatus=>2, -verbose=>0); } # Normal, non gdb run (verilator_coverage_bin() ." ".join(' ',@Opt_Verilator_Sw)); #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); } sub debug { shift; my $level = shift; $Debug = $level||3; } ####################################################################### ####################################################################### # Builds sub verilator_coverage_bin { my $bin = ""; # Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path my $basename = ($ENV{VERILATOR_COVERAGE_BIN} || "verilator_coverage_bin_dbg"); if (defined($ENV{VERILATOR_ROOT})) { my $dir = $ENV{VERILATOR_ROOT}; if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT $bin = "$dir/bin/$basename"; } else { $bin = "$dir/$basename"; # From pointing to kit directory } } else { if (-x "$RealBin/$basename") { $bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed } else { $bin = $basename; # Find in PATH } # Note we don't look under bin/$basename which would be right if running # in the kit dir. Running that would likely break, since # VERILATOR_ROOT wouldn't be set and Verilator won't find internal files. } return $bin; } ####################################################################### ####################################################################### # Utilities sub run { # Run command, check errors my $command = shift; $! = undef; # Cleanup -x print "\t$command\n" if $Debug>=3; system($command); my $status = $?; if ($status) { if ($! =~ /no such file or directory/i) { warn "%Error: verilator_coverage: Misinstalled, or VERILATOR_ROOT might need to be in environment\n"; } if ($Debug) { # For easy rerunning warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n"; warn "%Error: $command\n"; } if ($status & 127) { if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV warn "%Error: Verilator_coverage internal fault, sorry.\n" if !$Debug; } elsif (($status & 127) == 6) { # SIGABRT warn "%Error: Verilator_coverage aborted.\n" if !$Debug; } else { warn "%Error: Verilator_coverage threw signal $status.\n" if !$Debug; } } die "%Error: Command Failed $command\n"; } } ####################################################################### ####################################################################### package main; __END__ =pod =head1 NAME verilator_coverage - Verilator coverage analyzer =head1 SYNOPSIS verilator_coverage --help verilator_coverage --version verilator_coverage --annotate verilator_coverage -write merged.dat -read ... Verilator_coverage processes Verilator coverage reports. With --anotate, it reads the specified data file and generates annotated source code with coverage metrics annotated. If multiple coverage points exist on the same line, additional lines will be inserted to report the additional points. Additional Verilog-standard arguments specify the search paths necessary to find the source code that the coverage analysis was performed on. To get correct coverage percentages, you may wish to read logs/coverage.pl into Emacs and do a M-x keep-lines to include only those statistics of interest. For Verilog conditions that should never occur, you should add a $stop statement. This will remove the coverage during the next build. =head1 ARGUMENTS =over 4 =item I Specify input data file, may be repeated to read multiple inputs. If no data file is specified, by default coverage.dat is read. =item --annotate I Sprcifies the directory name that source files with annotated coverage data should be written to. =item --annotate-all Specifies all files should be shown. By default, only those source files which have low coverage are written to the output directory. =item --annotate-min I Specifies the minimum occurrence count that should be flagged if the coverage point does not include a specified threshold. Defaults to 10. =item --help Displays this message and program version and exits. =item --rank Print an experimental report listing the relative importance of each test in covering all of the coverage points. The report shows "Covered" which indicates the number of points that test covers; a test is considered to cover a point if it has a bucket count of at least 1. The "rank" column has a higher number t indicate the test is more important, and rank 0 means the test does not need to be run to cover the points. "RankPts" indicates the number of coverage points this test will contribute to overall coverage if all tests are run in the order of highest to lowest rank. =item --unlink When using --write to combine coverage data, unlink all input files after the output has been created. =item --version Displays program version and exits. =item --write I Specifies the aggregate coverage results, summed across all the files, should be written to the given filename. This is useful in scripts to combine many sequential runs into one master coverage file. =back =head1 VERILOG ARGUMENTS The following arguments are compatible with GCC, VCS and most Verilog programs. =over 4 =item +libext+I+I... Defines the extensions for Verilog files. =item +define+I+I =item -DI=I Defines the given variable. =item +incdir+I =item -II Specifies a directory for finding include files. =item -f I Specifies a file containing additional command line arguments. =item -y I Specifies a module search directory. =back =head1 DISTRIBUTION The latest version is available from L. Copyright 2003-2015 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO C L which is the source for this document. =cut ###################################################################### verilator-3.874/bin/verilator_profcfunc0000775000177100017500000001452712525171733020314 0ustar wsnyderwsnyder: # -*-Mode: perl;-*- use perl, wherever it is eval 'exec perl -wS $0 ${1+"$@"}' if 0; # See copyright, etc in below POD section. ###################################################################### require 5.006_001; use warnings; use Getopt::Long; use IO::File; use Pod::Usage; eval { use Data::Dumper; $Data::Dumper::Indent = 1; }; # Debug, ok if missing use strict; use vars qw ($Debug); #====================================================================== #====================================================================== # main $Debug = 0; my $Opt_File; autoflush STDOUT 1; autoflush STDERR 1; Getopt::Long::config ("no_auto_abbrev"); if (! GetOptions ( "help" => \&usage, "debug" => \&debug, "<>" => \¶meter, )) { die "%Error: Bad usage, try 'verilator_profcfunc --help'\n"; } defined $Opt_File or die "%Error: No filename given\n"; profcfunc($Opt_File); #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } sub debug { $Debug = 1; } sub parameter { my $param = shift; if (!defined $Opt_File) { $Opt_File = $param; } else { die "%Error: Unknown parameter: $param\n"; } } ####################################################################### sub profcfunc { my $filename = shift; # Remove hex numbers before diffing my $fh = IO::File->new ($filename) or die "%Error: $! $filename,"; my %funcs; while (defined (my $line=$fh->getline())) { # %time cumesec selfsec calls {stuff} name if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) { my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4; $funcs{$func}{pct} += $pct; $funcs{$func}{sec} += $sec; $funcs{$func}{calls} += $calls; } } $fh->close; # Find modules my %pointer_mods; my %verilated_mods; foreach my $func (keys %funcs) { if ($func =~ /(.*)::_eval\(([a-zA-Z_0-9]+__Syms).*\)$/) { $verilated_mods{$1} = qr/^$1/; $pointer_mods{$2} = $1; } } #print Dumper(\%pointer_mods, \%verilated_mods); # Resort by Verilog name my %vfuncs; my %groups; foreach my $func (keys %funcs) { my $pct = $funcs{$func}{pct}; my $vfunc = $func; my $design; if ($func =~ /\(([a-zA-Z_0-9]+__Syms)/) { $design = $pointer_mods{$1}; } foreach my $vde (keys %verilated_mods) { last if $design; if ($func =~ /$verilated_mods{$vde}/) { $design=$vde; last; } } if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__l?([0-9]+)\(/) { $vfunc = sprintf("VBlock %s:%d", $1, $2); $groups{type}{"Verilog Blocks under $design"} += $pct; $groups{design}{$design} += $pct; $groups{module}{$1} += $pct; } else { if ($design) { $vfunc = sprintf("VCommon %s", $func); $groups{type}{"Common code under $design"} += $pct; $groups{design}{$design} += $pct; $groups{module}{$design." common code"} += $pct; } elsif ($func =~ /^VL_[A-Z0-9_]+/ || $func =~ /^_?vl_[a-zA-Z0-9_]+/ || $func =~ /^verilated/i) { $vfunc = sprintf("VLib %s", $func); $groups{type}{'VLib'} += $pct; $groups{design}{'VLib'} += $pct; $groups{module}{'VLib'} += $pct; } elsif ($func =~ /^_mcount_private/) { $vfunc = sprintf("Prof %s", $func); $groups{type}{'Prof'} += $pct; $groups{design}{'Prof'} += $pct; $groups{module}{'Prof'} += $pct; } else { $vfunc = sprintf("C++ %s", $func); $groups{type}{'C++'} += $pct; $groups{design}{'C++'} += $pct; $groups{module}{'C++'} += $pct; } } $vfuncs{$vfunc} = $funcs{$func}; } foreach my $type (qw(type design module)) { my $missing = 100; foreach (sort (keys %{$groups{$type}})) { $missing -= $groups{$type}{$_}; } if ($missing) { $groups{$type}{"\377Unaccounted for/rounding error"} = $missing; } print("Overall summary by $type:\n"); printf(" %-6s %s\n","% time",$type); foreach my $what (sort (keys %{$groups{$type}})) { (my $pwhat = $what) =~ s/^\377//; # Just used to establish sort order printf(" %6.2f %s\n", $groups{$type}{$what}, $pwhat); } print("\n"); } print("Verilog code profile:\n"); print(" These are split into three categories:\n"); print(" C++: Time in non-Verilated C++ code\n"); print(" Prof: Time in profile overhead\n"); print(" VBlock: Time attributable to a block in a Verilog file and line\n"); print(" VCommon: Time in a Verilated module, due to all parts of the design\n"); print(" VLib: Time in Verilated common libraries, called by the Verilated code\n"); print("\n"); print(" % cumulative self \n"); print(" time seconds seconds calls type filename and line number\n"); my $cume = 0; foreach my $func (sort {$vfuncs{$b}{sec} <=> $vfuncs{$a}{sec} || $a cmp $b} (keys %vfuncs)) { $cume += $vfuncs{$func}{sec}; printf +("%6.2f %9.2f %8.2f %8d %s\n", $vfuncs{$func}{pct}, $cume, $vfuncs{$func}{sec}, $vfuncs{$func}{calls}, $func); } } ####################################################################### __END__ =pod =head1 NAME verilator_profcfunc - Read gprof report created with --profile-cfuncs =head1 SYNOPSIS verilator --profile-cfuncs .... gcc --ggdb -pg .... {run executable} gprof verilator_profcfuncs gprof.out =head1 DESCRIPTION Verilator_profcfunc reads a profile report created by gprof. The names of the functions are then transformed, assuming the user used verilator's --profile-cfuncs, and a report printed showing the percentage of time, etc, in each Verilog block. =head1 ARGUMENTS =over 4 =item --help Displays this message and program version and exits. =back =head1 DISTRIBUTION The latest version is available from L. Copyright 2007-2015 by Wilson Snyder. Verilator 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. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO C =cut ###################################################################### ### Local Variables: ### compile-command: "$V4/bin/verilator_profcfunc $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree" ### End: verilator-3.874/bin/verilator0000775000177100017500000043575412525172076016261 0ustar wsnyderwsnyder: # -*-Mode: perl;-*- use perl, wherever it is eval 'exec perl -wS $0 ${1+"$@"}' if 0; ###################################################################### # # Copyright 2003-2015 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ###################################################################### require 5.006_001; use warnings; BEGIN { if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) { # Magic to allow author testing of perl packages in local directory require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT}; } } use Getopt::Long; use FindBin qw($RealBin $RealScript); use IO::File; use Pod::Usage; use strict; use vars qw ($Debug @Opt_Verilator_Sw); ####################################################################### ####################################################################### # main autoflush STDOUT 1; autoflush STDERR 1; $Debug = 0; my $opt_gdb; my $opt_gdbbt; # No arguments can't do anything useful. Give help if ($#ARGV < 0) { pod2usage(-exitstatus=>2, -verbose=>0); } # Insert debugging options up front push @ARGV, (split ' ',$ENV{VERILATOR_TEST_FLAGS}||""); # We sneak a look at the flags so we can do some pre-environment checks # All flags will hit verilator... foreach my $sw (@ARGV) { $sw = "'$sw'" if $sw =~ m![^---a-zA-Z0-9_/\\:.+]!; push @Opt_Verilator_Sw, $sw; } Getopt::Long::config ("no_auto_abbrev","pass_through"); if (! GetOptions ( # Major operating modes "help" => \&usage, "debug:s" => \&debug, # "version!" => \&version, # Also passthru'ed # Switches "gdb!" => \$opt_gdb, "gdbbt!" => \$opt_gdbbt, # Additional parameters "<>" => sub {}, # Ignored )) { pod2usage(-exitstatus=>2, -verbose=>0); } # Determine runtime flags and run if ($opt_gdbbt && !gdb_works()) { warn "-Info: --gdbbt ignored: gdb doesn't seem to be working\n" if $Debug; $opt_gdbbt = 0; } if ($opt_gdb) { # Generic GDB interactive run (("gdb"||$ENV{VERILATOR_GDB}) ." ".verilator_bin() ." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'" ." -ex 'set width 0'" ." -ex 'bt'"); } elsif ($opt_gdbbt && $Debug) { # Run under GDB to get gdbbt run ("gdb" ." ".verilator_bin() ." --batch --quiet --return-child-result" ." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'" ." -ex 'set width 0'" ." -ex 'bt'"); } else { # Normal, non gdb run (verilator_bin() ." ".join(' ',@Opt_Verilator_Sw)); } #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); } sub debug { shift; my $level = shift; $Debug = $level||3; } ####################################################################### ####################################################################### # Builds sub verilator_bin { my $bin = ""; # Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path my $basename = ($ENV{VERILATOR_BIN} || ($Debug ? "verilator_bin_dbg" : "verilator_bin")); if (defined($ENV{VERILATOR_ROOT})) { my $dir = $ENV{VERILATOR_ROOT}; if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT $bin = "$dir/bin/$basename"; } else { $bin = "$dir/$basename"; # From pointing to kit directory } } else { if (-x "$RealBin/$basename") { $bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed } else { $bin = $basename; # Find in PATH } # Note we don't look under bin/$basename which would be right if running # in the kit dir. Running that would likely break, since # VERILATOR_ROOT wouldn't be set and Verilator won't find internal files. } return $bin; } ####################################################################### ####################################################################### # Utilities sub gdb_works { $! = undef; # Cleanup -x system("gdb /bin/echo" ." --batch-silent --quiet --return-child-result" ." -ex 'run -n'" # `echo -n` ." -ex 'set width 0'" ." -ex 'bt'"); my $status = $?; return $status==0; } sub run { # Run command, check errors my $command = shift; $! = undef; # Cleanup -x print "\t$command\n" if $Debug>=3; system($command); my $status = $?; if ($status) { if ($! =~ /no such file or directory/i) { warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n"; } if ($Debug) { # For easy rerunning warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n"; warn "%Error: $command\n"; } if ($status & 127) { if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug; } elsif (($status & 127) == 6) { # SIGABRT warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug; } else { warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug; } } die "%Error: Command Failed $command\n"; } } ####################################################################### ####################################################################### package main; __END__ =pod =head1 NAME Verilator - Convert Verilog code to C++/SystemC =head1 SYNOPSIS verilator --help verilator --version verilator --cc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so] verilator --sc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so] verilator --lint-only [top_level.v]... =head1 DESCRIPTION Verilator converts synthesizable (not behavioral) Verilog code, plus some Synthesis, SystemVerilog and a small subset of Verilog AMS assertions, into C++ or SystemC code. It is not a complete simulator, but a compiler. Verilator is invoked with parameters similar to GCC, Cadence Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage and waveform tracing code. For C++ and SystemC formats, it outputs .cpp and .h files. The files created by Verilator are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module, and passes this filename on the command line. These C files are compiled in C++, and linked with the Verilated files. The resulting executable will perform the actual simulation. To get started, jump down to "EXAMPLE C++ EXECUTION". =head1 ARGUMENT SUMMARY This is a short summary of the arguments to Verilator. See the detailed descriptions in the next sections for more information. {file.v} Verilog top level filenames {file.c/cc/cpp} Optional C++ files to compile in {file.a/o/so} Optional C++ files to link in +1364-1995ext+ Use Verilog 1995 with file extension +1364-2001ext+ Use Verilog 2001 with file extension +1364-2005ext+ Use Verilog 2005 with file extension +1800-2005ext+ Use SystemVerilog 2005 with file extension +1800-2009ext+ Use SystemVerilog 2009 with file extension +1800-2012ext+ Use SystemVerilog 2012 with file extension --assert Enable all assertions --autoflush Flush streams after all $displays --bbox-sys Blackbox unknown $system calls --bbox-unsup Blackbox unsupported language features --bin Override Verilator binary -CFLAGS C++ Compiler flags for makefile --cc Create C++ output --cdc Clock domain crossing analysis --clk Mark specified signal as clock --compiler Tune for specified C++ compiler --converge-limit Tune convergence settle time --coverage Enable all coverage --coverage-line Enable line coverage --coverage-toggle Enable toggle coverage --coverage-user Enable SVL user coverage --coverage-underscore Enable coverage of _signals -D[=] Set preprocessor define --debug Enable debugging --debug-check Enable debugging assertions --debugi Enable debugging at a specified level --debugi- Enable debugging a source file at a level --default-language Default language to parse +define+= Set preprocessor define --dump-tree Enable dumping .tree files --dump-treei Enable dumping .tree files at a level --dump-treei- Enable dumping .tree file at a source file at a level -E Preprocess, but do not compile --error-limit Abort after this number of errors --exe Link to create executable -F Parse options from a file, relatively -f Parse options from a file --gdb Run Verilator under GDB interactively --gdbbt Run Verilator under GDB for backtrace --help Display this help -I Directory to search for includes --if-depth Tune IFDEPTH warning +incdir+ Directory to search for includes --inhibit-sim Create function to turn off sim --inline-mult Tune module inlining -LDFLAGS Linker pre-object flags for makefile -LDLIBS Linker library flags for makefile --language Default language standard to parse +libext++[ext]... Extensions for finding modules --lint-only Lint, but do not make output --MMD Create .d dependency files --MP Create phony dependency targets --Mdir Name of output object directory --mod-prefix Name to prepend to lower classes --no-clk Prevent marking specified signal as clock --no-pins64 Don't use vluint64_t's for 33-64 bit sigs --no-skip-identical Disable skipping identical output +notimingchecks Ignored -O0 Disable optimizations -O3 High performance optimizations -O Selectable optimizations -o Name of final executable --no-order-clock-delay Disable ordering clock enable assignments --output-split Split .cpp files into pieces --output-split-cfuncs Split .cpp functions --output-split-ctrace Split tracing functions -P Disable line numbers and blanks with -E --pins-bv Specify types for top level ports --pins-sc-uint Specify types for top level ports --pins-sc-biguint Specify types for top level ports --pins-uint8 Specify types for top level ports --pipe-filter Filter all input through a script --prefix Name of top level class --profile-cfuncs Name functions for profiling --private Debugging; see docs --public Debugging; see docs --report-unoptflat Extra diagnostics for UNOPTFLAT --savable Enable model save-restore --sc Create SystemC output --stats Create statistics file --stats-vars Provide statistics on variables -sv Enable SystemVerilog parsing +systemverilogext+ Synonym for +1800-2012ext+ --top-module Name of top level input module --trace Enable waveform creation --trace-depth Depth of tracing --trace-max-array Maximum bit width for tracing --trace-max-width Maximum array depth for tracing --trace-params Enable tracing parameters --trace-structs Enable tracing structure names --trace-underscore Enable tracing of _signals -U Undefine preprocessor define --unroll-count Tune maximum loop iterations --unroll-stmts Tune maximum loop body size --unused-regexp Tune UNUSED lint signals -V Verbose version and config -v Verilog library +verilog1995ext+ Synonym for +1364-1995ext+ +verilog2001ext+ Synonym for +1364-2001ext+ -Werror- Convert warning to error -Wfuture- Disable unknown message warnings -Wno- Disable warning -Wno-lint Disable all lint warnings -Wno-style Disable all style warnings -Wno-fatal Disable fatal exit on warnings --x-assign Initially assign Xs to this value --x-initial-edge Enable initial X->0 and X->1 edge triggers -y Directory to search for modules =head1 ARGUMENTS =over 4 =item {file.v} Specifies the Verilog file containing the top module to be Verilated. =item {file.c/.cc/.cpp/.cxx} Specifies optional C++ files to be linked in with the Verilog code. If any C++ files are specified in this way, Verilator will include a make rule that generates a I executable. Without any C++ files, Verilator will stop at the I__ALL.a library, and presume you'll continue linking with make rules you write yourself. See also the -CFLAGS option. =item {file.a/.o/.so} Specifies optional object or library files to be linked in with the Verilog code, as a shorthand for -LDFLAGS "". If any files are specified in this way, Verilator will include a make rule that uses these files when linking the I executable. This generally is only useful when used with the --exe option. =item +1364-1995ext+I =item +1364-2001ext+I =item +1364-2005ext+I =item +1800-2005ext+I =item +1800-2009ext+I =item +1800-2012ext+I Specifies the language standard to be used with a specific filename extension, I. For compatibility with other simulators, see also the synonyms C<+verilog1995ext+>I, C<+verilog2001ext+>I, and C<+systemverilogext+>I. For any source file, the language specified by these options takes precedence over any language specified by the C<--default-language> or C<--language> options. These options take effect in the order they are encountered. Thus the following would use Verilog 1995 for C and Verilog 2001 for C. verilator ... +1364-1995ext+v a.v +1364-2001ext+v b.v These flags are only recommended for legacy mixed language designs, as the preferable option is to edit the code to repair new keywords, or add appropriate C<`begin_keywords>. B C<`begin_keywords> is a SystemVerilog construct, which specifies I which the set of keywords is to be recognized. Whatever set is chosen, the semantics will be those of SystemVerilog. By contrast C<+1364-1995ext+> etc. specify both the syntax I semantics to be used. =item --assert Enable all assertions. See also --x-assign and --x-initial-edge; setting "--x-assign unique" and/or "--x-initial-edge" may be desirable. =item --autoflush After every $display or $fdisplay, flush the output stream. This insures that messages will appear immediately but may reduce performance; for best performance call "fflush(stdout)" occasionally in the main C loop. Defaults off, which will buffer output as provided by the normal C stdio calls. =item --bbox-sys Black box any unknown $system task or function calls. System tasks will be simply NOPed, and system functions will be replaced by unsized zero. Arguments to such functions will be parsed, but not otherwise checked. This prevents errors when linting in the presence of company specific PLI calls. =item --bbox-unsup Black box some unsupported language features, currently UDP tables and the cmos and tran gate primitives. This may enable linting the rest of the design even when unsupported constructs are present. =item --bin I Rarely needed. Override the default filename for Verilator itself. When a dependency (.d) file is created, this filename will become a source dependency, such that a change in this binary will have make rebuild the output files. =item -CFLAGS I Add specified C compiler flags to the generated makefiles. When make is run on the generated makefile these will be passed to the C++ compiler (gcc/g++/msvc++). =item --cc Specifies C++ without SystemC output mode; see also --sc. =item --cdc Experimental. Perform some clock domain crossing checks and issue related warnings (CDCRSTLOGIC) and then exit; if warnings other than CDC warnings are needed make a second run with --lint-only. Additional warning information is also written to the file {prefix}__cdc.txt. Currently only checks some items that other CDC tools missed; if you have interest in adding more traditional CDC checks, please contact the authors. =item --clk I Sometimes it is quite difficult for Verilator to distinguish clock signals from other data signals. Occasionally the clock signals can end up in the checking list of signals which determines if further evaluation is needed. This will heavily degrade the performance of verilated model. With --clk , user can specified root clock into the model, then Verilator will mark the signal as clocker and propagate the clocker attribute automatically to other signals derived from that. In this way, Verilator will try to avoid taking the clocker signal into checking list. Note signal-name is specified by the RTL hiearchy path. For example, v.foo.bar. If the signal is the input to top-module, the directly the signal name. If you find it difficult to find the exact name, try to use C in RTL file to mark the signal directly. =item --compiler I Enables tunings and work-arounds for the specified C++ compiler. =over 4 =item clang Tune for clang. This may reduce execution speed as it enables several workarounds to avoid silly hardcoded limits in clang. This includes breaking deep structures as for msvc as described below. =item gcc Tune for Gnu C++, although generated code should work on almost any compliant C++ compiler. Currently the default. =item msvc Tune for Microsoft Visual C++. This may reduce execution speed as it enables several workarounds to avoid silly hardcoded limits in MSVC++. This includes breaking deeply nested parenthesized expressions into sub-expressions to avoid error C1009, and breaking deep blocks into functions to avoid error C1061. =back =item --converge-limit Rarely needed. Specifies the maximum number of runtime iterations before creating a model failed to converge error. Defaults to 100. =item --coverage Enables all forms of coverage, alias for "--coverage-line --coverage-toggle --coverage-user". =item --coverage-line Specifies basic block line coverage analysis code should be inserted. Coverage analysis adds statements at each code flow change point, which are the branches of IF and CASE statements, a super-set of normal Verilog Line Coverage. At each such branch a unique counter is incremented. At the end of a test, the counters along with the filename and line number corresponding to each counter are written into logs/coverage.pl. Verilator automatically disables coverage of branches that have a $stop in them, as it is assumed $stop branches contain an error check that should not occur. A /*verilator coverage_block_off*/ comment will perform a similar function on any code in that block or below, or /*verilator coverage_on/coverage_off*/ will disable coverage around lines of code. Note Verilator may over-count combinatorial (non-clocked) blocks when those blocks receive signals which have had the UNOPTFLAT warning disabled; for most accurate results do not disable this warning when using coverage. =item --coverage-toggle Specifies signal toggle coverage analysis code should be inserted. Every bit of every signal in a module has a counter inserted. The counter will increment on every edge change of the corresponding bit. Signals that are part of tasks or begin/end blocks are considered local variables and are not covered. Signals that begin with underscores, are integers, or are very wide (>256 bits total storage across all dimensions) are also not covered. Hierarchy is compressed, such that if a module is instantiated multiple times, coverage will be summed for that bit across ALL instantiations of that module with the same parameter set. A module instantiated with different parameter values is considered a different module, and will get counted separately. Verilator makes a minimally-intelligent decision about what clock domain the signal goes to, and only looks for edges in that clock domain. This means that edges may be ignored if it is known that the edge could never be seen by the receiving logic. This algorithm may improve in the future. The net result is coverage may be lower than what would be seen by looking at traces, but the coverage is a more accurate representation of the quality of stimulus into the design. There may be edges counted near time zero while the model stabilizes. It's a good practice to zero all coverage just before releasing reset to prevent counting such behavior. A /*verilator coverage_off/on */ comment pair can be used around signals that do not need toggle analysis, such as RAMs and register files. =item --coverage-underscore Enable coverage of signals that start with an underscore. Normally, these signals are not covered. See also --trace-underscore. =item --coverage-user Enables user inserted functional coverage. Currently, all functional coverage points are specified using SVA which must be separately enabled with --assert. For example, the following statement will add a coverage point, with the comment "DefaultClock": DefaultClock: cover property (@(posedge clk) cyc==3); =item -DI=I Defines the given preprocessor symbol, without allowing. Similar to +define; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility. =item --debug Select the debug built image of Verilator (if available), and enable more internal assertions (equivelent to C<--debug-check>), debugging messages (equivelent to C<--debugi 4>), and intermediate form dump files (equivilent to C<--dump-treei 3>). =item --debug-check Rarely needed. Enable internal debugging assertion checks, without changing debug verbosity. Enabled automatically when --debug specified. =item --debugi =item --debugi- Rarely needed - for developer use. Set internal debugging level globally to the specified debug level (1-10) or set the specified Verilator source file to the specified level (e.g. C<--debugi-V3Width 9>). Higher levels produce more detailed messages. =item --default-language I Select the language to be used by default when first processing each Verilog file. The language value must be "1364-1995", "1364-2001", "1364-2005", "1800-2005", "1800-2009" or "1800-2012". Any language associated with a particular file extension (see the various +Iext+ options) will be used in preference to the language specified by --default-language. The --default-language flag is only recommended for legacy code using the same language in all source files, as the preferable option is to edit the code to repair new keywords, or add appropriate C<`begin_keywords>. For legacy mixed language designs, the various +Iext+ options should be used. If no language is specified, either by this flag or +Iext+ options, then the latest SystemVerilog language (IEEE 1800-2012) is used. =item +define+I=I =item +define+I=I+I=I... Defines the given preprocessor symbol, or multiple symbols if separated by plusses. Similar to -D; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility. =item --dump-tree Rarely needed. Enable writing .tree debug files with dumping level 3, which dumps the standard critical stages. For details on the format see the Verilator Internals manual. --dump-tree is enabled automatically with --debug, so "--debug --no-dump-tree" may be useful if the dump files are large and not desired. =item --dump-treei =item --dump-treei- Rarely needed - for developer use. Set internal tree dumping level globally to a specific dumping level or set the specified Verilator source file to the specified tree dumping level (e.g. C<--dump-treei-V3Order 9>). Level 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9 enables dumping of every stage. =item -E Preprocess the source code, but do not compile, as with 'gcc -E'. Output is written to standard out. Beware of enabling debugging messages, as they will also go to standard out. =item --error-limit After this number of errors or warnings are encountered, exit. Defaults to 50. =item --exe Generate an executable. You will also need to pass additional .cpp files on the command line that implement the main loop for your simulation. =item -F I Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the directory containing the specified file. See also -f. Note -F is fairly standard across Verilog tools. =item -f I Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the current directory. See also -F. Note -f is fairly standard across Verilog tools. The file may contain // comments which are ignored to the end of the line. Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment variable. =item --gdb Run Verilator underneath an interactive GDB (or VERILATOR_GDB environment variable value) session. See also --gdbbt. =item --gdbbt If --debug is specified, run Verilator underneath a GDB process and print a backtrace on exit, then exit GDB immediately. Without --debug or if GDB doesn't seem to work, this flag is ignored. Intended for easy creation of backtraces by users; otherwise see the --gdb flag. =item --help Displays this message and program version and exits. =item -II See -y. =item --if-depth I Rarely needed. Set the depth at which the IFDEPTH warning will fire, defaults to 0 which disables this warning. =item +incdir+I See -y. =item --inhibit-sim Rarely needed. Create a "inhibitSim(bool)" function to enable and disable evaluation. This allows an upper level testbench to disable modules that are not important in a given simulation, without needing to recompile or change the SystemC modules instantiated. =item --inline-mult I Tune the inlining of modules. The default value of 2000 specifies that up to 2000 new operations may be added to the model by inlining, if more than this number of operations would result, the module is not inlined. Larger values, or a value <= 1 will inline everything, will lead to longer compile times, but potentially faster runtimes. This setting is ignored for very small modules; they will always be inlined, if allowed. =item -LDFLAGS I Add specified C linker flags to the generated makefiles. When make is run on the generated makefile these will be passed to the C++ linker (ld) *after* the primary file being linked. This flag is called -LDFLAGS as that's the traditional name in simulators; it's would have been better called LDLIBS as that's the Makefile variable it controls. (In Make, LDFLAGS is before the first object, LDLIBS after. -L libraries need to be in the Make variable LDLIBS, not LDFLAGS.) =item --language I A synonym for C<--default-langauge>, for compatibility with other tools and earlier versions of Verilator. =item +libext+I+I... Specify the extensions that should be used for finding modules. If for example module I is referenced, look in I.I. Note +libext+ is fairly standard across Verilog tools. Defaults to .v and .sv. =item --lint-only Check the files for lint violations only, do not create any other output. You may also want the -Wall option to enable messages that are considered stylistic and not enabled by default. If the design is not to be completely Verilated see also the --bbox-sys and --bbox-unsup options. =item --MMD Enable creation of .d dependency files, used for make dependency detection, similar to gcc -MMD option. On by default, use --no-MMD to disable. =item --MP When creating .d dependency files with --MMD, make phony targets. Similar to gcc -MP option. =item --Mdir I Specifies the name of the Make object directory. All generated files will be placed in this directory. If not specified, "obj_dir" is used. The directory is created if it does not exist and the parent directories exist; otherwise manually create the Mdir before calling Verilator. =item --mod-prefix I Specifies the name to prepend to all lower level classes. Defaults to the same as --prefix. =item --no-clk Prevent the specified signal from being marked as clock. See C<--clk>. =item --no-pins64 Backward compatible alias for "--pins-bv 33". =item --no-skip-identical Rarely needed. Disables skipping execution of Verilator if all source files are identical, and all output files exist with newer dates. =item +notimingchecks Ignored for compatibility with other simulators. =item -O0 Disables optimization of the model. =item -O3 Enables slow optimizations for the code Verilator itself generates (as opposed to "-CFLAGS -O3" which effects the C compiler's optimization. -O3 may reduce simulation runtimes at the cost of compile time. This currently sets --inline-mult -1. =item -OI Rarely needed. Enables or disables a specific optimizations, with the optimization selected based on the letter passed. A lowercase letter disables an optimization, an upper case letter enables it. This is intended for debugging use only; see the source code for version-dependent mappings of optimizations to -O letters. =item -o Specify the name for the final executable built if using --exe. Defaults to the --prefix if not specified. =item --no-order-clock-delay Rarely needed. Disables a bug fix for ordering of clock enables with delayed assignments. This flag should only be used when suggested by the developers. =item --output-split I Enables splitting the output .cpp/.sp files into multiple outputs. When a C++ file exceeds the specified number of operations, a new file will be created at the next function boundary. In addition, any slow routines will be placed into __Slow files. This accelerates compilation by as optimization can be disabled on the slow routines, and the remaining files can be compiled on parallel machines. Using --output-split should have only a trivial impact on performance. With GCC 3.3 on a 2GHz Opteron, --output-split 20000 will result in splitting into approximately one-minute-compile chunks. =item --output-split-cfuncs I Enables splitting functions in the output .cpp/.sp files into multiple functions. When a generated function exceeds the specified number of operations, a new function will be created. With --output-split, this will enable GCC to compile faster, at a small loss in performance that gets worse with decreasing split values. Note that this option is stronger than --output-split in the sense that --output-split will not split inside a function. =item --output-split-ctrace I Enables splitting trace functions in the output .cpp/.sp files into multiple functions. Defaults to same setting as --output-split-cfuncs. =item -P With -E, disable generation of `line markers and blank lines, similar to GCC -P flag. =item --pins64 Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64. =item --pins-bv I Specifies SystemC inputs/outputs of greater than or equal to I bits wide should use sc_bv's instead of uint32/vluint64_t's. The default is "--pins-bv 65". Versions before Verilator 3.671 defaulted to "--pins-bv 33". The more sc_bv is used, the worse for performance. Use the "/*verilator sc_bv*/" attribute to select specific ports to be sc_bv. =item --pins-sc-uint Specifies SystemC inputs/outputs of greater than 2 bits wide should use sc_uint between 2 and 64. When combined with the "--pins-sc-biguint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. =item --pins-sc-biguint Specifies SystemC inputs/outputs of greater than 65 bits wide should use sc_biguint between 65 and 512, and sc_bv from 513 upwards. When combined with the "--pins-sc-uint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. =item --pins-uint8 Specifies SystemC inputs/outputs that are smaller than the --pins-bv setting and 8 bits or less should use uint8_t instead of uint32_t. Likewise pins of width 9-16 will use uint16_t instead of uint32_t. =item --pipe-filter I Rarely needed and experimental. Verilator will spawn the specified command as a subprocess pipe, to allow the command to perform custom edits on the Verilog code before it reaches Verilator. Before reading each Verilog file, Verilator will pass the file name to the subprocess' stdin with 'read_verilog ""'. The filter may then read the file and perform any filtering it desires, and feeds the new file contents back to Verilator on stdout with 'Content-Length'. Output to stderr from the filter feeds through to Verilator's stdout and if the filter exits with non-zero status Verilator terminates. See the t/t_pipe_filter test for an example. To debug the output of the filter, try using the -E option to see preprocessed output. =item --prefix I Specifies the name of the top level class and makefile. Defaults to V prepended to the name of the --top-module switch, or V prepended to the first Verilog filename passed on the command line. =item --profile-cfuncs Modify the created C++ functions to support profiling. The functions will be minimized to contain one "basic" statement, generally a single always block or wire statement. (Note this will slow down the executable by ~5%.) Furthermore, the function name will be suffixed with the basename of the Verilog module and line number the statement came from. This allows gprof or oprofile reports to be correlated with the original Verilog source statements. =item --private Opposite of --public. Is the default; this option exists for backwards compatibility. =item --public This is only for historical debug use. Using it may result in mis-simulation of generated clocks. Declares all signals and modules public. This will turn off signal optimizations as if all signals had a /*verilator public*/ comments and inlining. This will also turn off inlining as if all modules had a /*verilator public_module*/, unless the module specifically enabled it with /*verilator inline_module*/. =item --report-unoptflat Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the 10 widest variables in the loop, and the 10 most fanned out variables in the loop. These are candidates for splitting into multiple variables to break the loop. In addition produces a GraphViz DOT file of the entire strongly connected components within the source associated with each loop. This is produced irrespective of whether --dump-tree is set. Such graphs may help in analyzing the problem, but can be very large indeed. Various commands exist for viewing and manipulating DOT files. For example the I command can be used to convert a DOT file to a PDF for printing. For example: dot -Tpdf -O Vt_unoptflat_simple_2_35_unoptflat.dot will generate a PDF Vt_unoptflat_simple_2_35_unoptflat.dot.pdf from the DOT file. =item --savable Enable including save and restore functions in the generated model. The user code must create a VerilatedSerialize or VerilatedDeserialze object then calling the << or >> operators on the generated model and any other data the process needs saved/restored. For example: void save_model(const char* filenamep) { VerilatedSave os; os.open(filenamep); os << main_time; // user code must save the timestamp, etc os << *topp; } void restore_model(const char* filenamep) { VerilatedRestore os; os.open(filenamep); os >> main_time; os >> *topp; } =item --sc Specifies SystemC output mode; see also --cc. =item --stats Creates a dump file with statistics on the design in {prefix}__stats.txt. =item --stats-vars Creates more detailed statistics including a list of all the variables by size (plain --stats just gives a count). See --stats, which is implied by this. =item -sv Specifies SystemVerilog language features should be enabled; equivalent to "--language 1800-2005". This option is selected by default, it exists for compatibility with other simulators. =item +systemverilogext+I A synonym for C<+1800-2012ext+>I. =item --top-module I When the input Verilog contains more than one top level module, specifies the name of the top level Verilog module to become the top, and sets the default for if --prefix is not used. This is not needed with standard designs with only one top. =item --trace Adds waveform tracing code to the model. Verilator will generate additional {prefix}__Trace*.cpp files that will need to be compiled. In addition verilated_vcd_sc.cpp (for SystemC traces) or verilated_vcd_c.cpp (for both) must be compiled and linked in. If using the Verilator generated Makefiles, these will be added as source targets for you. If you're not using the Verilator makefiles, you will need to add these to your Makefile manually. Having tracing compiled in may result in some small performance losses, even when waveforms are not turned on during model execution. =item --trace-depth I Specify the number of levels deep to enable tracing, for example --trace-level 1 to only see the top level's signals. Defaults to the entire model. Using a small number will decrease visibility, but greatly improve runtime and trace file size. =item --trace-max-array I Rarely needed. Specify the maximum array depth of a signal that may be traced. Defaults to 32, as tracing large arrays may greatly slow traced simulations. =item --trace-max-width I Rarely needed. Specify the maximum bit width of a signal that may be traced. Defaults to 256, as tracing large vectors may greatly slow traced simulations. =item --no-trace-params Disable tracing of parameters. =item --trace-structs Enable tracing to show the name of packed structure, union, and packed array fields, rather than a simgle combined packed bus. Due to VCD file format constraints this may result in significantly slower trace times and larger trace files. =item --trace-underscore Enable tracing of signals that start with an underscore. Normally, these signals are not output during tracing. See also --coverage-underscore. =item -UI Undefines the given preprocessor symbol. =item --unroll-count I Rarely needed. Specifies the maximum number of loop iterations that may be unrolled. See also BLKLOOPINIT warning. =item --unroll-stmts I Rarely needed. Specifies the maximum number of statements in a loop for that loop to be unrolled. See also BLKLOOPINIT warning. =item --unused-regexp I Rarely needed. Specifies a simple regexp with * and ? that if a signal name matches will suppress the UNUSED warning. Defaults to "*unused*". Setting it to "" disables matching. =item -V Shows the verbose version, including configuration information compiled into Verilator. (Similar to perl -V.) =item -v I Read the filename as a Verilog library. Any modules in the file may be used to resolve cell instantiations in the top level module, else ignored. Note -v is fairly standard across Verilog tools. =item +verilog1995ext+I =item +verilog2001ext+I Synonyms for C<+1364-1995ext+>I and C<+1364-2001ext+>I respectively =item -Wall Enable all warnings, including code style warnings that are normally disabled by default. =item -Werror-I Convert the specified warning message into an error message. This is generally to discourage users from violating important site-wide rules, for example C<-Werror-NOUNOPTFLAT>. =item -Wfuture-I Rarely needed. Suppress unknown Verilator comments or warning messages with the given message code. This is used to allow code written with pragmas for a later version of Verilator to run under a older version; add -Wfuture- arguments for each message code or comment that the new version supports which the older version does not support. =item -Wno-I Disable the specified warning message. This will override any lint_on directives in the source, i.e. the warning will still not be printed. =item -Wno-lint Disable all lint related warning messages, and all style warnings. This is equivalent to "-Wno-ALWCOMBORDER -Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEWITHX -Wno-CMPCONST -Wno-ENDLABEL -Wno-IMPLICIT -Wno-LITENDIAN -Wno-PINCONNECTEMPTY -Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED -Wno-WIDTH" plus the list shown for Wno-style. It is strongly recommended you cleanup your code rather than using this option, it is only intended to be use when running test-cases of code received from third parties. =item -Wno-style Disable all code style related warning messages (note by default they are already disabled). This is equivalent to "-Wno-DECLFILENAME -Wno-DEFPARAM -Wno-INCABSPATH -Wno-PINCONNECTEMPTY -Wno-PINNOCONNECT -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNUSED -Wno-VARHIDDEN". =item -Wno-fatal When warnings are detected, print them, but do not exit the simulator. Having warning messages in builds is sloppy. It is strongly recommended you cleanup your code, use inline lint_off, or use -Wno-... flags rather than using this option. =item -Wwarn-I Enables the specified warning message. =item -Wwarn-lint Enable all lint related warning messages (note by default they are already enabled), but do not affect style messages. This is equivalent to "-Wwarn-ALWCOMBORDER -Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX -Wwarn-CMPCONST -Wwarn-ENDLABEL -Wwarn-IMPLICIT -Wwarn-LITENDIAN -Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED -Wwarn-WIDTH". =item -Wwarn-style Enable all code style related warning messages. This is equivalent to "-Wwarn ASSIGNDLY -Wwarn-DECLFILENAME -Wwarn-DEFPARAM -Wwarn-INCABSPATH -Wwarn-PINNOCONNECT -Wwarn-SYNCASYNCNET -Wwarn-UNDRIVEN -Wwarn-UNUSED -Wwarn-VARHIDDEN". =item --x-assign 0 =item --x-assign 1 =item --x-assign fast (default) =item --x-assign unique Controls the two-state value that is replaced when an assignment to X is encountered. --x-assign=fast, the default, converts all Xs to whatever is best for performance. --x-assign=0 converts all Xs to 0s, and is also fast. --x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more likely to find reset bugs as active high logic will fire. --x-assign=unique will call a function to determine the value, this allows randomization of all Xs to find reset bugs and is the slowest, but safest for finding reset bugs in code. If using --x-assign unique, you may want to seed your random number generator such that each regression run gets a different randomization sequence. Use the system's srand48() or for Windows srand() function to do this. You'll probably also want to print any seeds selected, and code to enable rerunning with that same seed so you can reproduce bugs. B This option applies only to variables which are explicitly assigned to X in the Verilog source code. Initial values of clocks are set to 0 unless --x-initial-edge is specified. Initial values of all other state holding variables are set as though --x-assign unique had been specified. =item --x-initial-edge Enables emulation of event driven simulators which generally trigger an edge on a transition from X to 1 (C) or X to 0 (C). Thus the following code, where C is uninitialized would set C to C<1'b1> when C is first set to zero: reg res_n = 1'b0; always @(negedge rst_n) begin if (rst_n == 1'b0) begin res_n <= 1'b1; end end In Verilator, by default, uninitialized clocks are given a value of zero, so the above C block would not trigger. While it is not good practice, there are some designs that rely on X E 0 triggering a C, particularly in reset sequences. Using --x-initial-edge with Verilator will replicate this behavior. It will also ensure that X E 1 triggers a C. B Some users have reported that using this option can affect convergence, and that it may be necessary to use --converge-limit to increase the number of convergence iterations. This may be another indication of problems with the modelled design that should be addressed. =item -y I Add the directory to the list of directories that should be searched for include files or libraries. The three flags -y, +incdir and -I have similar effect; +incdir and +y are fairly standard across Verilog tools while -I is an alias for GCC compatibility. Verilator defaults to the current directory ("-y .") and any specified --Mdir, though these default paths are used after any user specified directories. This allows '-y "$(pwd)"' to be used if absolute filenames are desired for error messages instead of relative filenames. =back =head1 EXAMPLE C++ EXECUTION We'll compile this example into C++. mkdir test_our cd test_our cat <our.v module our; initial begin $display("Hello World"); $finish; end endmodule EOF cat <sim_main.cpp #include "Vour.h" #include "verilated.h" int main(int argc, char **argv, char **env) { Verilated::commandArgs(argc, argv); Vour* top = new Vour; while (!Verilated::gotFinish()) { top->eval(); } delete top; exit(0); } EOF If you installed Verilator from sources, or a tarball, but not as part of your operating system (as an RPM), first you need to point to the kit: export VERILATOR_ROOT=/path/to/where/verilator/was/installed export PATH=$VERILATOR_ROOT/bin:$PATH Now we run Verilator on our little example. verilator -Wall --cc our.v --exe sim_main.cpp We can see the source code under the "obj_dir" directory. See the FILES section below for descriptions of some of the files that were created. ls -l obj_dir We then can compile it cd obj_dir make -j -f Vour.mk Vour (Verilator included a default compile rule and link rule, since we used --exe and passed a .cpp file on the Verilator command line. You can also write your own compile rules, as we'll show in the SYSTEMC section.) And now we run it cd .. obj_dir/Vour And we get as output Hello World - our.v:2: Verilog $finish Really, you're better off writing a Makefile to do all this for you. Then, when your source changes it will automatically run all of these steps. See the test_c directory in the distribution for an example. =head1 EXAMPLE SYSTEMC EXECUTION This is an example similar to the above, but using SystemC. mkdir test_our_sc cd test_our_sc cat <our.v module our (clk); input clk; // Clock is required to get initial activation always @ (posedge clk) begin $display("Hello World"); $finish; end endmodule EOF cat <sc_main.cpp #include "Vour.h" int sc_main(int argc, char **argv) { Verilated::commandArgs(argc, argv); sc_clock clk ("clk",10, 0.5, 3, true); Vour* top; top = new Vour("top"); // SP_CELL (top, Vour); top->clk(clk); // SP_PIN (top, clk, clk); while (!Verilated::gotFinish()) { sc_start(1, SC_NS); } delete top; exit(0); } EOF If you installed Verilator from sources, or a tarball, but not as part of your operating system (as an RPM), first you need to point to the kit: export VERILATOR_ROOT=/path/to/where/verilator/was/installed export PATH=$VERILATOR_ROOT/bin:$PATH Now we run Verilator on our little example. verilator -Wall --sc our.v We then can compile it make -j -f Vour.mk Vour__ALL.a make -j -f Vour.mk ../sc_main.o verilated.o And link with SystemC. Note your path to the libraries may vary, depending on the operating system. export SYSTEMC_LIBDIR=/path/to/where/libsystemc.a/exists export LD_LIBRARY_PATH=$SYSTEMC_LIBDIR:$LD_LIBRARY_PATH # Might be needed if SystemC 2.3.0 export SYSTEMC_CXX_FLAGS=-pthread g++ -L$SYSTEMC_LIBDIR ../sc_main.o Vour__ALL*.o verilated.o \ -o Vour -lsystemc And now we run it cd .. obj_dir/Vour And we get the same output as the C++ example: Hello World - our.v:2: Verilog $finish Really, you're better off using a Makefile to do all this for you. Then, when your source changes it will automatically run all of these steps. See the test_sc directory in the distribution for an example. =head1 BENCHMARKING & OPTIMIZATION For best performance, run Verilator with the "-O3 --x-assign=fast --noassert" flags. The -O3 flag will require longer compile times, and --x-assign=fast may increase the risk of reset bugs in trade for performance; see the above documentation for these flags. Minor Verilog code changes can also give big wins. You should not have any UNOPTFLAT warnings from Verilator. Fixing these warnings can result in huge improvements; one user fixed their one UNOPTFLAT warning by making a simple change to a clock latch used to gate clocks and gained a 60% performance improvement. Beyond that, the performance of a Verilated model depends mostly on your C++ compiler and size of your CPU's caches. By default, the lib/verilated.mk file has optimization turned off. This is for the benefit of new users, as it improves compile times at the cost of runtimes. To add optimization as the default, set one of three variables, OPT, OPT_FAST, or OPT_SLOW lib/verilated.mk. Or, use the -CFLAGS and/or -LDFLAGS option on the verilator command line to pass the flags directly to the compiler or linker. Or, just for one run, pass them on the command line to make: make OPT_FAST="-O2" -f Vour.mk Vour__ALL.a OPT_FAST specifies optimizations for those programs that are part of the fast path, mostly code that is executed every cycle. OPT_SLOW specifies optimizations for slow-path files (plus tracing), which execute only rarely, yet take a long time to compile with optimization on. OPT specifies overall optimization and affects all compiles, including those OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2", and link with "-static". Nearly the same results can be had with much better compile times with OPT_FAST="-O1 -fstrict-aliasing". Higher optimization such as "-O3" may help, but gcc compile times may be excessive under O3 on even medium sized designs. Alternatively, some larger designs report better performance using "-Os". Unfortunately, using the optimizer with SystemC files can result in compiles taking several minutes. (The SystemC libraries have many little inlined functions that drive the compiler nuts.) For best results, use GCC 3.3 or newer. GCC 3.2 and earlier have optimization bugs around pointer aliasing detection, which can result in 2x performance losses. If you will be running many simulations on a single compile, investigate feedback driven compilation. With GCC, using -fprofile-arcs, then -fbranch-probabilities will yield another 15% or so. Modern compilers also support link-time optimization (LTO), which can help especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in both compilation and link. Note LTO may cause excessive compile times on large designs. If you are using your own makefiles, you may want to compile the Verilated code with -DVL_INLINE_OPT=inline. This will inline functions, however this requires that all cpp files be compiled in a single compiler run. You may uncover further tuning possibilities by profiling the Verilog code. Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run either oprofile or gprof to see where in the C++ code the time is spent. Run the gprof output through verilator_profcfunc and it will tell you what Verilog line numbers on which most of the time is being spent. When done, please let the author know the results. I like to keep tabs on how Verilator compares, and may be able to suggest additional improvements. =head1 FILES All output files are placed in the output directory name specified with the -Mdir option, or "obj_dir" if not specified. Verilator creates the following files in the output directory: {prefix}.mk // Make include file for compiling {prefix}_classes.mk // Make include file with class names For -cc and -sc mode, it also creates: {prefix}.cpp // Top level C++ file {prefix}.h // Top level header {prefix}{each_verilog_module}.cpp // Lower level internal C++ files {prefix}{each_verilog_module}.h // Lower level internal header files In certain optimization modes, it also creates: {prefix}__Dpi.h // DPI import and export declarations {prefix}__Inlines.h // Inline support functions {prefix}__Slow.cpp // Constructors and infrequent routines {prefix}__Syms.cpp // Global symbol table C++ {prefix}__Syms.h // Global symbol table header {prefix}__Trace.cpp // Wave file generation code (--trace) {prefix}__cdc.txt // Clock Domain Crossing checks (--cdc) {prefix}__stats.txt // Statistics (--stats) It also creates internal files that can be mostly ignored: {each_verilog_module}.vpp // Post-processed verilog (--debug) {prefix}.flags_vbin // Verilator dependencies {prefix}.flags_vpp // Pre-processor dependencies {prefix}__verFiles.dat // Timestamps for skip-identical {prefix}{misc}.d // Make dependencies (-MMD) {prefix}{misc}.dot // Debugging graph files (--debug) {prefix}{misc}.tree // Debugging files (--debug) After running Make, the C++ compiler should produce the following: {prefix} // Final executable (w/--exe argument) {prefix}__ALL.a // Library of all Verilated objects {prefix}{misc}.o // Intermediate objects =head1 ENVIRONMENT =over 4 =item LD_LIBRARY_PATH A generic Linux/OS variable specifying what directories have shared object (.so) files. This path should include SystemC and any other shared objects needed at runtime. =item OBJCACHE Optionally specifies a caching or distribution program to place in front of all runs of the C++ Compiler. For example, "objcache --read --write", or "ccache". If using distcc, it would generally be run under either objcache or ccache; see the documentation for those programs. =item SYSTEMC Deprecated. Used only if SYSTEMC_INCLUDE or SYSTEMC_LIBDIR is not set. If set, specifies the directory containing the SystemC distribution. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). =item SYSTEMC_ARCH Deprecated. Used only if SYSTEMC_LIBDIR is not set. Specifies the architecture name used by the SystemC kit. This is the part after the dash in the lib-{...} directory name created by a 'make' in the SystemC distribution. If not set, Verilator will try to intuit the proper setting, or use the default optionally specified at configure time (before Verilator was compiled). =item SYSTEMC_CXX_FLAGS Specifies additional flags that are required to be passed to GCC when building the SystemC model. System 2.3.0 may need this set to "-pthread". =item SYSTEMC_INCLUDE If set, specifies the directory containing the systemc.h header file. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/include. =item SYSTEMC_LIBDIR If set, specifies the directory containing the libsystemc.a library. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/lib-SYSTEMC_ARCH. =item VCS_HOME If set, specifies the directory containing the Synopsys VCS distribution. When set, a 'make test' in the Verilator distribution will also run VCS baseline regression tests. =item VERILATOR_BIN If set, specifies an alternative name of the Verilator binary. May be used for debugging and selecting between multiple operating system builds. =item VERILATOR_GDB If set, the command to run when using the --gdb option, such as "ddd". If not specified, it will use "gdb". =item VERILATOR_ROOT Specifies the directory containing the distribution kit. This is used to find the executable, Perl library, and include files. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). It should not be specified if using a pre-compiled Verilator RPM as the hardcoded value should be correct. =back =head1 CONNECTING TO C++ Verilator creates a .h and .cpp file for the top level module and all modules under it. See the test_c directory in the kit for an example. After the modules are completed, there will be a I.mk file that may be used with Make to produce a I__ALL.a file with all required objects in it. This is then linked with the user's top level to create the simulation executable. The user must write the top level of the simulation. Here's a simple example: #include // Defines common routines #include "Vtop.h" // From Verilating "top.v" Vtop *top; // Instantiation of module vluint64_t main_time = 0; // Current simulation time // This is a 64-bit integer to reduce wrap over issues and // allow modulus. You can also use a double, if you wish. double sc_time_stamp () { // Called by $time in Verilog return main_time; // converts to double, to match // what SystemC does } int main(int argc, char** argv) { Verilated::commandArgs(argc, argv); // Remember args top = new Vtop; // Create instance top->reset_l = 0; // Set some inputs while (!Verilated::gotFinish()) { if (main_time > 10) { top->reset_l = 1; // Deassert reset } if ((main_time % 10) == 1) { top->clk = 1; // Toggle clock } if ((main_time % 10) == 6) { top->clk = 0; } top->eval(); // Evaluate model cout << top->out << endl; // Read a output main_time++; // Time passes... } top->final(); // Done simulating // // (Though this example doesn't get here) delete top; } Note signals are read and written as member variables of the lower module. You call the eval() method to evaluate the model. When the simulation is complete call the final() method to wrap up any SystemVerilog final blocks, and complete any assertions. =head1 CONNECTING TO SYSTEMC Verilator will convert the top level module to a SC_MODULE. This module will plug directly into a SystemC netlist. The SC_MODULE gets the same pinout as the Verilog module, with the following type conversions: Pins of a single bit become bool. Pins 2-32 bits wide become uint32_t's. Pins 33-64 bits wide become sc_bv's or vluint64_t's depending on the --no-pins64 switch. Wider pins become sc_bv's. (Uints simulate the fastest so are used where possible.) Lower modules are not pure SystemC code. This is a feature, as using the SystemC pin interconnect scheme everywhere would reduce performance by an order of magnitude. =head1 DIRECT PROGRAMMING INTERFACE (DPI) Verilator supports SystemVerilog Direct Programming Interface import and export statements. Only the SystemVerilog form ("DPI-C") is supported, not the original Synopsys-only DPI. =head2 DPI Example In the SYSTEMC example above, if you wanted to import C++ functions into Verilog, put in our.v: import "DPI-C" function integer add (input integer a, input integer b); initial begin $display("%x + %x = %x", 1, 2, add(1,2)); endtask Then after Verilating, Verilator will create a file Vour__Dpi.h with the prototype to call this function: extern int add (int a, int b); From the sc_main.cpp file (or another .cpp file passed to the Verilator command line, or the link), you'd then: #include "svdpi.h" #include "Vour__Dpi.h" int add (int a, int b) { return a+b; } =head2 DPI System Task/Functions Verilator extends the DPI format to allow using the same scheme to efficiently add system functions. Simply use a dollar-sign prefixed system function name for the import, but note it must be escaped. export "DPI-C" function integer \$myRand; initial $display("myRand=%d", $myRand()); Going the other direction, you can export Verilog tasks so they can be called from C++: export "DPI-C" task publicSetBool; task publicSetBool; input bit in_bool; var_bool = in_bool; endtask Then after Verilating, Verilator will create a file Vour__Dpi.h with the prototype to call this function: extern bool publicSetBool(bool in_bool); From the sc_main.cpp file, you'd then: #include "Vour__Dpi.h" publicSetBool(value); Or, alternatively, call the function under the design class. This isn't DPI compatible but is easier to read and better supports multiple designs. #include "Vour__Dpi.h" Vour::publicSetBool(value); // or top->publicSetBool(value); Note that if the DPI task or function accesses any register or net within the RTL, it will require a scope to be set. This can be done using the standard functions within svdpi.h, after the module is instantiated, but before the task(s) and/or function(s) are called. For example, if the top level module is instantiated with the name "dut" and the name references within tasks are all hierarchical (dotted) names with respect to that top level module, then the scope could be set with #include "svdpi.h" ... svSetScope (svGetScopeFromName ("dut")); (Remember that Verilator adds a "V" to the top of the module hierarchy.) Scope can also be set from within a DPI imported C function that has been called from Verilog by querying the scope of that function. See the sections on DPI Context Functions and DPI Header Isolation below and the comments within the svdpi.h header for more information. =head2 DPI Display Functions Verilator allows writing $display like functions using this syntax: import "DPI-C" function void \$my_display (input string formatted /*verilator sformat*/ ); The /*verilator sformat*/ indicates that this function accepts a $display like format specifier followed by any number of arguments to satisfy the format. =head2 DPI Context Functions Verilator supports IEEE DPI Context Functions. Context imports pass the simulator context, including calling scope name, and filename and line number to the C code. For example, in Verilog: import "DPI-C" context function int dpic_line(); initial $display("This is line %d, again, line %d\n", `line, dpic_line()); This will call C++ code which may then use the svGet* functions to read information, in this case the line number of the Verilog statement that invoked the dpic_line function: int dpic_line() { // Get a scope: svScope scope = svGetScope(); const char* scopenamep = svGetNameFromScope(scope); assert(scopenamep); const char* filenamep = ""; int lineno = 0; if (svGetCallerInfo(&filenamep, &lineno)) { printf("dpic_line called from scope %s on line %d\n", scopenamep, lineno); return lineno; } else { return 0; } } See the IEEE Standard for more information. =head2 DPI Header Isolation Verilator places the IEEE standard header files such as svdpi.h into a separate include directory, vltstd (VeriLaTor STandarD). When compiling most applications $VERILATOR_ROOT/include/vltstd would be in the include path along with the normal $VERILATOR_ROOT/include. However, when compiling Verilated models into other simulators which have their own svdpi.h and similar standard files with different contents, the vltstd directory should not be included to prevent picking up incompatible definitions. =head2 Public Functions Instead of DPI exporting, there's also Verilator public functions, which are slightly faster, but less compatible. =head1 VERIFICATION PROCEDURAL INTERFACE (VPI) Verilator supports a very limited subset of the VPI. This subset allows inspection, examination, value change callbacks, and depositing of values to public signals only. To access signals via the VPI, Verilator must be told exactly which signals are to be accessed. This is done using the Verilator public pragmas documented below. Verilator has an important difference from an event based simulator; signal values that are changed by the VPI will not immediately propagate their values, instead the top level header file's eval() method must be called. Normally this would be part of the normal evaluation (IE the next clock edge), not as part of the value change. This makes the performance of VPI routines extremely fast compared to event based simulators, but can confuse some test-benches that expect immediate propagation. Note the VPI by it's specified implementation will always be much slower than accessing the Verilator values by direct reference (structure->module->signame), as the VPI accessors perform lookup in functions at runtime requiring at best hundreds of instructions, while the direct references are evaluated by the compiler and result in only a couple of instructions. =head2 VPI Example In the below example, we have readme marked read-only, and writeme which if written from outside the model will have the same semantics as if it changed on the specified clock edge. module t; reg readme /*verilator public_flat_rd*/; reg writeme /*verilator public_flat_rw @(posedge clk) */; endmodule There are many online tutorials and books on the VPI, but an example that accesses the above would be: void read_and_check() { vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.readme", NULL); if (!vh1) { error... } const char* name = vpi_get_str(vpiName, vh1); printf("Module name: %s\n"); // Prints "readme" s_vpi_value v; v.format = vpiIntVal; vpi_get_value(vh1, &v); printf("Value of v: %d\n", v.value.integer); // Prints "readme" } =head1 CROSS COMPILATION Verilator supports cross-compiling Verilated code. This is generally used to run Verilator on a Linux system and produce C++ code that is then compiled on Windows. Cross compilation involves up to three different OSes. The build system is where you configured and compiled Verilator, the host system where you run Verilator, and the target system where you compile the Verilated code and run the simulation. Currently, Verilator requires the build and host system type to be the same, though the target system type may be different. To support this, ./configure and make Verilator on the build system. Then, run Verilator on the host system. Finally, the output of Verilator may be compiled on the different target system. To support this, none of the files that Verilator produces will reference any configure generated build-system specific files, such as config.h (which is renamed in Verilator to config_build.h to reduce confusion.) The disadvantage of this approach is that include/verilatedos.h must self-detect the requirements of the target system, rather than using configure. The target system may also require edits to the Makefiles, the simple Makefiles produced by Verilator presume the target system is the same type as the build system. =head2 Cadence NC-SystemC Models Similar to compiling Verilated designs with gcc, Verilated designs may be compiled inside other simulators that support C++ or SystemC models. One such simulator is Cadence's NC-SystemC, part of their Incisive Verification Suite. (Highly recommended.) Using the example files above, the following command will build the model underneath NC: cd obj_dir ncsc_run \ sc_main.cpp \ Vour__ALLcls.cpp \ Vour__ALLsup.cpp \ verilated.cpp For larger designs you'll want to automate this using makefiles, which pull the names of the .cpp files to compile in from the make variables generated in obj_dir/Vour_classes.mk. =head1 CONFIGURATION FILES In addition to the command line, warnings and other features may be controlled by configuration files, typically named with the .vlt extension. An example: `verilator_config lint_off -msg WIDTH lint_off -msg CASEX -file "silly_vendor_code.v" This disables WIDTH warnings globally, and CASEX for a specific file. Configuration files are parsed after the normal Verilog preprocessing, so `ifdefs, `defines, and comments may be used as if it were normal Verilog code. The grammar of configuration commands is as follows: =over 4 =item `verilator_config Take remaining text up the the next `verilog mode switch and treat it as Verilator configuration commands. =item coverage_off [-file "" [-lines [ - ]]] Disable coverage for the specified filename (or wildcard with '*' or '?', or all files if omitted) and range of line numbers (or all lines if omitted). Often used to ignore an entire module for coverage analysis purposes. =item lint_off [-msg ] [-file "" [-lines [ - ]]] Disables the specified lint warning, in the specified filename (or wildcard with '*' or '?', or all files if omitted) and range of line numbers (or all lines if omitted). Using '*' will override any lint_on directives in the source, i.e. the warning will still not be printed. If the -msg is omitted, all lint warnings are disabled. This will override all later lint warning enables for the specified region. =item tracing_off [-file "" [-lines [ - ]]] Disable waveform tracing for all future signals declared in the specified filename (or wildcard with '*' or '?', or all files if omitted) and range of line numbers (or all lines if omitted). =back =head1 LANGUAGE STANDARD SUPPORT =head2 Verilog 2001 (IEEE 1364-2001) Support Verilator supports most Verilog 2001 language features. This includes signed numbers, "always @*", generate statements, multidimensional arrays, localparam, and C-style declarations inside port lists. =head2 Verilog 2005 (IEEE 1364-2005) Support Verilator supports most Verilog 2005 language features. This includes the `begin_keywords and `end_keywords compiler directives, $clog2, and the uwire keyword. =head2 SystemVerilog 2005 (IEEE 1800-2005) Support Verilator supports ==? and !=? operators, ++ and -- in some contexts, $bits, $countones, $error, $fatal, $info, $isunknown, $onehot, $onehot0, $unit, $warning, always_comb, always_ff, always_latch, bit, byte, chandle, const, do-while, enum, export, final, import, int, interface, logic, longint, modport, package, program, shortint, struct, time, typedef, union, var, void, priority case/if, and unique case/if. It also supports .name and .* interconnection. Verilator partially supports concurrent assert and cover statements; see the enclosed coverage tests for the syntax which is allowed. =head2 SystemVerilog 2012 (IEEE 1800-2012) Support Verilator implements a full SystemVerilog 2012 preprocessor, including function call-like preprocessor defines, default define arguments, `__FILE__, `__LINE__ and `undefineall. Verilator currently has some support for SystemVerilog synthesis constructs. As SystemVerilog features enter common usage they are added; please file a bug if a feature you need is missing. =head2 Verilog AMS Support Verilator implements a very small subset of Verilog AMS (Verilog Analog and Mixed-Signal Extensions) with the subset corresponding to those VMS keywords with near equivalents in the Verilog 2005 or SystemVerilog 2009 languages. AMS parsing is enabled with "--language VAMS" or "--language 1800+VAMS". At present Verilator implements ceil, exp, floor, ln, log, pow, sqrt, string, and wreal. =head2 Synthesis Directive Assertion Support With the --assert switch, Verilator reads any "//synopsys full_case" or "//synopsys parallel_case" directives. The same applies to any "//ambit synthesis", "//cadence" or "//pragma" directives of the same form. When these synthesis directives are discovered, Verilator will either formally prove the directive to be true, or failing that, will insert the appropriate code to detect failing cases at runtime and print an "Assertion failed" error message. Verilator likewise also asserts any "unique" or "priority" SystemVerilog keywords on case statement, as well as "unique" on if statements. However, "priority if" is currently simply ignored. =head1 LANGUAGE EXTENSIONS The following additional constructs are the extensions Verilator supports on top of standard Verilog code. Using these features outside of comments or `ifdef's may break other tools. =over 4 =item `__FILE__ The __FILE__ define expands to the current filename as a string, like C++'s __FILE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!) =item `__LINE__ The __LINE__ define expands to the current filename as a string, like C++'s __LINE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!) =item `error I This will report an error when encountered, like C++'s #error. =item $c(I, ...); The string will be embedded directly in the output C++ code at the point where the surrounding Verilog code is compiled. It may either be a standalone statement (with a trailing ; in the string), or a function that returns up to a 32-bit number (without a trailing ;). This can be used to call C++ functions from your Verilog code. String arguments will be put directly into the output C++ code. Expression arguments will have the code to evaluate the expression inserted. Thus to call a C++ function, $c("func(",a,")") will result in 'func(a)' in the output C++ code. For input arguments, rather than hard-coding variable names in the string $c("func(a)"), instead pass the variable as an expression $c("func(",a,")"). This will allow the call to work inside Verilog functions where the variable is flattened out, and also enable other optimizations. If you will be reading or writing any Verilog variables inside the C++ functions, the Verilog signals must be declared with /*verilator public*/. You may also append an arbitrary number to $c, generally the width of the output. [signal_32_bits = $c32("...");] This allows for compatibility with other simulators which require a differently named PLI function name for each different output width. =item $display, $write, $fdisplay, $fwrite, $sformat, $swrite Format arguments may use C fprintf sizes after the % escape. Per the Verilog standard, %x prints a number with the natural width, and %0x prints a number with minimum width. Verilator extends this so %5x prints 5 digits per the C standard (it's unspecified in Verilog). =item `coverage_block_off Specifies the entire begin/end block should be ignored for coverage analysis. Same as /* verilator coverage_block_off */. =item `systemc_header Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the output .h file's header. Despite the name of this macro, this also works in pure C++ code. =item `systemc_ctor Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class constructor. Despite the name of this macro, this also works in pure C++ code. =item `systemc_dtor Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class destructor. Despite the name of this macro, this also works in pure C++ code. =item `systemc_interface Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class interface. Despite the name of this macro, this also works in pure C++ code. =item `systemc_imp_header Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the header of all files for this C++ class implementation. Despite the name of this macro, this also works in pure C++ code. =item `systemc_implementation Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into a single file of the C++ class implementation. Despite the name of this macro, this also works in pure C++ code. If you will be reading or writing any Verilog variables in the C++ functions, the Verilog signals must be declared with /*verilator public*/. See also the public task feature; writing an accessor may result in cleaner code. =item `SYSTEMVERILOG The SYSTEMVERILOG, SV_COV_START and related standard defines are set by default when --language is 1800-*. =item `VERILATOR =item `verilator =item `verilator3 The VERILATOR, verilator and verilator3 defines are set by default so you may `ifdef around compiler specific constructs. =item `verilator_config Take remaining text up the the next `verilog mode switch and treat it as Verilator configuration commands. =item `verilog Switch back to processing Verilog code after a `systemc_... mode switch. The Verilog code returns to the last language mode specified with `begin_keywords, or SystemVerilog if none were specified. =item /*verilator clock_enable*/ Used after a signal declaration to indicate the signal is used to gate a clock, and the user takes responsibility for insuring there are no races related to it. (Typically by adding a latch, and running static timing analysis.) For example: reg enable_r /*verilator clock_enable*/; wire gated_clk = clk & enable_r; always_ff @ (posedge clk) enable_r <= enable_early; The clock_enable attribute will cause the clock gate to be ignored in the scheduling algorithm, sometimes required for correct clock behavior, and always improving performance. It's also a good idea to enable the IMPERFECTSCH warning, to insure all clock enables are properly recognized. =item /*verilator clocker*/ =item /*verilator no_clocker*/ Used after a signal declaration to indicate the signal is used as clock or not. This information is used by Verilator to mark the signal as clocker and propagate the clocker attribute automatically to derived signals. See C<--clk> for more information. =item /*verilator coverage_block_off*/ Specifies the entire begin/end block should be ignored for coverage analysis purposes. =item /*verilator coverage_off*/ Specifies that following lines of code should have coverage disabled. Often used to ignore an entire module for coverage analysis purposes. =item /*verilator coverage_on*/ Specifies that following lines of code should have coverage re-enabled (if appropriate --coverage flags are passed) after being disabled earlier with /*verilator coverage_off*/. =item /*verilator inline_module*/ Specifies the module the comment appears in may be inlined into any modules that use this module. This is useful to speed up simulation time with some small loss of trace visibility and modularity. Note signals under inlined submodules will be named I__DOT__I as C++ does not allow "." in signal names. When tracing such signals the tracing routines will replace the __DOT__ with the period. =item /*verilator isolate_assignments*/ Used after a signal declaration to indicate the assignments to this signal in any blocks should be isolated into new blocks. When there is a large combinatorial block that is resulting in a UNOPTFLAT warning, attaching this to the signal causing a false loop may clear up the problem. IE, with the following reg splitme /* verilator isolate_assignments*/; // Note the placement of the semicolon above always @* begin if (....) begin splitme = ....; other assignments end end Verilator will internally split the block that assigns to "splitme" into two blocks: It would then internally break it into (sort of): // All assignments excluding those to splitme always @* begin if (....) begin other assignments end end // All assignments to splitme always @* begin if (....) begin splitme = ....; end end =item /*verilator lint_off I*/ Disable the specified warning message for any warnings following the comment. =item /*verilator lint_on I*/ Re-enable the specified warning message for any warnings following the comment. =item /*verilator lint_restore*/ After a /*verilator lint_save*/, pop the stack containing lint message state. Often this is useful at the bottom of include files. =item /*verilator lint_save*/ Push the current state of what lint messages are turned on or turned off to a stack. Later meta-comments may then lint_on or lint_off specific messages, then return to the earlier message state by using /*verilator lint_restore*/. For example: // verilator lint_save // verilator lint_off SOME_WARNING ... // code needing SOME_WARNING turned off // verilator lint_restore If SOME_WARNING was on before the lint_off, it will now be restored to on, and if it was off before the lint_off it will remain off. =item /*verilator no_inline_task*/ Used in a function or task variable definition section to specify the function or task should not be inlined into where it is used. This may reduce the size of the final executable when a task is used a very large number of times. For this flag to work, the task and tasks below it must be pure; they cannot reference any variables outside the task itself. =item /*verilator public*/ (typedef enum) Used after an enum typedef declaration to indicate the emitted C code should have the enum values visible. Due to C++ language restrictions, this may only be used on 64-bit or narrower integral enumerations. typedef enum logic [2:0] { ZERO = 3'b0 } pub_t /*verilator public*/; =item /*verilator public*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will also declare this module public, otherwise use /*verilator public_flat*/. Instead of using public variables, consider instead making a DPI or public function that accesses the variable. This is nicer as it provides an obvious entry point that is also compatible across simulators. =item /*verilator public*/ (task/function) Used inside the declaration section of a function or task declaration to indicate the function or task should be made into a C++ function, public to outside callers. Public tasks will be declared as a void C++ function, public functions will get the appropriate non-void (bool, uint32_t, etc) return type. Any input arguments will become C++ arguments to the function. Any output arguments will become C++ reference arguments. Any local registers/integers will become function automatic variables on the stack. Wide variables over 64 bits cannot be function returns, to avoid exposing complexities. However, wide variables can be input/outputs; they will be passed as references to an array of 32-bit numbers. Generally, only the values of stored state (flops) should be written, as the model will NOT notice changes made to variables in these functions. (Same as when a signal is declared public.) You may want to use DPI exports instead, as it's compatible with other simulators. =item /*verilator public_flat*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will not declare this module public, which means the name of the signal or path to it may change based upon the module inlining which takes place. =item /*verilator public_flat_rd*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat (see above), but read-only. =item /*verilator public_flat_rw @() */ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat_rd (see above), and also writable, where writes should be considered to have the timing specified by the given sensitivity edge list. =item /*verilator public_module*/ Used after a module statement to indicate the module should not be inlined (unless specifically requested) so that C code may access the module. Verilator automatically sets this attribute when the module contains any public signals or `systemc_ directives. Also set for all modules when using the --public switch. =item /*verilator sc_clock*/ Rarely needed. Used after an input declaration to indicate the signal should be declared in SystemC as a sc_clock instead of a bool. This was needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require clock pins to be sc_clocks and this is no longer needed. =item /*verilator sc_bv*/ Used after a port declaration. It sets the port to be of sc_bv> type, instead of bool, vluint32_t or vluint64_t. This may be useful if the port width is parametrized and different of such modules interface a templated module (such as a transactor) or for other reasons. In general you should avoid using this attribute when not necessary as with increasing usage of sc_bv the performance increases significantly. =item /*verilator sformat*/ Attached to the final input of a function or task "input string" to 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 tracing_off*/ Disable waveform tracing for all future signals that are declared in this module, or cells below this module. Often this is placed just after a primitive's module statement, so that the entire module and cells below it are not traced. =item /*verilator tracing_on*/ Re-enable waveform tracing for all future signals or cells that are declared. =back =head1 LANGUAGE LIMITATIONS There are some limitations and lack of features relative to a commercial simulator, by intent. User beware. It is strongly recommended you use a lint tool before running this program. Verilator isn't designed to easily uncover common mistakes that a lint program will find for you. =head2 Synthesis Subset Verilator supports only the Synthesis subset with a few minor additions such as $stop, $finish and $display. That is, you cannot use hierarchical references, events or similar features of the Verilog language. It also simulates as Synopsys's Design Compiler would; namely a block of the form: always @ (x) y = x & z; This will recompute y when there is even a potential for change in x or a change in z, that is when the flops computing x or z evaluate (which is what Design Compiler will synthesize.) A compliant simulator would only calculate y if x changes. Use verilog-mode's /*AS*/ or Verilog 2001's always @* to reduce missing activity items. Avoid putting $displays in combo blocks, as they may print multiple times when not desired, even on compliant simulators as event ordering is not specified. =head2 Bind Verilator only supports "bind" to a target module name, not an instance path. =head2 Dotted cross-hierarchy references Verilator supports dotted references to variables, functions and tasks in different modules. However, references into named blocks and function-local variables are not supported. The portion before the dot must have a constant value; for example a[2].b is acceptable, while a[x].b is not. References into generated and arrayed instances use the instance names specified in the Verilog standard; arrayed instances are named {cellName}[{instanceNumber}] in Verilog, which becomes {cellname}__BRA__{instanceNumber}__KET__ inside the generated C++ code. Verilator creates numbered "genblk" when a begin: name is not specified around a block inside a generate statement. These numbers may differ between other simulators, but the Verilog specification does not allow users to use these names, so it should not matter. If you are having trouble determining where a dotted path goes wrong, note that Verilator will print a list of known scopes to help your debugging. =head2 Floating Point Floating Point (real) numbers are supported. =head2 Latches Verilator is optimized for edge sensitive (flop based) designs. It will attempt to do the correct thing for latches, but most performance optimizations will be disabled around the latch. =head2 Structures and Unions Verilator only presently supports packed structs and packed unions. Rand and randc tags on members are simply ignored. All structures and unions are represented as a single vector, which means that generating one member of a structure from blocking, and another from non-blocking assignments is unsupported. =head2 Time All delays (#) are ignored, as they are in synthesis. =head2 Unknown states Verilator is mostly a two state simulator, not a four state simulator. However, it has two features which uncover most initialization bugs (including many that a four state simulator will miss.) Identity comparisons (=== or !==) are converted to standard ==/!== when neither side is a constant. This may make the expression result differ from a four state simulator. An === comparison to X will always be false, so that Verilog code which checks for uninitialized logic will not fire. Assigning a variable to a X will actually assign the variable to a random value (see the --x-assign switch.) Thus if the value is actually used, the random value should cause downstream errors. Integers also randomize, even though the Verilog 2001 specification says they initialize to zero. All variables are randomly initialized using a function. By running several random simulation runs you can determine that reset is working correctly. On the first run, the function initializes variables to zero. On the second, have it initialize variables to one. On the third and following runs have it initialize them randomly. If the results match, reset works. (Note this is what the hardware will really do.) In practice, just setting all variables to one at startup finds most problems. B --x-assign applies to variables explicitly initialized or assigned to X. Uninitialized clocks are initialized to zero, while all other state holding variables are initialized to a random value. Event driven simulators will generally trigger an edge on a transition from X to 1 (C) or X to 0 (C). However, by default, since clocks are initialized to zero, Verilator will not trigger an initial negedge. Some code (particulary for reset) may rely on X->0 triggering an edge. Verilator provides a switch (see --x-initial-edge) to enable this behavior. Comparing runs with and without this switch will find such problems. =head2 Tri/Inout Verilator converts some simple tristate structures into two state. Pullup, pulldown, bufif0, bufif1, notif0, notif1, pmos, nmos, tri0 and tri1 are also supported. Simple comparisons with === 1'bz are also supported. An assignment of the form: inout driver; wire driver = (enable) ? output_value : 1'bz; Will be converted to input driver; // Value being driven in from "external" drivers output driver__en; // True if driven from this module output driver__out; // Value being driven from this module External logic will be needed to combine these signals with any external drivers. Tristate drivers are not supported inside functions and tasks; an inout there will be considered a two state variable that is read and written instead of a four state variable. =head2 Functions & Tasks All functions and tasks will be inlined (will not become functions in C.) The only support provided is for simple statements in tasks (which may affect global variables). Recursive functions and tasks are not supported. All inputs and outputs are automatic, as if they had the Verilog 2001 "automatic" keyword prepended. (If you don't know what this means, Verilator will do what you probably expect -- what C does. The default behavior of Verilog is different.) =head2 Generated Clocks Verilator attempts to deal with generated and enabled clocks correctly, however some cases cause problems in the scheduling algorithm which is optimized for performance. The safest option is to have all clocks as primary inputs to the model, or wires directly attached to primary inputs. For proper behavior clock enables may also need the /*verilator clock_enable*/ attribute. =head2 Ranges must be big-bit-endian Bit ranges must be numbered with the MSB being numbered greater or the same as the LSB. Little-bit-endian busses [0:15] are not supported as they aren't easily made compatible with C++. =head2 Gate Primitives The 2-state gate primitives (and, buf, nand, nor, not, or, xnor, xor) are directly converted to behavioral equivalents. The 3-state and MOS gate primitives are not supported. Tables are not supported. =head2 Specify blocks All specify blocks and timing checks are ignored. =head2 Array Initialization When initializing a large array, you need to use non-delayed assignments. Verilator will tell you when this needs to be fixed; see the BLKLOOPINIT error for more information. =head2 Array Out of Bounds Writing a memory element that is outside the bounds specified for the array may cause a different memory element inside the array to be written instead. For power-of-2 sized arrays, Verilator will give a width warning and the address. For non-power-of-2-sizes arrays, index 0 will be written. Reading a memory element that is outside the bounds specified for the array will give a width warning and wrap around the power-of-2 size. For non-power-of-2 sizes, it will return a unspecified constant of the appropriate width. =head2 Assertions Verilator is beginning to add support for assertions. Verilator currently only converts assertions to simple "if (...) error" statements, and coverage statements to increment the line counters described in the coverage section. Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. (Arguably SEREs are much of the point, but one must start somewhere.) =head2 Language Keyword Limitations This section describes specific limitations for each language keyword. =over 4 =item `__FILE__, `__LINE__, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `define, `else, `elsif, `end_keywords, `endif, `error, `ifdef, `ifndef, `include, `line, `systemc_ctor, `systemc_dtor, `systemc_header, `systemc_imp_header, `systemc_implementation, `systemc_interface, `timescale, `undef, `verilog Fully supported. =item always, always_comb, always_ff, always_latch, and, assign, begin, buf, byte, case, casex, casez, default, defparam, do-while, else, end, endcase, endfunction, endgenerate, endmodule, endspecify, endtask, final, for, function, generate, genvar, if, initial, inout, input, int, integer, localparam, logic, longint, macromodule, module, nand, negedge, nor, not, or, output, parameter, posedge, reg, scalared, shortint, signed, supply0, supply1, task, time, tri, typedef, var, vectored, while, wire, xnor, xor Generally supported. =item ++, -- operators Increment/decrement can only be used as standalone statements or in for loops. They cannot be used as side effect operators inside more complicate expressions ("a = b++;"). =item '{} operator Assignment patterns with order based, default, constant integer (array) or member identifier (struct/union) keys are supported. Data type keys and keys which are computed from a constant expression are not supported. =item cast operator Casting is supported only between simple scalar types, signed and unsigned, not arrays nor structs. =item chandle Treated as a "longint"; does not yet warn about operations that are specified as illegal on chandles. =item disable Disable statements may be used only if the block being disabled is a block the disable statement itself is inside. This was commonly used to provide loop break and continue functionality before SystemVerilog added the break and continue keywords. =item inside Inside expressions may not include unpacked array traversal or $ as an upper bound. Case inside and case matches are also unsupported. =item interface Interfaces and modports, including with generated data types are supported. Generate blocks around modports are not supported, nor are virtual interfaces nor unnamed interfaces. =item priority if, unique if Priority and unique if's are treated as normal ifs and not asserted to be full nor unique. =item specify specparam All specify blocks and timing checks are ignored. =item string String is supported only to the point that they can be assigned, concatenated, compared, and passed to DPI imports. Standard method calls on strings are not supported. =item timeunit, timeprecision All timing control statements are ignored. =item uwire Verilator does not perform warning checking on uwires, it treats the uwire keyword as if it were the normal wire keyword. =item $bits, $countones, $error, $fatal, $finish, $info, $isunknown, $onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time, $unsigned, $warning. Generally supported. =item $display, $write, $fdisplay, $fwrite, $swrite $display and friends must have a constant format string as the first argument (as with C's printf). The rare usage which lists variables standalone without a format is not supported. =item $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc The sized display functions are rarely used and so not supported. Replace them with a $write with the appropriate format specifier. =item $finish, $stop The rarely used optional parameter to $finish and $stop is ignored. =item $fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fscanf, $fwrite File descriptors passed to the file PLI calls must be file descriptors, not MCDs, which includes the mode parameter to $fopen being mandatory. =item $fscanf, $sscanf Only integer formats are supported; %e, %f, %m, %r, %v, and %z are not supported. =item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal, $setup, $setuphold, $skew, $timeskew, $width All specify blocks and timing checks are ignored. =item $random $random does not support the optional argument to set the seed. Use the srand function in C to accomplish this, and note there is only one random number generator (not one per module). =item $readmemb, $readmemh Read memory commands should work properly. Note Verilator and the Verilog specification does not include support for readmem to multi-dimensional arrays. =item $test$plusargs, $value$plusargs Supported, but the instantiating C++/SystemC testbench must call Verilated::commandArgs(argc, argv); to register the command line before calling $test$plusargs or $value$plusargs. =item $timeformat Not supported as Verilator needs to determine all formatting at compile time. Generally you can just ifdef them out for no ill effect. Note also VL_TIME_MULTIPLER can be defined at compile time to move the decimal point when displaying all times, model wide. =back =head1 ERRORS AND WARNINGS Warnings may be disabled in two ways. First, when the warning is printed it will include a warning code. Simply surround the offending line with a warn_off/warn_on pair: // verilator lint_off UNSIGNED if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop; // verilator lint_on UNSIGNED Warnings may also be globally disabled by invoking Verilator with the C<-Wno-I> switch. This should be avoided, as it removes all checking across the designs, and prevents other users from compiling your code without knowing the magic set of disables needed to successfully compile your design. List of all warnings: =over 4 =item ALWCOMBORDER Warns that an always_comb block has a variable which is set after it is used. This may cause simulation-synthesis mismatches, as not all commercial simulators allow this ordering. always_comb begin a = b; b = 1; end Ignoring this warning will only suppress the lint check, it will simulate correctly. =item ASSIGNIN Error that an assignment is being made to an input signal. This is almost certainly a mistake, though technically legal. input a; assign a = 1'b1; Ignoring this warning will only suppress the lint check, it will simulate correctly. =item ASSIGNDLY Warns that you have an assignment statement with a delayed time in front of it, for example: a <= #100 b; assign #100 a = b; Ignoring this warning may make Verilator simulations differ from other simulators, however at one point this was a common style so disabled by default as a code style warning. =item BLKANDNBLK BLKANDNBLK is an error that a variable comes from a mix of blocked and non-blocking assignments. Generally, this is caused by a register driven by both combo logic and a flop: always @ (posedge clk) foo[0] <= ... always @* foo[1] = ... Simply use a different register for the flop: always @ (posedge clk) foo_flopped[0] <= ... always @* foo[0] = foo_flopped[0]; always @* foo[1] = ... This is good coding practice anyways. It is also possible to disable this error when one of the assignments is inside a public task. Ignoring this warning may make Verilator simulations differ from other simulators. =item BLKSEQ This indicates that a blocking assignment (=) is used in a sequential block. Generally non-blocking/delayed assignments (<=) are used in sequential blocks, to avoid the possibility of simulator races. It can be reasonable to do this if the generated signal is used ONLY later in the same block, however this style is generally discouraged as it is error prone. always @ (posedge clk) foo = ... Disabled by default as this is a code style warning; it will simulate correctly. =item BLKLOOPINIT This indicates that the initialization of an array needs to use non-delayed assignments. This is done in the interest of speed; if delayed assignments were used, the simulator would have to copy large arrays every cycle. (In smaller loops, loop unrolling allows the delayed assignment to work, though it's a bit slower than a non-delayed assignment.) Here's an example always @ (posedge clk) if (~reset_l) begin for (i=0; i<`ARRAY_SIZE; i++) begin array[i] = 0; // Non-delayed for verilator end This message is only seen on large or complicated loops because Verilator generally unrolls small loops. You may want to try increasing --unroll-count (and occasionally --unroll-stmts) which will raise the small loop bar to avoid this error. =item CASEINCOMPLETE Warns that inside a case statement there is a stimulus pattern for which there is no case item specified. This is bad style, if a case is impossible, it's better to have a "default: $stop;" or just "default: ;" so that any design assumption violations will be discovered in simulation. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item CASEOVERLAP Warns that inside a case statement you have case values which are detected to be overlapping. This is bad style, as moving the order of case values will cause different behavior. Generally the values can be respecified to not overlap. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item CASEX Warns that it is simply better style to use casez, and C in place of C's. See L Ignoring this warning will only suppress the lint check, it will simulate correctly. =item CASEWITHX Warns that a case statement contains a constant with a C. Verilator is two-state so interpret such items as always false. Note a common error is to use a C in a case or casez statement item; often what the user instead intended is to use a casez with C. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item CDCRSTLOGIC With --cdc only, warns that asynchronous flop reset terms come from other than primary inputs or flopped outputs, creating the potential for reset glitches. =item CLKDATA Warns that clock signal is mixed used with/as data signal. The checking for this warning is enabled only if user has explicitly marked some signal as clocker using command line option or in-source meta comment (see C<--clk>). The warning can be disabled without affecting the simulation result. But it is recommended to check the warning as this may degrade the performance of the Verilated model. =item CMPCONST Warns that you are comparing a value in a way that will always be constant. For example "X > 1" will always be true when X is a single bit wide. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item COMBDLY Warns that you have a delayed assignment inside of a combinatorial block. Using delayed assignments in this way is considered bad form, and may lead to the simulator not matching synthesis. If this message is suppressed, Verilator, like synthesis, will convert this to a non-delayed assignment, which may result in logic races or other nasties. See L Ignoring this warning may make Verilator simulations differ from other simulators. =item DECLFILENAME Warns that a module or other declaration's name doesn't match the filename with path and extension stripped that it is declared in. The filename a modules/interfaces/programs is declared in should match the name of the module etc. so that -y directory searching will work. This warning is printed for only the first mismatching module in any given file, and -v library files are ignored. Disabled by default as this is a code style warning; it will simulate correctly. =item DEFPARAM Warns that the "defparam" statement was deprecated in Verilog 2001 and all designs should now be using the #(...) format to specify parameters. Disabled by default as this is a code style warning; it will simulate correctly. =item DETECTARRAY Error when Verilator tries to deal with a combinatorial loop that could not be flattened, and which involves a datatype which Verilator cannot handle, such as an unpacked struct or a large unpacked array. This typically ocurrs when -Wno-UNOPTFLAT has been used to override an UNOPTFLAT warning (see below). The solution is to break the loop, as described for UNOPTFLAT. =item ENDLABEL Warns that a label attached to a "end"-something statement does not match the label attached to the block start. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item GENCLK Warns that the specified signal is generated, but is also being used as a clock. Verilator needs to evaluate sequential logic multiple times in this situation. In somewhat contrived cases having any generated clock can reduce performance by almost a factor of two. For fastest results, generate ALL clocks outside in C++/SystemC and make them primary inputs to your Verilog model. (However once need to you have even one, don't sweat additional ones.) Ignoring this warning may make Verilator simulations differ from other simulators. =item IFDEPTH Warns that if/if else statements have exceeded the depth specified with --if-depth, as they are likely to result in slow priority encoders. Unique and priority if statements are ignored. Solutions include changing the code to a case statement, or a SystemVerilog 'unique if' or 'priority if'. Disabled by default as this is a code style warning; it will simulate correctly. =item IMPERFECTSCH Warns that the scheduling of the model is not absolutely perfect, and some manual code edits may result in faster performance. This warning defaults to off, and must be turned on explicitly before the top module statement is processed. =item IMPLICIT Warns that a wire is being implicitly declared (it is a single bit wide output from a sub-module.) While legal in Verilog, implicit declarations only work for single bit wide signals (not buses), do not allow using a signal before it is implicitly declared by a cell, and can lead to dangling nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for Emacs, available from L Ignoring this warning will only suppress the lint check, it will simulate correctly. =item IMPURE Warns that a task or function that has been marked with /*verilator no_inline_task*/ references variables that are not local to the task. Verilator cannot schedule these variables correctly. Ignoring this warning may make Verilator simulations differ from other simulators. =item INCABSPATH Warns that an `include filename specifies an absolute path. This means the code will not work on any other system with a different file system layout. Instead of using absolute paths, relative paths (preferably without any directory specified whatever) should be used, and +incdir used on the command line to specify the top include source directories. Disabled by default as this is a code style warning; it will simulate correctly. =item INITIALDLY Warns that you have a delayed assignment inside of an initial or final block. If this message is suppressed, Verilator will convert this to a non-delayed assignment. See also the COMBDLY warning. Ignoring this warning may make Verilator simulations differ from other simulators. =item LITENDIAN Warns that a packed vector is declared with little endian bit numbering (i.e. [0:7]). Big endian bit numbering is now the overwhelming standard, and little numbering is now thus often due to simple oversight instead of intent. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item MODDUP Error that a module has multiple definitions. Generally this indicates a coding error, or a mistake in a library file and it's good practice to have one module per file to avoid these issues. For some gate level netlists duplicates are unavoidable, and this error may be disabled. =item MULTIDRIVEN Warns that the specified signal comes from multiple always blocks. This is often unsupported by synthesis tools, and is considered bad style. It will also cause longer runtimes due to reduced optimizations. Ignoring this warning will only slow simulations, it will simulate correctly. =item MULTITOP Error that there are multiple top level modules, that is modules not instantiated by any other module. Verilator only supports a single top level, if you need more, create a module that wraps all of the top modules. Often this error is because some low level cell is being read in, but is not really needed. The best solution is to insure that each module is in a unique file by the same name. Otherwise, make sure all library files are read in as libraries with -v, instead of automatically with -y. =item PINCONNECTEMPTY Warns that a cell instantiation has a pin which is connected to .pin_name(), e.g. not another signal, but with an explicit mention of the pin. It may be desirable to disable PINCONNECTEMPTY, as this indicates intention to have a no-connect. Disabled by default as this is a code style warning; it will simulate correctly. =item PINMISSING Warns that a module has a pin which is not mentioned in a cell instantiation. If a pin is not missing it should still be specified on the cell declaration with a empty connection, using "(.pin_name())". Ignoring this warning will only suppress the lint check, it will simulate correctly. =item PINNOCONNECT Warns that a cell instantiation has a pin which is not connected to another signal. Disabled by default as this is a code style warning; it will simulate correctly. =item REALCVT Warns that a real number is being implicitly rounded to an integer, with possible loss of precision. =item REDEFMACRO Warns that you have redefined the same macro with a different value, for example: `define MACRO def1 //... `define MACRO otherdef The best solution is to use a different name for the second macro. If this is not possible, add a undef to indicate the code is overriding the value: `define MACRO def1 //... `undef MACRO `define MACRO otherdef =item SELRANGE Warns that a selection index will go out of bounds: wire vec[6:0]; initial out = vec[7]; // There is no 7 Verilator will assume zero for this value, instead of X. Note that in some cases this warning may be false, when a condition upstream or downstream of the access means the access out of bounds will never execute or be used. wire vec[6:0]; initial begin seven = 7; ... if (seven != 7) out = vec[seven]; // Never will use vec[7] =item STMTDLY Warns that you have a statement with a delayed time in front of it, for example: #100 $finish; Ignoring this warning may make Verilator simulations differ from other simulators. =item SYMRSVDWORD Warning that a symbol matches a C++ reserved word and using this as a symbol name would result in odd C compiler errors. You may disable this warning, but the symbol will be renamed by Verilator to avoid the conflict. =item SYNCASYNCNET Warns that the specified net is used in at least two different always statements with posedge/negedges (i.e. a flop). One usage has the signal in the sensitivity list and body, probably as an async reset, and the other usage has the signal only in the body, probably as a sync reset. Mixing sync and async resets is usually a mistake. The warning may be disabled with a lint_off pragma around the net, or either flopped block. Disabled by default as this is a code style warning; it will simulate correctly. =item TASKNSVAR Error when a call to a task or function has a output from that task tied to a non-simple signal. Instead connect the task output to a temporary signal of the appropriate width, and use that signal to set the appropriate expression as the next statement. For example: task foo; output sig; ... endtask always @* begin foo(bus_we_select_from[2]); // Will get TASKNSVAR error end Change this to: reg foo_temp_out; always @* begin foo(foo_temp_out); bus_we_select_from[2] = foo_temp_out; end Verilator doesn't do this conversion for you, as some more complicated cases would result in simulator mismatches. =item UNDRIVEN Warns that the specified signal is never sourced. Verilator is fairly liberal in the usage calculations; making a signal public, or loading only a single array element marks the entire signal as driven. Disabled by default as this is a code style warning; it will simulate correctly. =item UNOPT Warns that due to some construct, optimization of the specified signal or block is disabled. The construct should be cleaned up to improve runtime. A less obvious case of this is when a module instantiates two submodules. Inside submodule A, signal I is input and signal O is output. Likewise in submodule B, signal O is an input and I is an output. A loop exists and a UNOPT warning will result if AI & AO both come from and go to combinatorial blocks in both submodules, even if they are unrelated always blocks. This affects performance because Verilator would have to evaluate each submodule multiple times to stabilize the signals crossing between the modules. Ignoring this warning will only slow simulations, it will simulate correctly. =item UNOPTFLAT Warns that due to some construct, optimization of the specified signal is disabled. The signal specified includes a complete scope to the signal; it may be only one particular usage of a multiply instantiated block. The construct should be cleaned up to improve runtime; two times better performance may be possible by fixing these warnings. Unlike the UNOPT warning, this occurs after netlist flattening, and indicates a more basic problem, as the less obvious case described under UNOPT does not apply. Often UNOPTFLAT is caused by logic that isn't truly circular as viewed by synthesis which analyzes interconnection per-bit, but is circular to simulation which analyzes per-bus: wire [2:0] x = {x[1:0],shift_in}; This statement needs to be evaluated multiple times, as a change in "shift_in" requires "x" to be computed 3 times before it becomes stable. This is because a change in "x" requires "x" itself to change value, which causes the warning. For significantly better performance, split this into 2 separate signals: wire [2:0] xout = {x[1:0],shift_in}; and change all receiving logic to instead receive "xout". Alternatively, change it to wire [2:0] x = {xin[1:0],shift_in}; and change all driving logic to instead drive "xin". With this change this assignment needs to be evaluated only once. These sort of changes may also speed up your traditional event driven simulator, as it will result in fewer events per cycle. The most complicated UNOPTFLAT path we've seen was due to low bits of a bus being generated from an always statement that consumed high bits of the same bus processed by another series of always blocks. The fix is the same; split it into two separate signals generated from each block. The UNOPTFLAT warning may also be due to clock enables, identified from the reported path going through a clock gating cell. To fix these, use the clock_enable meta comment described above. The UNOPTFLAT warning may also occur where outputs from a block of logic are independent, but occur in the same always block. To fix this, use the isolate_assignments meta comment described above. To assist in resolving UNOPTFLAT, the option C<--report-unoptflat> can be used, which will provide suggestions for variables that can be split up, and a graph of all the nodes connected in the loop. See the L section for more details. Ignoring this warning will only slow simulations, it will simulate correctly. =item UNPACKED Warns that unpacked structs and unions are not supported. Ignoring this warning will make Verilator treat the structure as packed, which may make Verilator simulations differ from other simulators. =item UNSIGNED Warns that you are comparing a unsigned value in a way that implies it is signed, for example "X < 0" will always be true when X is unsigned. Ignoring this warning will only suppress the lint check, it will simulate correctly. =item UNUSED Warns that the specified signal is never sinked. Verilator is fairly liberal in the usage calculations; making a signal public, a signal matching --unused-regexp ("*unused*") or accessing only a single array element marks the entire signal as used. Disabled by default as this is a code style warning; it will simulate correctly. A recommended style for unused nets is to put at the bottom of a file code similar to the following: wire _unused_ok = &{1'b0, sig_not_used_a, sig_not_used_yet_b, // To be fixed 1'b0}; The reduction AND and constant zeros mean the net will always be zero, so won't use simulation time. The redundant leading and trailing zeros avoid syntax errors if there are no signals between them. The magic name "unused" (-unused-regexp) is recognized by Verilator and suppresses warnings; if using other lint tools, either teach to tool to ignore signals with "unused" in the name, or put the appropriate lint_off around the wire. Having unused signals in one place makes it easy to find what is unused, and reduces the number of lint_off pragmas, reducing bugs. =item VARHIDDEN Warns that a task, function, or begin/end block is declaring a variable by the same name as a variable in the upper level module or begin/end block (thus hiding the upper variable from being able to be used.) Rename the variable to avoid confusion when reading the code. Disabled by default as this is a code style warning; it will simulate correctly. =item WIDTH Warns that based on width rules of Verilog, two operands have different widths. Verilator generally can intuit the common usages of widths, and you shouldn't need to disable this message like you do with most lint programs. Generally other than simple mistakes, you have two solutions: If it's a constant 0 that's 32 bits or less, simply leave it unwidthed. Verilator considers zero to be any width needed. Concatenate leading zeros when doing arithmetic. In the statement wire [5:0] plus_one = from[5:0] + 6'd1 + carry[0]; The best fix, which clarifies intent and will also make all tools happy is: wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]}; Ignoring this warning will only suppress the lint check, it will simulate correctly. =item WIDTHCONCAT Warns that based on width rules of Verilog, a concatenate or replication has an indeterminate width. In most cases this violates the Verilog rule that widths inside concatenates and replicates must be sized, and should be fixed in the code. wire [63:0] concat = {1,2}; An example where this is technically legal (though still bad form) is: parameter PAR = 1; wire [63:0] concat = {PAR,PAR}; The correct fix is to either size the 1 ("32'h1"), or add the width to the parameter definition ("parameter [31:0]"), or add the width to the parameter usage ("{PAR[31:0],PAR[31:0]}". =back The following describes the less obvious errors: =over 4 =item Internal Error This error should never occur first, though may occur if earlier warnings or error messages have corrupted the program. If there are no other warnings or errors, submit a bug report. =item Unsupported: .... This error indicates that you are using a Verilog language construct that is not yet supported in Verilator. See the Limitations chapter. =item Verilated model didn't converge Verilator sometimes has to evaluate combinatorial logic multiple times, usually around code where a UNOPTFLAT warning was issued, but disabled. For example: always @ (a) b=~a; always @ (b) a=b will toggle forever and thus the executable will give the didn't converge error to prevent an infinite loop. To debug this, run Verilator with --profile-cfuncs. Run make on the generated files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in your main.cpp. This will cause each change in a variable to print a message. Near the bottom you'll see the code and variable that causes the problem. For the program above: CHANGE: filename.v:1: b CHANGE: filename.v:2: a =back =head1 FAQ/FREQUENTLY ASKED QUESTIONS =over 4 =item Does it run under Windows? Yes, using Cygwin. Verilated output should also compile under Microsoft Visual C++ Version 7 or newer, but this is not tested by the author. =item Can you provide binaries? Verilator is available as a RPM for SuSE, Fedora, and perhaps other systems; this is done by porters and may slightly lag the primary distribution. If there isn't a binary build for your distribution, how about you set one up? Please contact the authors for assistance. Note people sometimes request binaries when they are having problems with their C++ compiler. Alas, binaries won't help this, as in the end a fully working C++ compiler is required to compile the output of Verilator. =item How can it be faster than (name-the-simulator)? Generally, the implied part of the question is "... with all of their manpower they can put into it." Most commercial simulators have to be Verilog compliant, meaning event driven. This prevents them from being able to reorder blocks and make netlist-style optimizations, which are where most of the gains come from. Non-compliance shouldn't be scary. Your synthesis program isn't compliant, so your simulator shouldn't have to be -- and Verilator is closer to the synthesis interpretation, so this is a good thing for getting working silicon. =item Will Verilator output remain under my own license? Yes, it's just like using GCC on your programs; this is why Verilator uses the "GNU *Lesser* Public License Version 3" instead of the more typical "GNU Public License". See the licenses for details, but in brief, if you change Verilator itself or the header files Verilator includes, you must make the source code available under the GNU Lesser Public License. However, Verilator output (the Verilated code) only "include"s the licensed files, and so you are NOT required to release any output from Verilator. You also have the option of using the Perl Artistic License, which again does not require you release your Verilog or generated code, and also allows you to modify Verilator for internal use without distributing the modified version. But please contribute back to the community! One limit is that you cannot under either license release a commercial Verilog simulation product incorporating Verilator without making the source code available. As is standard with Open Source, contributions back to Verilator will be placed under the Verilator copyright and LGPL/Artistic license. Small test cases will be released into the public domain so they can be used anywhere, large tests under the LGPL/Artistic, unless requested otherwise. =item Why is Verilation so slow? Verilator needs more memory than the resulting simulator will require, as Verilator creates internally all of the state of the resulting simulator in order to optimize it. If it takes more than a minute or so (and you're not using --debug since debug is disk bound), see if your machine is paging; most likely you need to run it on a machine with more memory. Verilator is a full 64-bit application and may use more than 4GB, but about 1GB is the maximum typically needed. =item How do I generate waveforms (traces) in C++? See the next question for tracing in SystemC mode. Add the --trace switch to Verilator, and in your top level C code, call Verilated::traceEverOn(true). Then create a VerilatedVcdC object, and in your main loop call "trace_object->dump(time)" every time step, and finally call "trace_object->close()". For an example, see below and the test_c/sim_main.cpp file of the distribution. You also need to compile verilated_vcd_c.cpp and add it to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag. Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file. #include "verilated_vcd_c.h" ... int main(int argc, char **argv, char **env) { ... Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd"); ... while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += #; tfp->dump (main_time); } tfp->close(); } =item How do I generate waveforms (traces) in SystemC? Add the --trace switch to Verilator, and in your top level C sc_main code, include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then create a VerilatedVcdSc object as you would create a normal SystemC trace file. For an example, see the call to VerilatedVcdSc in the test_sc/sc_main.cpp file of the distribution, and below. Alternatively you may use the C++ trace mechanism described in the previous question, however the timescale and timeprecision will not inherited from your SystemC settings. You also need to compile verilated_vcd_sc.cpp and verilated_vcd_c.cpp and add them to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag. Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file. #include "verilated_vcd_sc.h" ... int main(int argc, char **argv, char **env) { ... Verilated::traceEverOn(true); VerilatedVcdSc* tfp = new VerilatedVcdSc; topp->trace (tfp, 99); tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd"); ... sc_start(1); ... tfp->close(); } =item How do I view waveforms (traces)? Verilator makes standard VCD (Value Change Dump) files. They are viewable with the public domain Dinotrace or GtkWave programs, or any of the many commercial offerings. =item How do I reduce the size of large waveform (trace) files? First, instead of calling VerilatedVcdC->open at the beginning of time, delay calling it until the time stamp where you want to tracing to begin. Likewise you can also call VerilatedVcdC->open before the end of time (perhaps a short period after you detect a verification error.) Next, add /*verilator tracing_off*/ to any very low level modules you never want to trace (such as perhaps library cells). Finally, use the --trace-depth option to limit the depth of tracing, for example --trace-depth 1 to see only the top level signals. Also be sure you write your trace files to a local disk, instead of to a network disk. Network disks are generally far slower. =item How do I do coverage analysis? Verilator supports both block (line) coverage and user inserted functional coverage. First, run verilator with the --coverage option. If you're using your own makefile, compile the model with the GCC flag -DVM_COVERAGE (if using Verilator's, it will do this for you.) Run your tests in different directories. Each test will create a logs/coverage.pl file. After running all of your tests, verilator_coverage is executed. Verilator_coverage reads the logs/coverage.pl file(s), and creates an annotated source code listing showing code coverage details. For an example, after running 'make test' in the Verilator distribution, see the test_sc/logs directory. Grep for lines starting with '%' to see what lines Verilator believes need more coverage. =item Where is the translate_off command? (How do I ignore a construct?) Translate on/off pragmas are generally a bad idea, as it's easy to have mismatched pairs, and you can't see what another tool sees by just preprocessing the code. Instead, use the preprocessor; Verilator defines the "VERILATOR" define for you, so just wrap the code in an ifndef region: `ifndef VERILATOR Something_Verilator_Dislikes; `endif =item Why do I get "unexpected `do'" or "unexpected `bit'" errors? Do, bit, ref, return, and other words are now SystemVerilog keywords. You should change your code to not use them to insure it works with newer tools. Alternatively, surround them by the Verilog 2005/SystemVerilog begin_keywords pragma to indicate Verilog 2001 code. `begin_keywords "1364-2001" integer bit; initial bit = 1; `end_keywords If you want the whole file to be parsed as Verilog 2001, just create a file with `begin_keywords "1364-2001" and add it before other Verilog files on the command line. (Note this will also change the default for --prefix, so if you're not using --prefix, you will now need to.) =item How do I prevent my assertions from firing during reset? Call Verilated::assertOn(false) before you first call the model, then turn it back on after reset. It defaults to true. When false, all assertions controlled by --assert are disabled. =item Why do I get "undefined reference to `sc_time_stamp()'"? In C++ (non SystemC) code you need to define this function so that the simulator knows the current time. See the "CONNECTING TO C++" examples. =item Why do I get "undefined reference to `VL_RAND_RESET_I' or `Verilated::...'"? You need to link your compiled Verilated code against the verilated.cpp file found in the include directory of the Verilator kit. This is one target in the $(VK_GLOBAL_OBJS) make variable, which should be part of your Makefile's link rule. =item Is the PLI supported? Only somewhat. More specifically, the common PLI-ish calls $display, $finish, $stop, $time, $write are converted to C++ equivalents. You can also use the "import DPI" SystemVerilog feature to call C code (see the chapter above). There is also limited VPI access to public signals. If you want something more complex, since Verilator emits standard C++ code, you can simply write your own C++ routines that can access and modify signal values without needing any PLI interface code, and call it with $c("{any_c++_statement}"). =item How do I make a Verilog module that contain a C++ object? You need to add the object to the structure that Verilator creates, then use $c to call a method inside your object. The test_regress/t/t_extend_class files show an example of how to do this. =item How do I get faster build times? Between GCC 3.0 to 3.3, each compiled progressively slower, thus if you can use GCC 2.95, or GCC 3.4 you'll have faster builds. Two ways to cheat are to compile on parallel machines and avoid compilations altogether. See the --output-split option, and the web for the ccache, distcc and icecream packages. ccache will skip GCC runs between identical source builds, even across different users. You can use the OBJCACHE environment variable to use these CC wrappers. =item Why do so many files need to recompile when I add a signal? Adding a new signal requires the symbol table to be recompiled. Verilator uses one large symbol table, as that results in 2-3 less assembly instructions for each signal access. This makes the execution time 10-15% faster, but can result in more compilations when something changes. =item How do I access functions/tasks in C? Use the SystemVerilog Direct Programming Interface. You write a Verilog function or task with input/outputs that match what you want to call in with C. Then mark that function as an external function. See the DPI chapter in the manual. =item How do I access signals in C? The best thing is to make a SystemVerilog "export DPI task" or function that accesses that signal, as described in the DPI chapter in the manual and DPI tutorials on the web. This will allow Verilator to better optimize the model and should be portable across simulators. If you really want raw access to the signals, declare the signals you will be accessing with a /*verilator public*/ comment before the closing semicolon. Then scope into the C++ class to read the value of the signal, as you would any other member variable. Signals are the smallest of 8-bit chars, 16-bit shorts, 32-bit longs, or 64-bit long longs that fits the width of the signal. Generally, you can use just uint32_t's for 1 to 32 bits, or vluint64_t for 1 to 64 bits, and the compiler will properly up-convert smaller entities. Signals wider than 64 bits are stored as an array of 32-bit uint32_t's. Thus to read bits 31:0, access signal[0], and for bits 63:32, access signal[1]. Unused bits (for example bit numbers 65-96 of a 65-bit vector) will always be zero. if you change the value you must make sure to pack zeros in the unused bits or core-dumps may result. (Because Verilator strips array bound checks where it believes them to be unnecessary.) In the SYSTEMC example above, if you had in our.v: input clk /*verilator public*/; // Note the placement of the semicolon above From the sc_main.cpp file, you'd then: #include "Vour.h" #include "Vour_our.h" cout << "clock is " << top->v->clk << endl; In this example, clk is a bool you can read or set as any other variable. The value of normal signals may be set, though clocks shouldn't be changed by your code or you'll get strange results. =item Should a module be in Verilog or SystemC? Sometimes there is a block that just interconnects cells, and have a choice as to if you write it in Verilog or SystemC. Everything else being equal, best performance is when Verilator sees all of the design. So, look at the hierarchy of your design, labeling cells as to if they are SystemC or Verilog. Then: A module with only SystemC cells below must be SystemC. A module with a mix of Verilog and SystemC cells below must be SystemC. (As Verilator cannot connect to lower-level SystemC cells.) A module with only Verilog cells below can be either, but for best performance should be Verilog. (The exception is if you have a design that is instantiated many times; in this case Verilating one of the lower modules and instantiating that Verilated cells multiple times into a SystemC module *may* be faster.) =back =head1 BUGS First, check the the coding limitations section. Next, try the --debug switch. This will enable additional internal assertions, and may help identify the problem. Finally, reduce your code to the smallest possible routine that exhibits the bug. Even better, create a test in the test_regress/t directory, as follows: cd test_regress cp -p t/t_EXAMPLE.pl t/t_BUG.pl cp -p t/t_EXAMPLE.v t/t_BUG.v There are many hits on how to write a good test in the driver.pl documentation which can be seen by running: cd $VERILATOR_ROOT # Need the original distribution kit test_regress/driver.pl --help Edit t/t_BUG.pl to suit your example; you can do anything you want in the Verilog code there; just make sure it retains the single clk input and no outputs. Now, the following should fail: cd $VERILATOR_ROOT # Need the original distribution kit cd test_regress t/t_BUG.pl # Run on Verilator t/t_BUG.pl --debug # Run on Verilator, passing --debug to Verilator t/t_BUG.pl --vcs # Run on a commercial simulator t/t_BUG.pl --nc|--iv|--ghdl # Likewise on other simulators The test driver accepts a number of options, many of which mirror the main Verilator option. For example the previous test could have been run with debugging enabled. The full set of test options can be seen by running driver.pl --help as shown above. Finally, report the bug using the bug tracker at L. The bug will become publicly visible; if this is unacceptable, mail the bug report to C. =head1 HISTORY Verilator was conceived in 1994 by Paul Wasson at the Core Logic Group at Digital Equipment Corporation. The Verilog code that was converted to C was then merged with a C based CPU model of the Alpha processor and simulated in a C based environment called CCLI. In 1995 Verilator started being used also for Multimedia and Network Processor development inside Digital. Duane Galbi took over active development of Verilator, and added several performance enhancements. CCLI was still being used as the shell. In 1998, through the efforts of existing DECies, mainly Duane Galbi, Digital graciously agreed to release the source code. (Subject to the code not being resold, which is compatible with the GNU Public License.) In 2001, Wilson Snyder took the kit, and added a SystemC mode, and called it Verilator2. This was the first packaged public release. In 2002, Wilson Snyder created Verilator3 by rewriting Verilator from scratch in C++. This added many optimizations, yielding about a 2-5x performance gain. In 2009, major SystemVerilog and DPI language support was added. Currently, various language features and performance enhancements are added as the need arises. Verilator is now about 3x faster than in 2002, and is faster than many popular commercial simulators. =head1 AUTHORS When possible, please instead report bugs to L. Wilson Snyder Major concepts by Paul Wasson, Duane Galbi and Jie Xu. =head1 CONTRIBUTORS Many people have provided ideas and other assistance with Verilator. The major corporate sponsors of Verilator, by providing significant contributions of time or funds include include Atmel Corporation, Cavium Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc., and SiCortex Inc. The people who have contributed major functionality are Byron Bradley, Jeremy Bennett, Jie Xu, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers include Jeff Dutton, Jonathon Donaldson, Ralf Karge, David Hewson, Iztok Jeras, Wim Michiels, Alex Solomatnikov, Sebastien Van Cauwenberghe, Gene Weber, and Clifford Wolf. Some of the people who have provided ideas and feedback for Verilator include: Yves Mathieu, David Addison, Nikana Anastasiadis, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad Bagri, Andrew Bardsley, Geoff Barrett, J Baxter, Julius Baxter, Jeremy Bennett, Michael Berman, David Binderman, David Black, Daniel Bone, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Charlie Brej, Lane Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Ted Campbell, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike Denio, John Deroo, Philip Derrick, John Dickol, R. Diez, Ruben Diez, Danny Ding, Ivan Djordjevic, Jonathon Donaldson, Alex Duller, Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete, Fabrizio Ferrandi, Andrea Foletto, Bob Fredieu, Christian Gelinek, Glen Gibb, Shankar Giri, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Junji Hashimoto, Thomas Hawkins, David Hewson, Hiroki Honda, Alex Hornung, Jae Hossell, Ben Jackson, Krzysztof Jankowski, HyungKi Jeong, Iztok Jeras, James Johnson, Christophe Joly, Franck Jullien, Mike Kagen, Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Sobhan Klnv, Gernot Koch, Soon Koh, Steve Kolecki, Brett Koonce, Wojciech Koszek, Varun Koyyalagunta, David Kravitz, Roland Kruse, Ed Lander, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber, Igor Lesik, John Li, Eivind Liland, Charlie Lind, Andrew Ling, Paul Liu, Derek Lockhart, Arthur Low, Stefan Ludwig, Dan Lussier, Fred Ma, Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Wai Sum Mong, Sean Moore, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Bob Newgard, Cong Van Nguyen, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, David Pierce, Dominic Plunkett, David Poole, Rich Porter, Niranjan Prabhu, Usha Priyadharshini, Mark Jackson Pulver, Prateek Puri, Chris Randall, Frederic Requin, Alberto Del Rio, Oleg Rodionov, Jan Egil Ruud, John Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Steven Slatter, Brian Small, Wilson Snyder, Alex Solomatnikov, Art Stamness, John Stevenson, Todd Strader, John Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu Takatsukasa, Peter Tengstrand, Stefan Thiede, Gary Thomas, Kevin Thompson, Mike Thyer, Steve Tong, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston, Joshua Wise, Clifford Wolf, Johan Wouters, Ding Xiaoliang, Jie Xu, and Amir Yazdanbakhsh. Thanks to them, and all those we've missed including above. =head1 DISTRIBUTION The latest version is available from L. Copyright 2003-2015 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. =head1 SEE ALSO L, L, L, L which is the source for this document, and internals.txt in the distribution. =cut ###################################################################### verilator-3.874/bin/verilator_includer0000775000177100017500000000127112525171733020124 0ustar wsnyderwsnyder: # -*-Mode: perl;-*- use perl, wherever it is eval 'exec perl -wS $0 ${1+"$@"}' if 0; # DESCRIPTION: Print include statements for each ARGV # # Copyright 2003-2015 by Wilson Snyder. This package 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. ###################################################################### require 5.005; use warnings; print "// DESCR"."IPTION: Generated by verilator_includer via makefile\n"; foreach my $param (@ARGV) { if ($param =~ /^-D([^=]+)=(.*)/) { print "#define $1 $2\n" } else { print "#include \"$param\"\n" } } verilator-3.874/MANIFEST.SKIP0000664000177100017500000000075112525172076015433 0ustar wsnyderwsnyder^CVS/ /CVS/ \.git/ \.svn/ \.(bak|old)/ \.(bak|old)$ \.tar\. .*\.tgz .*\.log \..*\.swp .*\.tmp .*\.tex .*\.key .*\.vcd .*\.1 /obj_dir/ /obj_dbg/ /obj_opt/ /INCA_libs/ /cov_work/ /logs/ ^Makefile$ src/Makefile$ src/Makefile_obj$ include/verilated.mk$ test_regress/.gdbinit$ config.cache$ config.status$ verilator.log verilator.tex verilator.pc$ verilator_bin.* verilator_coverage_bin.* .vcsmx_rebuild$ autom4te\.cache/ nodist/ /simv$ /simv.daidir/ /vc_hdrs.h$ /csrc/ doxygen-doc/.* TAGS .*~ verilator-3.874/.gitignore0000664000177100017500000000037512525172076015527 0ustar wsnyderwsnyder*~ *.old *.gz *.gz.uu *.html *.info *.log *.1 .*.swp *.tmp *.tex *.pdf /Makefile README TAGS autom4te.cache config.cache config.status configure dddrun* doxygen-doc gdbrun* internals.txt verilator.txt verilator_bin* verilator_coverage_bin* verilator.pc verilator-3.874/test_sc/0000775000177100017500000000000012534632371015175 5ustar wsnyderwsnyderverilator-3.874/test_sc/.gitignore0000664000177100017500000000006212111011552017142 0ustar wsnyderwsnyder*.old *.dmp *.log *.csrc *.vcd obj_* logs project verilator-3.874/test_sc/Makefile_obj0000664000177100017500000000214312525171734017470 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-2015 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. # #***************************************************************************** default: simx include Vtop.mk ####################################################################### CPPFLAGS += -Wno-deprecated CPPFLAGS += $(SYSTEMC_CXX_FLAGS) LDFLAGS += $(SYSTEMC_CXX_FLAGS) ####################################################################### # Linking final exe -- presumes have a sim_main.cpp SC_LIB = $(SYSTEMC_LIBDIR)/libsystemc.a simx: sc_main.o $(VK_GLOBAL_OBJS) \ $(VM_PREFIX)__ALL.a $(SC_LIB) $(LINK) $(LDFLAGS) -g $^ $(LOADLIBES) $(LDLIBS) -o $@ $(SC_LIBS) $(LIBS) 2>&1 | c++filt sc_main.o: sc_main.cpp $(VM_PREFIX).h verilator-3.874/test_sc/sc_main.cpp0000664000177100017500000000720712525171734017321 0ustar wsnyderwsnyder// -*- SystemC -*- // DESCRIPTION: Verilator Example: Top level main for invoking SystemC model // // Copyright 2003-2015 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. //==================================================================== #include #include #include #include #include "systemc.h" // SystemC global header #include "verilated_vcd_sc.h" // Tracing #include "Vtop.h" // Top level header, generated from verilog Vtop *top; int sc_main(int argc, char* argv[]) { Verilated::commandArgs(argc, argv); Verilated::randReset(2); Verilated::debug(0); // We compiled with it on for testing, turn it back off // General logfile ios::sync_with_stdio(); // Defaults #if (SYSTEMC_VERSION>20011000) #else sc_time dut(1.0, sc_ns); sc_set_default_time_unit(dut); #endif //========== // Define the Clocks cout << "Defining Clocks\n"; #if (SYSTEMC_VERSION>=20070314) sc_clock clk ("clk", 10,SC_NS, 0.5, 3,SC_NS, true); sc_clock fastclk ("fastclk", 2,SC_NS, 0.5, 2,SC_NS, true); #else sc_clock clk ("clk", 10, 0.5, 3, true); sc_clock fastclk ("fastclk", 2, 0.5, 2, true); #endif cout << "Defining Interconnect\n"; sc_signal reset_l; sc_signal passed; sc_signal in_small; sc_signal in_quad; sc_signal > in_wide; sc_signal out_small; sc_signal out_quad; sc_signal > out_wide; //========== // Part under test Vtop* top = new Vtop("top"); top->clk (clk); top->fastclk (fastclk); top->reset_l (reset_l); top->passed (passed); top->in_small (in_small); top->in_quad (in_quad); top->in_wide (in_wide); top->out_small (out_small); top->out_quad (out_quad); top->out_wide (out_wide); //========== // Waves #if VM_TRACE // Before any evaluation, need to know to calculate those signals only used for tracing Verilated::traceEverOn(true); #endif // You must do one evaluation before enabling waves, in order to allow // SystemC to interconnect everything for testing. cout <<("Test initialization...\n"); reset_l = 1; #if (SYSTEMC_VERSION>=20070314) sc_start(1,SC_NS); #else sc_start(1); #endif //========== // Waves #if VM_TRACE cout << "Enabling waves...\n"; VerilatedVcdSc* tfp = new VerilatedVcdSc; top->trace (tfp, 99); tfp->open ("vlt_dump.vcd"); #endif //========== // Start of Test cout <<("Test beginning...\n"); reset_l = 1; while (VL_TIME_Q() < 60 && !Verilated::gotFinish()) { #if VM_TRACE // Flush the wave files each cycle so we can immediately see the output // Don't do this in "real" programs, do it in an abort() handler instead if (tfp) tfp->flush(); #endif if (VL_TIME_Q() > 10) { reset_l = 1; // Deassert reset } else if (VL_TIME_Q() > 1) { reset_l = 0; // Assert reset } #if (SYSTEMC_VERSION>=20070314) sc_start(1,SC_NS); #else sc_start(1); #endif } top->final(); //========== // Close Waves #if VM_TRACE if (tfp) tfp->close(); #endif if (!passed) { VL_PRINTF ("A Test failed!!\n"); abort(); } //========== // Coverage analysis (since test passed) mkdir("logs", 0777); #if VM_COVERAGE SpCoverage::write(); // Writes logs/coverage.pl #endif //========== // Close LogFiles cout << "*-* All Finished *-*\n"; // Magic if using perl's Log::Detect return(0); } verilator-3.874/test_sc/Makefile0000664000177100017500000000350112525171734016635 0ustar wsnyderwsnyder#***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside source directory # # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # # Copyright 2003-2015 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. # #****************************************************************************/ default: test_default # This must point to the root of the VERILATOR kit VERILATOR_ROOT := $(shell pwd)/.. export VERILATOR_ROOT # Pick up PERL and other variable settings include $(VERILATOR_ROOT)/include/verilated.mk DEBUG_ON = --debug SYSTEMC_TESTING ?= $(SYSTEMC)$(SYSTEMC_INCLUDE) ###################################################################### ifneq ($(SYSTEMC_TESTING),) test_default: precopy prep compile run test_debug: precopy prep_dbg compile run else test_default: nosc test_debug: nosc endif V_FLAGS = -f $(VERILATOR_ROOT)/test_v/input.vc VERILATOR_FLAGS = --sc $(V_FLAGS) top.v VERILATOR_FLAGS += --trace precopy: prep: $(PERL) $(VERILATOR_ROOT)/bin/verilator $(VERILATOR_FLAGS) prep_dbg: $(PERL) $(VERILATOR_ROOT)/bin/verilator $(DEBUG_ON) $(VERILATOR_FLAGS) compile: cd obj_dir ; $(MAKE) -j 3 -f ../Makefile_obj run: obj_dir/simx ###################################################################### obj_dir: mkdir $@ nosc: @echo @echo %Skip: SYSTEMC_INCLUDE not in environment @echo ###################################################################### maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir *.log *.dmp *.vpd *.vcd core verilator-3.874/COPYING.LESSER0000664000177100017500000001672512111011551015551 0ustar wsnyderwsnyder GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. verilator-3.874/internals.html0000664000177100017500000011334012534631201016407 0ustar wsnyderwsnyder NAME


NAME

Verilator Internals


INTRODUCTION

This file discusses internal and programming details for Verilator. It's the first for reference for developers and debugging problems.

See also the Verilator internals presentation at http://www.veripool.org.


CODE FLOWS

Verilator Flow

The main flow of Verilator can be followed by reading the Verilator.cpp process() function:

First, the files specified on the command line are read. Reading involves preprocessing, then lexical analysis with Flex and parsing with Bison. This produces an abstract syntax tree (AST) representation of the design, which is what is visible in the .tree files described below.

Verilator then makes a series of passes over the AST, progressively refining and optimizing it.

Cells in the AST first linked, which will read and parse additional files as above.

Functions, variable and other references are linked to their definitions.

Parameters are resolved and the design is elaborated.

Verilator then performs many additional edits and optimizations on the hierarchical design. This includes coverage, assertions, X elimination, inlining, constant propagation, and dead code elimination.

References in the design are then pseudo-flattened. Each module's variables and functions get "Scope" references. A scope reference is an occurrence of that un-flattened variable in the flattened hierarchy. A module that occurs only once in the hierarchy will have a single scope and single VarScope for each variable. A module that occurs twice will have a scope for each occurrence, and two VarScopes for each variable. This allows optimizations to proceed across the flattened design, while still preserving the hierarchy.

Additional edits and optimizations proceed on the pseudo-flat design. These include module references, function inlining, loop unrolling, variable lifetime analysis, lookup table creation, always splitting, and logic gate simplifications (pushing inverters, etc).

Verilator orders the code. Best case, this results in a single "eval" function which has all always statements flowing from top to bottom with no loops.

Verilator mostly removes the flattening, so that code may be shared between multiple invocations of the same module. It localizes variables, combines identical functions, expands macros to C primitives, adds branch prediction hints, and performs additional constant propagation.

Verilator finally writes the C++ modules.

Key Classes Used in the Verilator Flow

AstNode

The AST is represented at the top level by the class AstNode. This abstract class has derived classes for the individual components (e.g. AstGenerate for a generate block) or groups of components (e.g. AstNodeFTask for functions and tasks, which in turn has AstFunc and AstTask as derived classes).

Each AstNode has pointers to up to four children, accessed by the op1p through op4p methods. These methods are then abstracted in a specific Ast* node class to a more specific name. For example with the AstIf node (for if statements), ifsp calls op2p to give the pointer to the AST for the "then" block, while elsesp calls op3p to give the pointer to the AST for the "else" block, or NULL if there is not one.

AstNode has the concept of a next and previous AST - for example the next and previous statements in a block. Pointers to the AST for these statements (if they exist) can be obtained using the back and next methods.

It is useful to remember that the derived class AstNetlist is at the top of the tree, so checking for this class is the standard way to see if you are at the top of the tree.

By convention, each function/method uses the variable nodep as a pointer to the AstNode currently being processed.

AstNVisitor

The passes are implemented by AST visitor classes (see Visitor Functions). These are implemented by subclasses of the abstract class, AstNVisitor. Each pass creates an instance of the visitor class, which in turn implements a method to perform the pass.

V3Graph

A number of passes use graph algorithms, and the class V3Graph is provided to represent those graphs. Graphs are directed, and algorithms are provided to manipulate the graphs and to output them in GraphViz dot format (see http://www.graphviz.org/). V3Graph.h provides documentation of this class.

V3GraphVertex

This is the base class for vertices in a graph. Vertices have an associated fanout, color and rank, which may be used in algorithms for ordering the graph. A generic user/userp member variable is also provided.

Virtual methods are provided to specify the name, color, shape and style to be used in dot output. Typically users provide derived classes from V3GraphVertex which will reimplement these methods.

Iterators are provided to access in and out edges. Typically these are used in the form:

    for (V3GraphEdge *edgep = vertexp->inBeginp();
         edgep;
         edgep = edgep->inNextp()) {
V3GraphEdge

This is the base class for directed edges between pairs of vertices. Edges have an associated weight and may also be made cutable. A generic user/userp member variable is also provided.

Accessors, fromp and top return the "from" and "to" vertices respectively.

Virtual methods are provided to specify the label, color and style to be used in dot output. Typically users provided derived classes from V3GraphEdge which will reimplement these methods.

V3GraphAlg

This is the base class for graph algorithms. It implements a bool method, followEdge which algorithms can use to decide whether an edge is followed. This method returns true if the graph edge has weight greater than one and a user function, edgeFuncp (supplied in the constructor) returns true.

A number of predefined derived algorithm classes and access methods are provided and documented in V3GraphAlg.cpp.

Verilated Flow

The evaluation loop outputted by Verilator is designed to allow a single function to perform evaluation under most situations.

On the first evaluation, the Verilated code calls initial blocks, and then "settles" the modules, by evaluating functions (from always statements) until all signals are stable.

On other evaluations, the Verilated code detects what input signals have changes. If any are clocks, it calls the appropriate sequential functions (from always @ posedge statements). Interspersed with sequential functions it calls combo functions (from always @*). After this is complete, it detects any changes due to combo loops or internally generated clocks, and if one is found must reevaluate the model again.

For SystemC code, the eval() function is wrapped in a SystemC SC_METHOD, sensitive to all inputs. (Ideally it would only be sensitive to clocks and combo inputs, but tracing requires all signals to cause evaluation, and the performance difference is small.)

If tracing is enabled, a callback examines all variables in the design for changes, and writes the trace for each change. To accelerate this process the evaluation process records a bitmask of variables that might have changed; if clear, checking those signals for changes may be skipped.


CODING CONVENTIONS

Indentation style

To match the indentation of Verilator C++ sources, use 4 spaces per level, and leave tabs at 8 columns, so every other indent level is a tab stop.

All files should contain the magic header to insure standard indentation:

    // -*- mode: C++; c-file-style: "cc-mode" -*-

This sets indentation to the cc-mode defaults. (Verilator predates a CC-mode change of several years ago which overrides the defaults with GNU style indentation; the c-set-style undoes that.)

The astgen script

Some of the code implementing passes is extremely repetitive, and must be implemented for each sub-class of AstNode. However, while repetitive, there is more variability than can be handled in C++ macros.

In Verilator this is implemented by using a Perl script, astgen to pre-process the C++ code. For example in V3Const.cpp this is used to implement the visit() functions for each binary operation using the TREEOP macro.

The original C++ source code is transformed into C++ code in the obj_opt and obj_dbg sub-directories (the former for the optimized version of Verilator, the latter for the debug version). So for example V3Const.cpp into V3Const__gen.cpp.

Visitor Functions

Verilator uses the Visitor design pattern to implement its refinement and optimization passes. This allows separation of the pass algorithm from the AST on which it operates. Wikipedia provides an introduction to the concept at http://en.wikipedia.org/wiki/Visitor_pattern.

As noted above, all visitors are derived classes of AstNVisitor. All derived classes of AstNode implement the accept method, which takes as argument a reference to an instance or a AstNVisitor derived class and applies the visit method of the AstNVisitor to the invoking AstNode instance (i.e. this).

One possible difficulty is that a call to accept may perform an edit which destroys the node it receives as argument. The acceptSubtreeReturnEdits method of AstNode is provided to apply accept and return the resulting node, even if the original node is destroyed (if it is not destroyed it will just return the original node).

The behavior of the visitor classes is achieved by overloading the visit function for the different AstNode derived classes. If a specific implementation is not found, the system will look in turn for overloaded implementations up the inheritance hierarchy. For example calling accept on AstIf will look in turn for:

  void visit (AstIf* nodep, AstNUser* vup)
  void visit (AstNodeIf* nodep, AstNUser* vup)
  void visit (AstNodeStmt* nodep, AstNUser* vup)
  void visit (AstNode* nodep, AstNUser* vup)

There are three ways data is passed between visitor functions.

  1. A visitor-class member variable. This is generally for passing "parent" information down to children. m_modp is a common example. It's set to NULL in the constructor, where that node (AstModule visitor) sets it, then the children are iterated, then it's cleared. Children under an AstModule will see it set, while nodes elsewhere will see it clear. If there can be nested items (for example an AstFor under an AstFor) the variable needs to be save-set-restored in the AstFor visitor, otherwise exiting the lower for will lose the upper for's setting.

  2. User attributes. Each AstNode (Note. The AST node, not the visitor) has five user attributes, which may be accessed as an integer using the user1() through user5() methods, or as a pointer (of type AstNUser) using the user1p() through user5p() methods (a common technique lifted from graph traversal packages).

    A visitor first clears the one it wants to use by calling AstNode::user#ClearTree(), then it can mark any node's user() with whatever data it wants. Readers just call nodep->user(), but may need to cast appropriately, so you'll often see nodep->userp()->castSOMETYPE(). At the top of each visitor are comments describing how the user() stuff applies to that visitor class. For example:

        // NODE STATE
        // Cleared entire netlist
        //   AstModule::user1p()     // bool. True to inline this module

    This says that at the AstNetlist user1ClearTree() is called. Each AstModule's user1() is used to indicate if we're going to inline it.

    These comments are important to make sure a user#() on a given AstNode type is never being used for two different purposes.

    Note that calling user#ClearTree is fast, it doesn't walk the tree, so it's ok to call fairly often. For example, it's commonly called on every module.

  3. Parameters can be passed between the visitors in close to the "normal" function caller to callee way. This is the second vup parameter of type AstNUser that is ignored on most of the visitor functions. V3Width does this, but it proved more messy than the above and is deprecated. (V3Width was nearly the first module written. Someday this scheme may be removed, as it slows the program down to have to pass vup everywhere.)

Iterators

AstNode provides a set of iterators to facilitate walking over the tree. Each takes two arguments, a visitor, v, of type AstNVisitor and an optional pointer user data, vup, of type AstNUser*. The second is one of the ways to pass parameters to visitors described in Visitor Functions, but its use is now deprecated and should not be used for new visitor classes.

iterate()

This just applies the accept method of the AstNode to the visitor function.

iterateAndNextIgnoreEdit

Applies the accept method of each AstNode in a list (i.e. connected by nextp and backp pointers).

iterateAndNext

Applies the accept method of each AstNode in a list. If a node is edited by the call to accept, apply accept again, until the node does not change.

iterateListBackwards

Applies the accept method of each AstNode in a list, starting with the last one.

iterateChildren

Apply the iterateAndNext method on each child op1p through op4p in turn.

iterateChildrenBackwards

Apply the iterateListBackwards method on each child op1p through op4p in turn.

Caution on Using Iterators When Child Changes

Visitors often replace one node with another node; V3Width and V3Const are major examples. A visitor which is the parent of such a replacement needs to be aware that calling iteration may cause the children to change. For example:

    // nodep->lhsp() is 0x1234000
    nodep->lhsp()->iterateAndNext(...);  // and under covers nodep->lhsp() changes
    // nodep->lhsp() is 0x5678400
    nodep->lhsp()->iterateAndNext(...);

Will work fine, as even if the first iterate causes a new node to take the place of the lhsp(), that edit will update nodep->lhsp() and the second call will correctly see the change. Alternatively:

    lp = nodep->lhsp();
    // nodep->lhsp() is 0x1234000, lp is 0x1234000
    lp->iterateAndNext(...); **lhsp=NULL;** // and under covers nodep->lhsp() changes
    // nodep->lhsp() is 0x5678400, lp is 0x1234000
    lp->iterateAndNext(...);

This will cause bugs or a core dump, as lp is a dangling pointer. Thus it is advisable to set lhsp=NULL shown in the *'s above to make sure these dangles are avoided. Another alternative used in special cases mostly in V3Width is to use acceptSubtreeReturnEdits, which operates on a single node and returns the new pointer if any. Note acceptSubtreeReturnEdits does not follow nextp() links.

    lp = lp->acceptSubtreeReturnEdits()

Identifying derived classes

A common requirement is to identify the specific AstNode class we are dealing with. For example a visitor might not implement separate visit methods for AstIf and AstGenIf, but just a single method for the base class:

  void visit (AstNodeIf* nodep, AstNUser* vup)

However that method might want to specify additional code if it is called for AstGenIf. Verilator does this by providing a castSOMETYPE() method for each possible node type, using C++ dynamic_cast. This either returns a pointer to the object cast to that type (if it is of class SOMETYPE, or a derived class of SOMETYPE) or else NULL. So our visit method could use:

  if (nodep->castAstGenIf()) {
      <code specific to AstGenIf>
  }

A common test is for AstNetlist, which is the node at the root of the AST.


TESTING

For an overview of how to write a test see the BUGS section of the Verilator primary manual.

It is important to add tests for failures as well as success (for example to check that an error message is correctly triggered).

Tests that fail should by convention have the suffix _bad in their name, and include fails => 1 in either their compile or execute step as appropriate.

Preparing to Run Tests

For all tests to pass you must install the following packages:

* SystemC to compile the SystemC outputs, see http://systemc.org

* Parallel::Forker from CPAN to run tests in parallel, you can install this with e.g. "sudo cpan install Parallel::Forker".

* vcddiff to find differences in VCD outputs. See the readme at https://github.com/veripool/vcddiff

Controlling the Test Driver

Test drivers are written in PERL. All invoke the main test driver script, which can provide detailed help on all the features available when writing a test driver.

  test_regress/t/driver.pl --help

For convenience, a summary of the most commonly used features is provided here. All drivers require a call to compile subroutine to compile the test. For run-time tests, this is followed by a call to the execute subroutine. Both of these functions can optionally be provided with a hash table as argument specifying additional options.

The test driver assumes by default that the source Verilog file name matches the PERL driver name. So a test whose driver is t/t_mytest.pl will expect a Verilog source file t/t_mytest.v. This can be changed using the top_filename subroutine, for example

  top_filename("t/t_myothertest.v");

By default all tests will run with major simulators (Icarus Verilog, NC, VCS, ModelSim) as well as Verilator, to allow results to be compared. However if you wish a test only to be used with Verilator, you can use the following:

  $Self->{vlt} or $Self->skip("Verilator only test");

Of the many options that can be set through arguments to compiler and execute, the following are particularly useful:

verilator_flags2

A list of flags to be passed to verilator when compiling.

fails

Set to 1 to indicate that the compilation or execution is intended to fail.

For example the following would specify that compilation requires two defines and is expected to fail.

  compile (
      verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"],
      fails => 1,
      );

Regression Testing for Developers

Developers will also want to call ./configure with two extra flags:

--enable-ccwarn

Causes the build to stop on warnings as well as errors. A good way to ensure no sloppy code gets added, however it can be painful when it comes to testing, since third party code used in the tests (e.g. SystemC) may not be warning free.

--enable-longtests

In addition to the standard C, SystemC tests also run the tests in the test_verilated and test_regress directories when using make test. This is disabled by default as SystemC installation problems would otherwise falsely indicate a Verilator problem.

When enabling the long tests, some additional PERL modules are needed, which you can install using cpan.

    cpan install Unix::Processors

There are some traps to avoid when running regression tests

  • When checking the MANIFEST, the test will barf on unexpected code in the Verilator tree. So make sure to keep any such code outside the tree.

  • Not all Linux systems install Perldoc by default. This is needed for the --help option to Verilator, and also for regression testing. This can be installed using cpan:

        cpan install Pod::Perldoc

    Many Linux systems also offer a standard package for this. Red Hat/Fedora/Centos offer perl-Pod-Perldoc, while Debian/Ubuntu/Linux Mint offer perl-doc.

  • Running regression may exhaust resources on some Linux systems, particularly file handles and user processes. Increase these to respectively 16,384 and 4,096. The method of doing this is system dependent, but on Fedora Linux it would require editing the /etc/security/limits.conf file as root.


DEBUGGING

--debug

When you run with --debug there are two primary output file types placed into the obj_dir, .tree and .dot files.

.dot output

Dot files are dumps of internal graphs in Graphviz http://www.graphviz.org/ dot format. When a dot file is dumped, Verilator will also print a line on stdout that can be used to format the output, for example:

    dot -Tps -o ~/a.ps obj_dir/Vtop_foo.dot

You can then print a.ps. You may prefer gif format, which doesn't get scaled so can be more useful with large graphs.

For dynamic graph viewing consider ZGRViewer http://zvtm.sourceforge.net/zgrviewer.html. If you know of better viewers let us know; ZGRViewer isn't great for large graphs.

.tree output

Tree files are dumps of the AST Tree and are produced between every major algorithmic stage. An example:

     NETLIST 0x90fb00 <e1> {a0}
    1: MODULE 0x912b20 <e8822> {a8}  top  L2 [P]
   *1:2: VAR 0x91a780 <e74#> {a22} @dt=0xa2e640(w32)  out_wide [O] WIRE
    1:2:1: BASICDTYPE 0xa2e640 <e2149> {e24} @dt=this(sw32)  integer kwd=integer range=[31:0]

The following summarizes the above example dump, with more detail on each field in the section below.

"1:2:" indicates the hierarchy of the VAR is the op2p pointer under the MODULE, which in turn is the op1p pointer under the NETLIST

"VAR" is the AstNodeType.

"0x91a780" is the address of this node.

"<e74>" means the 74th edit to the netlist was the last modification to this node.

"{a22}" indicates this node is related to line 22 in the source filename "a", where "a" is the first file read, "z" the 26th, and "aa" the 27th.

"@dt=0x..." indicates the address of the data type this node contains.

"w32" indicates the width is 32 bits.

"out_wide" is the name of the node, in this case the name of the variable.

"[O]" are flags which vary with the type of node, in this case it means the variable is an output.

In more detail the following fields are dumped common to all nodes. They are produced by the AstNode::dump() method:

Tree Hierarchy

The dump lines begin with numbers and colons to indicate the child node hierarchy. As noted above in Key Classes Used in the Verilator Flow, AstNode has lists of items at the same level in the AST, connected by the nextp() and prevp() pointers. These appear as nodes at the same level. For example after inlining:

     NETLIST 0x929c1c8 <e1> {a0} w0
    1: MODULE 0x92bac80 <e3144> {e14} w0  TOP_t  L1 [P]
    1:1: CELLINLINE 0x92bab18 <e3686#> {e14} w0  v -> t
    1:1: CELLINLINE 0x92bc1d8 <e3688#> {e24} w0  v__DOT__i_test_gen -> test_gen
    ...
    1: MODULE 0x92b9bb0 <e503> {e47} w0  test_gen  L3
    ...
AstNode type

The textual name of this node AST type (always in capitals). Many of these correspond directly to Verilog entities (for example MODULE and TASK), but others are internal to Verialtor (for example NETLIST and BASICDTYPE).

Address of the node

A hexadecimal address of the node in memory. Useful for examining with the debugger.

Last edit number

Of the form <ennnn> or <ennnn#> , where nnnn is the number of the last edit to modify this node. The trailing # indicates the node has been edited since the last tree dump (which typically means in the last refinement or optimization pass). GDB can watch for this, see Debugging with GDB.

Source file and line

Of the form {xxnnnn}, where C{xx} is the filename letter (or letters) and nnnn is the line number within that file. The first file is a, the 26th is z, the 27th is aa and so on.

User pointers

Shows the value of the node's user1p...user5p, if non-NULL.

Data type

Many nodes have an explicit data type. "@dt=0x..." indicates the address of the data type (AstNodeDType) this node uses.

If a data type is present and is numeric, it then prints the width of the item. This field is a sequence of flag characters and width data as follows:

s if the node is signed.

d if the node is a double (i.e a floating point entity).

w always present, indicating this is the width field.

u if the node is unsized.

/nnnn if the node is unsized, where nnnn is the minimum width.

Name of the entity represented by the node if it exists

For example for a VAR it is the name of the variable.

Many nodes follow these fields with additional node specific information. Thus the VARREF node will print either [LV] or [RV] to indicate a left value or right value, followed by the node of the variable being referred to. For example:

    1:2:1:1: VARREF 0x92c2598 <e509> {e24} w0  clk [RV] <- VAR 0x92a2e90 <e79> {e18} w0  clk [I] INPUT

In general, examine the dump() method in V3AstNodes.cpp of the node type in question to determine additional fields that may be printed.

The MODULE has a list of CELLINLINE nodes referred to by its op1p() pointer, connected by nextp() and prevp() pointers.

Similarly the NETLIST has a list of modules referred to by its op1p() pointer.

Debugging with GDB

The test_regress/driver.pl script accepts --debug --gdb to start Verilator under gdb and break when an error is hit or the program is about to exit. You can also use --debug --gdbbt to just backtrace and then exit gdb. To debug the Verilated executable, use --gdbsim.

If you wish to start Verilator under GDB (or another debugger), then you can use --debug and look at the underlying invocation of verilator_dgb. For example

  t/t_alw_dly.pl --debug

shows it invokes the command:

  ../verilator_bin_dbg --prefix Vt_alw_dly --x-assign unique --debug
    -cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v

Start GDB, then start with the remaining arguments.

  gdb ../verilator_bin_dbg
  ...
  (gdb) start --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir
            obj_dir/t_alw_dly --debug-check  -f input.vc t/t_alw_dly.v
            > obj_dir/t_alw_dly/vlt_compile.log
  ...
  Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc)
      at ../Verilator.cpp:615
  615         ios::sync_with_stdio();
  (gdb)

You can then continue execution with breakpoints as required.

To break at a specific edit number which changed a node (presumably to find what made a <e####> line in the tree dumps):

   watch AstNode::s_editCntGbl==####

To print a node:

   pn nodep
   # or: call nodep->dumpGdb() # aliased to "pn" in src/.gdbinit
   pnt nodep
   # or: call nodep->dumpTreeGdb()  # aliased to "pnt" in src/.gdbinit

When GDB halts, it is useful to understand that the backtrace will commonly show the iterator functions between each invocation of visit in the backtrace. You will typically see a frame sequence something like

  ...
  visit()
  iterateChildren()
  iterateAndNext()
  accept()
  visit()
  ...


ADDING A NEW FEATURE

Generally what would you do to add a new feature?

  1. File a bug (if there isn't already) so others know what you're working on.

  2. Make a testcase in the test_regress/t/t_EXAMPLE format, see TESTING.

  3. If grammar changes are needed, look at the git version of VerilogPerl's src/VParseGrammar.y, as this grammar supports the full SystemVerilog language and has a lot of back-and-forth with Verilator's grammar. Copy the appropriate rules to src/verilog.y and modify the productions.

  4. If a new Ast type is needed, add it to V3AstNodes.h.

Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree file which you can examine to see if the parsing worked. See also the sections above on debugging.

Modify the later visitor functions to process the new feature as needed.

Adding a new pass

For more substantial changes you may need to add a new pass. The simplest way to do this is to copy the .cpp and .h files from an existing pass. You'll need to add a call into your pass from the process() function in src/verilator.cpp.

To get your pass to build you'll need to add its binary filename to the list in src/Makefile_obj.in and reconfigure.


DISTRIBUTION

The latest version is available from http://www.veripool.org/.

Copyright 2008-2015 by Wilson Snyder. Verilator 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.

verilator-3.874/README.html0000664000177100017500000002060512534631200015345 0ustar wsnyderwsnyder NAME


NAME

This is the Verilator package README file.


DISTRIBUTION

http://www.veripool.org/verilator

This package is Copyright 2003-2015 by Wilson Snyder. (Report bugs to http://www.veripool.org/.)

Verilator 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. (See the documentation for more details.)

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.


DESCRIPTION

Verilator converts synthesizable (generally not behavioral) Verilog code into C++ or SystemC code. It is not a complete simulator, just a translator.

Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage code. For C++ format, it outputs .cpp and .h files. For SystemC format, it outputs .cpp and .h files using the standard SystemC headers.

The resulting files are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module. This is compiled in C++, and linked with the Verilated files.

The resulting executable will perform the actual simulation.


SUPPORTED SYSTEMS

Verilator is developed and has primary testing on Ubuntu. Versions have also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It should run with minor porting on any Linix-ish platform. Verilator also works on Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated output (not Verilator itself) compiles under MSVC++ 2008 and newer.


INSTALLATION

For more details see http://www.veripool.org/projects/verilator/wiki/Installing.

If you will be modifying Verilator, you should use the "git" method as it will let you track changes.

The latest version is available at http://www.veripool.org/verilator.

Download the latest package from that site, and decompress.

    tar xvzf verilator_version.tgz

If you will be using SystemC (vs straight C++ output), download SystemC from http://www.systemc.org. Follow their installation instructions. You will need to set SYSTEMC_INCLUDE to point to the include directory with systemc.h in it, and SYSTEMC_LIBDIR to points to the directory with libsystemc.a in it. (Older installations may set SYSTEMC and SYSTEMC_ARCH instead.)

You will need the flex and bison packages installed.

cd to the Verilator directory containing this README.

You now have to decide how you're going to eventually install the kit.

Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE, and SYSTEMC_LIBDIR as defaults into the executable, so try to have them correct before configuring.

  1. Our personal favorite is to always run Verilator from the kit directory. This allows the easiest experimentation and upgrading. It's also how most EDA tools operate; to run you point to the tarball, no install is needed.

        export VERILATOR_ROOT=`pwd`   # if your shell is bash
        setenv VERILATOR_ROOT `pwd`   # if your shell is csh
        ./configure
  2. To install globally onto a "cad" disk with multiple versions of every tool, and add it to path using Modules/modulecmd:

        unset VERILATOR_ROOT      # if your shell is bash
        unsetenv VERILATOR_ROOT   # if your shell is csh
        # For the tarball, use the version number instead of git describe
        ./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"`
        After installing you'll want a module file like the following:
        set install_root /CAD_DISK/verilator/{version-number-used-above}
        setenv VERILATOR_ROOT $install_root
        prepend-path PATH $install_root/bin
        prepend-path MANPATH $install_root/man
  3. The next option is to install it globally, using the normal system paths:

        unset VERILATOR_ROOT      # if your shell is bash
        unsetenv VERILATOR_ROOT   # if your shell is csh
        ./configure
  4. Alternatively you can configure a prefix that install will populate, as most GNU tools support:

        unset VERILATOR_ROOT      # if your shell is bash
        unsetenv VERILATOR_ROOT   # if your shell is csh
        ./configure --prefix /opt/verilator-VERSION

    Then after installing you will need to add /opt/verilator-VERSION/bin to PATH.

Type make to compile Verilator.

Type make test to check the compilation.

Configure with --enable-longtests for more complete developer tests. Additional packages may be required for these tests.

You may get a error about a typedef conflict for uint32_t. Edit verilated.h to change the typedef to work, probably to @samp{typedef unsigned long uint32_t;}.

If you used the VERILATOR_ROOT scheme you're done. Programs should set the environment variable VERILATOR_ROOT to point to this distribution, then execute $VERILATOR_ROOT/bin/verilator, which will find the path to all needed files.

If you used the prefix scheme, now do a make install. To run verilator, have the verilator binary directory in your PATH (this should already be true if using the default configure), and make sure VERILATOR_ROOT is not set.


USAGE DOCUMENTATION

Detailed documentation and the man page can be seen by running:

    bin/verilator --help

or reading verilator.txt in the same directory as this README.


DIRECTORY STRUCTURE

The directories in the kit after de-taring are as follows:

    bin/verilator               => Compiler Wrapper invoked to Verilate code
    include/                    => Files that should be in your -I compiler path
    include/verilated*.cpp      => Global routines to link into your simulator
    include/verilated*.h        => Global headers
    include/verilated.v         => Stub defines for linting
    include/verilated.mk        => Common makefile
    src/                        => Translator source code
    test_v                      => Example Verilog code for other test dirs
    test_c                      => Example Verilog->C++ conversion
    test_sc                     => Example Verilog->SystemC conversion
    test_verilated              => Internal tests
    test_regress                => Internal tests


LIMITATIONS

See verilator.txt (or execute bin/verilator --help) for limitations.

verilator-3.874/README.pod0000664000177100017500000001477112525172076015205 0ustar wsnyderwsnyder# DESCRIPTION: DOCUMENT source run through perl to produce README file # Use 'make README' to produce the output file =pod =head1 NAME This is the Verilator package README file. =head1 DISTRIBUTION http://www.veripool.org/verilator This package is Copyright 2003-2015 by Wilson Snyder. (Report bugs to L.) Verilator 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. (See the documentation for more details.) This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. =head1 DESCRIPTION Verilator converts synthesizable (generally not behavioral) Verilog code into C++ or SystemC code. It is not a complete simulator, just a translator. Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage code. For C++ format, it outputs .cpp and .h files. For SystemC format, it outputs .cpp and .h files using the standard SystemC headers. The resulting files are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module. This is compiled in C++, and linked with the Verilated files. The resulting executable will perform the actual simulation. =head1 SUPPORTED SYSTEMS Verilator is developed and has primary testing on Ubuntu. Versions have also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It should run with minor porting on any Linix-ish platform. Verilator also works on Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated output (not Verilator itself) compiles under MSVC++ 2008 and newer. =head1 INSTALLATION For more details see L. If you will be modifying Verilator, you should use the "git" method as it will let you track changes. =over 4 =item The latest version is available at L. Download the latest package from that site, and decompress. tar xvzf verilator_version.tgz =item If you will be using SystemC (vs straight C++ output), download SystemC from L. Follow their installation instructions. You will need to set SYSTEMC_INCLUDE to point to the include directory with systemc.h in it, and SYSTEMC_LIBDIR to points to the directory with libsystemc.a in it. (Older installations may set SYSTEMC and SYSTEMC_ARCH instead.) =item You will need the C and C packages installed. =item C to the Verilator directory containing this README. =item You now have to decide how you're going to eventually install the kit. Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE, and SYSTEMC_LIBDIR as defaults into the executable, so try to have them correct before configuring. =over 4 =item 1. Our personal favorite is to always run Verilator from the kit directory. This allows the easiest experimentation and upgrading. It's also how most EDA tools operate; to run you point to the tarball, no install is needed. export VERILATOR_ROOT=`pwd` # if your shell is bash setenv VERILATOR_ROOT `pwd` # if your shell is csh ./configure =item 2. To install globally onto a "cad" disk with multiple versions of every tool, and add it to path using Modules/modulecmd: unset VERILATOR_ROOT # if your shell is bash unsetenv VERILATOR_ROOT # if your shell is csh # For the tarball, use the version number instead of git describe ./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"` After installing you'll want a module file like the following: set install_root /CAD_DISK/verilator/{version-number-used-above} setenv VERILATOR_ROOT $install_root prepend-path PATH $install_root/bin prepend-path MANPATH $install_root/man =item 3. The next option is to install it globally, using the normal system paths: unset VERILATOR_ROOT # if your shell is bash unsetenv VERILATOR_ROOT # if your shell is csh ./configure =item 4. Alternatively you can configure a prefix that install will populate, as most GNU tools support: unset VERILATOR_ROOT # if your shell is bash unsetenv VERILATOR_ROOT # if your shell is csh ./configure --prefix /opt/verilator-VERSION Then after installing you will need to add /opt/verilator-VERSION/bin to PATH. =back =item Type C to compile Verilator. Type C to check the compilation. Configure with C<--enable-longtests> for more complete developer tests. Additional packages may be required for these tests. You may get a error about a typedef conflict for uint32_t. Edit verilated.h to change the typedef to work, probably to @samp{typedef unsigned long uint32_t;}. =item If you used the VERILATOR_ROOT scheme you're done. Programs should set the environment variable VERILATOR_ROOT to point to this distribution, then execute $VERILATOR_ROOT/bin/verilator, which will find the path to all needed files. If you used the prefix scheme, now do a C. To run verilator, have the verilator binary directory in your PATH (this should already be true if using the default configure), and make sure VERILATOR_ROOT is not set. =back =head1 USAGE DOCUMENTATION Detailed documentation and the man page can be seen by running: bin/verilator --help or reading verilator.txt in the same directory as this README. =head1 DIRECTORY STRUCTURE The directories in the kit after de-taring are as follows: bin/verilator => Compiler Wrapper invoked to Verilate code include/ => Files that should be in your -I compiler path include/verilated*.cpp => Global routines to link into your simulator include/verilated*.h => Global headers include/verilated.v => Stub defines for linting include/verilated.mk => Common makefile src/ => Translator source code test_v => Example Verilog code for other test dirs test_c => Example Verilog->C++ conversion test_sc => Example Verilog->SystemC conversion test_verilated => Internal tests test_regress => Internal tests =head1 LIMITATIONS See verilator.txt (or execute C) for limitations. verilator-3.874/internals.pod0000664000177100017500000007033612525172076016246 0ustar wsnyderwsnyder# DESCRIPTION: DOCUMENT source run through perl to produce internals.txt file # Use 'make internals.txt' to produce the output file =pod =head1 NAME Verilator Internals =head1 INTRODUCTION This file discusses internal and programming details for Verilator. It's the first for reference for developers and debugging problems. See also the Verilator internals presentation at http://www.veripool.org. =head1 CODE FLOWS =head2 Verilator Flow The main flow of Verilator can be followed by reading the Verilator.cpp process() function: First, the files specified on the command line are read. Reading involves preprocessing, then lexical analysis with Flex and parsing with Bison. This produces an abstract syntax tree (AST) representation of the design, which is what is visible in the .tree files described below. Verilator then makes a series of passes over the AST, progressively refining and optimizing it. Cells in the AST first linked, which will read and parse additional files as above. Functions, variable and other references are linked to their definitions. Parameters are resolved and the design is elaborated. Verilator then performs many additional edits and optimizations on the hierarchical design. This includes coverage, assertions, X elimination, inlining, constant propagation, and dead code elimination. References in the design are then pseudo-flattened. Each module's variables and functions get "Scope" references. A scope reference is an occurrence of that un-flattened variable in the flattened hierarchy. A module that occurs only once in the hierarchy will have a single scope and single VarScope for each variable. A module that occurs twice will have a scope for each occurrence, and two VarScopes for each variable. This allows optimizations to proceed across the flattened design, while still preserving the hierarchy. Additional edits and optimizations proceed on the pseudo-flat design. These include module references, function inlining, loop unrolling, variable lifetime analysis, lookup table creation, always splitting, and logic gate simplifications (pushing inverters, etc). Verilator orders the code. Best case, this results in a single "eval" function which has all always statements flowing from top to bottom with no loops. Verilator mostly removes the flattening, so that code may be shared between multiple invocations of the same module. It localizes variables, combines identical functions, expands macros to C primitives, adds branch prediction hints, and performs additional constant propagation. Verilator finally writes the C++ modules. =head2 Key Classes Used in the Verilator Flow =over 4 =item C The AST is represented at the top level by the class C. This abstract class has derived classes for the individual components (e.g. C for a generate block) or groups of components (e.g. C for functions and tasks, which in turn has C and C as derived classes). Each C has pointers to up to four children, accessed by the C through C methods. These methods are then abstracted in a specific Ast* node class to a more specific name. For example with the C node (for C statements), C calls C to give the pointer to the AST for the "then" block, while C calls C to give the pointer to the AST for the "else" block, or NULL if there is not one. C has the concept of a next and previous AST - for example the next and previous statements in a block. Pointers to the AST for these statements (if they exist) can be obtained using the C and C methods. It is useful to remember that the derived class C is at the top of the tree, so checking for this class is the standard way to see if you are at the top of the tree. By convention, each function/method uses the variable C as a pointer to the C currently being processed. =item C The passes are implemented by AST visitor classes (see L). These are implemented by subclasses of the abstract class, C. Each pass creates an instance of the visitor class, which in turn implements a method to perform the pass. =item C A number of passes use graph algorithms, and the class C is provided to represent those graphs. Graphs are directed, and algorithms are provided to manipulate the graphs and to output them in I dot format (see L). C provides documentation of this class. =item C This is the base class for vertices in a graph. Vertices have an associated C, C and C, which may be used in algorithms for ordering the graph. A generic C/C member variable is also provided. Virtual methods are provided to specify the name, color, shape and style to be used in dot output. Typically users provide derived classes from C which will reimplement these methods. Iterators are provided to access in and out edges. Typically these are used in the form: for (V3GraphEdge *edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { =item C This is the base class for directed edges between pairs of vertices. Edges have an associated C and may also be made C. A generic C/C member variable is also provided. Accessors, C and C return the "from" and "to" vertices respectively. Virtual methods are provided to specify the label, color and style to be used in dot output. Typically users provided derived classes from C which will reimplement these methods. =item C This is the base class for graph algorithms. It implements a C method, C which algorithms can use to decide whether an edge is followed. This method returns true if the graph edge has weight greater than one and a user function, C (supplied in the constructor) returns C. A number of predefined derived algorithm classes and access methods are provided and documented in C. =back =head2 Verilated Flow The evaluation loop outputted by Verilator is designed to allow a single function to perform evaluation under most situations. On the first evaluation, the Verilated code calls initial blocks, and then "settles" the modules, by evaluating functions (from always statements) until all signals are stable. On other evaluations, the Verilated code detects what input signals have changes. If any are clocks, it calls the appropriate sequential functions (from always @ posedge statements). Interspersed with sequential functions it calls combo functions (from always @*). After this is complete, it detects any changes due to combo loops or internally generated clocks, and if one is found must reevaluate the model again. For SystemC code, the eval() function is wrapped in a SystemC SC_METHOD, sensitive to all inputs. (Ideally it would only be sensitive to clocks and combo inputs, but tracing requires all signals to cause evaluation, and the performance difference is small.) If tracing is enabled, a callback examines all variables in the design for changes, and writes the trace for each change. To accelerate this process the evaluation process records a bitmask of variables that might have changed; if clear, checking those signals for changes may be skipped. =head1 CODING CONVENTIONS =head2 Indentation style To match the indentation of Verilator C++ sources, use 4 spaces per level, and leave tabs at 8 columns, so every other indent level is a tab stop. All files should contain the magic header to insure standard indentation: // -*- mode: C++; c-file-style: "cc-mode" -*- This sets indentation to the cc-mode defaults. (Verilator predates a CC-mode change of several years ago which overrides the defaults with GNU style indentation; the c-set-style undoes that.) =head2 The C script Some of the code implementing passes is extremely repetitive, and must be implemented for each sub-class of C. However, while repetitive, there is more variability than can be handled in C++ macros. In Verilator this is implemented by using a Perl script, C to pre-process the C++ code. For example in C this is used to implement the C functions for each binary operation using the TREEOP macro. The original C++ source code is transformed into C++ code in the C and C sub-directories (the former for the optimized version of Verilator, the latter for the debug version). So for example C into C. =head2 Visitor Functions Verilator uses the I design pattern to implement its refinement and optimization passes. This allows separation of the pass algorithm from the AST on which it operates. Wikipedia provides an introduction to the concept at L. As noted above, all visitors are derived classes of C. All derived classes of C implement the C method, which takes as argument a reference to an instance or a C derived class and applies the visit method of the C to the invoking AstNode instance (i.e. C). One possible difficulty is that a call to C may perform an edit which destroys the node it receives as argument. The C method of C is provided to apply C and return the resulting node, even if the original node is destroyed (if it is not destroyed it will just return the original node). The behavior of the visitor classes is achieved by overloading the C function for the different C derived classes. If a specific implementation is not found, the system will look in turn for overloaded implementations up the inheritance hierarchy. For example calling C on C will look in turn for: void visit (AstIf* nodep, AstNUser* vup) void visit (AstNodeIf* nodep, AstNUser* vup) void visit (AstNodeStmt* nodep, AstNUser* vup) void visit (AstNode* nodep, AstNUser* vup) There are three ways data is passed between visitor functions. =over 4 =item 1. A visitor-class member variable. This is generally for passing "parent" information down to children. C is a common example. It's set to NULL in the constructor, where that node (C visitor) sets it, then the children are iterated, then it's cleared. Children under an C will see it set, while nodes elsewhere will see it clear. If there can be nested items (for example an C under an C) the variable needs to be save-set-restored in the C visitor, otherwise exiting the lower for will lose the upper for's setting. =item 2. User attributes. Each C (B The AST node, not the visitor) has five user attributes, which may be accessed as an integer using the C through C methods, or as a pointer (of type C) using the C through C methods (a common technique lifted from graph traversal packages). A visitor first clears the one it wants to use by calling C, then it can mark any node's user() with whatever data it wants. Readers just call C<< nodep->user() >>, but may need to cast appropriately, so you'll often see C<< nodep->userp()->castSOMETYPE() >>. At the top of each visitor are comments describing how the C stuff applies to that visitor class. For example: // NODE STATE // Cleared entire netlist // AstModule::user1p() // bool. True to inline this module This says that at the C C is called. Each C's C is used to indicate if we're going to inline it. These comments are important to make sure a C on a given C type is never being used for two different purposes. Note that calling C is fast, it doesn't walk the tree, so it's ok to call fairly often. For example, it's commonly called on every module. =item 3. Parameters can be passed between the visitors in close to the "normal" function caller to callee way. This is the second C parameter of type C that is ignored on most of the visitor functions. V3Width does this, but it proved more messy than the above and is deprecated. (V3Width was nearly the first module written. Someday this scheme may be removed, as it slows the program down to have to pass vup everywhere.) =back =head2 Iterators C provides a set of iterators to facilitate walking over the tree. Each takes two arguments, a visitor, C, of type C and an optional pointer user data, C, of type C. The second is one of the ways to pass parameters to visitors described in L, but its use is now deprecated and should I be used for new visitor classes. =over 4 =item C This just applies the C method of the C to the visitor function. =item C Applies the C method of each C in a list (i.e. connected by C and C pointers). =item C Applies the C method of each C in a list. If a node is edited by the call to C, apply C again, until the node does not change. =item C Applies the C method of each C in a list, starting with the last one. =item C Apply the C method on each child C through C in turn. =item C Apply the C method on each child C through C in turn. =back =head3 Caution on Using Iterators When Child Changes Visitors often replace one node with another node; V3Width and V3Const are major examples. A visitor which is the parent of such a replacement needs to be aware that calling iteration may cause the children to change. For example: // nodep->lhsp() is 0x1234000 nodep->lhsp()->iterateAndNext(...); // and under covers nodep->lhsp() changes // nodep->lhsp() is 0x5678400 nodep->lhsp()->iterateAndNext(...); Will work fine, as even if the first iterate causes a new node to take the place of the lhsp(), that edit will update nodep->lhsp() and the second call will correctly see the change. Alternatively: lp = nodep->lhsp(); // nodep->lhsp() is 0x1234000, lp is 0x1234000 lp->iterateAndNext(...); **lhsp=NULL;** // and under covers nodep->lhsp() changes // nodep->lhsp() is 0x5678400, lp is 0x1234000 lp->iterateAndNext(...); This will cause bugs or a core dump, as lp is a dangling pointer. Thus it is advisable to set lhsp=NULL shown in the *'s above to make sure these dangles are avoided. Another alternative used in special cases mostly in V3Width is to use acceptSubtreeReturnEdits, which operates on a single node and returns the new pointer if any. Note acceptSubtreeReturnEdits does not follow nextp() links. lp = lp->acceptSubtreeReturnEdits() =head2 Identifying derived classes A common requirement is to identify the specific C class we are dealing with. For example a visitor might not implement separate C methods for C and C, but just a single method for the base class: void visit (AstNodeIf* nodep, AstNUser* vup) However that method might want to specify additional code if it is called for C. Verilator does this by providing a C method for each possible node type, using C++ C. This either returns a pointer to the object cast to that type (if it is of class C, or a derived class of C) or else NULL. So our C method could use: if (nodep->castAstGenIf()) { } A common test is for C, which is the node at the root of the AST. =head1 TESTING For an overview of how to write a test see the BUGS section of the Verilator primary manual. It is important to add tests for failures as well as success (for example to check that an error message is correctly triggered). Tests that fail should by convention have the suffix C<_bad> in their name, and include C 1> in either their C or C step as appropriate. =head2 Preparing to Run Tests For all tests to pass you must install the following packages: * SystemC to compile the SystemC outputs, see http://systemc.org * Parallel::Forker from CPAN to run tests in parallel, you can install this with e.g. "sudo cpan install Parallel::Forker". * vcddiff to find differences in VCD outputs. See the readme at https://github.com/veripool/vcddiff =head2 Controlling the Test Driver Test drivers are written in PERL. All invoke the main test driver script, which can provide detailed help on all the features available when writing a test driver. test_regress/t/driver.pl --help For convenience, a summary of the most commonly used features is provided here. All drivers require a call to C subroutine to compile the test. For run-time tests, this is followed by a call to the C subroutine. Both of these functions can optionally be provided with a hash table as argument specifying additional options. The test driver assumes by default that the source Verilog file name matches the PERL driver name. So a test whose driver is C will expect a Verilog source file C. This can be changed using the C subroutine, for example top_filename("t/t_myothertest.v"); By default all tests will run with major simulators (Icarus Verilog, NC, VCS, ModelSim) as well as Verilator, to allow results to be compared. However if you wish a test only to be used with Verilator, you can use the following: $Self->{vlt} or $Self->skip("Verilator only test"); Of the many options that can be set through arguments to C and C, the following are particularly useful: =over 4 =item C A list of flags to be passed to verilator when compiling. =item C Set to 1 to indicate that the compilation or execution is intended to fail. =back For example the following would specify that compilation requires two defines and is expected to fail. compile ( verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"], fails => 1, ); =head2 Regression Testing for Developers Developers will also want to call ./configure with two extra flags: =over 4 =item --enable-ccwarn Causes the build to stop on warnings as well as errors. A good way to ensure no sloppy code gets added, however it can be painful when it comes to testing, since third party code used in the tests (e.g. SystemC) may not be warning free. =item --enable-longtests In addition to the standard C, SystemC tests also run the tests in the C and C directories when using I. This is disabled by default as SystemC installation problems would otherwise falsely indicate a Verilator problem. =back When enabling the long tests, some additional PERL modules are needed, which you can install using cpan. cpan install Unix::Processors There are some traps to avoid when running regression tests =over 4 =item * When checking the MANIFEST, the test will barf on unexpected code in the Verilator tree. So make sure to keep any such code outside the tree. =item * Not all Linux systems install Perldoc by default. This is needed for the I<--help> option to Verilator, and also for regression testing. This can be installed using cpan: cpan install Pod::Perldoc Many Linux systems also offer a standard package for this. Red Hat/Fedora/Centos offer I, while Debian/Ubuntu/Linux Mint offer I. =item * Running regression may exhaust resources on some Linux systems, particularly file handles and user processes. Increase these to respectively 16,384 and 4,096. The method of doing this is system dependent, but on Fedora Linux it would require editing the C file as root. =back =head1 DEBUGGING =head2 --debug When you run with --debug there are two primary output file types placed into the obj_dir, .tree and .dot files. =head2 .dot output Dot files are dumps of internal graphs in Graphviz L dot format. When a dot file is dumped, Verilator will also print a line on stdout that can be used to format the output, for example: dot -Tps -o ~/a.ps obj_dir/Vtop_foo.dot You can then print a.ps. You may prefer gif format, which doesn't get scaled so can be more useful with large graphs. For dynamic graph viewing consider ZGRViewer L. If you know of better viewers let us know; ZGRViewer isn't great for large graphs. =head2 .tree output Tree files are dumps of the AST Tree and are produced between every major algorithmic stage. An example: NETLIST 0x90fb00 {a0} 1: MODULE 0x912b20 {a8} top L2 [P] *1:2: VAR 0x91a780 {a22} @dt=0xa2e640(w32) out_wide [O] WIRE 1:2:1: BASICDTYPE 0xa2e640 {e24} @dt=this(sw32) integer kwd=integer range=[31:0] =over 4 The following summarizes the above example dump, with more detail on each field in the section below. "1:2:" indicates the hierarchy of the C is the C pointer under the C, which in turn is the C pointer under the C "VAR" is the AstNodeType. "0x91a780" is the address of this node. "" means the 74th edit to the netlist was the last modification to this node. "{a22}" indicates this node is related to line 22 in the source filename "a", where "a" is the first file read, "z" the 26th, and "aa" the 27th. "@dt=0x..." indicates the address of the data type this node contains. "w32" indicates the width is 32 bits. "out_wide" is the name of the node, in this case the name of the variable. "[O]" are flags which vary with the type of node, in this case it means the variable is an output. =back In more detail the following fields are dumped common to all nodes. They are produced by the C method: =over 4 =item Tree Hierarchy The dump lines begin with numbers and colons to indicate the child node hierarchy. As noted above in L, C has lists of items at the same level in the AST, connected by the C and C pointers. These appear as nodes at the same level. For example after inlining: NETLIST 0x929c1c8 {a0} w0 1: MODULE 0x92bac80 {e14} w0 TOP_t L1 [P] 1:1: CELLINLINE 0x92bab18 {e14} w0 v -> t 1:1: CELLINLINE 0x92bc1d8 {e24} w0 v__DOT__i_test_gen -> test_gen ... 1: MODULE 0x92b9bb0 {e47} w0 test_gen L3 ... =item AstNode type The textual name of this node AST type (always in capitals). Many of these correspond directly to Verilog entities (for example C and C), but others are internal to Verialtor (for example C and C). =item Address of the node A hexadecimal address of the node in memory. Useful for examining with the debugger. =item Last edit number Of the form C<< >> or C<< >> , where C is the number of the last edit to modify this node. The trailing C<#> indicates the node has been edited since the last tree dump (which typically means in the last refinement or optimization pass). GDB can watch for this, see L. =item Source file and line Of the form C<< {xxnnnn} >>, where C{xx} is the filename letter (or letters) and C is the line number within that file. The first file is C, the 26th is C, the 27th is C and so on. =item User pointers Shows the value of the node's user1p...user5p, if non-NULL. =item Data type Many nodes have an explicit data type. "@dt=0x..." indicates the address of the data type (AstNodeDType) this node uses. If a data type is present and is numeric, it then prints the width of the item. This field is a sequence of flag characters and width data as follows: C if the node is signed. C if the node is a double (i.e a floating point entity). C always present, indicating this is the width field. C if the node is unsized. C if the node is unsized, where C is the minimum width. =item Name of the entity represented by the node if it exists For example for a C it is the name of the variable. =back Many nodes follow these fields with additional node specific information. Thus the C node will print either C<[LV]> or C<[RV]> to indicate a left value or right value, followed by the node of the variable being referred to. For example: 1:2:1:1: VARREF 0x92c2598 {e24} w0 clk [RV] <- VAR 0x92a2e90 {e18} w0 clk [I] INPUT In general, examine the C method in C of the node type in question to determine additional fields that may be printed. The C has a list of C nodes referred to by its C pointer, connected by C and C pointers. Similarly the C has a list of modules referred to by its C pointer. =head2 Debugging with GDB The test_regress/driver.pl script accepts --debug --gdb to start Verilator under gdb and break when an error is hit or the program is about to exit. You can also use --debug --gdbbt to just backtrace and then exit gdb. To debug the Verilated executable, use --gdbsim. If you wish to start Verilator under GDB (or another debugger), then you can use --debug and look at the underlying invocation of verilator_dgb. For example t/t_alw_dly.pl --debug shows it invokes the command: ../verilator_bin_dbg --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v Start GDB, then C with the remaining arguments. gdb ../verilator_bin_dbg ... (gdb) start --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v > obj_dir/t_alw_dly/vlt_compile.log ... Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc) at ../Verilator.cpp:615 615 ios::sync_with_stdio(); (gdb) You can then continue execution with breakpoints as required. To break at a specific edit number which changed a node (presumably to find what made a line in the tree dumps): watch AstNode::s_editCntGbl==#### To print a node: pn nodep # or: call nodep->dumpGdb() # aliased to "pn" in src/.gdbinit pnt nodep # or: call nodep->dumpTreeGdb() # aliased to "pnt" in src/.gdbinit When GDB halts, it is useful to understand that the backtrace will commonly show the iterator functions between each invocation of C in the backtrace. You will typically see a frame sequence something like ... visit() iterateChildren() iterateAndNext() accept() visit() ... =head1 ADDING A NEW FEATURE Generally what would you do to add a new feature? =over 4 =item 1. File a bug (if there isn't already) so others know what you're working on. =item 2. Make a testcase in the test_regress/t/t_EXAMPLE format, see L. =item 3. If grammar changes are needed, look at the git version of VerilogPerl's src/VParseGrammar.y, as this grammar supports the full SystemVerilog language and has a lot of back-and-forth with Verilator's grammar. Copy the appropriate rules to src/verilog.y and modify the productions. =item 4. If a new Ast type is needed, add it to V3AstNodes.h. =back Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree file which you can examine to see if the parsing worked. See also the sections above on debugging. Modify the later visitor functions to process the new feature as needed. =head2 Adding a new pass For more substantial changes you may need to add a new pass. The simplest way to do this is to copy the C<.cpp> and C<.h> files from an existing pass. You'll need to add a call into your pass from the C function in C. To get your pass to build you'll need to add its binary filename to the list in C and reconfigure. =head1 DISTRIBUTION The latest version is available from L. Copyright 2008-2015 by Wilson Snyder. Verilator 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. =cut ###################################################################### verilator-3.874/test_regress/0000775000177100017500000000000012534632371016242 5ustar wsnyderwsnyderverilator-3.874/test_regress/.gitignore0000664000177100017500000000016012473477707020243 0ustar wsnyderwsnyder*.old obj_dir vcs.key csrc cov_work simv* simx* *.log *.key ncverilog.* INCA_libs logs .vcsmx_rebuild vc_hdrs.h verilator-3.874/test_regress/driver.pl0000775000177100017500000016201312525172036020075 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### require 5.006_001; BEGIN { if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) { # Magic to allow author testing of perl packages in local directory require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT}; } } use Cwd; use Getopt::Long; use IO::File; use Pod::Usage; use Data::Dumper; $Data::Dumper::Sortkeys=1; use strict; use vars qw ($Debug %Vars $Driver $Fork); use POSIX qw(strftime); $::Driver = 1; $::Have_Forker = 0; eval "use Parallel::Forker; \$Fork=Parallel::Forker->new(use_sig_child=>1); \$::Have_Forker=1;"; $Fork = Forker->new(use_sig_child=>1) if !$Fork; $SIG{CHLD} = sub { $Fork->sig_child() if $Fork; }; $SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork; die "Quitting...\n"; }; our $Have_System_Perl; eval "use SystemC::Netlist; \$Have_System_Perl=1;"; #====================================================================== #====================================================================== # main autoflush STDOUT 1; autoflush STDERR 1; our @Orig_ARGV = @ARGV; our @Orig_ARGV_Sw; foreach (@Orig_ARGV) { push @Orig_ARGV_Sw, $_ if /^-/ && !/^-j/; } our $Start = time(); $Debug = 0; my $opt_atsim; my $opt_benchmark; my @opt_tests; my $opt_gdb; my $opt_gdbbt; my $opt_gdbsim; my $opt_ghdl; my $opt_iv; my $opt_jobs = 1; my $opt_ms; my $opt_nc; my $opt_optimize; my $opt_site; my $opt_stop; my $opt_trace; my $opt_vlt; my $opt_vcs; my $opt_verbose; my $Opt_Verilated_Debug; our $Opt_Unsupported; our $Opt_Verilation = 1; our @Opt_Driver_Verilator_Flags; Getopt::Long::config ("pass_through"); if (! GetOptions ( "benchmark:i" => sub { $opt_benchmark = $_[1] ? $_[1] : 1; }, "debug" => \&debug, #debugi see parameter() "atsim|athdl!"=> \$opt_atsim, "gdb!" => \$opt_gdb, "gdbbt!" => \$opt_gdbbt, "gdbsim!" => \$opt_gdbsim, "ghdl!" => \$opt_ghdl, "golden!" => sub { $ENV{HARNESS_UPDATE_GOLDEN} = 1; }, "help" => \&usage, "iverilog!" => \$opt_iv, "j=i" => \$opt_jobs, "ms!" => \$opt_ms, "nc!" => \$opt_nc, "optimize:s" => \$opt_optimize, "site!" => \$opt_site, "stop!" => \$opt_stop, "trace!" => \$opt_trace, "unsupported!"=> \$Opt_Unsupported, "v3!" => \$opt_vlt, # Old "vl!" => \$opt_vlt, # Old "vlt!" => \$opt_vlt, "vcs!" => \$opt_vcs, "verbose!" => \$opt_verbose, "verilation!" => \$Opt_Verilation, # Undocumented debugging "verilated_debug!" => \$Opt_Verilated_Debug, #W see parameter() "<>" => \¶meter, )) { die "%Error: Bad usage, try '$0 --help'\n"; } $opt_jobs = calc_jobs() if defined $opt_jobs && $opt_jobs==0; $Fork->max_proc($opt_jobs); if (!$opt_atsim && !$opt_ghdl && !$opt_iv && !$opt_vcs && !$opt_ms && !$opt_nc && !$opt_vlt) { $opt_vlt = 1; } our @Test_Dirs = "t"; push @Test_Dirs, split(/:/,$ENV{VERILATOR_TESTS_SITE}) if (($#opt_tests<0 ? $opt_site : 1) && $ENV{VERILATOR_TESTS_SITE}); if ($#opt_tests<0) { my %uniq; foreach my $dir (@Test_Dirs) { my @stats = stat($dir); # Uniquify by inode, so different paths to same place get combined next if !$stats[1] || $uniq{$stats[1]}++; push @opt_tests, sort(glob ("${dir}/t_*.pl")); } } if ($#opt_tests>=2 && $opt_jobs>=2) { # Without this tests such as t_debug_sigsegv_bt_bad.pl will occasionally # block on input and cause a SIGSTOP, then a "fg" was needed to resume testing. print STDERR "== Many jobs; redirecting STDIN\n"; open(STDIN, "+>/dev/null"); } mkdir "obj_dir"; our $Log_Filename = "obj_dir/driver_".strftime("%Y%m%d_%H%M%S.log", localtime); my $LeftCnt=0; my $OkCnt=0; my $FailCnt=0; my $SkipCnt=0; my $UnsupCnt=0; my @fails; foreach my $testpl (@opt_tests) { one_test(pl_filename => $testpl, atsim=>1) if $opt_atsim; one_test(pl_filename => $testpl, ghdl=>1) if $opt_ghdl; one_test(pl_filename => $testpl, iv=>1) if $opt_iv; one_test(pl_filename => $testpl, ms=>1) if $opt_ms; one_test(pl_filename => $testpl, nc=>1) if $opt_nc; one_test(pl_filename => $testpl, vcs=>1) if $opt_vcs; one_test(pl_filename => $testpl, vlt=>1, 'v3'=>1) if $opt_vlt; } $Fork->wait_all(); # Wait for all children to finish sub one_test { my @params = @_; my %params = (@params); $LeftCnt++; $Fork->schedule ( test_pl_filename => $params{pl_filename}, run_on_start => sub { # Running in context of child, so can't pass data to parent directly print ("="x70,"\n"); my $test = VTest->new(@params); $test->oprint("="x50,"\n"); unlink $test->{status_filename}; $test->prep; $test->read; if ($test->ok) { $test->oprint("Test PASSED\n"); } elsif ($test->skips && !$test->errors) { $test->oprint("%Skip: $test->{skips}\n"); } elsif ($test->unsupporteds && !$test->errors) { $test->oprint("%Unsupported: $test->{unsupporteds}\n"); } else { $test->error("Missing ok\n") if !$test->errors; $test->oprint("%Error: $test->{errors}\n"); } $test->write_status; }, run_on_finish => sub { my $test = VTest->new(@params); $test->read_status; if ($test->ok) { $OkCnt++; } elsif ($test->skips && !$test->errors) { $SkipCnt++; } elsif ($test->unsupporteds && !$test->errors) { $UnsupCnt++; } else { $test->oprint("FAILED: ","*"x60,"\n"); my $j = ($opt_jobs>1?" -j":""); push @fails, ("\t#".$test->soprint("%Error: $test->{errors}\n") ."\t\tmake$j && test_regress/" .$test->{pl_filename}." ".join(' ',@Orig_ARGV_Sw)."\n"); $FailCnt++; report(\@fails, $Log_Filename); my $other = ""; foreach my $proc ($Fork->running) { $other .= " ".$proc->{test_pl_filename}; } $test->oprint("Simultaneous running tests:",$other,"\n") if $other; if ($opt_stop) { die "%Error: --stop and errors found\n"; } } $LeftCnt--; my $LeftMsg = $::Have_Forker ? $LeftCnt : "NO-FORKER"; print STDERR "==SUMMARY: Left $LeftMsg Passed $OkCnt Unsup $UnsupCnt Skipped $SkipCnt Failed $FailCnt\n"; }, )->ready(); } report(\@fails, undef); report(\@fails, $Log_Filename); exit(10) if $FailCnt; #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } sub debug { $Debug = 1; push @Opt_Driver_Verilator_Flags, "--debug --no-skip-identical"; } our $_Parameter_Next_Level; sub parameter { my $param = shift; if ($_Parameter_Next_Level) { ($param =~ /^(\d+)$/) or die "%Error: Expected number following $_Parameter_Next_Level: $param\n"; push @Opt_Driver_Verilator_Flags, $param; $_Parameter_Next_Level = undef; } elsif ($param =~ /\.pl/) { push @opt_tests, $param; } elsif ($param =~ /^-?(-debugi|-dump-treei)/) { push @Opt_Driver_Verilator_Flags, $param; $_Parameter_Next_Level = $param; } elsif ($param =~ /^-?(-W||-debug-check)/) { push @Opt_Driver_Verilator_Flags, $param; } else { die "%Error: Unknown parameter: $param\n"; } } sub calc_jobs { my $ok = eval " use Unix::Processors; return Unix::Processors->new->max_online; "; $ok && !$@ or die "%Error: Can't use -j: $@\n"; print "driver.pl: Found $ok cores, using -j ",$ok+1,"\n"; return $ok + 1; } sub report { my $fails = shift; my $filename = shift; my $fh = \*STDOUT; if ($filename) { $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename,"; } my $delta = time() - $Start; $fh->print("\n"); $fh->print("="x70,"\n"); $fh->printf("TESTS Passed $OkCnt Unsup $UnsupCnt Skipped $SkipCnt Failed $FailCnt Time %d:%02d\n", int($delta/60),$delta%60); foreach my $f (sort @$fails) { chomp $f; $fh->print("$f\n"); } $fh->printf("TESTS Passed $OkCnt Unsup $UnsupCnt Skipped $SkipCnt Failed $FailCnt Time %d:%02d\n", int($delta/60),$delta%60); } ####################################################################### ####################################################################### ####################################################################### ####################################################################### # Test class package VTest; use Carp; use Cwd; use Data::Dumper; use File::Spec; use vars qw ($Self $Self); use strict; sub new { my $class = shift; my $self = {@_}; $self->{name} ||= $2 if $self->{pl_filename} =~ m!^(.*/)?([^/]*)\.pl$!; $self->{mode} = ""; $self->{mode} ||= "atsim" if $self->{atsim}; $self->{mode} ||= "ghdl" if $self->{ghdl}; $self->{mode} ||= "vcs" if $self->{vcs}; $self->{mode} ||= "vlt" if $self->{vlt}; $self->{mode} ||= "nc" if $self->{nc}; $self->{mode} ||= "ms" if $self->{ms}; $self->{mode} ||= "iv" if $self->{iv}; # For backward compatibility, the verilator tests have no prefix $self->{obj_dir} ||= ("obj_dir/".($self->{mode} eq 'vlt' ? "" : $self->{mode}."_") ."$self->{name}"); foreach my $dir (@::Test_Dirs) { # t_dir used both absolutely and under obj_dir if (-e "$dir/$self->{name}.pl") { # Note most tests require error messages of the form t/x.v # Therefore pl_filename must be t/ for local tests $self->{pl_filename} = File::Spec->abs2rel("$dir/$self->{name}.pl"); # t_dir must be absolute - used under t or under obj_dir $self->{t_dir} ||= File::Spec->rel2abs($dir); last; } } $self->{t_dir} or die "%Error: Can't locate dir for $self->{name},"; $self = { name => undef, # Set below, name of this test pl_filename => undef, # Name of .pl file to get setup from make_top_shell => 1, # Make a default __top.v file make_main => 1, # Make __main.cpp make_pli => 0, # need to compile pli sim_time => 1100, benchmark => $opt_benchmark, verbose => $opt_verbose, run_env => '', # All compilers v_flags => [split(/\s+/,(" -f input.vc " .($self->{t_dir} !~ m!/test_regress! # Don't include standard dir, only site's ? " +incdir+$self->{t_dir} -y $self->{t_dir}" : "") .($opt_verbose ? " +define+TEST_VERBOSE=1":"") .($opt_benchmark ? " +define+TEST_BENCHMARK=$opt_benchmark":"") .($opt_trace ? " +define+WAVES=1":"") ))], v_flags2 => [], # Overridden in some sim files v_other_filenames => [], # After the filename so we can spec multiple files all_run_flags => [], pli_flags => ["-I$ENV{VERILATOR_ROOT}/include/vltstd -fPIC -shared" .(($^O eq "darwin" ) ? " -Wl,-undefined,dynamic_lookup" : " -export-dynamic") ." -o $self->{obj_dir}/libvpi.so"], # ATSIM atsim => 0, atsim_flags => [split(/\s+/,"-c +sv +define+ATSIM"), "+sv_dir+$self->{obj_dir}/.athdl_compile"], atsim_flags2 => [], # Overridden in some sim files atsim_run_flags => [], # GHDL ghdl => 0, ghdl_work_dir => "$self->{obj_dir}/ghdl_compile", ghdl_flags => [($::Debug?"-v":""), "--workdir=$self->{obj_dir}/ghdl_compile", ], ghdl_flags2 => [], # Overridden in some sim files ghdl_run_flags => [], # IV iv => 0, iv_flags => [split(/\s+/,"+define+iverilog -o $self->{obj_dir}/simiv")], iv_flags2 => [], # Overridden in some sim files iv_pli => 0, # need to use pli iv_run_flags => [], # VCS vcs => 0, vcs_flags => [split(/\s+/,"+vcs+lic+wait +cli -I +define+VCS+1 -q -sverilog -CFLAGS '-DVCS' ")], vcs_flags2 => [], # Overridden in some sim files vcs_run_flags => [split(/\s+/,"+vcs+lic_wait")], # NC nc => 0, nc_flags => [split(/\s+/,("+licqueue +nowarn+LIBNOU +define+NC=1 -q +assert +sv -c " .($opt_trace ? " +access+r":"")))], nc_flags2 => [], # Overridden in some sim files nc_run_flags => [split(/\s+/,"+licqueue -q +assert +sv -R")], # ModelSim ms => 0, ms_flags => [split(/\s+/,("-sv -work $self->{obj_dir}/work"))], ms_flags2 => [], # Overridden in some sim files ms_run_flags => [split(/\s+/,"-lib $self->{obj_dir}/work -c -do 'run -all;quit' ")], # Verilator vlt => 0, 'v3' => 0, verilator_flags => ["-cc", "-Mdir $self->{obj_dir}", "-OD", # As currently disabled unless -O3 "--debug-check"], verilator_flags2 => [], verilator_flags3 => ["--clk clk"], verilator_make_gcc => 1, verilated_debug => $Opt_Verilated_Debug, stdout_filename => undef, # Redirect stdout %$self}; bless $self, $class; $self->{VM_PREFIX} ||= "V".$self->{name}; $self->{stats} ||= "$self->{obj_dir}/V".$self->{name}."__stats.txt"; $self->{status_filename} ||= "$self->{obj_dir}/V".$self->{name}.".status"; $self->{run_log_filename} ||= "$self->{obj_dir}/vlt_sim.log"; $self->{coverage_filename} ||= "$self->{obj_dir}/coverage.dat"; $self->{vcd_filename} ||= "$self->{obj_dir}/sim.vcd"; $self->{main_filename} ||= "$self->{obj_dir}/$self->{VM_PREFIX}__main.cpp"; ($self->{top_filename} = $self->{pl_filename}) =~ s/\.pl$//; if (-e ($self->{top_filename}.".vhd")) { # If VHDL file exists $self->{vhdl} = 1; $self->{top_filename} .= ".vhd"; } else { $self->{top_filename} .= ".v"; } if (!$self->{make_top_shell}) { $self->{top_shell_filename} = $self->{top_filename}; } else { $self->{top_shell_filename} = "$self->{obj_dir}/$self->{VM_PREFIX}__top.v"; } return $self; } sub soprint { my $self = shift; my $str = "$self->{mode}/$self->{name}: ".join('',@_); $str =~ s/\n\n+$/\n/s; return $str; } sub oprint { my $self = shift; print $self->soprint(@_); } sub error { my $self = shift; my $msg = join('',@_); warn "%Warning: $self->{mode}/$self->{name}: ".$msg."\n"; $self->{errors} ||= $msg; } sub skip { my $self = shift; my $msg = join('',@_); warn "%Skip: $self->{mode}/$self->{name}: ".$msg."\n"; $self->{skips} ||= "Skip: ".$msg; } sub unsupported { my $self = shift; my $msg = join('',@_); warn "%Unsupported: $self->{mode}/$self->{name}: ".$msg."\n"; if (!$::Opt_Unsupported) { $self->{unsupporteds} ||= "Unsupported: ".$msg; } } sub prep { my $self = shift; mkdir $self->{obj_dir}; # Ok if already exists } sub read { my $self = shift; # Read the control file (-r $self->{pl_filename}) or return $self->error("Can't open $self->{pl_filename}\n"); $Self = $self; delete $INC{$self->{pl_filename}}; require $self->{pl_filename}; } sub write_status { my $self = shift; my $filename = $self->{status_filename}; my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,"; print $fh Dumper($self); print $fh "1;"; $fh->close(); } sub read_status { my $self = shift; my $filename = $self->{status_filename}; use vars qw($VAR1); local $VAR1; require $filename or die "%Error: $! $filename,"; if ($VAR1) { %{$self} = %{$VAR1}; } } #---------------------------------------------------------------------- # Methods invoked by tests sub compile_vlt_flags { my $self = (ref $_[0]? shift : $Self); my %param = (%{$self}, @_); # Default arguments are from $self return 1 if $self->errors || $self->skips || $self->unsupporteds; my $checkflags = join(' ',@{$param{v_flags}}, @{$param{v_flags2}}, @{$param{verilator_flags}}, @{$param{verilator_flags2}}, @{$param{verilator_flags3}}); $self->{sc} = 1 if ($checkflags =~ /-sc\b/); $self->{sp} = 1 if ($checkflags =~ /-sp\b/); $self->{trace} = 1 if ($opt_trace || $checkflags =~ /-trace\b/); $self->{savable} = 1 if ($checkflags =~ /-savable\b/); $self->{coverage} = 1 if ($checkflags =~ /-coverage\b/); my @verilator_flags = @{$param{verilator_flags}}; unshift @verilator_flags, "--gdb" if $opt_gdb; unshift @verilator_flags, "--gdbbt" if $opt_gdbbt; unshift @verilator_flags, @Opt_Driver_Verilator_Flags; unshift @verilator_flags, "--x-assign unique"; # More likely to be buggy unshift @verilator_flags, "--trace" if $opt_trace; if (defined $opt_optimize) { my $letters = ""; if ($opt_optimize =~ /[a-zA-Z]/) { $letters = $opt_optimize; } else { # Randomly turn on/off different optimizations foreach my $l ('a'..'z') { $letters .= ((rand() > 0.5) ? $l : uc $l); } unshift @verilator_flags, "--trace" if rand() > 0.5; unshift @verilator_flags, "--coverage" if rand() > 0.5; } unshift @verilator_flags, "--O".$letters; } my @cmdargs = ("perl","../bin/verilator", "--prefix ".$param{VM_PREFIX}, @verilator_flags, @{$param{verilator_flags2}}, @{$param{verilator_flags3}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, @{$param{v_other_filenames}}, ($param{stdout_filename}?"> ".$param{stdout_filename}:""), ); return @cmdargs; } sub compile { my $self = (ref $_[0]? shift : $Self); my %param = (%{$self}, @_); # Default arguments are from $self return 1 if $self->errors || $self->skips || $self->unsupporteds; $self->oprint("Compile\n"); compile_vlt_flags(%param); if (!$self->{make_top_shell}) { $param{top_shell_filename} = $self->{top_shell_filename} = $self->{top_filename}; } else { $param{top_shell_filename} = $self->{top_shell_filename} = "$self->{obj_dir}/$self->{VM_PREFIX}__top.".$self->v_suffix; } if ($param{atsim}) { $self->_make_top(); $self->_run(logfile=>"$self->{obj_dir}/atsim_compile.log", fails=>$param{fails}, cmd=>[($ENV{VERILATOR_ATSIM}||"atsim"), @{$param{atsim_flags}}, @{$param{atsim_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}, ]); } elsif ($param{ghdl}) { mkdir $self->{ghdl_work_dir}; $self->_make_top(); $self->_run(logfile=>"$self->{obj_dir}/ghdl_compile.log", fails=>$param{fails}, cmd=>[($ENV{VERILATOR_GHDL}||"ghdl"), # Add -c here, as having -c twice freaks it out ((($ENV{VERILATOR_GHDL}||' ') =~ / -c\b/) ? "" : "-c"), @{$param{ghdl_flags}}, @{$param{ghdl_flags2}}, #@{$param{v_flags}}, # Not supported #@{$param{v_flags2}}, # Not supported $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}, "-e t", ]); } elsif ($param{vcs}) { $self->_make_top(); $self->_run(logfile=>"$self->{obj_dir}/vcs_compile.log", fails=>$param{fails}, cmd=>[($ENV{VERILATOR_VCS}||"vcs"), @{$param{vcs_flags}}, @{$param{vcs_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}, ]); } elsif ($param{nc}) { $self->_make_top(); my @more_args; if ($self->vhdl) { ((my $ts = $param{top_shell_filename}) =~ s!\.v!!); $ts =~ s!.*/!!;; push @more_args, "-vhdltop", $ts; } $self->_run(logfile=>"$self->{obj_dir}/nc_compile.log", fails=>$param{fails}, cmd=>[($ENV{VERILATOR_NCVERILOG}||"ncverilog"), @{$param{nc_flags}}, @{$param{nc_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}, @more_args ]); } elsif ($param{ms}) { $self->_make_top(); $self->_run(logfile=>"$self->{obj_dir}/ms_compile.log", fails=>$param{fails}, cmd=>[("vlib $self->{obj_dir}/work && "), ($ENV{VERILATOR_MODELSIM}||"vlog"), @{$param{ms_flags}}, @{$param{ms_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}} ]); } elsif ($param{iv}) { $self->_make_top(); my @cmd = (($ENV{VERILATOR_IVERILOG}||"iverilog"), @{$param{iv_flags}}, @{$param{iv_flags2}}, @{$param{v_flags}}, @{$param{v_flags2}}, $param{top_filename}, $param{top_shell_filename}, @{$param{v_other_filenames}}); @cmd = grep { s/\+define\+/-D /g; $_; } @cmd; $self->_run(logfile=>"$self->{obj_dir}/iv_compile.log", fails=>$param{fails}, cmd=>\@cmd); } elsif ($param{vlt}) { my @cmdargs = $self->compile_vlt_flags(%param); if ($self->sc_or_sp && !defined $ENV{SYSTEMC} && !defined $ENV{SYSTEMC_INCLUDE}) { $self->skip("Test requires SystemC; ignore error since not installed\n"); return 1; } if (!$param{fails} && $param{verilator_make_gcc} && $param{make_main}) { $self->_make_main(); } $self->_run(logfile=>"$self->{obj_dir}/vlt_compile.log", fails=>$param{fails}, expect=>$param{expect}, cmd=>\@cmdargs) if $::Opt_Verilation; return 1 if $self->errors || $self->skips || $self->unsupporteds; if (!$param{fails} && $param{verilator_make_gcc}) { if ($self->sp) { $self->_sp_preproc(%param); } $self->oprint("GCC\n"); $self->_run(logfile=>"$self->{obj_dir}/vlt_gcc.log", cmd=>["cd $self->{obj_dir} && ", "make", "-f".getcwd()."/Makefile_obj", "VM_PREFIX=$self->{VM_PREFIX}", "CPPFLAGS_DRIVER=-D".uc($self->{name}), ($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""), ($param{make_main}?"":"MAKE_MAIN=0"), ($param{benchmark}?"OPT_FAST=-O2":""), "$self->{VM_PREFIX}", # bypass default rule, as we don't need archive ($param{make_flags}||""), ]); } } else { $self->error("No compile step for this simulator"); } if ($param{make_pli}) { $self->oprint("Compile vpi\n"); my @cmd = ('c++', @{$param{pli_flags}}, "-DIS_VPI", "$self->{t_dir}/$self->{name}.cpp"); $self->_run(logfile=>"$self->{obj_dir}/pli_compile.log", fails=>$param{fails}, cmd=>\@cmd); } return 1; } sub execute { my $self = (ref $_[0]? shift : $Self); return 1 if $self->errors || $self->skips || $self->unsupporteds; my %param = (%{$self}, @_); # Default arguments are from $self # params may be expect or {tool}_expect $self->oprint("Run\n"); my $run_env = $param{run_env}; $run_env .= ' ' if $run_env; if ($param{atsim}) { $self->_run(logfile=>"$self->{obj_dir}/atsim_sim.log", fails=>$param{fails}, cmd=>["echo q | ".$run_env."$self->{obj_dir}/athdl_sv", @{$param{atsim_run_flags}}, @{$param{all_run_flags}}, ], %param, expect=>$param{atsim_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{ghdl}) { $self->_run(logfile=>"$self->{obj_dir}/ghdl_sim.log", fails=>$param{fails}, cmd=>[$run_env."$self->{obj_dir}/simghdl", @{$param{ghdl_run_flags}}, @{$param{all_run_flags}}, ], %param, expect=>$param{ghdl_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{iv}) { my @cmd = ($run_env."$self->{obj_dir}/simiv", @{$param{iv_run_flags}}, @{$param{all_run_flags}}, ); if ($param{iv_pli}) { unshift @cmd, "vvp -n -m $self->{obj_dir}/libvpi.so"; # don't enter command line on $stop, include vpi } $self->_run(logfile=>"$self->{obj_dir}/iv_sim.log", fails=>$param{fails}, cmd=> \@cmd, %param, expect=>$param{iv_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{ms}) { $self->_run(logfile=>"$self->{obj_dir}/ms_sim.log", fails=>$param{fails}, cmd=>["echo q | ".$run_env.($ENV{VERILATOR_MODELSIM}||"vsim"), @{$param{ms_run_flags}}, @{$param{all_run_flags}}, (" top") ], %param, expect=>$param{ms_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{nc}) { $self->_run(logfile=>"$self->{obj_dir}/nc_sim.log", fails=>$param{fails}, cmd=>["echo q | ".$run_env.($ENV{VERILATOR_NCVERILOG}||"ncverilog"), @{$param{nc_run_flags}}, @{$param{all_run_flags}}, ], %param, expect=>$param{nc_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{vcs}) { #my $fh = IO::File->new(">simv.key") or die "%Error: $! simv.key,"; #$fh->print("quit\n"); $fh->close; $self->_run(logfile=>"$self->{obj_dir}/vcs_sim.log", cmd=>["echo q | ".$run_env."./simv", @{$param{vcs_run_flags}}, @{$param{all_run_flags}}, ], %param, expect=>$param{vcs_run_expect}, # non-verilator expect isn't the same ); } elsif ($param{vlt} #&& (!$param{needs_v4} || -r "$ENV{VERILATOR_ROOT}/src/V3Gate.cpp") ) { $param{executable} ||= "$self->{obj_dir}/$param{VM_PREFIX}"; $self->_run(logfile=>"$self->{obj_dir}/vlt_sim.log", cmd=>[($run_env .($opt_gdbsim ? ("gdb"||$ENV{VERILATOR_GDB})." " : "") .$param{executable} .($opt_gdbsim ? " -ex 'run " : "")), @{$param{all_run_flags}}, ($opt_gdbsim ? "'" : ""), ], %param, expect=>$param{expect}, # backward compatible name ); } else { $self->error("No execute step for this simulator"); } } sub inline_checks { my $self = (ref $_[0]? shift : $Self); return 1 if $self->errors || $self->skips || $self->unsupporteds; return 1 if !$self->{vlt}; my %param = (%{$self}, @_); # Default arguments are from $self my $covfn = $Self->{coverage_filename}; my $contents = $self->file_contents($covfn); $self->oprint("Extract checks\n"); my $fh = IO::File->new("<$self->{top_filename}"); while (defined(my $line = $fh->getline)) { if ($line =~ /CHECK/) { if ($line =~ /CHECK_COVER *\( *([---0-9]+) *, *"([^"]+)" *, *("([^"]+)" *,|) *(\d+) *\)/) { my $lineno=($. + $1); my $hier=$2; my $comment=$4; my $count=$5; my $regexp = "\001l\002".$lineno; $regexp .= ".*\001o\002".quotemeta($comment) if $comment; $regexp .= ".*\001h\002".quotemeta($hier); $regexp .= ".*' ".$count; if ($contents !~ /$regexp/) { $self->error("CHECK_COVER: $covfn: Regexp not found: $regexp\n". "From $self->{top_filename}:$.: $line"); } } elsif ($line =~ /CHECK_COVER_MISSING *\( *([---0-9]+) *\)/) { my $lineno=($. + $1); my $regexp = "\001l\002".$lineno; if ($contents =~ /$regexp/) { $self->error("CHECK_COVER_MISSING: $covfn: Regexp found: $regexp\n". "From $self->{top_filename}:$.: $line"); } } else { $self->error("$self->{top_filename}:$.: Unknown CHECK request: $line"); } } } $fh->close; } #---------------------------------------------------------------------- # Accessors sub ok { my $self = (ref $_[0]? shift : $Self); $self->{ok} = $_[0] if defined $_[0]; $self->{ok} = 0 if $self->{errors} || $self->{skips} || $self->unsupporteds; return $self->{ok}; } sub continuing { my $self = (ref $_[0]? shift : $Self); return !($self->errors || $self->skips || $self->unsupporteds); } sub errors { my $self = (ref $_[0]? shift : $Self); return $self->{errors}; } sub skips { my $self = (ref $_[0]? shift : $Self); return $self->{skips}; } sub unsupporteds { my $self = (ref $_[0]? shift : $Self); return $self->{unsupporteds}; } sub top_filename { my $self = (ref $_[0]? shift : $Self); $self->{top_filename} = shift if defined $_[0]; return $self->{top_filename}; } sub vhdl { my $self = (ref $_[0]? shift : $Self); $self->{vhdl} = shift if defined $_[0]; if ($self->{vhdl}) { $self->{top_filename} =~ s/\.v$/\.vhdl/; } return $self->{vhdl}; } sub v_suffix { my $self = (ref $_[0]? shift : $Self); # Suffix for file type, e.g. .vhdl or .v return $self->{vhdl} ? "vhdl" : "v"; } sub sp { my $self = (ref $_[0]? shift : $Self); return $self->{sp}; } sub sc { my $self = (ref $_[0]? shift : $Self); return $self->{sc}; } sub sc_or_sp { return sc($_[0]) || sp($_[0]); } #---------------------------------------------------------------------- sub _run { my $self = (ref $_[0]? shift : $Self); my %param = (tee=>1, @_); my $command = join(' ',@{$param{cmd}}); $command = "time $command" if $opt_benchmark; print "\t$command"; print " > $param{logfile}" if $param{logfile}; print "\n"; # Execute command redirecting output, keeping order between stderr and stdout. # Must do low-level IO so GCC interaction works (can't be line-based) my $status; { pipe(PARENTRD, CHILDWR) or die "%Error: Can't Pipe, stopped"; autoflush PARENTRD 1; autoflush CHILDWR 1; my $logfh; if ($param{logfile}) { $logfh = IO::File->new(">$param{logfile}") or die "%Error: Can't open $param{logfile}"; } my $pid=fork(); if ($pid) { # Parent close CHILDWR; while (1) { my $buf = ''; my $got = sysread PARENTRD,$buf,10000; last if defined $got && $got==0; print $buf if $param{tee}; print $logfh $buf if $logfh; } close PARENTRD; close $logfh if $logfh; } else { # Child close PARENTRD; close $logfh if $logfh; # Reset signals $SIG{ALRM} = 'DEFAULT'; $SIG{CHLD} = 'DEFAULT'; # Logging open(STDOUT, ">&CHILDWR") or croak "%Error: Can't redirect stdout, stopped"; open(STDERR, ">&STDOUT") or croak "%Error: Can't dup stdout, stopped"; autoflush STDOUT 1; autoflush STDERR 1; system "$command"; exit ($? ? 10 : 0); # $?<<8 misses coredumps } waitpid($pid,0); $status = $? || 0; } flush STDOUT; flush STDERR; if (!$param{fails} && $status) { $self->error("Exec of $param{cmd}[0] failed\n"); } if ($param{fails} && $status) { print "(Exec expected to fail, and did.)\n"; } if ($param{fails} && !$status) { $self->error("Exec of $param{cmd}[0] ok, but expected to fail\n"); } return if $self->errors || $self->skips || $self->unsupporteds; # Read the log file a couple of times to allow for NFS delays if ($param{check_finished} || $param{expect}) { for (my $try=7; $try>=0; $try--) { sleep 1 if ($try!=7); my $moretry = $try!=0; my $fh = IO::File->new("<$param{logfile}"); next if !$fh && $moretry; local $/; undef $/; my $wholefile = <$fh>; $fh->close(); # Strip debugging comments $wholefile =~ s/^- [^\n]+\n//mig; $wholefile =~ s/^- [a-z.0-9]+:\d+:[^\n]+\n//mig; $wholefile =~ s/^dot [^\n]+\n//mig; # Finished? if ($param{check_finished} && $wholefile !~ /\*\-\* All Finished \*\-\*/) { next if $moretry; $self->error("Missing All Finished\n"); } if ($param{expect}) { # Compare my $quoted = quotemeta ($param{expect}); my $bad = ($wholefile !~ /$param{expect}/ms && $wholefile !~ /$quoted/ms); if ($bad) { #print "**BAD $self->{name} $param{logfile} MT $moretry $try\n"; next if $moretry; $self->error("Mismatch in output from $param{cmd}[0]\n"); print "GOT:\n"; print $wholefile; print "ENDGOT\n"; print "EXPECT:\n"; print $param{expect}; print "ENDEXPECT\n"; } } last; } } } ####################################################################### # Little utilities sub _make_main { my $self = shift; if ($self->vhdl) { $self->_read_inputs_vhdl(); } else { $self->_read_inputs_v(); } my $filename = $self->{main_filename}; my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,"; print $fh "// Test defines\n"; print $fh "#define VL_TIME_MULTIPLIER $self->{vl_time_multiplier}\n" if $self->{vl_time_multiplier}; print $fh "// Generated header\n"; my $VM_PREFIX = $self->{VM_PREFIX}; print $fh "#include \"$VM_PREFIX.h\"\n"; print $fh "// General headers\n"; print $fh "#include \"verilated.h\"\n"; print $fh "#include \"systemc.h\"\n" if $self->sc; print $fh "#include \"systemperl.h\"\n" if $self->sp; print $fh "#include \"verilated_vcd_c.h\"\n" if $self->{trace} && !$self->sp; print $fh "#include \"verilated_save.h\"\n" if $self->{savable}; print $fh "#include \"SpTraceVcd.h\"\n" if $self->{trace} && $self->sp; print $fh "$VM_PREFIX * topp;\n"; if (!$self->sc_or_sp) { print $fh "vluint64_t main_time = false;\n"; print $fh "double sc_time_stamp () {\n"; print $fh " return main_time;\n"; print $fh "}\n"; } if ($self->{savable}) { $fh->print("\n"); $fh->print("void save_model(const char* filenamep) {\n"); $fh->print(" VL_PRINTF(\"Saving model to '%s'\\n\", filenamep);\n"); $fh->print(" VerilatedSave os;\n"); $fh->print(" os.open(filenamep);\n"); $fh->print(" os << main_time;\n"); $fh->print(" os << *topp;\n"); $fh->print(" os.close();\n"); $fh->print("}\n"); $fh->print("\n"); $fh->print("void restore_model(const char* filenamep) {\n"); $fh->print(" VL_PRINTF(\"Restoring model from '%s'\\n\", filenamep);\n"); $fh->print(" VerilatedRestore os;\n"); $fh->print(" os.open(filenamep);\n"); $fh->print(" os >> main_time;\n"); $fh->print(" os >> *topp;\n"); $fh->print(" os.close();\n"); $fh->print("}\n"); } #### Main if ($self->sc_or_sp) { print $fh "extern int sc_main(int argc, char **argv);\n"; print $fh "int sc_main(int argc, char **argv) {\n"; print $fh " sc_signal fastclk;\n" if $self->{inputs}{fastclk}; print $fh " sc_signal clk;\n" if $self->{inputs}{clk}; print $fh " sc_time sim_time ($self->{sim_time}, SC_NS);\n"; } else { print $fh "int main(int argc, char **argv, char **env) {\n"; print $fh " double sim_time = $self->{sim_time};\n"; } print $fh " Verilated::commandArgs(argc, argv);\n"; print $fh " Verilated::debug(".($self->{verilated_debug}?1:0).");\n"; print $fh " Verilated::randReset(".$self->{verilated_randReset}.");\n" if defined $self->{verilated_randReset}; print $fh " topp = new $VM_PREFIX (\"top\");\n"; my $set; if ($self->sp) { print $fh " SP_PIN(topp,fastclk,fastclk);\n" if $self->{inputs}{fastclk}; print $fh " SP_PIN(topp,clk,clk);\n" if $self->{inputs}{clk}; $set = ""; } elsif ($self->sc) { print $fh " topp->fastclk(fastclk);\n" if $self->{inputs}{fastclk}; print $fh " topp->clk(clk);\n" if $self->{inputs}{clk}; $set = ""; } else { print $fh " topp->eval();\n"; $set = "topp->"; } if ($self->{trace}) { $fh->print("\n"); $fh->print("#if VM_TRACE\n"); $fh->print(" Verilated::traceEverOn(true);\n"); if ($self->{sp}) { $fh->print(" SpTraceFile* tfp = new SpTraceFile;\n"); } else { $fh->print(" VerilatedVcdC* tfp = new VerilatedVcdC;\n"); } $fh->print(" topp->trace (tfp, 99);\n"); $fh->print(" tfp->open (\"$self->{obj_dir}/simx.vcd\");\n"); if ($self->{trace} && !$self->sc_or_sp) { $fh->print(" if (tfp) tfp->dump (main_time);\n"); } $fh->print("#endif\n"); } if ($self->{savable}) { $fh->print(" const char* save_time_strp = Verilated::commandArgsPlusMatch(\"save_time=\");\n"); $fh->print(" const char* save_restore_strp = Verilated::commandArgsPlusMatch(\"save_restore=\");\n"); $fh->print(" unsigned int save_time = !save_time_strp[0] ? 0 : atoi(save_time_strp+strlen(\"+save_time=\"));\n"); $fh->print(" unsigned int save_restore = !save_restore_strp[0] ? 0 : 1;\n"); } if ($self->{savable}) { $fh->print(" if (save_restore) {\n"); $fh->print(" restore_model(\"$self->{obj_dir}/saved.vltsv\");\n"); $fh->print(" } else {\n"); } else { $fh->print(" {\n"); } print $fh " ${set}fastclk = false;\n" if $self->{inputs}{fastclk}; print $fh " ${set}clk = false;\n" if $self->{inputs}{clk}; _print_advance_time($self, $fh, 10); print $fh " }\n"; print $fh " while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {\n"; for (my $i=0; $i<5; $i++) { my $action = 0; if ($self->{inputs}{fastclk}) { print $fh " ${set}fastclk=!${set}fastclk;\n"; $action = 1; } if ($i==0 && $self->{inputs}{clk}) { print $fh " ${set}clk=!${set}clk;\n"; $action = 1; } if ($self->{savable}) { $fh->print(" if (sc_time_stamp() == save_time && save_time) {\n"); $fh->print(" save_model(\"$self->{obj_dir}/saved.vltsv\");\n"); $fh->print(" printf(\"Exiting after save_model\\n\");\n"); $fh->print(" exit(0);\n"); $fh->print(" }\n"); } _print_advance_time($self, $fh, 1, $action); } print $fh " }\n"; print $fh " if (!Verilated::gotFinish()) {\n"; print $fh ' vl_fatal(__FILE__,__LINE__,"main", "%Error: Timeout; never got a $finish");',"\n"; print $fh " }\n"; print $fh " topp->final();\n"; if ($self->{coverage}) { $fh->print("#if VM_COVERAGE\n"); $fh->print(" VerilatedCov::write(\"",$self->{coverage_filename},"\");\n"); $fh->print("#endif //VM_COVERAGE\n"); } if ($self->{trace}) { $fh->print("#if VM_TRACE\n"); $fh->print(" if (tfp) tfp->close();\n"); $fh->print("#endif //VM_TRACE\n"); } $fh->print("\n"); print $fh " delete topp; topp=NULL;\n"; print $fh " exit(0L);\n"; print $fh "}\n"; $fh->close(); } sub _print_advance_time { my $self = shift; my $fh = shift; my $time = shift; my $action = shift; my $set; if ($self->sp) { $set = ""; } elsif ($self->sc) { $set = ""; } else { $set = "topp->"; } if ($self->sc_or_sp) { print $fh "#if (SYSTEMC_VERSION>=20070314)\n"; print $fh " sc_start(${time},SC_NS);\n"; print $fh "#else\n"; print $fh " sc_start(${time});\n"; print $fh "#endif\n"; } else { if ($action) { print $fh " ${set}eval();\n"; if ($self->{trace} && !$self->sc_or_sp) { $fh->print("#if VM_TRACE\n"); $fh->print(" if (tfp) tfp->dump (main_time);\n"); $fh->print("#endif //VM_TRACE\n"); } } print $fh " main_time += ${time};\n"; } } ####################################################################### sub _make_top { my $self = shift; if ($self->vhdl) { $self->_make_top_vhdl; } else { $self->_make_top_v; } } sub _make_top_v { my $self = shift; $self->_read_inputs_v(); my $fh = IO::File->new(">$self->{top_shell_filename}") or die "%Error: $! $self->{top_shell_filename},"; print $fh "module top;\n"; foreach my $inp (sort (keys %{$self->{inputs}})) { print $fh " reg ${inp};\n"; } # Inst print $fh " t t (\n"; my $comma=""; foreach my $inp (sort (keys %{$self->{inputs}})) { print $fh "\t${comma}.${inp} (${inp})\n"; $comma=","; } print $fh " );\n"; # Waves print $fh "\n"; print $fh "`ifdef WAVES\n"; print $fh " initial begin\n"; print $fh " \$display(\"-Tracing Waves to Dumpfile: $self->{vcd_filename}\");\n"; print $fh " \$dumpfile(\"$self->{vcd_filename}\");\n"; print $fh " \$dumpvars(0, top);\n"; print $fh " end\n"; print $fh "`endif\n"; # Test print $fh "\n"; print $fh " initial begin\n"; print $fh " fastclk=0;\n" if $self->{inputs}{fastclk}; print $fh " clk=0;\n" if $self->{inputs}{clk}; print $fh " #10;\n"; print $fh " fastclk=1;\n" if $self->{inputs}{fastclk}; print $fh " clk=1;\n" if $self->{inputs}{clk}; print $fh " while (\$time < $self->{sim_time}) begin\n"; for (my $i=0; $i<5; $i++) { print $fh " #1;\n"; print $fh " fastclk=!fastclk;\n" if $self->{inputs}{fastclk}; print $fh " clk=!clk;\n" if $i==4 && $self->{inputs}{clk}; } print $fh " end\n"; print $fh " end\n"; print $fh "endmodule\n"; $fh->close(); } sub _make_top_vhdl { my $self = shift; $self->_read_inputs_vhdl(); my $fh = IO::File->new(">$self->{top_shell_filename}") or die "%Error: $! $self->{top_shell_filename},"; print $fh "library ieee;\n"; my @ports = sort (keys %{$self->{inputs}}); print $fh "entity t_ent is\n"; if ($#ports >= 0) { print $fh " port(\n"; my $semi = ""; foreach my $inp (@ports) { print $fh "\t${semi}${inp} : in std_logic\n"; $semi=";"; } print $fh " );\n"; } print $fh "end;\n"; print $fh "entity top is\n"; print $fh "end;\n"; # Inst print $fh "architecture t_beh of t_ent is\n"; if ($#ports >= 0) { foreach my $inp (@ports) { print $fh "\tsignal ${inp} : std_logic := '0';\n"; } } print $fh " begin\n"; print $fh " t : t_ent\n"; if ($#ports >= 0) { print $fh " port map(\n"; my $comma=""; foreach my $inp (@ports) { print $fh "\t${comma}${inp} => ${inp}\n"; $comma=","; } print $fh " )\n"; } print $fh " ;\n"; print $fh " end;\n"; # Waves TBD # Test TBD print $fh "end;\n"; $fh->close(); } ####################################################################### sub _sp_preproc { my $self = shift; my %param = (%{$self}, @_); # Default arguments are from $self $self->oprint("Preproc\n"); $self->_run(logfile=>"simx.log", fails=>0, cmd=>["cd $self->{obj_dir} ; sp_preproc", "--preproc", "$self->{VM_PREFIX}.sp", ]); } ####################################################################### sub _read_inputs_v { my $self = shift; my $filename = $self->top_filename; $filename = "$self->{t_dir}/$filename" if !-r $filename; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename,"; my $get_sigs=1; my %inputs; while (defined(my $line = $fh->getline)) { if ($get_sigs) { if ($line =~ /^\s*input\s*(\S+)\s*(\/[^\/]+\/|)\s*;/) { $inputs{$1} = $1; } if ($line =~ /^\s*(function|task|endmodule)/) { $get_sigs = 0; } } if ($line =~ /^\s*module\s+t\b/) { # Ignore any earlier inputs; Module 't' has precedence %inputs = (); $get_sigs = 1; } } $self->{inputs}{$_} = $inputs{$_} foreach keys %inputs; $fh->close(); } ####################################################################### sub _read_inputs_vhdl { my $self = shift; my $filename = $self->top_filename; $filename = "$self->{t_dir}/$filename" if !-r $filename; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename,"; while (defined(my $line = $fh->getline)) { # Only supports this form right now: # signal: in ... # signal: out ... if ($line =~ /^\s*(\S+)\s*:\s*(in)\b\s*/) { $self->{inputs}{$1} = $1; } if ($line =~ /^\s*(architecture)/) { last; } } $fh->close(); } ####################################################################### # Verilator utilities our $_Verilator_Version; sub verilator_version { if (!defined $_Verilator_Version) { my @args = ("perl","../bin/verilator", "--version"); my $args = join(' ',@args); $_Verilator_Version = `$args`; $_Verilator_Version or die "can't fork: $! ".join(' ',@args); chomp $_Verilator_Version; } return $_Verilator_Version if defined $_Verilator_Version; } ####################################################################### # File utilities sub files_identical { my $fn1 = shift; my $fn2 = shift; my $f1 = IO::File->new ("<$fn1"); if (!$f1) { warn "%Error: $! $fn1\n"; return 0; } my $f2 = IO::File->new ("<$fn2"); if (!$f2) { warn "%Error: $! $fn2\n"; return 0; } my @l1 = $f1->getlines(); my @l2 = $f2->getlines(); my $nl = $#l1; $nl = $#l2 if ($#l2 > $nl); for (my $l=0; $l<=$nl; $l++) { if (($l1[$l]||"") ne ($l2[$l]||"")) { warn ("%Warning: Line ".($l+1)." mismatches; $fn1 != $fn2\n" ."F1: ".($l1[$l]||"*EOF*\n") ."F2: ".($l2[$l]||"*EOF*\n")); if ($ENV{HARNESS_UPDATE_GOLDEN}) { # Update golden files with current warn "%Warning: HARNESS_UPDATE_GOLDEN set: cp $fn1 $fn2\n"; eval "use File::Copy;"; File::Copy::copy($fn1,$fn2); } else { warn "To update reference: HARNESS_UPDATE_GOLDEN=1 {command} or --golden\n"; } return 0; } } return 1; } sub vcd_identical { my $self = (ref $_[0]? shift : $Self); my $fn1 = shift; my $fn2 = shift; if (!-r $fn1) { $self->error("File does not exist $fn1\n"); return 0; } if (!-r $fn2) { $self->error("File does not exist $fn2\n"); return 0; } { # vcddiff to check transitions, if installed my $out = `vcddiff --help`; if ($out !~ /Usage:/) { $self->skip("No vcddiff installed\n"); return 0; } my $cmd = qq{vcddiff "$fn1" "$fn2"}; print "\t$cmd\n" if $::Debug; $out = `$cmd`; if ($out ne '') { print $out; $self->error("VCD miscompare $fn1 $fn2\n"); if ($ENV{HARNESS_UPDATE_GOLDEN}) { # Update golden files with current warn "%Warning: HARNESS_UPDATE_GOLDEN set: cp $fn1 $fn2\n"; eval "use File::Copy;"; File::Copy::copy($fn1,$fn2); } return 0; } } { # vcddiff doesn't check module and variable scope, so check that # Also provides backup if vcddiff not installed my $h1 = $self->_vcd_read($fn1); my $h2 = $self->_vcd_read($fn2); $Data::Dumper::Sortkeys=1; my $a = Dumper($h1); my $b = Dumper($h2); if ($a ne $b) { print "$a\n$b\n" if $::Debug; $self->error("VCD hier mismatch $fn1 $fn2\n"); return 0; } } return 1; } sub _vcd_read { my $self = (ref $_[0]? shift : $Self); my $filename = shift; my $data = {}; my $fh = IO::File->new ("<$filename"); if (!$fh) { warn "%Error: $! $filename\n"; return $data; } my @hier = ($data); while (defined(my $line = $fh->getline)) { if ($line =~ /\$scope module\s+(\S+)/) { $hier[$#hier]->{$1} ||= {}; push @hier, $hier[$#hier]->{$1}; } elsif ($line =~ /(\$var \S+\s+\d+\s+)\S+\s+(\S+)/) { $hier[$#hier]->{$1.$2} ||= 1; } elsif ($line =~ /\$enddefinitions/) { last; } while ($line =~ s/\$upscope//) { pop @hier; } } return $data; } sub file_grep_not { my $self = (ref $_[0]? shift : $Self); my $filename = shift; my $regexp = shift; my $expvalue = shift; return if $self->errors || $self->skips || $self->unsupporteds; !defined $expvalue or $self->error("file_grep_not: Unexpected 3rd argument: $expvalue"); my $contents = $self->file_contents($filename); return if ($contents eq "_Already_Errored_"); if ($contents =~ /$regexp/) { $self->error("File_grep_not: $filename: Regexp found: $regexp\n"); } } sub file_grep { my $self = (ref $_[0]? shift : $Self); my $filename = shift; my $regexp = shift; my $expvalue = shift; return if $self->errors || $self->skips || $self->unsupporteds; my $contents = $self->file_contents($filename); return if ($contents eq "_Already_Errored_"); if ($contents !~ /$regexp/) { $self->error("File_grep: $filename: Regexp not found: $regexp\n"); } elsif ($expvalue && $expvalue ne $1) { $self->error("File_grep: $filename: Got='$1' Expected='$expvalue' in regexp: $regexp\n"); } } my %_File_Contents_Cache; sub file_contents { my $self = (ref $_[0]? shift : $Self); my $filename = shift; if (!$_File_Contents_Cache{$filename}) { my $fh = IO::File->new("<$filename"); if (!$fh) { $_File_Contents_Cache{$filename} = "_Already_Errored_"; $self->error("File_grep file not found: ".$filename."\n"); return $_File_Contents_Cache{$filename}; } local $/; undef $/; my $wholefile = <$fh>; $fh->close(); $_File_Contents_Cache{$filename} = $wholefile; } return $_File_Contents_Cache{$filename}; } sub write_wholefile { my $self = (ref $_[0]? shift : $Self); my $filename = shift; my $contents = shift; my $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename,"; print $fh $contents; $fh->close; } ####################################################################### ####################################################################### ####################################################################### ####################################################################### # Forker class package Forker; use strict; # This is a shell that matches Parallel::Forker. # If that package is not installed, this runs the tests in *series* sub new { my $class = shift; my $self = {@_}; bless $self, $class; return $self; } sub schedule { my $self = shift; my %params = (@_); &{$params{run_on_start}}(); &{$params{run_on_finish}}(); return $self; } sub max_proc {} sub sig_child {} sub kill_tree_all {} sub wait_all {} sub ready {} sub running {} ####################################################################### 1; package main; __END__ =pod =head1 NAME driver.pl - Run regression tests =head1 SYNOPSIS driver.pl =head1 DESCRIPTION driver.pl invokes Verilator or another simulator on each test file. The driver reports the number of tests which pass, fail, skipped (some resource required by the test is not available, such as SystemC), or are unsupported (buggy or require a feature change before will pass.) There are hundreds of tests, and for faster completion you may want to run the regression tests with CCACHE enabled and in parallel on a machine with many cores. See the -j option. =head1 TEST CONFIGURATION The Perl script (e.g. C) controls how the test will run by driver.pl. In general it includes a call to the C subroutine to compile the test with Verilator (or an alternative simulator), followed by a call to the C subroutine to run the test. Compile-only tests omit the call to C. If those complete, the script calls C to increment the count of successful tests and then returns 1 as its result. Both C and C take an optional argument hash table to control their behavior. For example: compile ( verilator_flags2 => ["--lint-only"], fails => 1, ); indicates that when compiling this test, the C<--lint-only> flag should be passed and that the test is expected to fail. The full list of arguments can be found by looking at the C source code. Some commonly used arguments are: =over 4 =item all_run_flags A list of flags to be passed when running the simulator (Verilated model or one of the other simulators). =item check_finished Set to 1 to indicate successful completion of the test is indicated by the string C<*-* All Finished *-*> being printed on standard output. This is the normal way for successful tests to finish. =item expect A quoted list of strings or regular expression to be matched in the output. See for more detail on how this argument should be used. =item fails Set to 1 to indicate this step (C or C) is expected to fail. Tests that are expected to fail generally have _bad in their filename. =item make_main Set to 0 to disable the automatic creation of a C++ test wrapper (for example when a hand-written test wrapper is provided using C<--exe>). =item make_top_shell Set to 0 to disable the automatic creation of a top level shell to run the executable (for example when a hand-written test wrapper is provided using C<--exe>). =item ms_flags =item ms_flags2 =item ms_run_flags The equivalent of C, C and C, but only for use with the ModelSim simulator. =item nc_flags =item nc_flags2 =item nc_run_flags The equivalent of C, C and C, but only for use with the Cadence NC simulator. =item iv_flags =item iv_flags2 =item iv_run_flags The equivalent of C, C and C, but only for use with the Icarus Verilog simulator. =item v_flags A list of standard Verilog simulator flags to be passed to the simulator compiler (Verilator or one of the other simulators). This list is create by the driver and rarely changed, use v_flags2 instead. =item v_flags2 A list of standard Verilog simulator flags to be passed to the simulator compiler (Verilator or one of the other simulators). Unlike v_flags, these options may be overridden in some simulation files. Similar sets of flags exist for atsim, GHDL, Cadence NC, Modelsim and Synopsys VCS. =item vcs_flags =item vcs_flags2 =item vcs_run_flags The equivalent of C, C and C, but only for use with the Synopsys VCS simulator. =item verilator_flags =item verilator_flags2 The equivalent of C and C, but only for use with Verilator. If a flag is a standard flag (+incdir for example) v_flags2 should be used instead. =back =head2 HINTS ON WRITING TESTS There is generally no need for the test to create its own main program or top level shell as the driver creates one automatically, however some tests require their own C++ or SystemC test harness. This is commonly given the same name as the test, but with .cpp as suffix (C). This can be specified as follows: compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], ); Tests should be self-checking, rather than producing lots of output. If a test succeeds it should print C<*-* All Finished *-*> to standard output and terminate (in Verilog C<$finish>), if not it should just stop (in Verilog C<$stop>) as that signals an error. If termination should be triggered from the C++ wrapper, the following code can be used: vl_fatal (__FILE__, __LINE__, "dut", ""); exit (1); This can be particularly useful if checking that the Verilator model has not unexpectedly terminated. if (Verilated::gotFinish ()) { vl_fatal (__FILE__, __LINE__, "dut", ""); exit (1); } Where it might be useful for a test to produce output, it should qualify this with C. For example in Verilog: `ifdef TEST_VERBOSE $write ("Conditional generate if MASK [%1d] = %d\n", g, MASK[g]); `endif Or in a hand-written C++ wrapper: #ifdef TEST_VERBOSE cout << "Read a = " << a << endl; #endif The C argument should not generally be used to decide if a test has succeeded. However, in the case of tests that are designed to fail at compile time, it is the only option. For example: compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Error: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Error: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Error: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Error: Exiting due to .*}, ); The strings to match should be made general - for example the line numbers in the Verilog should not be critical and the total number of errors should not matter. This makes it easier to extend or modify the test in future. =head1 DRIVER ARGUMENTS =over 4 =item --atsim Run using ATSIM simulator. =item --benchmark [] Show execution times of each step. If an optional number is given, specifies the number of simulation cycles (for tests that support it). =item --debug Same as C: Use the debug version of Verilator which enables additional assertions, debugging messages, and structure dump files. =item --debugi(-) Same as C: Set Verilator internal debugging level globally to the specified debug level (1-10) or set the specified source file to the specified level. Higher levels produce more detailed messages (plain C<--debug> is equivalent to C<--debugi 4>). =item --dump-tree Same as C: Enable Verilator writing .tree debug files with dumping level 3, which dumps the standard critical stages. For details on the format see the Verilator Internals manual. =item --gdb Same as C: Run Verilator under the debugger. =item --gdbbt Same as C: Run Verilator under the debugger, only to print backtrace information. Requires --debug. =item --gdbsim Run Verilator generated executable under the debugger. =item --ghdl Run using GHDL simulator. =item --golden Update golden files, equivalent to setting HARNESS_UPDATE_GOLDEN=1. =item --help Displays this message and program version and exits. =item --iverilog Run using Icarus Verilog simulator. =item --j # Run number of parallel tests, or 0 to determine the count based on the number of cores installed. Requires Perl's Parallel::Forker package. =item --ms Run using ModelSim simulator. =item --nc Run using Cadence NC-Verilog simulator. =item --optimize Randomly turn on/off different optimizations. With specific flags, use those optimization settings =item --site Run site specific tests also. =item --stop Stop on the first error. =item --trace Set the simulator specific flags to request waveform tracing. =item --unsupported Run tests even if marked as unsupported. =item --vcs Run using Synopsys VCS simulator. =item --verbose Compile and run the test in verbose mode. This means C will be defined for the test (Verilog and any C++/SystemC wrapper). =item --vlt Run using Verilator. Defaults set unless another simulator is requested. =back =head1 ENVIRONMENT =over 4 =item SYSTEMC Root directory name of SystemC kit. Only used if SYSTEMC_INCLUDE not set. =item SYSTEMC_INCLUDE Directory name with systemc.h in it. =item VERILATOR_GHDL Command to use to invoke GHDL. =item VERILATOR_IVERILOG Command to use to invoke Icarus Verilog. =item VERILATOR_MODELSIM Command to use to invoke ModelSim. =item VERILATOR_NCVERILOG Command to use to invoke ncverilog. =item VERILATOR_TESTS_SITE With --site, directory of tests to be added to testlist. =item VERILATOR_VCS Command to use to invoke VCS. =back =head1 DISTRIBUTION The latest version is available from L. Copyright 2003-2015 by Wilson Snyder. Verilator 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. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO L =cut ###################################################################### verilator-3.874/test_regress/Makefile_obj0000664000177100017500000000367612525171734020551 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-2015 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. # #***************************************************************************** default: $(VM_PREFIX) ifneq ($(MAKE_MAIN),0) # Add main to classes rather then SP_SRCS to save a compiler run VM_CLASSES += ${VM_PREFIX}__main $(VM_USER_CLASSES) $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW) endif include $(VM_PREFIX).mk VPATH += ../../$(VM_USER_DIR) ####################################################################### # Needed by DPI tests CPPFLAGS += -DVERILATOR=1 # Needed by tracing routines CPPFLAGS += -DVL_DEBUG=1 CPPFLAGS += -DVM_PREFIX=$(VM_PREFIX) CPPFLAGS += $(CPPFLAGS_DRIVER) CPPFLAGS += $(CPPFLAGS_DRIVER2) CPPFLAGS += $(CPPFLAGS_ADD) ####################################################################### # Linking final exe ifeq ($(VM_SP_OR_SC),1) LIBS += $(SC_LIBS) endif #Default compile, pick up OBJCACHE %.o: %.cpp $(OBJCACHE) $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< #Default link, using normal make rules #$(VM_PREFIX): $(VK_GLOBAL_OBJS) $(VK_OBJS) # $(LINK) $(LDFLAGS) -g $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) 2>&1 | c++filt #Our own compile rules; Faster compile, all in one file $(VM_PREFIX)__ALLboth.cpp: $(VK_CLASSES_CPP) $(VK_SUPPORT_CPP) $(VERILATOR_INCLUDER) -DVL_INLINE_OPT=inline $^ > $@ $(VM_PREFIX)__ALLboth.o: $(VM_PREFIX)__ALLboth.cpp $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $< ifneq ($(MAKE_MAIN),0) $(VM_PREFIX): $(VM_PREFIX)__ALLboth.o $(LINK) $(LDFLAGS) -g $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) 2>&1 | c++filt endif verilator-3.874/test_regress/input.vc0000664000177100017500000000013412473477707017745 0ustar wsnyderwsnyder +librescan +libext+.v -y t -y obj_dir/ +incdir+t +incdir+../include +incdir+obj_dir/ verilator-3.874/test_regress/Makefile0000664000177100017500000000433112525171734017704 0ustar wsnyderwsnyder#***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside source directory # # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # # Copyright 2003-2015 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. # #****************************************************************************/ default: test # This must point to the root of the VERILATOR kit VERILATOR_ROOT := $(shell pwd)/.. export VERILATOR_ROOT # Pick up PERL and other variable settings include $(VERILATOR_ROOT)/include/verilated.mk ###################################################################### ifneq ($(VCS_HOME),) #Default to off, even with vcs; not all tests are insured to be working #PRODUCTS += --vcs endif ifneq ($(NC_ROOT),) #Default to off, even with vcs; not all tests are insured to be working #PRODUCTS += --nc endif PRODUCTS += --vlt # Run tests in parallel. Requires Parallel::Forker to be installed. ifeq ($(CFG_WITH_LONGTESTS),yes) DRIVER_FLAGS += -j 0 endif ###################################################################### .PHONY: test test: $(PERL) driver.pl $(DRIVER_FLAGS) $(PRODUCTS) ###################################################################### vcs: $(PERL) driver.pl $(DRIVER_FLAGS) --vcs --stop ###################################################################### nc: $(PERL) driver.pl $(DRIVER_FLAGS) --nc --stop ###################################################################### vlt: $(PERL) driver.pl $(DRIVER_FLAGS) --vlt --stop ###################################################################### random: $(PERL) driver.pl $(DRIVER_FLAGS) --optimize : --stop random_forever: while ( VERILATOR_NO_DEBUG=1 CPPFLAGS_ADD=-Wno-error $(MAKE) random ) ; do \ echo ; \ done ###################################################################### maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir simv* simx* csrc cov_work INCA_libs *.log *.key logs vc_hdrs.h verilator-3.874/test_regress/t/0000775000177100017500000000000012534632375016511 5ustar wsnyderwsnyderverilator-3.874/test_regress/t/t_func_twocall.pl0000775000177100017500000000071712473477707022071 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_zx_bad.pl0000775000177100017500000000117012473477707021645 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Warning-CASEWITHX: t/t_case_zx_bad.v:\d+: Use of x constant in casez statement, \(perhaps intended \?/z in constant\) .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_array.pl0000775000177100017500000000077312473477707021756 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2=>["-Wno-UNOPTFLAT"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_topmodule_bad.pl0000775000177100017500000000145612473477707023221 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. top_filename("t/t_flag_topmodule.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( fails=>$Self->{v3}, nc=>0, # Need to get it not to give the prompt expect=> '%Error-MULTITOP: t/t_flag_topmodule.v:\d+: Unsupported: Multiple top level modules: .* %Error-MULTITOP: t/t_flag_topmodule.v:\d+: Fix, or use --top-module option to select which you want. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_combo.pl0000775000177100017500000000076612473477707021741 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ['+define+ALLOW_UNOPT'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_program.v0000664000177100017500000000040512473477707020701 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. program t; initial begin $write("*-* All Finished *-*\n"); $finish; end endprogram verilator-3.874/test_regress/t/t_bitsel_struct2.v0000664000177100017500000000274712473477707022215 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t (/*AUTOARG*/); typedef struct packed { logic [3:2] a; logic [5:4][3:2] b; } ab_t; typedef ab_t [7:6] c_t; // array of structs typedef struct packed { c_t [17:16] d; } e_t; `define checkb(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='b%x exp='b%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); initial begin e_t e; `checkh($bits(ab_t),6); `checkh($bits(c_t),12); `checkh($bits(e_t),24); `checkh($bits(e), 24); `checkh($bits(e.d[17]),12); `checkh($bits(e.d[16][6]),6); `checkh($bits(e.d[16][6].b[5]),2); `checkh($bits(e.d[16][6].b[5][2]), 1); // e = 24'b101101010111010110101010; `checkb(e, 24'b101101010111010110101010); e.d[17] = 12'b111110011011; `checkb(e, 24'b111110011011010110101010); e.d[16][6] = 6'b010101; `checkb(e, 24'b111110011011010110010101); e.d[16][6].b[5] = 2'b10; `checkb(e, 24'b111110011011010110011001); e.d[16][6].b[5][2] = 1'b1; // $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_var_pins_sc32.pl0000775000177100017500000000405112473477707022057 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -no-pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.874/test_regress/t/t_mem_multi_io2.cpp0000664000177100017500000000355512473477707022321 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks #if defined(T_MEM_MULTI_IO2_CC) # include "Vt_mem_multi_io2_cc.h" #elif defined(T_MEM_MULTI_IO2_SC) # include "Vt_mem_multi_io2_sc.h" #else # error "Unknown test" #endif VM_PREFIX* tb = NULL; bool pass = true; double sc_time_stamp() { return 0; } void check(const char* bus, int got, int exp) { if (got != exp) { VL_PRINTF("%%Error: Data mismatch on '%s', got=%x, exp=%x\n", bus, got, exp); pass = false; } } int main() { Verilated::debug(0); tb = new VM_PREFIX ("tb"); #ifdef SYSTEMC_VERSION sc_signal i3; sc_signal o3; sc_signal i34[4]; sc_signal o34[4]; sc_signal i345[4][5]; sc_signal o345[4][5]; tb->i3(i3); tb->o3(o3); for (int i=0; i<4; i++) { tb->i34[i](i34[i]); tb->o34[i](o34[i]); for (int j=0; j<5; j++) { tb->i345[i][j](i345[i][j]); tb->o345[i][j](o345[i][j]); } } #endif // loop through every possibility and check the result #ifdef SYSTEMC_VERSION sc_start(1,SC_NS); # define ASSIGN(s,v) s.write(v) # define READ(s) s.read() #else tb->eval(); # define ASSIGN(s,v) tb->s = (v) # define READ(s) tb->s #endif ASSIGN(i3, 13); for (int i=0; i<4; i++) { ASSIGN(i34[i], i); for (int j=0; j<5; j++) { ASSIGN(i345[i][j], i*8 + j); } } #ifdef SYSTEMC_VERSION sc_start(1,SC_NS); #else tb->eval(); #endif check("o3", READ(o3), 13); for (int i=0; i<4; i++) { check("o34", READ(o34[i]), i); for (int j=0; j<5; j++) { check("o345", READ(o345[i][j]), i*8 + j); } } if (pass) { VL_PRINTF("*-* All Finished *-*\n"); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from test\n"); } return 0; } verilator-3.874/test_regress/t/t_inst_first_a.v0000664000177100017500000000142112473477707021715 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_inst_first_a (/*AUTOARG*/ // Outputs o_w5, o_w5_d1r, o_w40, o_w104, // Inputs clk, i_w5, i_w40, i_w104 ); input clk; input [4:0] i_w5; output [4:0] o_w5; output [4:0] o_w5_d1r; input [39:0] i_w40; output [39:0] o_w40; input [104:0] i_w104; output [104:0] o_w104; wire [4:0] o_w5 = i_w5; wire [39:0] o_w40 = i_w40; wire [104:0] o_w104 = i_w104; /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [4:0] o_w5_d1r; // End of automatics always @ (posedge clk) begin o_w5_d1r <= i_w5; end endmodule verilator-3.874/test_regress/t/t_vlcov_data_a.dat0000664000177100017500000000026712473477707022165 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint0ffile1.sphl159' 0 C 'CoverPoint1ffile1.sphl159' 1 C 'CoverPoint2ffile1.sphl159' 10 C 'CoverPoint3ffile1.sphl159' 0 verilator-3.874/test_regress/t/t_case_dupitems.v0000664000177100017500000000344712473477707022070 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [1:0] in = crc[1:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [1:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[1:0]), // Inputs .in (in[1:0])); // Aggregate outputs into a single result vector wire [63:0] result = {62'h0, out}; // What checksum will we end up with `define EXPECTED_SUM 64'hbb2d9709592f64bd // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs in ); input [1:0] in; output reg [1:0] out; always @* begin // bug99: Internal Error: ../V3Ast.cpp:495: New node already linked? case (in[1:0]) 2'd0, 2'd1, 2'd2, 2'd3: begin out = in; end endcase end endmodule verilator-3.874/test_regress/t/t_func_plog.pl0000775000177100017500000000071712473477707021365 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_alw.pl0000775000177100017500000000071712473477707021025 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_file_scan.pl0000775000177100017500000000112312473477707022222 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. unlink("$Self->{obj_dir}/t_sys_file_scan_test.log"); compile ( ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/t_sys_file_scan_test.log", "# a 1 "); ok(1); 1; verilator-3.874/test_regress/t/t_tri_eqcase.pl0000775000177100017500000000071712473477707021530 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_rand.pl0000775000177100017500000000116112473477707021342 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_blocking.pl0000775000177100017500000000071712473477707021201 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_graphcirc.v0000664000177100017500000000177312473477707022220 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (clk); input clk; integer cyc; initial cyc=0; always @(posedge clk) begin cyc <= cyc + 1; if (cyc == 1) begin ReadContDisps; end else if (cyc == 5) begin $write("*-* All Finished *-*\n"); $finish; end `ifndef verilator DispContDisps; `endif end task ReadContDisps; begin $display("%m: Here: %d", cyc); end endtask integer dindex; task DispContDisps; /* verilator public */ begin if (cyc >= 2) begin if ( cyc >= 4 ) begin dindex = dindex + 2; //*** Error line $display("%m: DIndex increment %d", cyc); `ifdef VERILATOR $c("VL_PRINTF(\"Hello1?\\n\");"); `endif end `ifdef VERILATOR $c("VL_PRINTF(\"Hello2?\\n\");"); $c("VL_PRINTF(\"Hello3?\\n\");"); `endif end end endtask endmodule verilator-3.874/test_regress/t/t_interface_down_gen.v0000664000177100017500000000321012473477707023047 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // This test demonstrates how not only parameters but the type of a parent // interface could propagate down to child modules, changing their data type // determinations. Note presently unsupported in all commercial simulators. interface ifc; parameter MODE = 0; generate // Note block must be named per SystemVerilog 2005 if (MODE==1) begin : g integer value; end else if (MODE==2) begin : g real value; end endgenerate endinterface module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc #(1) itop1a(); ifc #(1) itop1b(); ifc #(2) itop2a(); ifc #(2) itop2b(); wrapper c1 (.isuba(itop1a), .isubb(itop1b), .i_valuea(14.1), .i_valueb(15.2)); wrapper c2 (.isuba(itop2a), .isubb(itop2b), .i_valuea(24.3), .i_valueb(25.4)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==20) begin if (itop1a.g.value != 14) $stop; if (itop1b.g.value != 15) $stop; if (itop2a.g.value != 24) $stop; if (itop2b.g.value != 25) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module wrapper ( ifc isuba, ifc isubb, input real i_valuea, input real i_valueb ); lower subsuba (.isub(isuba), .i_value(i_valuea)); lower subsubb (.isub(isubb), .i_value(i_valueb)); endmodule module lower ( ifc isub, input real i_value ); always @* begin `error Commercial sims choke on cross ref here isub.g.value = i_value; end endmodule verilator-3.874/test_regress/t/t_preproc_ifdef.pl0000775000177100017500000000071712473477707022220 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_v2k.v0000664000177100017500000000271312473477707020775 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; supply0 [1:0] low; supply1 [1:0] high; reg [7:0] isizedwire; reg ionewire; `ifdef never_just_for_verilog_mode wire oonewire; // From sub of t_inst_v2k__sub.v `endif wire [7:0] osizedreg; // From sub of t_inst_v2k__sub.v wire [1:0] tied; wire [3:0] tied_also; hello hsub (.tied_also); // Double underscore tests bug631 t_inst_v2k__sub sub ( // Outputs .osizedreg (osizedreg[7:0]), // verilator lint_off IMPLICIT .oonewire (oonewire), // verilator lint_on IMPLICIT .tied (tied[1:0]), // Inputs .isizedwire (isizedwire[7:0]), .ionewire (ionewire)); always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin ionewire <= 1'b1; isizedwire <= 8'd8; end if (cyc==2) begin if (low != 2'b00) $stop; if (high != 2'b11) $stop; if (oonewire !== 1'b1) $stop; if (isizedwire !== 8'd8) $stop; if (tied != 2'b10) $stop; if (tied_also != 4'b1010) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule module hello(tied_also); initial $write ("Hello\n"); output reg [3:0] tied_also = 4'b1010; endmodule verilator-3.874/test_regress/t/t_chg_first.v0000664000177100017500000000330612473477707021205 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk, fastclk ); input clk; input fastclk; // surefire lint_off_line UDDIXN integer _mode; initial _mode=0; reg [31:0] ord1; initial ord1 = 32'h1111; wire [31:0] ord2; reg [31:0] ord3; wire [31:0] ord4; wire [31:0] ord5; wire [31:0] ord6; wire [31:0] ord7; // verilator lint_off UNOPT t_chg_a a ( .a(ord1), .a_p1(ord2), .b(ord4), .b_p1(ord5), .c(ord3), .c_p1(ord4), .d(ord6), .d_p1(ord7) ); // surefire lint_off ASWEMB assign ord6 = ord5 + 1; // verilator lint_on UNOPT always @ (/*AS*/ord2) ord3 = ord2 + 1; always @ (fastclk) begin // surefire lint_off_line ALWLTR ALWMTR if (_mode==1) begin //$write("[%0t] t_chg: %d: Values: %x %x %x %x %x %x %x\n",$time,fastclk,ord1,ord2,ord3,ord4,ord5,ord6,ord7); //if (ord2 == 2 && ord7 != 7) $stop; end end always @ (posedge clk) begin if (_mode==0) begin $write("[%0t] t_chg: Running\n", $time); _mode<=1; ord1 <= 1; end else if (_mode==1) begin _mode<=2; if (ord7 !== 7) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module t_chg_a (/*AUTOARG*/ // Outputs a_p1, b_p1, c_p1, d_p1, // Inputs a, b, c, d ); input [31:0] a; output [31:0] a_p1; wire [31:0] a_p1 = a + 1; input [31:0] b; output [31:0] b_p1; wire [31:0] b_p1 = b + 1; input [31:0] c; output [31:0] c_p1; wire [31:0] c_p1 = c + 1; input [31:0] d; output [31:0] d_p1; wire [31:0] d_p1 = d + 1; endmodule verilator-3.874/test_regress/t/t_param_concat.v0000664000177100017500000000105512473477707021663 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter UNSIZED = 10; integer cyc=1; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==1) begin if ({UNSIZED,UNSIZED+1} != {32'd10, 32'd11}) $stop; if ({2{UNSIZED}} != {32'd10, 32'd10}) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_math_signed3.v0000664000177100017500000000610112473477707021576 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) module t (/*AUTOARG*/); // verilator lint_off WIDTH wire [1:0] bug729_au = ~0; wire signed [1:0] bug729_as = ~0; wire [2:0] bug729_b = ~0; // the $signed output is unsigned because the input is unsigned; the signedness does not change. wire [0:0] bug729_yuu = $signed(2'b11) == 3'b111; //1'b0 wire [0:0] bug729_ysu = $signed(2'sb11) == 3'b111; //1'b0 wire [0:0] bug729_yus = $signed(2'b11) == 3'sb111; //1'b1 wire [0:0] bug729_yss = $signed(2'sb11) == 3'sb111; //1'b1 wire [0:0] bug729_zuu = 2'sb11 == 3'b111; //1'b0 wire [0:0] bug729_zsu = 2'sb11 == 3'b111; //1'b0 wire [0:0] bug729_zus = 2'sb11 == 3'sb111; //1'b1 wire [0:0] bug729_zss = 2'sb11 == 3'sb111; //1'b1 wire [3:0] bug733_a = 4'b0010; wire [3:0] bug733_yu = $signed(|bug733_a); // 4'b1111 note | is always unsigned wire signed [3:0] bug733_ys = $signed(|bug733_a); // 4'b1111 wire [3:0] bug733_zu = $signed(2'b11); // 4'b1111 wire signed [3:0] bug733_zs = $signed(2'sb11); // 4'b1111 // When RHS of assignment is fewer bits than lhs, RHS sign or zero extends based on RHS's sign wire [3:0] bug733_qu = 2'sb11; // 4'b1111 wire signed [3:0] bug733_qs = 2'sb11; // 4'b1111 reg signed [32:0] bug349_s; reg signed [32:0] bug349_u; wire signed [1:0] sb11 = 2'sb11; wire [3:0] subout_u; sub sub (.a(2'sb11), .z(subout_u)); initial `checkh(subout_u, 4'b1111); wire [5:0] cond_a = 1'b1 ? 3'sb111 : 5'sb11111; initial `checkh(cond_a, 6'b111111); wire [5:0] cond_b = 1'b0 ? 3'sb111 : 5'sb11111; initial `checkh(cond_b, 6'b111111); initial begin // verilator lint_on WIDTH `checkh(bug729_yuu, 1'b0); `checkh(bug729_ysu, 1'b0); `checkh(bug729_yus, 1'b1); `checkh(bug729_yss, 1'b1); `checkh(bug729_zuu, 1'b0); `checkh(bug729_zsu, 1'b0); `checkh(bug729_zus, 1'b1); `checkh(bug729_zss, 1'b1); `checkh(bug733_yu, 4'b1111); `checkh(bug733_ys, 4'b1111); `checkh(bug733_zu, 4'b1111); `checkh(bug733_zs, 4'b1111); `checkh(bug733_qu, 4'b1111); `checkh(bug733_qs, 4'b1111); // verilator lint_off WIDTH bug349_s = 4'sb1111; `checkh(bug349_s, 33'h1ffffffff); bug349_u = 4'sb1111; `checkh(bug349_u, 33'h1ffffffff); bug349_s = 4'sb1111 - 1'b1; `checkh(bug349_s,33'he); bug349_s = 4'sb1111 - 5'b00001; `checkh(bug349_s,33'he); case (2'sb11) 4'b1111: ; default: $stop; endcase case (sb11) 4'b1111: ; default: $stop; endcase $write("*-* All Finished *-*\n"); $finish; end endmodule module sub (input [3:0] a, output [3:0] z); assign z = a; endmodule verilator-3.874/test_regress/t/t_debug_fatalsrc_bt_bad.pl0000775000177100017500000000144012473477707023643 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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. $ENV{VERILATOR_TEST_NO_GDB} and $Self->skip("Skipping due to VERILATOR_TEST_NO_GDB"); compile ( v_flags2 => ["--lint-only --debug --gdbbt --debug-fatalsrc"], fails=>$Self->{v3}, expect=> '%Error: Internal Error: .*: --debug-fatal-src %Error: Internal Error: See the manual and http://www.veripool.org/verilator for more assistance. .*in V3Options::.* .*%Error: Command Failed.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_chg_first.pl0000775000177100017500000000072212473477707021355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_cat_reopen.out0000664000177100017500000001745012473477707023101 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Sat Feb 23 20:18:07 2013 $end $timescale 1ns $end $scope module top $end $var wire 1 $ clk $end $scope module v $end $var wire 1 $ clk $end $var wire 32 # cyc [31:0] $end $upscope $end $upscope $end $enddefinitions $end #0 b00000000000000000000000000000001 # 1$ #1 0$ #2 b00000000000000000000000000000010 # 1$ #3 0$ #4 b00000000000000000000000000000011 # 1$ #5 0$ #6 b00000000000000000000000000000100 # 1$ #7 0$ #8 b00000000000000000000000000000101 # 1$ #9 0$ #10 b00000000000000000000000000000110 # 1$ #11 0$ #12 b00000000000000000000000000000111 # 1$ #13 0$ #14 b00000000000000000000000000001000 # 1$ #15 0$ #16 b00000000000000000000000000001001 # 1$ #17 0$ #18 b00000000000000000000000000001010 # 1$ #19 0$ #20 b00000000000000000000000000001011 # 1$ #21 0$ #22 b00000000000000000000000000001100 # 1$ #23 0$ #24 b00000000000000000000000000001101 # 1$ #25 0$ #26 b00000000000000000000000000001110 # 1$ #27 0$ #28 b00000000000000000000000000001111 # 1$ #29 0$ #30 b00000000000000000000000000010000 # 1$ #31 0$ #32 b00000000000000000000000000010001 # 1$ #33 0$ #34 b00000000000000000000000000010010 # 1$ #35 0$ #36 b00000000000000000000000000010011 # 1$ #37 0$ #38 b00000000000000000000000000010100 # 1$ #39 0$ #40 b00000000000000000000000000010101 # 1$ #41 0$ #42 b00000000000000000000000000010110 # 1$ #43 0$ #44 b00000000000000000000000000010111 # 1$ #45 0$ #46 b00000000000000000000000000011000 # 1$ #47 0$ #48 b00000000000000000000000000011001 # 1$ #49 0$ #50 b00000000000000000000000000011010 # 1$ #51 0$ #52 b00000000000000000000000000011011 # 1$ #53 0$ #54 b00000000000000000000000000011100 # 1$ #55 0$ #56 b00000000000000000000000000011101 # 1$ #57 0$ #58 b00000000000000000000000000011110 # 1$ #59 0$ #60 b00000000000000000000000000011111 # 1$ #61 0$ #62 b00000000000000000000000000100000 # 1$ #63 0$ #64 b00000000000000000000000000100001 # 1$ #65 0$ #66 b00000000000000000000000000100010 # 1$ #67 0$ #68 b00000000000000000000000000100011 # 1$ #69 0$ #70 b00000000000000000000000000100100 # 1$ #71 0$ #72 b00000000000000000000000000100101 # 1$ #73 0$ #74 b00000000000000000000000000100110 # 1$ #75 0$ #76 b00000000000000000000000000100111 # 1$ #77 0$ #78 b00000000000000000000000000101000 # 1$ #79 0$ #80 b00000000000000000000000000101001 # 1$ #81 0$ #82 b00000000000000000000000000101010 # 1$ #83 0$ #84 b00000000000000000000000000101011 # 1$ #85 0$ #86 b00000000000000000000000000101100 # 1$ #87 0$ #88 b00000000000000000000000000101101 # 1$ #89 0$ #90 b00000000000000000000000000101110 # 1$ #91 0$ #92 b00000000000000000000000000101111 # 1$ #93 0$ #94 b00000000000000000000000000110000 # 1$ #95 0$ #96 b00000000000000000000000000110001 # 1$ #97 0$ #98 b00000000000000000000000000110010 # 1$ #99 0$ #100 b00000000000000000000000000110011 # 1$ #101 0$ #102 b00000000000000000000000000110100 # 1$ #103 0$ #104 b00000000000000000000000000110101 # 1$ #105 0$ #106 b00000000000000000000000000110110 # 1$ #107 0$ #108 b00000000000000000000000000110111 # 1$ #109 0$ #110 b00000000000000000000000000111000 # 1$ #111 0$ #112 b00000000000000000000000000111001 # 1$ #113 0$ #114 b00000000000000000000000000111010 # 1$ #115 0$ #116 b00000000000000000000000000111011 # 1$ #117 0$ #118 b00000000000000000000000000111100 # 1$ #119 0$ #120 b00000000000000000000000000111101 # 1$ #121 0$ #122 b00000000000000000000000000111110 # 1$ #123 0$ #124 b00000000000000000000000000111111 # 1$ #125 0$ #126 b00000000000000000000000001000000 # 1$ #127 0$ #128 b00000000000000000000000001000001 # 1$ #129 0$ #130 b00000000000000000000000001000010 # 1$ #131 0$ #132 b00000000000000000000000001000011 # 1$ #133 0$ #134 b00000000000000000000000001000100 # 1$ #135 0$ #136 b00000000000000000000000001000101 # 1$ #137 0$ #138 b00000000000000000000000001000110 # 1$ #139 0$ #140 b00000000000000000000000001000111 # 1$ #141 0$ #142 b00000000000000000000000001001000 # 1$ #143 0$ #144 b00000000000000000000000001001001 # 1$ #145 0$ #146 b00000000000000000000000001001010 # 1$ #147 0$ #148 b00000000000000000000000001001011 # 1$ #149 0$ #150 b00000000000000000000000001001100 # 1$ #151 0$ #152 b00000000000000000000000001001101 # 1$ #153 0$ #154 b00000000000000000000000001001110 # 1$ #155 0$ #156 b00000000000000000000000001001111 # 1$ #157 0$ #158 b00000000000000000000000001010000 # 1$ #159 0$ #160 b00000000000000000000000001010001 # 1$ #161 0$ #162 b00000000000000000000000001010010 # 1$ #163 0$ #164 b00000000000000000000000001010011 # 1$ #165 0$ #166 b00000000000000000000000001010100 # 1$ #167 0$ #168 b00000000000000000000000001010101 # 1$ #169 0$ #170 b00000000000000000000000001010110 # 1$ #171 0$ #172 b00000000000000000000000001010111 # 1$ #173 0$ #174 b00000000000000000000000001011000 # 1$ #175 0$ #176 b00000000000000000000000001011001 # 1$ #177 0$ #178 b00000000000000000000000001011010 # 1$ #179 0$ #180 b00000000000000000000000001011011 # 1$ #181 0$ #182 b00000000000000000000000001011100 # 1$ #183 0$ #184 b00000000000000000000000001011101 # 1$ #185 0$ #186 b00000000000000000000000001011110 # 1$ #187 0$ #188 b00000000000000000000000001011111 # 1$ #189 0$ #190 b00000000000000000000000001100000 # 1$ #191 0$ #192 b00000000000000000000000001100001 # 1$ #193 0$ #194 b00000000000000000000000001100010 # 1$ #195 0$ #196 b00000000000000000000000001100011 # 1$ #197 0$ #198 b00000000000000000000000001100100 # 1$ #199 0$ #200 b00000000000000000000000001100101 # 1$ #201 0$ #202 b00000000000000000000000001100110 # 1$ #203 0$ #204 b00000000000000000000000001100111 # 1$ #205 0$ #206 b00000000000000000000000001101000 # 1$ #207 0$ #208 b00000000000000000000000001101001 # 1$ #209 0$ #210 b00000000000000000000000001101010 # 1$ #211 0$ #212 b00000000000000000000000001101011 # 1$ #213 0$ #214 b00000000000000000000000001101100 # 1$ #215 0$ #216 b00000000000000000000000001101101 # 1$ #217 0$ #218 b00000000000000000000000001101110 # 1$ #219 0$ #220 b00000000000000000000000001101111 # 1$ #221 0$ #222 b00000000000000000000000001110000 # 1$ #223 0$ #224 b00000000000000000000000001110001 # 1$ #225 0$ #226 b00000000000000000000000001110010 # 1$ #227 0$ #228 b00000000000000000000000001110011 # 1$ #229 0$ #230 b00000000000000000000000001110100 # 1$ #231 0$ #232 b00000000000000000000000001110101 # 1$ #233 0$ #234 b00000000000000000000000001110110 # 1$ #235 0$ #236 b00000000000000000000000001110111 # 1$ #237 0$ #238 b00000000000000000000000001111000 # 1$ #239 0$ #240 b00000000000000000000000001111001 # 1$ #241 0$ #242 b00000000000000000000000001111010 # 1$ #243 0$ #244 b00000000000000000000000001111011 # 1$ #245 0$ #246 b00000000000000000000000001111100 # 1$ #247 0$ #248 b00000000000000000000000001111101 # 1$ #249 0$ #250 b00000000000000000000000001111110 # 1$ #251 0$ #252 b00000000000000000000000001111111 # 1$ #253 0$ #254 b00000000000000000000000010000000 # 1$ #255 0$ #256 b00000000000000000000000010000001 # 1$ #257 0$ #258 b00000000000000000000000010000010 # 1$ #259 0$ #260 b00000000000000000000000010000011 # 1$ #261 0$ #262 b00000000000000000000000010000100 # 1$ #263 0$ #264 b00000000000000000000000010000101 # 1$ #265 0$ #266 b00000000000000000000000010000110 # 1$ #267 0$ #268 b00000000000000000000000010000111 # 1$ #269 0$ #270 b00000000000000000000000010001000 # 1$ #271 0$ #272 b00000000000000000000000010001001 # 1$ #273 0$ #274 b00000000000000000000000010001010 # 1$ #275 0$ #276 b00000000000000000000000010001011 # 1$ #277 0$ #278 b00000000000000000000000010001100 # 1$ #279 0$ #280 b00000000000000000000000010001101 # 1$ #281 0$ #282 b00000000000000000000000010001110 # 1$ #283 0$ #284 b00000000000000000000000010001111 # 1$ #285 0$ #286 b00000000000000000000000010010000 # 1$ #287 0$ #288 b00000000000000000000000010010001 # 1$ #289 0$ #290 b00000000000000000000000010010010 # 1$ #291 0$ #292 b00000000000000000000000010010011 # 1$ #293 0$ #294 b00000000000000000000000010010100 # 1$ #295 0$ #296 b00000000000000000000000010010101 # 1$ #297 0$ #298 b00000000000000000000000010010110 # 1$ #299 0$ verilator-3.874/test_regress/t/t_dist_fixme.pl0000775000177100017500000000201212473477707021532 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. use IO::File; my $root = ".."; my $Debug; if (!-r "$root/.git") { $Self->skip("Not in a git repository"); } else { ### Must trim output before and after our file list my $files = `cd $root && git ls-files --exclude-standard`; print "ST $files\n" if $Debug; $files =~ s/\s+/ /g; my $cmd = "cd $root && fgrep -n FIX"."ME $files | sort | grep -v t_dist_fixme"; my $grep = `$cmd`; print "$grep\n"; if ($grep ne "") { my %names; foreach my $line (split /\n/, $grep) { $names{$1} = 1 if $line =~ /^([^:]+)/; } $Self->error("Files with FIX"."MEs: ",join(' ',sort keys %names)); } } ok(1); 1; verilator-3.874/test_regress/t/t_select_bad_msb.v0000664000177100017500000000060412473477707022161 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. module t (clk); input clk; reg [43:0] mi; reg [3:0] sel2; reg [0:22] backwd; always @ (posedge clk) begin mi = 44'h123; sel2 = mi[1:4]; $write ("Bad select %x\n", sel2); end endmodule verilator-3.874/test_regress/t/t_order_doubleloop.v0000664000177100017500000000456212473477707022601 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // verilator lint_off UNOPT // verilator lint_off UNOPTFLAT // verilator lint_off MULTIDRIVEN // verilator lint_off BLKANDNBLK reg [31:0] comcnt; reg [31:0] dlycnt; initial dlycnt=0; reg [31:0] lastdlycnt; initial lastdlycnt = 0; reg [31:0] comrun; initial comrun = 0; reg [31:0] comrunm1; reg [31:0] dlyrun; initial dlyrun = 0; reg [31:0] dlyrunm1; always @ (posedge clk) begin $write("[%0t] cyc %d\n",$time,cyc); cyc <= cyc + 1; if (cyc==2) begin // Test # of iters lastdlycnt = 0; comcnt = 0; dlycnt <= 0; end if (cyc==3) begin dlyrun <= 5; dlycnt <= 0; end if (cyc==4) begin comrun = 4; end end always @ (negedge clk) begin if (cyc==5) begin $display("%d %d\n", dlycnt, comcnt); if (dlycnt != 32'd5) $stop; if (comcnt != 32'd19) $stop; $write("*-* All Finished *-*\n"); $finish; end end // This forms a "loop" where we keep going through the always till comrun=0 reg runclk; initial runclk = 1'b0; always @ (/*AS*/comrunm1 or dlycnt) begin if (lastdlycnt != dlycnt) begin comrun = 3; $write ("[%0t] comrun=%0d start\n", $time, comrun); end else if (comrun > 0) begin comrun = comrunm1; if (comrunm1==1) begin runclk = 1; $write ("[%0t] comrun=%0d [trigger clk]\n", $time, comrun); end else $write ("[%0t] comrun=%0d\n", $time, comrun); end lastdlycnt = dlycnt; end always @ (/*AS*/comrun) begin if (comrun!=0) begin comrunm1 = comrun - 32'd1; comcnt = comcnt + 32'd1; $write("[%0t] comcnt=%0d\n",$time,comcnt); end end // This forms a "loop" where we keep going through the always till dlyrun=0 reg runclkrst; always @ (posedge runclk) begin runclkrst <= 1; $write ("[%0t] runclk\n", $time); if (dlyrun > 0) begin dlyrun <= dlyrun - 32'd1; dlycnt <= dlycnt + 32'd1; $write ("[%0t] dlyrun<=%0d\n", $time, dlyrun-32'd1); end end always @* begin if (runclkrst) begin $write ("[%0t] runclk reset\n", $time); runclkrst = 0; runclk = 0; end end endmodule verilator-3.874/test_regress/t/t_lint_input_eq_bad.v0000664000177100017500000000035612473477707022717 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t ( input wire i, input wire i2 = i // BAD ); endmodule verilator-3.874/test_regress/t/t_lint_restore_bad.v0000664000177100017500000000057612473477707022562 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (); reg [3:0] four; reg [4:0] five; // verilator lint_save // verilator lint_off WIDTH initial four = 64'h1; // verilator lint_restore initial five = 64'h1; initial $stop; endmodule verilator-3.874/test_regress/t/t_interface_top_bad.v0000664000177100017500000000065512473477707022671 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. interface ifc; logic [3:0] value; logic reset; modport counter_mp (input reset, output value); modport core_mp (output reset, input value); endinterface module t (// Inputs input clk, ifc.counter_mp c_data ); integer cyc=1; endmodule verilator-3.874/test_regress/t/t_vlcov_data_d.dat0000664000177100017500000000007712473477707022167 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint6ffile1.sphl159' 12 verilator-3.874/test_regress/t/t_clk_first.pl0000775000177100017500000000072212473477707021365 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_nest.v0000664000177100017500000000201312473477707021604 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. typedef struct packed { logic [1:0] b1; logic [1:0] b2; logic [1:0] b3; logic [1:0] b4; } t__aa_bbbbbbb_ccccc_dddddd_eee; typedef struct packed { logic [31:0] a; union packed { logic [7:0] fbyte; t__aa_bbbbbbb_ccccc_dddddd_eee pairs; } b1; logic [23:0] b2; logic [7:0] c1; logic [23:0] c2; logic [31:0] d; } t__aa_bbbbbbb_ccccc_dddddd; typedef struct packed { logic [31:0] a; logic [31:0] b; logic [31:0] c; logic [31:0] d; } t__aa_bbbbbbb_ccccc_eee; typedef union packed { t__aa_bbbbbbb_ccccc_dddddd dddddd; t__aa_bbbbbbb_ccccc_eee eee; } t__aa_bbbbbbb_ccccc; module t ( input t__aa_bbbbbbb_ccccc xxxxxxx_yyyyy_zzzz, output logic [15:0] datao_pre ); always_comb datao_pre = { xxxxxxx_yyyyy_zzzz.dddddd.b1.fbyte, xxxxxxx_yyyyy_zzzz.dddddd.c1 }; endmodule verilator-3.874/test_regress/t/t_flag_wfatal.pl0000775000177100017500000000155512473477707021661 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_flag_wfatal.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only -Wno-fatal"], fails=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> q{%Warning-WIDTH: t/t_flag_wfatal.v:\d+: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS.s CONST '6'h2e' generates 6 bits. %Warning-WIDTH: Use .* and lint_on around source to disable this message. }, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_array.v0000664000177100017500000000416412525171734021523 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jeremy Bennett. module t (/*AUTOARG*/); typedef enum int { PADTYPE_DEFAULT = 32'd0, PADTYPE_GPIO, PADTYPE_VDD, PADTYPE_GND } t_padtype; localparam int STR_PINID [0:15] = '{ "DEF", "ERR", "ERR", "ERR", "ERR", "ERR", "ERR", "ERR", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7" }; typedef struct packed { t_padtype padtype; int aux; } t_pin_descriptor; localparam t_pin_descriptor PINOUT[ 1: 6] = '{ '{default:0, padtype:PADTYPE_GPIO, aux:1}, '{default:0, padtype:PADTYPE_GPIO}, '{default:0, padtype:PADTYPE_GPIO}, '{default:0, padtype:PADTYPE_GPIO}, '{default:0, padtype:PADTYPE_VDD}, '{default:0, padtype:PADTYPE_GND} }; localparam int PINOUT_SIZE = 6; localparam int PINOUT_WA[1:PINOUT_SIZE][3] = '{ '{0, PADTYPE_GPIO, 0}, '{1, PADTYPE_GPIO, 0}, '{2, PADTYPE_GPIO, 0}, '{5, PADTYPE_GPIO, 0}, '{6, PADTYPE_VDD, 0}, '{8, PADTYPE_GND , 0} }; const int pinout_static_const[1:PINOUT_SIZE][3] = '{ '{0, PADTYPE_GPIO, 0}, '{1, PADTYPE_GPIO, 0}, '{2, PADTYPE_GPIO, 0}, '{5, PADTYPE_GPIO, 0}, '{6, PADTYPE_VDD, 0}, '{8, PADTYPE_GND , 0} }; // Make sure consants propagate checkstr #(.PINID(STR_PINID[1]), .EXP("ERR")) substr1 (); checkstr #(.PINID(STR_PINID[8]), .EXP("PA0")) substr8 (); initial begin $display("PINID1 %s", STR_PINID[1]); $display("PINID8 %s", STR_PINID[8]); if (STR_PINID[1] != "ERR") $stop; if (STR_PINID[8] != "PA0") $stop; if (pinout_static_const[1][0] != 0) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module checkstr; parameter int PINID = " "; parameter int EXP = " "; initial begin $display("PID %s EXP %s", PINID, EXP); if (EXP != "ERR" && EXP != "PA0") $stop; if (PINID != EXP) $stop; end endmodule verilator-3.874/test_regress/t/t_math_synmul.v0000664000177100017500000000532512473477707021600 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg negate; reg enable; wire [31:0] datA = crc[31:0]; wire [31:0] datB = crc[63:32]; // Predict result wire [63:0] muled = (negate ? (- {32'h0,datA} * {32'h0,datB}) : ( {32'h0,datA} * {32'h0,datB})); reg [63:0] muled_d1; reg [63:0] muled_d2; reg [63:0] muled_d3; reg [63:0] muled_d4; reg enable_d1; reg enable_d2; reg enable_d3; always @ (posedge clk) enable_d1 <= enable; always @ (posedge clk) enable_d2 <= enable_d1; always @ (posedge clk) enable_d3 <= enable_d2; always @ (posedge clk) if (enable) muled_d1 <= muled; always @ (posedge clk) if (enable_d1) muled_d2 <= muled_d1; always @ (posedge clk) if (enable_d2) muled_d3 <= muled_d2; always @ (posedge clk) if (enable_d3) muled_d4 <= muled_d3; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [64:0] product_d4; // From test of t_math_synmul_mul.v // End of automatics t_math_synmul_mul test (/*AUTOINST*/ // Outputs .product_d4 (product_d4[64:0]), // Inputs .clk (clk), .enable (enable), .negate (negate), .datA (datA[31:0]), .datB (datB[31:0])); integer cycs_enabled; initial cycs_enabled = 0; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x e=%x n=%x a*b=%x synmul=%x\n",$time, cyc, crc, enable, negate, muled_d4, product_d4[63:0]); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; negate <= 1'b0; // Negation not currently supported // Always enable in low cycle counts to clear out the pipe //enable <= 1'b1; // 100% activity factor enable <= (cyc<10 || cyc[4]); // 50% activity factor //enable <= (cyc<10 || cyc[4]&cyc[3]); // 25% activity factor if (enable) cycs_enabled=cycs_enabled+1; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin end else begin if (product_d4[63:0] !== muled_d4) begin $write("[%0t] BAD product, got=%x exp=%x\n",$time, product_d4[63:0], muled_d4); $stop; end if (cyc==99) begin if (crc !== 64'hc77bb9b3784ea091) $stop; end `ifndef SIM_CYCLES `define SIM_CYCLES 99 `endif if (cyc==`SIM_CYCLES) begin $write("- Cycles=%0d, Activity factor=%0d%%\n", cyc, ((cycs_enabled*100)/cyc)); $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_clk_latchgate.pl0000775000177100017500000000071712473477707022176 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_bound1.pl0000775000177100017500000000072212473477707022134 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_only.v0000664000177100017500000000033412473477707021242 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (); initial begin $stop; end endmodule verilator-3.874/test_regress/t/t_lint_realcvt_bad.pl0000775000177100017500000000141712473477707022703 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["--lint-only -Wwarn-REALCVT"], verilator_make_gcc => 0, fails=>1, expect=> '%Warning-REALCVT: t/t_lint_realcvt_bad.v:\d+: Implicit conversion of real to integer %Warning-REALCVT: Use .* to disable this message. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_langext_3_bad.pl0000775000177100017500000000103612473477707022076 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_langext_3.v"); # This is a compile only test. compile ( v_flags2 => ["+1364-2001ext+v"], fails => 1 ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_multidim_trace.pl0000775000177100017500000000103612473477707023244 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_mem_multidim.v"); compile ( verilator_flags2 => ['--cc --trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_grey.pl0000775000177100017500000000071712473477707021372 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_assert_synth.pl0000775000177100017500000000102512473477707022130 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_defparam.v0000664000177100017500000000040712473477707022041 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t; sub sub (); defparam sub.P = 2; endmodule module sub; parameter P = 6; endmodule verilator-3.874/test_regress/t/t_func_bad_width.pl0000775000177100017500000000151512473477707022346 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> q{%Warning-WIDTH: t/t_func_bad_width.v:\d+: Operator FUNCREF 'MUX' expects 40 bits on the Function Argument, but Function Argument's VARREF 'in' generates 39 bits. %Warning-WIDTH: Use [^\n]+ %Warning-WIDTH: t/t_func_bad_width.v:\d+: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS.s FUNCREF 'MUX' generates 32 bits. %Error: Exiting due to}, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_gate_nmos.pl0000775000177100017500000000133712473477707022242 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_tri_gate.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ['+define+T_NMOS',], make_flags => 'CPPFLAGS_ADD=-DT_NMOS', verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_dangle.v0000664000177100017500000000103712473477707021344 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/ // Inouts AVDD, AVSS ); inout AVDD; inout AVSS; sub sub (/*AUTOINST*/ // Inouts .AVDD (AVDD), .AVSS (AVSS)); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule module sub (/*AUTOARG*/ // Inouts AVDD, AVSS ); // verilator no_inline_module inout AVDD; inout AVSS; endmodule verilator-3.874/test_regress/t/t_package_abs.v0000664000177100017500000000135412473477707021456 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. // see bug491 package functions; function real abs (real num); abs = (num <0) ? -num : num; endfunction function real neg (real num); return -abs(num); // Check package funcs can call package funcs endfunction endpackage module t (); import functions::*; localparam P = 1; generate if (P == 1) begin initial begin if (abs(-2.1) != 2.1) $stop; if (abs(2.2) != 2.2) $stop; if (neg(-2.1) != -2.1) $stop; if (neg(2.2) != -2.2) $stop; $write("*-* All Finished *-*\n"); $finish; end end endgenerate endmodule verilator-3.874/test_regress/t/t_param_type.v0000664000177100017500000000277012473477707021402 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; // counters int cnt; int cnt_bit ; int cnt_byte; int cnt_int ; int cnt_ar1d; int cnt_ar2d; // sizes int siz_bit ; int siz_byte; int siz_int ; int siz_ar1d; int siz_ar2d; // add all counters assign cnt = cnt_bit + cnt_byte + cnt_int + cnt_ar1d + cnt_ar2d; // finish report always @ (posedge clk) if (cnt == 5) begin if (siz_bit != 1) $stop(); if (siz_byte != 8) $stop(); if (siz_int != 32) $stop(); if (siz_ar1d != 24) $stop(); if (siz_ar2d != 16) $stop(); end else if (cnt > 5) begin $write("*-* All Finished *-*\n"); $finish; end // instances with various types mod_typ #(.TYP (bit )) mod_bit (clk, cnt_bit [ 1-1:0], siz_bit ); mod_typ #(.TYP (byte )) mod_byte (clk, cnt_byte[ 8-1:0], siz_byte); mod_typ #(.TYP (int )) mod_int (clk, cnt_int [32-1:0], siz_int ); mod_typ #(.TYP (bit [23:0] )) mod_ar1d (clk, cnt_ar1d[24-1:0], siz_ar1d); mod_typ #(.TYP (bit [3:0][3:0])) mod_ar2d (clk, cnt_ar2d[16-1:0], siz_ar2d); endmodule : t module mod_typ #( parameter type TYP = byte )( input logic clk, output TYP cnt = 0, output int siz ); always @ (posedge clk) cnt <= cnt + 1; assign siz = $bits (cnt); endmodule verilator-3.874/test_regress/t/t_flag_topmodule.v0000664000177100017500000000075012473477707022236 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module a; c c (); initial begin $write("Bad top modules\n"); $stop; end endmodule module b; d d (); endmodule module c; initial begin $write("Bad top modules\n"); $stop; end endmodule module d; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_dpi_context.v0000664000177100017500000000327512473477707021562 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. module t (); sub a (.inst(1)); sub b (.inst(2)); initial begin a.test1; b.test1; a.test2; b.test2; $write("*-* All Finished *-*\n"); $finish; end endmodule module sub (input integer inst); import "DPI-C" context function int dpic_line(); import "DPI-C" context function int dpic_save(int value); import "DPI-C" context function int dpic_restore(); import "DPI-C" context function int unsigned dpic_getcontext(); int result; task test1; // Check line numbering `ifndef verilator // Not all sims support SV2009 `__LINE__, and some that do fail the specific-line test result = dpic_line(); if (!result) $stop; `else result = dpic_line(); if (result !== `__LINE__) $stop; // result = dpic_line(); if (result !== `__LINE__) $stop; `endif // Check save-restore result = dpic_save(23+inst); if (result==0) $stop; endtask task test2; if (dpic_restore() != 23+inst) $stop; endtask int unsigned cntxt1; int unsigned cntxt2; initial begin cntxt1 = dpic_getcontext(); begin : caller_context // call from a different scope - should still get the context of the function declaration cntxt2 = dpic_getcontext(); end // svContext should be the context of the function declaration, not the context of the function call if (cntxt1 != cntxt2) $stop; end endmodule verilator-3.874/test_regress/t/t_var_assign_landr.pl0000775000177100017500000000072212473477707022721 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_sel_range_bad.pl0000775000177100017500000000167212473477707023337 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. # Really we shouldn't need to warn in this case. # When supported, make a new test case that checks the warning #$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug477"); top_filename("t/t_param_sel_range.v"); compile ( v_flags2 => ["--lint-only"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning-SELRANGE: t/t_param_sel_range.v:\d+: Selection index out of range: 7:7 outside 4:0 %Warning-SELRANGE: Use .* to disable this message. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_signed.v0000664000177100017500000000312412525172076021526 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; wire signed [7:0] sgn_wide; wire [7:0] unsgn_wide; // The instantiation will Z extend, not sign extend // verilator lint_off WIDTH sub sub (.clk, .sgn(sgn_wide), .unsgn(unsgn_wide), .iss(3'sh7), .isu(3'h7), .ius(3'sh7), .iuu(3'h7)); // verilator lint_on WIDTH always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("out: 'b%b 'b%b\n", sgn_wide, unsgn_wide); `endif if (sgn_wide[2:0] != 3'sh7) $stop; if (unsgn_wide[2:0] != 3'h7) $stop; // Simulators differ here. if (sgn_wide !== 8'sbzzzzz111 // z-extension - NC && sgn_wide !== 8'sb11111111) $stop; // sign extension - VCS if (unsgn_wide !== 8'sbzzzzz111 && unsgn_wide!== 8'sb00000111) $stop; cyc <= cyc + 1; if (cyc==3) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub ( input clk, output wire signed [2:0] sgn, output wire [2:0] unsgn, input signed [7:0] iss, input signed [7:0] isu, input [7:0] ius, input [7:0] iuu); assign sgn = 3'sh7; assign unsgn = 3'h7; always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("in: %x %x %x %x\n", iss, isu, ius, iuu); if (iss != 8'hff) $stop; if (isu != 8'h07) $stop; if (ius != 8'hff) $stop; if (iuu != 8'h07) $stop; `endif end endmodule verilator-3.874/test_regress/t/t_stream2.pl0000775000177100017500000000072212473477707020762 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_first.pl0000775000177100017500000000071712473477707021376 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface.pl0000775000177100017500000000072212473477707021345 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_types_bad.v0000664000177100017500000000260612473477707022061 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/); // IEEE: integer_atom_type byte d_byte; shortint d_shortint; int d_int; longint d_longint; integer d_integer; time d_time; chandle d_chandle; // IEEE: integer_atom_type bit d_bit; logic d_logic; reg d_reg; bit [0:0] d_bit1; logic [0:0] d_logic1; reg [0:0] d_reg1; bit d_bitz; logic d_logicz; reg d_regz; // IEEE: non_integer_type //UNSUP shortreal d_shortreal; real d_real; realtime d_realtime; initial begin // below errors might cause spurious warnings // verilator lint_off WIDTH d_bitz[0] = 1'b1; // Illegal range d_logicz[0] = 1'b1; // Illegal range d_regz[0] = 1'b1; // Illegal range `ifndef VERILATOR //UNSUPPORTED, it's just a 64 bit int right now d_chandle[0] = 1'b1; // Illegal `endif d_real[0] = 1'b1; // Illegal d_realtime[0] = 1'b1; // Illegal // verilator lint_on WIDTH d_byte[0] = 1'b1; // OK d_shortint[0] = 1'b1; // OK d_int[0] = 1'b1; // OK d_longint[0] = 1'b1; // OK d_integer[0] = 1'b1; // OK d_time[0] = 1'b1; // OK d_bit1[0] = 1'b1; // OK d_logic1[0] = 1'b1; // OK d_reg1[0] = 1'b1; // OK end endmodule verilator-3.874/test_regress/t/t_alw_dly.v0000664000177100017500000000266412473477707020676 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg posedge_wr_clocks; reg prev_wr_clocks; reg [31:0] m_din; reg [31:0] m_dout; always @(negedge clk) begin prev_wr_clocks = 0; end reg comb_pos_1; reg comb_prev_1; always @ (/*AS*/clk or posedge_wr_clocks or prev_wr_clocks) begin comb_pos_1 = (clk &~ prev_wr_clocks); comb_prev_1 = comb_pos_1 | posedge_wr_clocks; comb_pos_1 = 1'b1; end always @ (posedge clk) begin posedge_wr_clocks = (clk &~ prev_wr_clocks); //surefire lint_off_line SEQASS prev_wr_clocks = prev_wr_clocks | posedge_wr_clocks; //surefire lint_off_line SEQASS if (posedge_wr_clocks) begin //$write("[%0t] Wrclk\n", $time); m_dout <= m_din; end end always @ (posedge clk) begin if (cyc!=0) begin cyc<=cyc+1; if (cyc==1) begin $write(" %x\n",comb_pos_1); m_din <= 32'hfeed; end if (cyc==2) begin $write(" %x\n",comb_pos_1); m_din <= 32'he11e; end if (cyc==3) begin m_din <= 32'he22e; $write(" %x\n",comb_pos_1); if (m_dout!=32'hfeed) $stop; end if (cyc==4) begin if (m_dout!=32'he11e) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_mem_packed.pl0000775000177100017500000000071712473477707021476 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_readmem_bad_end.pl0000775000177100017500000000107412473477707023352 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( fails=>$Self->{v3}, expect=> '%Error: t/t_sys_readmem_bad_end.mem:\d+: \$readmem file ended before specified ending-address', ); ok(1); 1; verilator-3.874/test_regress/t/t_func_task_bad.v0000664000177100017500000000046412473477707022022 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/); initial begin if (task_as_func(1'b0)) $stop; end task task_as_func; input ign; endtask endmodule verilator-3.874/test_regress/t/t_math_repl.pl0000775000177100017500000000071712473477707021364 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_pp_pragmas.v0000664000177100017500000000241312473477707021364 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. `timescale 1ns/10ps `verilog `suppress_faults `nosuppress_faults `enable_portfaults `disable_portfaults `delay_mode_distributed `delay_mode_path `delay_mode_unit `delay_mode_zero `default_decay_time 1 `default_decay_time 1.0 `default_decay_time infinite // unsupported (recommended not to): `default_trireg_strength 10 `default_nettype wire // unsupported: `default_nettype tri // unsupported: `default_nettype tri0 // unsupported: `default_nettype wand // unsupported: `default_nettype triand // unsupported: `default_nettype wor // unsupported: `default_nettype trior // unsupported: `default_nettype trireg `default_nettype none `autoexpand_vectornets `accelerate `noaccelerate `expand_vectornets `noexpand_vectornets `remove_gatenames `noremove_gatenames `remove_netnames `noremove_netnames `resetall // unsupported: `unconnected_drive pull1 // unsupported: `unconnected_drive pull0 `nounconnected_drive `line 100 "hallo.v" 0 // unsupported: `uselib file=../moto_lib.v // unsupported: `uselib dir=../lib.dir libext=.v module t; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_math_signed5.v0000664000177100017500000001321412534630412021561 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0) `define checkf(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0) `ifdef VERILATOR `define c(v,vs) ($c(vs)) // Don't constify a value `else `define c(v,vs) (v) `endif module t (/*AUTOARG*/ // Outputs ow4_u ); bit fail; reg signed [3:0] w4_s; reg signed [4:0] w5_s; reg [2:0] w3_u; reg [3:0] w4_u; reg [4:0] w5_u; reg [5:0] w6_u; reg [15:0] w16a_u; reg [15:0] w16_u; reg [31:0] w32_u; real r; reg signed [4:0] bug754_a; integer i; //verilator lint_off WIDTH wire a = (5'b0 == (5'sb11111 >>> 3'd7)); wire b = (5'sb11111 == (5'sb11111 >>> 3'd7)); wire c = (1'b0+(5'sb11111 >>> 3'd7)); wire d = (1'sb0+(5'sb11111 >>> 3'd7)); wire e = (5'b0 == (5'sb11111 / 5'sd3)); wire f = (5'sb0 == (5'sb11111 / 5'sd3)); wire g = (5'b01010 == (5'b11111 / 5'sd3)); initial begin // verilator lint_off STMTDLY #1; `ifdef VCS // I-2014.03 `checkh({a, b, c, d, e, f, g}, 7'b1101111); `else `checkh({a, b, c, d, e, f, g}, 7'b1101011); `endif //====================================================================== if ((-1 >>> 3) != -1) $stop; // Decimals are signed i = 3'sb111 >>> 3; `checkh(i, -1); i = -1 >>> 3; `checkh(i, -1); bug754_a = -1; w4_u = |0 != (bug754_a >>> 3'd7); `checkh(w4_u, 4'b0); // Sanity check: -1>>7 == -1 w5_u = (5'sb11111 >>> 3'd7); `checkh(w5_u, 5'b11111); // bug756 w4_u = (5'b0 == (5'sb11111 >>> 3'd7)); `checkh(w4_u, 4'b0001); w4_u = ((5'b0 == (5'sb11111 >>> 3'd7))); // Exp 0 Vlt 0 `checkh(w4_u, 4'b0001); w4_u = ((5'b01111 == (5'sb11111 / 5'sd2))); // Strength-reduces to >>> `ifdef VCS // I-2014.03 `checkh(w4_u, 4'b0000); // Wrong, gets 5'b0==..., unsigned does not propagate `else `checkh(w4_u, 4'b0001); // NC-Verilog, Modelsim, XSim, ... `endif // Does == sign propagate from lhs to rhs? Yes, but not in VCS w4_u = ((5'b01010 == (5'sb11111 / 5'sd3))); // Exp 0 Vlt 0 // Must be signed result (-1/3) to make this result zero `ifdef VCS // I-2014.03 `checkh(w4_u, 4'b0000); // Wrong, gets 5'b0==..., unsigned does not propagate `else `checkh(w4_u, 4'b0001); // NC-Verilog, Modelsim, XSim, ... `endif w4_u = (1'b0+(5'sb11111 >>> 3'd7)); // Exp 00000 Vlt 000000 Actually the signedness of result does NOT matter `checkh(w4_u, 4'b0000); w4_u = (5'sb0 == (5'sb11111 / 5'sd3)); // Must be signed result (-1/3) to make this result zero `checkh(w4_u, 4'b0001); // Does == width propagate from lhs to rhs? Yes w4_u = (3'b100==(3'b111 << 2)); `checkh(w4_u, 4'b0001); w4_u = (4'b100==(3'b111 << 2)); `checkh(w4_u, 4'b0000); w4_u = (4'b1100==(3'b111 << 2)); `checkh(w4_u, 4'b0001); // Does >>> sign propagate from input same as for +? Yes w4_u = (1'b0+(5'sb11111 >>> 3'd7)); `checkh(w4_u, 4'b0000); w4_u = (1'sb0+(5'sb11111 >>> 3'd7)); `checkh(w4_u, 4'b1111); // Does << width propagate from input same as for +? Yes w4_u = (3'b0+(3'b111 << 2)); `checkh(w4_u, 4'b1100); // width 4 =='s LHS w4_u = (4'b0+(3'b111 << 2)); `checkh(w4_u, 4'b1100); w4_u = (5'sb11111 == (5'sb11111 >>> 3'd7)); // WHAT? Signedness does propagate across ==????? `checkh(w4_u, 4'b0001); w4_u = ((5'b0 == (5'sb11111 >>> 3'd7))); `checkh(w4_u, 4'b0001); // bug756 w5_s = -1; w3_u = 7; w4_u = |0 != (w5_s >>> w3_u); `checkh(w4_u, 4'b0000); // bug763 w3_u = 2; w4_u = (w3_u >> 2'b11) >> 1; `checkh(w4_u, 4'b0000); // bug766 w16a_u = 16'h1234; w16_u = (w16a_u >> 16) >>> 32'h7ffffff1; `checkh(w16_u, 16'h0000); // bug768 w4_s = 4'sd4; w4_u = $signed(5'd1 > w4_s-w4_s); `checkh(w4_u, 4'b1111); w4_s = `c(4,"4"); // Eval at runtime w4_u = $signed(5'd1 > w4_s-w4_s); `checkh(w4_u, 4'b1111); // bug772 w4_s = w4_u << 1 <<< 0/0; `ifndef VERILATOR // In v4 can't check value as not 4-state `checkh(w4_s, 4'bxxxx); `endif // bug773 w5_u = `c(31, 31); w5_s = w5_u >> ((w5_u ? 1 : 2) << w5_u); `checkh(w5_s, 5'b0); // bug774 w4_u = `c(4, 5); w6_u = `c(6, 35); w4_u = 64'd0 | (w4_u << w6_u); `checkh(w4_u, 0); // bug776 w4_u = `c(4, 1); w4_u = (w4_u >> w4_u) ^~ (w4_u >> w4_u); `checkh(w4_u, 4'b1111); // bug828 // verilator lint_off WIDTH w32_u = 32'(signed'({4'b0001,5'b10000}) << 3); `checkh(w32_u, 32'h0000_0180); w32_u = 32'(signed'({4'b0011,5'b10000}) << 3); `checkh(w32_u, 32'h0000_0380); w32_u = signed'(32'({4'b0001,5'b10000}) << 3); `checkh(w32_u, 32'h0000_0180); w32_u = signed'(32'({4'b0011,5'b10000}) << 3); `checkh(w32_u, 32'h0000_0380); // verilator lint_on WIDTH w32_u = 32'(signed'({4'b0011,5'b10000})) << 3; // Check no width warning `checkh(w32_u, 32'h0000_0380); if (fail) $stop; $write("*-* All Finished *-*\n"); $finish; end // bug775 output [3:0] ow4_u; // Must be consumed assign ow4_u = ((0/0) ? 1 : 2) % 0; endmodule verilator-3.874/test_regress/t/t_flag_werror_bad1.pl0000775000177100017500000000146012473477707022605 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_flag_werror.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> q{%Warning-WIDTH: t/t_flag_werror.v:\d+: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS.s CONST '6'h2e' generates 6 bits. %Warning-WIDTH: Use .* and lint_on around source to disable this message. %Error: Exiting due to}, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_public.pl0000775000177100017500000000115412473477707022043 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. if ($Self->{vlt}) { compile ( verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], make_top_shell => 0, make_main => 0, ); } else { compile ( ); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_pp_underline_bad.v0000664000177100017500000000037512473477707022532 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t; // verilator_no_inline_module initial $stop; // Should have failed endmodule verilator-3.874/test_regress/t/t_flag_topmodule_inline.pl0000775000177100017500000000104312473477707023741 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--top-module b"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_initial_dlyass.v0000664000177100017500000000103212473477707022237 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc = 0; integer a; integer b; initial begin a <= 22; b <= 33; end always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==99) begin if (a != 22) $stop; if (b != 33) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_lint_always_comb_bad.v0000664000177100017500000000146212473477707023372 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs mid, o3, // Inputs clk, i3 ); input clk; output logic mid; input i3; output logic o3; wire [15:0] temp1; wire [15:0] temp1_d1r; logic setbefore; always_comb begin setbefore = 1'b1; if (setbefore) setbefore = 1'b0; // fine end always_comb begin if (mid) temp1 = 'h0; else temp1 = (temp1_d1r - 'h1); mid = (temp1_d1r == 'h0); // BAD end always_comb begin o3 = 'h0; case (i3) 1'b1: begin o3 = i3; end default: ; endcase end always_ff @ (posedge clk) begin temp1_d1r <= temp1; end endmodule verilator-3.874/test_regress/t/t_select_lhs_oob2.pl0000775000177100017500000000071712473477707022457 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gate_basic.pl0000775000177100017500000000071712473477707021472 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_array_bufif.v0000664000177100017500000000600012473477707022376 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; parameter DW = 4; wire [3:0] drv_a = crc[3:0]; wire [3:0] drv_b = crc[7:4]; wire [3:0] drv_e = crc[19:16]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [DW-1:0] drv; // To/From test1 of Test1.v wire [DW-1:0] drv2; // From test2 of Test2.v // End of automatics Test1 test1 (/*AUTOINST*/ // Inouts .drv (drv[DW-1:0]), // Inputs .drv_a (drv_a[DW-1:0]), .drv_b (drv_b[DW-1:0]), .drv_e (drv_e[DW-1:0])); Test2 test2 (/*AUTOINST*/ // Outputs .drv2 (drv2[DW-1:0]), // Inputs .drv_a (drv_a[DW-1:0]), .drv_b (drv_b[DW-1:0]), .drv_e (drv_e[DW-1:0])); // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, drv}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x drv=%x %x (%b??%b:%b)\n",$time, cyc, crc, drv, drv2, drv_e,drv_a,drv_b); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin if (drv2 != drv) $stop; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hd95d216c5a2945d0 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test1 #( parameter DW = 4 )( input wire [DW-1:0] drv_a, input wire [DW-1:0] drv_b, input wire [DW-1:0] drv_e, inout wire [DW-1:0] drv ); wire drv_0, drv_1, drv_2, drv_3; bufif1 bufa0 (drv_0, drv_a[0], drv_e[0]); bufif1 bufb0 (drv_0, drv_b[0], ~drv_e[0]); bufif1 bufa1 (drv_1, drv_a[1], drv_e[1]); bufif1 bufb1 (drv_1, drv_b[1], ~drv_e[1]); bufif1 bufa2 (drv_2, drv_a[2], drv_e[2]); bufif1 bufb2 (drv_2, drv_b[2], ~drv_e[2]); bufif1 bufa3 (drv_3, drv_a[3], drv_e[3]); bufif1 bufb3 (drv_3, drv_b[3], ~drv_e[3]); assign drv = {drv_3,drv_2,drv_1,drv_0}; endmodule module Test2 #( parameter DW = 4 )( input wire [DW-1:0] drv_a, input wire [DW-1:0] drv_b, input wire [DW-1:0] drv_e, inout wire [DW-1:0] drv2 ); wire [DW-1:0] drv_all; bufif1 bufa [DW-1:0] (drv_all, drv_a, drv_e); // Below ~= bufif1 bufb [DW-1:0] (drv_all, drv_b, ~drv_e); bufif1 bufb [DW-1:0] ({drv_all[3], drv_all[2], drv_all[1], drv_all[0]}, {drv_b[3], drv_b[2], drv_b[1], drv_b[0]}, {~drv_e[3], ~drv_e[2], ~drv_e[1], ~drv_e[0]}); assign drv2 = drv_all; endmodule verilator-3.874/test_regress/t/t_flag_topmodule.pl0000775000177100017500000000104412473477707022404 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--top-module b "], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_accessors.cpp0000664000177100017500000005675712473477707022415 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // 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. // // Verilator is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // // Contributed by Jeremy Bennett and Jie Xu // //************************************************************************* #include #include #include "svdpi.h" #include "Vt_dpi_accessors.h" #include "Vt_dpi_accessors__Dpi.h" using std::cout; using std::dec; using std::endl; using std::hex; using std::setfill; using std::setw; // Convenience function to check we didn't finish unexpectedly static void checkFinish (const char *msg) { if (Verilated::gotFinish ()) { vl_fatal (__FILE__, __LINE__, "dut", msg); exit (1); } } // checkFinish () // Convenience function to log the value of a register in hex. Only in verbose // mode. static void logReg (int clk, const char *desc, int val, const char *note) { #ifdef TEST_VERBOSE cout << "clk = " << clk << ", " << desc << " = " << val << note << endl; #endif } // logReg () // Convenience function to log the value of a register in hex. Only in verbose // mode. static void logRegHex (int clk, const char *desc, int bitWidth, int val, const char *note) { #ifdef TEST_VERBOSE cout << "clk = " << clk << ", " << desc << " = " << bitWidth << "\'h" << hex << setw ((bitWidth - 1) / 4 + 1) << setfill ('0') << val << setfill (' ') << setw (0) << dec << note << endl; #endif } // logRegHex () // Convenience function to check we got an expected result. Silent on success. static void checkResult (bool p, const char *msg_fail) { if (!p) { vl_fatal (__FILE__, __LINE__, "dut", msg_fail); } } // checkResult () // Main function instantiates the model and steps through the test. int main () { Vt_dpi_accessors *dut = new Vt_dpi_accessors ("dut"); svSetScope (svGetScopeFromName ("dut.v")); // evaluate the model with no signal changes to get the initial blocks // executed. dut->eval (); #ifdef TEST_VERBOSE cout << "Initial DPI values" << endl; cout << "==================" << endl; #endif int a = (int) a_read (); int b = (int) b_read (); int mem32 = (int) mem32_read (); int c = (int) c_read (); int d = (int) d_read (); int e = (int) e_read (); int f = (int) f_read (); #ifdef TEST_VERBOSE cout << "Read a = " << a << endl; cout << "Read b = 8'h" << hex << setw (2) << setfill ('0') << b << setfill (' ') << setw (0) << dec << endl; cout << "Read mem32 = 8'h" << hex << setw (2) << setfill ('0') << mem32 << setfill (' ') << setw (0) << dec << endl; cout << "Read c = " << c << endl; cout << "Read d = 8'h" << hex << setw (2) << setfill ('0') << d << setfill (' ') << setw (0) << dec << endl; cout << "Read e = 8'h" << hex << setw (2) << setfill ('0') << e << setfill (' ') << setw (0) << dec << endl; cout << "Read f = 8'h" << hex << setw (2) << setfill ('0') << f << setfill (' ') << setw (0) << dec << endl; cout << endl; #endif checkResult ((0 == a) && (0x00 == b) && (0x20 == mem32) && (1 == c) && (0xff == d) && (0x00 == e) && (0x00 == f), "Bad initial DPI values."); // Initialize the clock dut->clk = 0; // Check we can read a scalar register. #ifdef TEST_VERBOSE cout << "Test of scalar register reading" << endl; cout << "===============================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; a = (int) a_read (); logReg (dut->clk, "read a", a, " (before clk)"); dut->eval (); int a_after = (int) a_read (); logReg (dut->clk, "read a", a_after, " (after clk)"); #ifdef TEST_VERBOSE cout << endl; #endif // On a posedge, a should toggle, on a negedge it should stay the // same. checkResult ( ((dut->clk == 1) && (a_after == (1 - a))) || ((dut->clk == 0) && (a_after == a )), "Test of scalar register reading failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Check we can read a vector register. #ifdef TEST_VERBOSE cout << "Test of vector register reading" << endl; cout << "===============================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; b = (int) b_read (); logRegHex (dut->clk, "read b", 8, b, " (before clk)"); dut->eval (); int b_after = (int) b_read (); logRegHex (dut->clk, "read b", 8, b_after, " (after clk)"); // b should increment on a posedge and stay the same on a negedge. checkResult ( ((dut->clk == 1) && (b_after == (b + 1))) || ((dut->clk == 0) && (b_after == b )), "Test of vector register reading failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Test we can read an array element #ifdef TEST_VERBOSE cout << endl; cout << "Test of array element reading" << endl; cout << "=============================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; mem32 = (int) mem32_read (); logRegHex (dut->clk, "read mem32", 8, mem32, " (before clk)"); dut->eval (); mem32 = (int) mem32_read (); logRegHex (dut->clk, "read mem32", 8, mem32, " (after clk)"); // In this case, the value never changes. But we should check it is // waht we expect (0x20). checkResult (mem32 == 0x20, "Test of array element reading failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Check we can read a scalar wire #ifdef TEST_VERBOSE cout << endl; cout << "Test of scalar wire reading" << endl; cout << "===========================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; a = (int) a_read (); c = (int) c_read (); logReg (dut->clk, "read a", a, " (before clk)"); logReg (dut->clk, "read c", c, " (before clk)"); dut->eval (); a = (int) a_read (); c = (int) c_read (); logReg (dut->clk, "read a", a, " (after clk)"); logReg (dut->clk, "read c", c, " (after clk)"); // "c" is continuously assigned as the inverse of "a", but in // Verilator, that means that it will only change value when "a" // changes on the posedge of a clock. Put simply, "c" always holds the // inverse of the "after clock" value of "a". checkResult (c == (1 - a), "Test of scalar wire reading failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Check we can read a vector wire #ifdef TEST_VERBOSE cout << endl; cout << "Test of vector wire reading" << endl; cout << "===========================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; b = (int) b_read (); d = (int) d_read (); logRegHex (dut->clk, "read b", 8, b, " (before clk)"); logRegHex (dut->clk, "read d", 8, d, " (before clk)"); dut->eval (); b = (int) b_read (); d = (int) d_read (); logRegHex (dut->clk, "read b", 8, b, " (after clk)"); logRegHex (dut->clk, "read d", 8, d, " (after clk)"); // "d" is continuously assigned as the (8-bit) bitwise inverse of "b", // but in Verilator, that means that it will only change value when // "b" changes on the posedge of a clock. Put simply, "d" always holds // the inverse of the "after clock" value of "b". checkResult (d == ((~b) & 0xff), "Test of vector wire reading failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Check we can write a scalar register #ifdef TEST_VERBOSE cout << endl; cout << "Test of scalar register writing" << endl; cout << "===============================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; a = 1 - (int) a_read (); a_write (a); logReg (dut->clk, "write a", a, " (before clk)"); a = a_read (); logReg (dut->clk, "read a", a, " (before clk)"); dut->eval (); int a_after = (int) a_read (); logReg (dut->clk, "read a", a_after, " (after clk)"); // On a posedge clock, the value of a that is written should toggle, // on a negedge, it should not. checkResult ( ((dut->clk == 1) && (a_after == (1 - a))) || ((dut->clk == 0) && (a_after == a )), "Test of scalar register writing failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Check we can write a vector register #ifdef TEST_VERBOSE cout << endl; cout << "Test of vector register writing" << endl; cout << "===============================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; b = (int) b_read () - 1; b_write ((const svBitVecVal *) &b); logRegHex (dut->clk, "write b", 8, b, " (before clk)"); b = (int) b_read (); logRegHex (dut->clk, "read b", 8, b, " (before clk)"); dut->eval (); int b_after = (int) b_read (); logRegHex (dut->clk, "read b", 8, b_after, " (after clk)"); // The value of "b" written should increment on a posedge and stay the // same on a negedge. checkResult ( ((dut->clk == 1) && (b_after == (b + 1))) || ((dut->clk == 0) && (b_after == b )), "Test of vector register writing failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Test we can write an array element #ifdef TEST_VERBOSE cout << endl; cout << "Test of array element writing" << endl; cout << "=============================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; mem32 = (int) mem32_read () - 1; mem32_write ((const svBitVecVal *) &mem32); logRegHex (dut->clk, "write mem32", 8, mem32, " (before clk)"); mem32 = (int) mem32_read (); logRegHex (dut->clk, "read mem32", 8, mem32, " (before clk)"); dut->eval (); int mem32_after = (int) mem32_read (); logRegHex (dut->clk, "read mem32", 8, mem32_after, " (after clk)"); // In this case, the value we write never changes (this would only // happen if this part of the test coincided with the 32nd element // being overwritten, which it does not. Check that the value after // the clock is the same as before the clock. checkResult (mem32_after == mem32, "Test of array element writing failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Check we can read a vector register slice #ifdef TEST_VERBOSE cout << endl; cout << "Test of vector register slice reading" << endl; cout << "=====================================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; b = (int) b_read (); int b_slice = (int) b_slice_read (); logRegHex (dut->clk, "read b [7:0]", 8, b, " (before clk)"); logRegHex (dut->clk, "read b [3:0]", 4, b_slice, " (before clk)"); dut->eval (); b = (int) b_read (); b_slice = (int) b_slice_read (); logRegHex (dut->clk, "read b [7:0]", 8, b, " (after clk)"); logRegHex (dut->clk, "read b [3:0]", 4, b_slice, " (after clk)"); // The slice of "b" should always be the bottom 4 bits of "b" checkResult (b_slice == (b & 0x0f), "Test of vector register slice reading failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Test we can read an array element slice #ifdef TEST_VERBOSE cout << endl; cout << "Test of array element slice reading" << endl; cout << "===================================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; mem32 = (int) mem32_read (); int mem32_slice = (int) mem32_slice_read (); logRegHex (dut->clk, "read mem32 [7:0] ", 8, mem32, " (before clk)"); logRegHex (dut->clk, "read mem32 [7:6,2:0]", 5, mem32_slice, " (before clk)"); dut->eval (); mem32 = (int) mem32_read (); mem32_slice = (int) mem32_slice_read (); logRegHex (dut->clk, "read mem32 [7:0] ", 8, mem32," (after clk)"); logRegHex (dut->clk, "read mem32 [7:6,2:0]", 5, mem32_slice, " (after clk)"); // The slice of "mem32" should always be the concatenation of the top // 2 and bottom 3 bits of "mem32" checkResult (mem32_slice == (((mem32 & 0xc0) >> 3) | (mem32 & 0x07)), "Test of array element slice reading failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Check we can read a vector wire slice #ifdef TEST_VERBOSE cout << endl; cout << "Test of vector wire slice reading" << endl; cout << "=================================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; b = (int) b_read (); d = (int) d_read (); int d_slice = (int) d_slice_read (); logRegHex (dut->clk, "read b [7:0]", 8, b, " (before clk)"); logRegHex (dut->clk, "read d [7:0]", 8, d, " (before clk)"); logRegHex (dut->clk, "read d [6:1]", 6, d_slice, " (before clk)"); dut->eval (); b = (int) b_read (); d = (int) d_read (); d_slice = (int) d_slice_read (); logRegHex (dut->clk, "read b [7:0]", 8, b, " (after clk)"); logRegHex (dut->clk, "read d [7:0]", 8, d, " (after clk)"); logRegHex (dut->clk, "read d [6:1]", 6, d_slice, " (after clk)"); // The slice of "d" should always be the middle 6 bits of "d". checkResult (d_slice == ((d & 0x7e) >> 1), "Test of vector wire slice reading failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Check we can write a vector register slice #ifdef TEST_VERBOSE cout << endl; cout << "Test of vector register slice writing" << endl; cout << "=====================================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; b = (int) b_read (); int b_slice = (int) b_slice_read (); logRegHex (dut->clk, "read b [7:0]", 8, b, " (before write)"); logRegHex (dut->clk, "read b [3:0]", 4, b_slice, " (before write)"); b_slice--; b_slice_write ((const svBitVecVal *) &b_slice); logRegHex (dut->clk, "write b [3:0]", 4, b_slice, " (before clk)"); int b_after = (int) b_read (); int b_slice_after = (int) b_slice_read (); logRegHex (dut->clk, "read b [7:0]", 8, b_after, " (before clk)"); logRegHex (dut->clk, "read b [3:0]", 4, b_slice_after, " (before clk)"); // We must test that when we wrote the slice of "b", we only wrote the // correct bits. The slice of b is b[3:0] int b_new = (b & 0xf0) | (b_slice &0x0f); checkResult (b_after == b_new, "Test of vector register slice writing failed."); dut->eval (); b = (int) b_read (); b_slice = (int) b_slice_read (); logRegHex (dut->clk, "read b [7:0]", 8, b, " (after clk)"); logRegHex (dut->clk, "read b [3:0]", 4, b_slice, " (after clk)"); } checkFinish ("t_dpi_accessors unexpected finish"); // Test we can write an array element slice #ifdef TEST_VERBOSE cout << endl; cout << "Test of array element slice writing" << endl; cout << "===================================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; mem32 = (int) mem32_read (); int mem32_slice = (int) mem32_slice_read (); logRegHex (dut->clk, "read mem32 [7:0] ", 8, mem32, " (before write)"); logRegHex (dut->clk, "read mem32 [7:6,2:0]", 5, mem32_slice, " (before write)"); mem32_slice--; mem32_slice_write ((const svBitVecVal *) &mem32_slice); logRegHex (dut->clk, "write mem32 [7:6,2:0]", 5, mem32_slice, " (before clk)"); int mem32_after = (int) mem32_read (); int mem32_slice_after = (int) mem32_slice_read (); logRegHex (dut->clk, "read mem32 [7:0] ", 8, mem32_after, " (before clk)"); logRegHex (dut->clk, "read mem32 [7:6,2:0]", 5, mem32_slice_after, " (before clk)"); // We must test that when we wrote the slice of "mem32", we only wrote // the correct bits. The slice of "mem32" is {mem32[7:6], mem32[2:0]}. int mem32_new = (mem32 & 0x38) | ((mem32_slice & 0x18) << 3) | (mem32_slice & 0x7); checkResult (mem32_after == mem32_new, "Test of vector register slice writing failed."); dut->eval (); mem32 = (int) mem32_read (); mem32_slice = (int) mem32_slice_read (); logRegHex (dut->clk, "read mem32 [7:0] ", 8, mem32," (after clk)"); logRegHex (dut->clk, "read mem32 [7:6,2:0]", 5, mem32_slice, " (after clk)"); // We have already tested that array element writing works, so we just // check that dhe slice of "mem32" after the clock is the // concatenation of the top 2 and bottom 3 bits of "mem32" checkResult (mem32_slice == (((mem32 & 0xc0) >> 3) | (mem32 & 0x07)), "Test of array element slice writing failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Check we can read complex registers #ifdef TEST_VERBOSE cout << endl; cout << "Test of complex register reading" << endl; cout << "================================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; b = (int) b_read (); mem32 = (int) mem32_read (); e = (int) e_read (); int l1 = (int) l1_read (); logRegHex (dut->clk, "read b ", 8, b, " (before clk)"); logRegHex (dut->clk, "read mem32", 8, mem32, " (before clk)"); logRegHex (dut->clk, "read e ", 8, e, " (before clk)"); logRegHex (dut->clk, "read l1 ", 15, l1, " (before clk)"); dut->eval (); b = (int) b_read (); mem32 = (int) mem32_read (); e = (int) e_read (); l1 = (int) l1_read (); logRegHex (dut->clk, "read b ", 8, b, " (after clk)"); logRegHex (dut->clk, "read mem32", 8, mem32, " (after clk)"); logRegHex (dut->clk, "read e ", 8, e, " (after clk)"); logRegHex (dut->clk, "read l1 ", 15, l1, " (after clk)"); // We have already tested that reading of registers, memory elements // and wires works. So we just need to check that l1 reads back as the // correct combination of bits after the clock. It should be the 15 // bits: {b[3:0],mem[32][7:6],e[6:1],mem[32][2:0]}. checkResult (l1 == ( (((b & 0x0f) >> 0) << 11) | (((mem32 & 0xc0) >> 6) << 9) | (((e & 0x7e) >> 1) << 3) | (((mem32 & 0x07) >> 0) << 0)), "Test of complex register reading l1 failed."); } #ifdef TEST_VERBOSE cout << endl; #endif checkFinish ("t_dpi_accessors unexpected finish"); for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; e = 0x05 | (i << 4); f = 0xa0 | i; e_write ((const svBitVecVal *) &e); f_write ((const svBitVecVal *) &f); e = (int) e_read (); f = (int) f_read (); int l2 = (int) l2_read (); logRegHex (dut->clk, "read e ", 8, e, " (before clk)"); logRegHex (dut->clk, "read f ", 8, f, " (before clk)"); logRegHex (dut->clk, "read l2", 8, l2, " (before clk)"); dut->eval (); e = (int) e_read (); f = (int) f_read (); l2 = (int) l2_read (); logRegHex (dut->clk, "read e ", 8, e, " (before clk)"); logRegHex (dut->clk, "read f ", 8, f, " (before clk)"); logRegHex (dut->clk, "read l2", 8, l2, " (before clk)"); // We have already tested that reading of registers, memory elements // and wires works. So we just need to check that l1 reads back as the // correct combination of bits after the clock. It should be the 8 // bits: {e[7:4], f[3:0]}. checkResult (l2 == ((e & 0xf0) | (f & 0x0f)), "Test of complex register reading l2 failed."); } checkFinish ("t_dpi_accessors unexpected finish"); // Test we can write a complex register #ifdef TEST_VERBOSE cout << endl; cout << "Test of complex register writing" << endl; cout << "================================" << endl; #endif for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; b = (int) b_read (); mem32 = (int) mem32_read (); e = (int) e_read (); logRegHex (dut->clk, "read b ", 8, b, " (before write)"); logRegHex (dut->clk, "read mem32", 8, mem32, " (before write)"); logRegHex (dut->clk, "read e ", 8, e, " (before write)"); int l1 = 0x5a5a; l1_write ((const svBitVecVal *) &l1); logRegHex (dut->clk, "write l1 ", 15, l1, " (before clk)"); int b_after = (int) b_read (); int mem32_after = (int) mem32_read (); int e_after = (int) e_read (); int l1_after = (int) l1_read (); logRegHex (dut->clk, "read b ", 8, b_after, " (before clk)"); logRegHex (dut->clk, "read mem32", 8, mem32_after, " (before clk)"); logRegHex (dut->clk, "read e ", 8, e_after, " (before clk)"); logRegHex (dut->clk, "read l1 ", 15, l1_after, " (before clk)"); // We need to check that when we write l1, the correct fields, and // only the correct fields are set in its component registers, wires // and memory elements. l1 is 15 bits: // {b[3:0],mem[32][7:6],e[6:1],mem[32][2:0]}. int b_new = (b & 0xf0) | ((l1 & 0x7800) >> 11); int mem32_new = (mem32 & 0x38) | ((l1 & 0x0600) >> 3) | (l1 & 0x0007); int e_new = (e & 0x81) | ((l1 & 0x01f8) >> 2); checkResult ( (b_new == b_after) && (mem32_new == mem32_after) && (e_new == e_after), "Test of complex register writing l1 failed."); dut->eval (); b = (int) b_read (); mem32 = (int) mem32_read (); d = (int) d_read (); l1 = (int) l1_read (); logRegHex (dut->clk, "read b ", 8, b, " (after clk)"); logRegHex (dut->clk, "read mem32", 8, mem32, " (after clk)"); logRegHex (dut->clk, "read d ", 8, d, " (after clk)"); logRegHex (dut->clk, "read l1 ", 15, l1, " (after clk)"); } #ifdef TEST_VERBOSE cout << endl; #endif checkFinish ("t_dpi_accessors unexpected finish"); for (int i = 0; !Verilated::gotFinish () && (i < 4); i++) { dut->clk = 1 - dut->clk; e = (int) e_read (); f = (int) f_read (); logRegHex (dut->clk, "read e ", 8, e, " (before write)"); logRegHex (dut->clk, "read f ", 8, f, " (before write)"); int l2 = 0xa5 + i; l2_write ((const svBitVecVal *) &l2); logRegHex (dut->clk, "write l2", 8, l2, " (before clk)"); int e_after = (int) e_read (); int f_after = (int) f_read (); int l2_after = (int) l2_read (); logRegHex (dut->clk, "read e ", 8, e_after, " (before clk)"); logRegHex (dut->clk, "read f ", 8, f_after, " (before clk)"); logRegHex (dut->clk, "read l2", 8, l2_after, " (before clk)"); // We need to check that when we write l2, the correct fields, and // only the correct fields are set in its component registers. l is 8 // bits: {e[5:2], f[5:2]} int e_new = (e & 0xc3) | ((l2 & 0xf0) >> 2); int f_new = (f & 0xc3) | ((l2 & 0x0f) << 2); checkResult ((e_new == e_after) && (f_new == f_after), "Test of complex register writing l2 failed."); dut->eval (); e = (int) e_read (); f = (int) f_read (); l2 = (int) l2_read (); logRegHex (dut->clk, "read e ", 8, e, " (before clk)"); logRegHex (dut->clk, "read f ", 8, f, " (before clk)"); logRegHex (dut->clk, "read l2", 8, l2, " (before clk)"); } checkFinish ("t_dpi_accessors unexpected finish"); // Tidy up dut->final (); cout << "*-* All Finished *-*" << endl;; } // main () // Local Variables: // c-file-style:"cc-mode" // End: verilator-3.874/test_regress/t/t_order_comboloop.pl0000775000177100017500000000071712473477707022575 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_topmodule_bad2.pl0000775000177100017500000000134012473477707023273 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. top_filename("t/t_flag_topmodule.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( fails=>$Self->{v3}, v_flags2 => ["--top-module notfound"], nc=>0, # Need to get it not to give the prompt expect=> '%Error: Specified --top-module \'notfound\' was not found in design. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_dtree.v0000664000177100017500000000261212473477707021374 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; `ifdef INLINE_A //verilator inline_module `else //verilator no_inline_module `endif bmod bsub3 (.clk, .n(3)); bmod bsub2 (.clk, .n(2)); bmod bsub1 (.clk, .n(1)); bmod bsub0 (.clk, .n(0)); endmodule module bmod (input clk, input [31:0] n); `ifdef INLINE_B //verilator inline_module `else //verilator no_inline_module `endif cmod csub (.clk, .n); endmodule module cmod (input clk, input [31:0] n); `ifdef INLINE_C //verilator inline_module `else //verilator no_inline_module `endif reg [31:0] clocal; always @ (posedge clk) clocal <= n; dmod dsub (.clk, .n); endmodule module dmod (input clk, input [31:0] n); `ifdef INLINE_D //verilator inline_module `else //verilator no_inline_module `endif reg [31:0] dlocal; always @ (posedge clk) dlocal <= n; int cyc; always @(posedge clk) begin cyc <= cyc+1; end always @(posedge clk) begin if (cyc>10) begin `ifdef TEST_VERBOSE $display("%m: csub.clocal=%0d dlocal=%0d", csub.clocal, dlocal); `endif if (csub.clocal !== n) $stop; if (dlocal !== n) $stop; end if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_inst_array_bad.v0000664000177100017500000000112112473477707022207 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [7:0] bitout; reg [7:0] allbits; reg [7:0] onebit; reg [8:0] onebitbad; // Wrongly sized sub sub [7:0] (allbits, onebitbad, bitout); // This is ok. wire [9:8] b; wire [1:0] c; sub sub2 [9:8] (allbits,b,c); endmodule module sub (input [7:0] allbits, input onebit, output bitout); wire bitout = onebit ^ (^ allbits); endmodule verilator-3.874/test_regress/t/t_dpi_accessors_inc.vh0000664000177100017500000000316312473477707023060 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Accessor definitions for test of DPI accessors // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by Jeremy Bennett and Jie Xu // See t_dpi_accessors.v for details of the test. This file should be included // by the top level module to define all the accessors needed. // Use the macros to provide the desire access to our data. First simple // access to the registers, array elements and wires. For consistency with // simulators, we do not attempt to write wires. `RW_ACCESS ([0:0], a, {t.i_test_sub.a}); `RW_ACCESS ([7:0], b, {t.i_test_sub.b}); `RW_ACCESS ([7:0], mem32, {t.i_test_sub.mem[32]}); `R_ACCESS ([0:0], c, {t.i_test_sub.c}); `R_ACCESS ([7:0], d, {t.i_test_sub.d}); `RW_ACCESS ([7:0], e, {t.i_test_sub.e}); `RW_ACCESS ([7:0], f, {t.i_test_sub.f}); // Slices of vectors and array elements. For consistency with simulators, // we do not attempt to write wire slices. `RW_ACCESS ([3:0], b_slice, {t.i_test_sub.b[3:0]}); `RW_ACCESS ([4:0], mem32_slice, {t.i_test_sub.mem[32][7:6],t.i_test_sub.mem[32][2:0]}); `R_ACCESS ([5:0], d_slice, {t.i_test_sub.d[6:1]}); // Complex registers, one with distinct read and write. We avoid use of // wires for consistency with simulators. `RW_ACCESS ([14:0], l1, {t.i_test_sub.b[3:0], t.i_test_sub.mem[32][7:6], t.i_test_sub.e[6:1], t.i_test_sub.mem[32][2:0]}); `R_ACCESS ([7:0], l2, {t.i_test_sub.e[7:4], t.i_test_sub.f[3:0]}); `W_ACCESS ([7:0], l2, {t.i_test_sub.e[5:2], t.i_test_sub.f[5:2]}); verilator-3.874/test_regress/t/t_param_mem_attr.v0000664000177100017500000000211312473477707022220 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // A test case for parameterized module. // // When a module is instantiatied with parameter, there will be two modules in // the tree and eventually one will be removed after param and deadifyModules. // // This test is to check that the removal of dead module will not cause // compilation error. Possible error was/is seen as: // // pure virtual method called // terminate called without an active exception // %Error: Verilator aborted. Consider trying --debug --gdbbt // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jie Xu. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [71:0] ctrl; wire [7:0] cl; // this line is added memory #(.words(72)) i_memory (.clk (clk)); assign ctrl = i_memory.mem[0]; assign cl = i_memory.mem[0][7:0]; // and this line endmodule // memory module, which is used with parameter module memory (clk); input clk; parameter words = 16384, bits = 72; reg [bits-1 :0] mem[words-1 : 0]; endmodule verilator-3.874/test_regress/t/t_package_ddecl.pl0000775000177100017500000000102612473477707022131 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug474"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_preproc_inc_bad.v0000664000177100017500000000034712473477707022350 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. //See bug289 `include "t_preproc_inc_inc_bad.vh" module t; endmodule verilator-3.874/test_regress/t/t_func_outp.pl0000775000177100017500000000071712473477707021413 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_endian.v0000664000177100017500000000534312473477707021511 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; wire noswap = crc[32]; wire nibble = crc[33]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v wire [31:0] swapped; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[31:0]), .swapped (swapped[31:0]), // Inputs .clk (clk), .noswap (noswap), .nibble (nibble), .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== 64'h89522c3f5e5ca324) $stop; $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, swapped, // Inputs clk, noswap, nibble, in ); input clk; input noswap; input nibble; input [31:0] in; output [31:0] out; output [31:0] swapped; function [7:0] EndianSwap; input Nibble; input [7:0] Data; begin EndianSwap = (Nibble ? { Data[0], Data[1], Data[2], Data[3], Data[4], Data[5], Data[6], Data[7] } : { 4'h0, Data[0], Data[1], Data[2], Data[3] }); end endfunction assign out[31:24] = (noswap ? in[31:24] : EndianSwap(nibble, in[31:24])); assign out[23:16] = (noswap ? in[23:16] : EndianSwap(nibble, in[23:16])); assign out[15:8] = (noswap ? in[15:8] : EndianSwap(nibble, in[15:8])); assign out[7:0] = (noswap ? in[7:0] : EndianSwap(nibble, in[7:0])); reg [31:0] swapped; always @(posedge clk) begin swapped[31:24] <= EndianSwap(nibble, in[31:24]); swapped[23:16] <= EndianSwap(nibble, in[23:16]); swapped[15:8] <= EndianSwap(nibble, in[15:8] ); swapped[7:0] <= EndianSwap(nibble, in[7:0] ); end endmodule verilator-3.874/test_regress/t/t_math_concat.v0000664000177100017500000000546512473477707021525 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [255:0] i; wire [255:0] q; assign q = { i[176],i[168],i[126],i[177],i[097],i[123],i[231],i[039], i[156],i[026],i[001],i[052],i[005],i[240],i[157],i[048], i[111],i[088],i[133],i[225],i[046],i[038],i[004],i[234], i[115],i[008],i[069],i[099],i[137],i[130],i[255],i[122], i[223],i[195],i[224],i[083],i[094],i[018],i[067],i[034], i[221],i[105],i[104],i[107],i[053],i[066],i[020],i[174], i[010],i[196],i[003],i[041],i[071],i[194],i[154],i[110], i[186],i[210],i[040],i[044],i[243],i[236],i[239],i[183], i[164],i[064],i[086],i[193],i[055],i[206],i[203],i[128], i[190],i[233],i[023],i[022],i[135],i[108],i[061],i[139], i[180],i[043],i[109],i[090],i[229],i[238],i[095],i[173], i[208],i[054],i[025],i[024],i[148],i[079],i[246],i[142], i[181],i[129],i[120],i[220],i[036],i[159],i[201],i[119], i[216],i[152],i[175],i[138],i[242],i[143],i[101],i[035], i[228],i[082],i[211],i[062],i[076],i[124],i[150],i[149], i[235],i[227],i[250],i[134],i[068],i[032],i[060],i[144], i[042],i[163],i[087],i[059],i[213],i[251],i[200],i[070], i[145],i[204],i[249],i[191],i[127],i[247],i[106],i[017], i[028],i[045],i[215],i[162],i[205],i[073],i[065],i[084], i[153],i[158],i[085],i[197],i[212],i[114],i[096],i[118], i[146],i[030],i[058],i[230],i[141],i[000],i[199],i[171], i[182],i[185],i[021],i[016],i[033],i[237],i[015],i[112], i[222],i[253],i[244],i[031],i[248],i[092],i[226],i[179], i[189],i[056],i[132],i[116],i[072],i[184],i[027],i[002], i[103],i[125],i[009],i[078],i[178],i[245],i[170],i[161], i[102],i[047],i[192],i[012],i[057],i[207],i[187],i[151], i[218],i[254],i[214],i[037],i[131],i[165],i[011],i[098], i[169],i[209],i[167],i[202],i[100],i[172],i[147],i[013], i[136],i[166],i[252],i[077],i[051],i[074],i[140],i[050], i[217],i[198],i[081],i[091],i[075],i[121],i[188],i[219], i[160],i[241],i[080],i[155],i[019],i[006],i[014],i[029], i[089],i[049],i[113],i[232],i[007],i[117],i[063],i[093] }; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("%x %x\n", q, i); `endif if (cyc==1) begin i <= 256'hed388e646c843d35de489bab2413d77045e0eb7642b148537491f3da147e7f26; end if (cyc==2) begin i <= 256'h0e17c88f3d5fe51a982646c8e2bd68c3e236ddfddddbdad20a48e039c9f395b8; if (q != 256'h697bad4b0cf2d7fa4ad22809293710bb67d1eb3131e8eb2135f2c7bd820baa84) $stop; end if (cyc==3) begin if (q != 256'h320eda5078b3e942353d16dddc8b29fd773b4fcec8323612dadfb1fa483f602c) $stop; end if (cyc==4) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_enum_int.v0000664000177100017500000000461212473477707021054 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; enum integer { EP_State_IDLE , EP_State_CMDSHIFT0 , EP_State_CMDSHIFT13 , EP_State_CMDSHIFT14 , EP_State_CMDSHIFT15 , EP_State_CMDSHIFT16 , EP_State_DWAIT , EP_State_DSHIFT0 , EP_State_DSHIFT1 , EP_State_DSHIFT15 } m_state_xr, m_state2_xr; // Beginning of automatic ASCII enum decoding reg [79:0] m_stateAscii_xr; // Decode of m_state_xr always @(m_state_xr) begin case ({m_state_xr}) EP_State_IDLE: m_stateAscii_xr = "idle "; EP_State_CMDSHIFT0: m_stateAscii_xr = "cmdshift0 "; EP_State_CMDSHIFT13: m_stateAscii_xr = "cmdshift13"; EP_State_CMDSHIFT14: m_stateAscii_xr = "cmdshift14"; EP_State_CMDSHIFT15: m_stateAscii_xr = "cmdshift15"; EP_State_CMDSHIFT16: m_stateAscii_xr = "cmdshift16"; EP_State_DWAIT: m_stateAscii_xr = "dwait "; EP_State_DSHIFT0: m_stateAscii_xr = "dshift0 "; EP_State_DSHIFT1: m_stateAscii_xr = "dshift1 "; EP_State_DSHIFT15: m_stateAscii_xr = "dshift15 "; default: m_stateAscii_xr = "%Error "; endcase end // End of automatics integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; //$write("%d %x %x %x\n", cyc, data, wrapcheck_a, wrapcheck_b); if (cyc==1) begin m_state_xr <= EP_State_IDLE; m_state2_xr <= EP_State_IDLE; end if (cyc==2) begin if (m_stateAscii_xr != "idle ") $stop; m_state_xr <= EP_State_CMDSHIFT13; if (m_state2_xr != EP_State_IDLE) $stop; m_state2_xr <= EP_State_CMDSHIFT13; end if (cyc==3) begin if (m_stateAscii_xr != "cmdshift13") $stop; m_state_xr <= EP_State_CMDSHIFT16; if (m_state2_xr != EP_State_CMDSHIFT13) $stop; m_state2_xr <= EP_State_CMDSHIFT16; end if (cyc==4) begin if (m_stateAscii_xr != "cmdshift16") $stop; m_state_xr <= EP_State_DWAIT; if (m_state2_xr != EP_State_CMDSHIFT16) $stop; m_state2_xr <= EP_State_DWAIT; end if (cyc==9) begin if (m_stateAscii_xr != "dwait ") $stop; if (m_state2_xr != EP_State_DWAIT) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_lint_blksync_loop.v0000664000177100017500000000453212473477707022763 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs data_out, // Inputs wr, wa, rst_l, rd, ra, data_in, clk ); input clk; /*AUTOINPUT*/ // Beginning of automatic inputs (from unused autoinst inputs) input [31:0] data_in; // To sub of reg_1r1w.v input [7:0] ra; // To sub of reg_1r1w.v input rd; // To sub of reg_1r1w.v input rst_l; // To sub of reg_1r1w.v input [7:0] wa; // To sub of reg_1r1w.v input wr; // To sub of reg_1r1w.v // End of automatics /*AUTOOUTPUT*/ // Beginning of automatic outputs (from unused autoinst outputs) output [31:0] data_out; // From sub of reg_1r1w.v // End of automatics reg_1r1w #(.WIDTH(32), .DEPTH(256), .ADRWID(8)) sub (/*AUTOINST*/ // Outputs .data_out (data_out[31:0]), // Inputs .data_in (data_in[31:0]), .ra (ra[7:0]), .wa (wa[7:0]), .wr (wr), .rd (rd), .clk (clk), .rst_l (rst_l)); endmodule module reg_1r1w #( parameter WIDTH=32, parameter ADRWID=10, parameter DEPTH=1024, parameter RST=0 ) (/*AUTOARG*/ // Outputs data_out, // Inputs data_in, ra, wa, wr, rd, clk, rst_l ); input [WIDTH-1:0] data_in; input [ADRWID-1:0] ra; input [ADRWID-1:0] wa; input wr; input rd; input clk; input rst_l; output [WIDTH-1:0] data_out; reg [WIDTH-1:0] array [DEPTH-1:0]; reg [ADRWID-1:0] ra_r, wa_r; reg [WIDTH-1:0] data_in_r; reg wr_r; reg rd_r; integer x; // Message 679 always @(posedge clk) begin int tmp = x + 1; if (tmp !== x + 1) $stop; end always @(posedge clk or negedge rst_l) begin if (!rst_l) begin for (x=0; x{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--trace"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_display_bad.pl0000775000177100017500000000132412473477707021657 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_display_bad.v:\d+: Missing arguments for \$display-like format %Error: t/t_display_bad.v:\d+: Extra arguments for \$display-like format %Error: t/t_display_bad.v:\d+: Unknown \$display-like format code: %q %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_sformat.pl0000775000177100017500000000071712473477707021762 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_local.v0000664000177100017500000000170712473477707021202 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; integer top; integer top_assign=1; task automatic tsk; integer task_assign = 1; if (task_assign != 1) $stop; task_assign = 2; if (task_assign != 2) $stop; endtask initial begin begin : a integer lower; integer lower_assign=1; lower = 1; top = 1; if (lower != 1) $stop; if (lower_assign != 1) $stop; begin : aa integer lev2; lev2 = 1; lower = 2; lower_assign = 2; top = 2; end if (lower != 2) $stop; if (lower_assign != 2) $stop; end begin : b integer lower; lower = 1; top = 2; begin : empty begin : empty end end end tsk; tsk; // Second time to insure we reinit the initial value $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_math_mul.pl0000775000177100017500000000071712473477707021217 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_converge_unopt_bad.pl0000775000177100017500000000125012473477707024472 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2007 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. top_filename("t/t_unopt_converge.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( fails=>1, expect=> '%Warning-UNOPT: t/t_unopt_converge.v:\d+: Signal unoptimizable: Feedback to public clock or circular logic: x .* %Error: Exiting due to ' ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_dff.pl0000775000177100017500000000072212473477707021201 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_slice.v0000664000177100017500000000547012525171734021163 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic use_AnB; logic [1:0] active_command [8:0]; logic [1:0] command_A [8:0]; logic [1:0] command_B [8:0]; logic [1:0] active_command2 [8:0]; logic [1:0] command_A2 [8:0]; logic [1:0] command_B2 [8:0]; logic [1:0] active_command3 [1:0][2:0][3:0]; logic [1:0] command_A3 [1:0][2:0][3:0]; logic [1:0] command_B3 [1:0][2:0][3:0]; logic [2:0] use_A4nB4; logic [8:0][1:0] active_command4; logic [8:0][1:0] command_A4; logic [8:0][1:0] command_B4; logic [8:0] pipe1 [7:0]; logic [8:0] pipe1_input; integer cyc; assign active_command[8:0] = (use_AnB) ? command_A[8:0] : command_B[8:0]; assign active_command2 = (use_AnB) ? command_A2 : command_B2; // Illegal to have [1:0][x:y] here - IEEE only allows single dimension slicing assign active_command3[1:0] = (use_AnB) ? command_A3[1:0] : command_B3[1:0]; // Check we can cope with things other than packed arrays assign active_command4 = (use_A4nB4[0]) ? command_A4 : command_B4; always @ (posedge clk) begin pipe1_input <= pipe1_input + 1; pipe1[0] <= pipe1_input; pipe1[7:1] <= pipe1[6:0]; end logic [3:0][13:0] iq_read_data [15:0]; logic [3:0][13:0] iq_data; logic [3:0] sel; assign iq_data = iq_read_data[sel]; always @ (posedge clk) begin sel = sel + 1; end initial begin cyc = 0; use_AnB = 0; for (int i = 0; i < 7; ++i) begin command_A[i] = 2'b00; command_B[i] = 2'b11; command_A2[i] = 2'b00; command_B2[i] = 2'b11; pipe1_input = 9'b0; end for (int i = 0; i < 2; ++i) begin for (int j = 0; j < 3; ++j) begin for (int k = 0; k < 4; ++k) begin command_A3[i][j][k] = 2'b00; command_B3[i][j][k] = 2'b11; end end end end always @ (posedge clk) begin use_AnB <= ~use_AnB; cyc <= cyc + 1; if (use_AnB) begin if (active_command[3] != 2'b00) begin $stop; end if (active_command2[3] != 2'b00) begin $stop; end if (active_command3[0][1][2] != 2'b00) begin $stop; end end if (!use_AnB) begin if (active_command[3] != 2'b11) begin $stop; end if (active_command2[3] != 2'b11) begin $stop; end end end logic [8:0] last_pipe; always @(posedge clk) begin if (cyc < 3) begin last_pipe <= pipe1[0]; end else begin if (last_pipe + 1 != pipe1[0]) begin $stop; end else begin last_pipe <= pipe1[0]; end end if (cyc > 10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule : t verilator-3.874/test_regress/t/t_var_bad_hide.pl0000775000177100017500000000132012473477707021767 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only -Wwarn-VARHIDDEN"], fails=>$Self->{v3}, expect=> '%Warning-VARHIDDEN: t/t_var_bad_hide.v:\d+: Declaration of signal hides declaration in upper scope: top .* %Warning-VARHIDDEN: t/t_var_bad_hide.v:\d+: ... Location of original declaration %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_order_comboclkloop.v0000664000177100017500000000321512473477707023112 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // verilator lint_off BLKANDNBLK // verilator lint_off COMBDLY // verilator lint_off UNOPT // verilator lint_off UNOPTFLAT // verilator lint_off MULTIDRIVEN reg [31:0] runnerm1, runner; initial runner = 0; reg [31:0] runcount; initial runcount = 0; reg [31:0] clkrun; initial clkrun = 0; reg [31:0] clkcount; initial clkcount = 0; always @ (/*AS*/runner) begin runnerm1 = runner - 32'd1; end reg run0; always @ (/*AS*/runnerm1) begin if ((runner & 32'hf)!=0) begin runcount = runcount + 1; runner = runnerm1; $write (" seq runcount=%0d runner =%0x\n",runcount, runnerm1); end run0 = (runner[8:4]!=0 && runner[3:0]==0); end always @ (posedge run0) begin // Do something that forces another combo run clkcount <= clkcount + 1; runner[8:4] <= runner[8:4] - 1; runner[3:0] <= 3; $write ("[%0t] posedge runner=%0x\n", $time, runner); end reg [7:0] cyc; initial cyc=0; always @ (posedge clk) begin $write("[%0t] %x counts %0x %0x\n",$time,cyc,runcount,clkcount); cyc <= cyc + 8'd1; case (cyc) 8'd00: begin runner <= 0; end 8'd01: begin runner <= 32'h35; end default: ; endcase case (cyc) 8'd02: begin if (runcount!=32'he) $stop; if (clkcount!=32'h3) $stop; end 8'd03: begin $write("*-* All Finished *-*\n"); $finish; end default: ; endcase end endmodule verilator-3.874/test_regress/t/t_inst_tree_inl0_pub1.pl0000775000177100017500000000132212473477707023247 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_tree.v"); compile ( verilator_flags2 => ['+define+NOUSE_INLINE', '+define+USE_PUBLIC', '--stats'], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 16); } execute ( check_finished=>1, expect=> '\] (%m|.*v\.ps): Clocked ', ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_defparam.pl0000775000177100017500000000071712473477707022021 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_public.v0000664000177100017500000000253212473477707021671 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t ( input wire CLK, output reg RESET ); neg neg (.clk(CLK)); little little (.clk(CLK)); glbl glbl (); // A vector logic [2:1] vec [4:3]; integer val = 0; always @ (posedge CLK) begin if (RESET) val <= 0; else val <= val + 1; vec[3] <= val[1:0]; vec[4] <= val[3:2]; end initial RESET = 1'b1; always @ (posedge CLK) RESET <= glbl.GSR; endmodule module glbl(); `ifdef PUB_FUNC wire GSR; task setGSR; /* verilator public */ input value; GSR = value; endtask `else wire GSR /*verilator public*/; `endif endmodule module neg ( input clk ); reg [0:-7] i8; initial i8 = '0; reg [-1:-48] i48; initial i48 = '0; reg [63:-64] i128; initial i128 = '0; always @ (posedge clk) begin i8 <= ~i8; i48 <= ~i48; i128 <= ~i128; end endmodule module little ( input clk ); // verilator lint_off LITENDIAN reg [0:7] i8; initial i8 = '0; reg [1:49] i48; initial i48 = '0; reg [63:190] i128; initial i128 = '0; // verilator lint_on LITENDIAN always @ (posedge clk) begin i8 <= ~i8; i48 <= ~i48; i128 <= ~i128; end endmodule verilator-3.874/test_regress/t/t_math_clog2.pl0000775000177100017500000000071712473477707021430 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_pull01.pl0000775000177100017500000000071712473477707021404 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_pins_sc_uint_biguint.pl0000775000177100017500000000475112473477707024501 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc --pins-sc-uint --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.874/test_regress/t/t_gen_mislevel.v0000664000177100017500000000121212473477707021700 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. /// We define the modules in "backward" order. module d; endmodule module b; generate if (1) begin c c1 (); c c2 (); end endgenerate endmodule module c; generate if (1) begin d d1 (); d d2 (); end endgenerate endmodule module a; generate if (1) begin b b1 (); b b2 (); end endgenerate endmodule module t (/*AUTOARG*/); a a1 (); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_func_under2.v0000664000177100017500000000201712473477707021445 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. // bug598 module t (/*AUTOARG*/ // Outputs val, // Inputs clk ); input clk; output integer val; integer dbg_addr = 0; function func1; input en; input [31:0] a; func1 = en && (a == 1); endfunction function func2; input en; input [31:0] a; func2 = en && (a == 2); endfunction always @(posedge clk) begin case( 1'b1 ) // This line is OK: func1(1'b1, dbg_addr) : val = 1; // This fails: // %Error: Internal Error: test.v:23: ../V3Task.cpp:993: Function not underneath a statement // %Error: Internal Error: See the manual and http://www.veripool.org/verilator for more assistance. func2(1'b1, dbg_addr) : val = 2; default : val = 0; endcase // $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_func_begin2.v0000664000177100017500000000150212473477707021412 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module init; task t1; reg ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz; reg ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,ct,cu,cv,cw,cx,cy,cz; reg da,db,dc,dd,de,df,dg,dh,di,dj,dk,dl,dm,dn, dp,dq,dr,ds,dt,du,dv,dw,dx,dy,dz; begin : READER $display ("Time: %0t Instance: %m", $time); end endtask task t2; reg ba,bb,bc,bd,be,bf,bg,bh,bi,bj,bk,bl,bm,bn,bo,bp,bq,br,bs,bt,bu,bv,bw,bx,by,bz; begin : READER $display ("Time: %0t Instance: %m", $time); end endtask endmodule module test(); init u_ram1(); init u_ram2(); endmodule verilator-3.874/test_regress/t/t_math_divw.v0000664000177100017500000001363312473477707021223 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // verilator lint_off WIDTH //============================================================ reg bad; initial begin bad=0; c96(96'h0_0000_0000_0000_0000, 96'h8_8888_8888_8888_8888, 96'h0_0000_0000_0000_0000, 96'h0); c96(96'h8_8888_8888_8888_8888, 96'h0_0000_0000_0000_0000, 96'h0_0000_0000_0000_0000, 96'h0); c96(96'h8_8888_8888_8888_8888, 96'h0_0000_0000_0000_0002, 96'h4_4444_4444_4444_4444, 96'h0); c96(96'h8_8888_8888_8888_8888, 96'h0_2000_0000_0000_0000, 96'h0_0000_0000_0000_0044, 96'h0_0888_8888_8888_8888); c96(96'h8_8888_8888_8888_8888, 96'h8_8888_8888_8888_8888, 96'h0_0000_0000_0000_0001, 96'h0); c96(96'h8_8888_8888_8888_8888, 96'h8_8888_8888_8888_8889, 96'h0_0000_0000_0000_0000, 96'h8_8888_8888_8888_8888); c96(96'h1_0000_0000_8eba_434a, 96'h0_0000_0000_0000_0001, 96'h1_0000_0000_8eba_434a, 96'h0); c96(96'h0003, 96'h0002, 96'h0001, 96'h0001); c96(96'h0003, 96'h0003, 96'h0001, 96'h0000); c96(96'h0003, 96'h0004, 96'h0000, 96'h0003); c96(96'h0000, 96'hffff, 96'h0000, 96'h0000); c96(96'hffff, 96'h0001, 96'hffff, 96'h0000); c96(96'hffff, 96'hffff, 96'h0001, 96'h0000); c96(96'hffff, 96'h0003, 96'h5555, 96'h0000); c96(96'hffff_ffff, 96'h0001, 96'hffff_ffff, 96'h0000); c96(96'hffff_ffff, 96'hffff, 96'h0001_0001, 96'h0000); c96(96'hfffe_ffff, 96'hffff, 96'h0000_ffff, 96'hfffe); c96(96'h1234_5678, 96'h9abc, 96'h0000_1e1e, 96'h2c70); c96(96'h0000_0000, 96'h0001_0000, 96'h0000, 96'h0000_0000); c96(96'h0007_0000, 96'h0003_0000, 96'h0002, 96'h0001_0000); c96(96'h0007_0005, 96'h0003_0000, 96'h0002, 96'h0001_0005); c96(96'h0006_0000, 96'h0002_0000, 96'h0003, 96'h0000_0000); c96(96'h8000_0001, 96'h4000_7000, 96'h0001, 96'h3fff_9001); c96(96'hbcde_789a, 96'hbcde_789a, 96'h0001, 96'h0000_0000); c96(96'hbcde_789b, 96'hbcde_789a, 96'h0001, 96'h0000_0001); c96(96'hbcde_7899, 96'hbcde_789a, 96'h0000, 96'hbcde_7899); c96(96'hffff_ffff, 96'hffff_ffff, 96'h0001, 96'h0000_0000); c96(96'hffff_ffff, 96'h0001_0000, 96'hffff, 96'h0000_ffff); c96(96'h0123_4567_89ab, 96'h0001_0000, 96'h0123_4567, 96'h0000_89ab); c96(96'h8000_fffe_0000, 96'h8000_ffff, 96'h0000_ffff, 96'h7fff_ffff); c96(96'h8000_0000_0003, 96'h2000_0000_0001, 96'h0003, 96'h2000_0000_0000); c96(96'hffff_ffff_0000_0000, 96'h0001_0000_0000, 96'hffff_ffff, 96'h0000_0000_0000); c96(96'hffff_ffff_0000_0000, 96'hffff_0000_0000, 96'h0001_0001, 96'h0000_0000_0000); c96(96'hfffe_ffff_0000_0000, 96'hffff_0000_0000, 96'h0000_ffff, 96'hfffe_0000_0000); c96(96'h1234_5678_0000_0000, 96'h9abc_0000_0000, 96'h0000_1e1e, 96'h2c70_0000_0000); c96(96'h0000_0000_0000_0000, 96'h0001_0000_0000_0000, 96'h0000, 96'h0000_0000_0000_0000); c96(96'h0007_0000_0000_0000, 96'h0003_0000_0000_0000, 96'h0002, 96'h0001_0000_0000_0000); c96(96'h0007_0005_0000_0000, 96'h0003_0000_0000_0000, 96'h0002, 96'h0001_0005_0000_0000); c96(96'h0006_0000_0000_0000, 96'h0002_0000_0000_0000, 96'h0003, 96'h0000_0000_0000_0000); c96(96'h8000_0001_0000_0000, 96'h4000_7000_0000_0000, 96'h0001, 96'h3fff_9001_0000_0000); c96(96'hbcde_789a_0000_0000, 96'hbcde_789a_0000_0000, 96'h0001, 96'h0000_0000_0000_0000); c96(96'hbcde_789b_0000_0000, 96'hbcde_789a_0000_0000, 96'h0001, 96'h0000_0001_0000_0000); c96(96'hbcde_7899_0000_0000, 96'hbcde_789a_0000_0000, 96'h0000, 96'hbcde_7899_0000_0000); c96(96'hffff_ffff_0000_0000, 96'hffff_ffff_0000_0000, 96'h0001, 96'h0000_0000_0000_0000); c96(96'hffff_ffff_0000_0000, 96'h0001_0000_0000_0000, 96'hffff, 96'h0000_ffff_0000_0000); c96(96'h7fff_8000_0000_0000, 96'h8000_0000_0001, 96'h0000_fffe, 96'h7fff_ffff_0002); c96(96'h8000_0000_fffe_0000, 96'h8000_0000_ffff, 96'h0000_ffff, 96'h7fff_ffff_ffff); c96(96'h0008_8888_8888_8888_8888, 96'h0002_0000_0000_0000, 96'h0004_4444, 96'h0000_8888_8888_8888); if (bad) $stop; $write("*-* All Finished *-*\n"); $finish; end task c96; input [95:0] u; input [95:0] v; input [95:0] expq; input [95:0] expr; c96u( u, v, expq, expr); c96s( u, v, expq, expr); c96s(-u, v,-expq,-expr); c96s( u,-v,-expq, expr); c96s(-u,-v, expq,-expr); endtask task c96u; input [95:0] u; input [95:0] v; input [95:0] expq; input [95:0] expr; reg [95:0] gotq; reg [95:0] gotr; gotq = u/v; gotr = u%v; if (gotq != expq && v!=0) begin bad = 1; end if (gotr != expr && v!=0) begin bad = 1; end if (bad `ifdef TEST_VERBOSE || 1 `endif ) begin $write(" %x /u %x = got %x exp %x %% got %x exp %x", u,v,gotq,expq,gotr,expr); // Test for v=0 to prevent Xs causing grief if (gotq != expq && v!=0) $write(" BADQ"); if (gotr != expr && v!=0) $write(" BADR"); $write("\n"); end endtask task c96s; input signed [95:0] u; input signed [95:0] v; input signed [95:0] expq; input signed [95:0] expr; reg signed [95:0] gotq; reg signed [95:0] gotr; gotq = u/v; gotr = u%v; if (gotq != expq && v!=0) begin bad = 1; end if (gotr != expr && v!=0) begin bad = 1; end if (bad `ifdef TEST_VERBOSE || 1 `endif ) begin $write(" %x /s %x = got %x exp %x %% got %x exp %x", u,v,gotq,expq,gotr,expr); // Test for v=0 to prevent Xs causing grief if (gotq != expq && v!=0) $write(" BADQ"); if (gotr != expr && v!=0) $write(" BADR"); $write("\n"); end endtask endmodule verilator-3.874/test_regress/t/t_mod_dup_bad.v0000664000177100017500000000041012473477707021463 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module a(); endmodule module test(); a a(); endmodule module a(); endmodule module b(); endmodule verilator-3.874/test_regress/t/t_param_value.v0000664000177100017500000000333112473477707021527 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // 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. module t (/*AUTOARG*/); `define ASSERT(x) initial if (!(x)) $stop // See IEEE 6.20.2 on value parameters localparam unsigned [63:0] UNSIGNED =64'h99934567_89abcdef; localparam signed [63:0] SIGNED =64'sh99934567_89abcdef; localparam real REAL=1.234; `ASSERT(UNSIGNED > 0); `ASSERT(SIGNED < 0); // bullet 1 localparam A1_WIDE = UNSIGNED; `ASSERT($bits(A1_WIDE)==64); localparam A2_REAL = REAL; `ASSERT(A2_REAL == 1.234); localparam A3_SIGNED = SIGNED; `ASSERT($bits(A3_SIGNED)==64 && A3_SIGNED < 0); localparam A4_EXPR = (2'b01 + 2'b10); `ASSERT($bits(A4_EXPR)==2 && A4_EXPR==2'b11); // bullet 2 localparam [63:0] B_UNSIGNED = SIGNED; `ASSERT($bits(B_UNSIGNED)==64 && B_UNSIGNED > 0); // bullet 3 localparam signed C_SIGNED = UNSIGNED; `ASSERT($bits(C_SIGNED)==64 && C_SIGNED < 0); localparam unsigned C_UNSIGNED = SIGNED; `ASSERT($bits(C_UNSIGNED)==64 && C_UNSIGNED > 0); // bullet 4 // verilator lint_off WIDTH localparam signed [59:0] D_SIGNED = UNSIGNED; `ASSERT($bits(D_SIGNED)==60 && D_SIGNED < 0); // verilator lint_on WIDTH // verilator lint_off WIDTH localparam unsigned [59:0] D_UNSIGNED = SIGNED; `ASSERT($bits(D_UNSIGNED)==60 && D_UNSIGNED > 0); // verilator lint_on WIDTH // bullet 6 localparam UNSIZED = 23; `ASSERT($bits(UNSIZED)>=32); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_math_vgen.pl0000775000177100017500000000071712473477707021361 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_lsb.v0000664000177100017500000000404212473477707020644 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [3:0] datai = crc[3:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) logic [3:0] datao; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .datao (datao[3:0]), // Inputs .clk (clk), .datai (datai[3:0])); // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, datao}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h3db7bc8bfe61f983 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( input logic clk, input logic [3:0] datai, output logic [3:0] datao ); genvar i; parameter SIZE = 4; logic [SIZE:1][3:0] delay; always_ff @(posedge clk) begin delay[1][3:0] <= datai; end generate for (i = 2; i < (SIZE+1); i++) begin always_ff @(posedge clk) begin delay[i][3:0] <= delay[i-1][3:0]; end end endgenerate always_comb datao = delay[SIZE][3:0]; endmodule verilator-3.874/test_regress/t/t_select_plus.pl0000775000177100017500000000071712473477707021733 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_mlog2.v0000664000177100017500000000234512473477707021272 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2008 by Wilson Snyder. module t (clk); input clk; integer cyc; initial cyc=1; integer sum; integer cpre; always @ (posedge clk) begin if (cyc!=0) begin cpre = cyc; cyc <= cyc + 1; if (cyc==1) begin if (mlog2(32'd0) != 32'd0) $stop; if (mlog2(32'd1) != 32'd0) $stop; if (mlog2(32'd3) != 32'd2) $stop; sum <= 32'd0; end else if (cyc<90) begin // (cyc) so if we trash the variable things will get upset. sum <= mlog2(cyc) + sum * 32'd42; if (cpre != cyc) $stop; end else if (cyc==90) begin if (sum !== 32'h0f12bb51) $stop; $write("*-* All Finished *-*\n"); $finish; end end end function integer mlog2; input [31:0] value; integer i; begin if(value < 32'd1) begin mlog2 = 0; end else begin value = value - 32'd1; mlog2 = 0; for(i=0;i<32;i=i+1) begin if(value > 32'd0) begin mlog2 = mlog2 + 1; end value = value >> 1; end end end endfunction endmodule verilator-3.874/test_regress/t/t_dpi_string_c.cpp0000664000177100017500000000237412473477707022222 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2009 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include "svdpi.h" //====================================================================== #if defined(VERILATOR) # include "Vt_dpi_string__Dpi.h" #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef NEED_EXTERNS extern "C" { extern int dpii_string (const char* s); } #endif //====================================================================== int dpii_string(const char* s) { printf("dpii_string: %s\n",s); return strlen(s); } verilator-3.874/test_regress/t/t_inside.v0000664000177100017500000000404112473477707020505 0ustar wsnyderwsnyder// DESCRIPTION::Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t; `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); typedef enum logic [1:0] { ZERO = 2'd0, ONE = 2'd1, TWO = 2'd2, THREE = 2'd3, XXX = 2'dx } num_t; function automatic logic is_odd; input en; input num_t number; case (en) 1'b1: begin unique if (number inside {ONE, THREE}) is_odd = 1'b1; else if (number inside {ZERO, TWO}) is_odd = 1'b0; else is_odd = 1'bx; end 1'b0: is_odd = 1'bx; default: is_odd = 1'bx; endcase endfunction initial begin `checkh ((4'd4 inside {4'd1,4'd5}), 1'b0); `checkh ((4'd4 inside {4'd1,4'd4}), 1'b1); // `checkh ((4'b1011 inside {4'b1001}), 1'b0); `checkh ((4'b1011 inside {4'b1xx1}), 1'b1); // Uses ==? `checkh ((4'b1001 inside {4'b1xx1}), 1'b1); // Uses ==? `checkh ((4'b1001 inside {4'b1??1}), 1'b1); `ifndef VERILATOR `checkh ((4'b1z11 inside {4'b11?1, 4'b1011}),1'bx); `endif // Range `checkh ((4'd4 inside {[4'd5:4'd3], [4'd10:4'd8]}), 1'b0); // If left of colon < never matches `checkh ((4'd3 inside {[4'd1:4'd2], [4'd3:4'd5]}), 1'b1); `checkh ((4'd4 inside {[4'd1:4'd2], [4'd3:4'd5]}), 1'b1); `checkh ((4'd5 inside {[4'd1:4'd2], [4'd3:4'd5]}), 1'b1); // // Unsupported $ bound // // Unsupported if unpacked array, elements tranversed //int unpackedarray [$] = '{8,9}; //( expr inside {2, 3, unpackedarray}) // { 2,3,8,9} // `checkh (is_odd(1'b1, ZERO), 1'd0); `checkh (is_odd(1'b1, ONE), 1'd1); `checkh (is_odd(1'b1, TWO), 1'd0); `checkh (is_odd(1'b1, THREE),1'd1); `ifndef VERILATOR `checkh (is_odd(1'b1, XXX), 1'dx); `endif // $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_lint_unused_bad.v0000664000177100017500000000160612473477707022375 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/); sub sub (); endmodule module sub; wire pub /*verilator public*/; // Ignore publics wire [5:0] assunu1 = 0; // Assigned but unused wire [3:0] assunub2 = 0; // Assigned but bit 2 unused wire [15:10] udrb2; // [14:13,11] is undriven assign udrb2[15] = 0; assign udrb2[12] = 0; assign udrb2[10] = 0; wire unu3; // Totally unused wire [3:0] mixed; // [3] unused & undr, [2] unused, [1] undr, [0] ok assign mixed[2] = 0; assign mixed[0] = 0; localparam THREE = 3; initial begin if (0 && assunu1[0] != 0 && udrb2 != 0) begin end if (0 && assunub2[THREE] && assunub2[1:0]!=0) begin end if (0 && mixed[1:0] != 0) begin end end endmodule verilator-3.874/test_regress/t/t_vlcov_data_c.dat0000664000177100017500000000007712473477707022166 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint6ffile1.sphl159' 10 verilator-3.874/test_regress/t/t_struct_notfound_bad.v0000664000177100017500000000052212473477707023300 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/); typedef struct packed { bit m; } struct_t; struct_t s; initial begin s.nfmember = 0; // Member not found $finish; end endmodule verilator-3.874/test_regress/t/t_udp_bad.pl0000775000177100017500000000120412473477707020777 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_udp.v"); compile ( fails=>$Self->{vlt}, expect=> '%Error: t/t_udp.v:\d+: Unsupported: Verilog 1995 UDP Tables. Use --bbox-unsup to ignore tables. %Error: Exiting due to ' ); execute ( ) if !$Self->{vlt}; ok(1); 1; verilator-3.874/test_regress/t/t_param_repl.v0000664000177100017500000000230212473477707021352 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter [31:0] TWENTY4 = 24; parameter [31:0] PA = TWENTY4/8; parameter [1:0] VALUE = 2'b10; parameter [5:0] REPL = {PA{VALUE}}; parameter [7:0] CONC = {REPL,VALUE}; parameter DBITS = 32; parameter INIT_BYTE = 8'h1F; parameter DWORDS_LOG2 = 7; parameter DWORDS = (1< ["--stats"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Split always\s+(\d+)/i, 0); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_first.pl0000775000177100017500000000071712473477707021553 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_concat.pl0000775000177100017500000000077412473477707022043 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--Wno-WIDTHCONCAT"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_vgen.v0000664000177100017500000002422212473477707021205 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg check; initial check = 1'b0; // verilator lint_off WIDTH //============================================================ reg [ 1:0] W0095; //=3 reg [ 58:0] W0101; //=0000000FFFFFFFF always @(posedge clk) begin if (cyc==1) begin W0095 = ((2'h3)); W0101 = ({27'h0,({16{(W0095)}})}); end end always @(posedge clk) begin if (cyc==2) begin if ((W0101) != (59'h0FFFFFFFF)) if (check) $stop; end end //============================================================ reg [ 0:0] W1243; //=1 always @(posedge clk) begin if (cyc==1) begin W1243 = ((1'h1)); end end always @(posedge clk) begin if (cyc==2) begin // Width violation, but still... if (((-W1243) < 32'h01) != (1'h0)) if (check) $stop; if (({32{W1243}} < 32'h01) != (1'h0)) if (check) $stop; end end //============================================================ reg [ 0:0] W0344; //=0 always @(posedge clk) begin if (cyc==1) begin W0344 = 1'b0; end end always @(posedge clk) begin if (cyc==2) begin if ((W0344) != (1'h0)) if (check) $stop; if (({116{(((- 95'h7FFFFFFFFFFFFFFFFFFFFFFF) ^ 95'h7FFFFFFFFFFFFFFFFFFFFFFF ) == ({94'h0,W0344}))}})) if (check) $stop; end end //============================================================ reg [ 63:0] W0372; //=FFFFFFFFFFFFFFFF reg [118:0] W0420; //=7FFFFFFFFFFFFFFFFFFFFFFFFFFFFF reg [115:0] W0421; //=00000000000000000000000000000 always @(posedge clk) begin if (cyc==1) begin W0372 = ({64{((1'h1))}}); W0421 = 116'h0; W0420 = ({119{((W0372) <= (W0372))}}); end end always @(posedge clk) begin if (cyc==2) begin if ((W0420[(- (W0421[115:110]))]) != (1'h1)) if (check) $stop; end end //============================================================ // gcc_2_96_bug reg [ 31:0] W0161; //=FFFFFFFF reg [ 62:0] W0217; //=0000000000000000 reg [ 53:0] W0219; //=00000000000000 always @(posedge clk) begin if (cyc==1) begin W0161 = 32'hFFFFFFFF; W0217 = 63'h0; W0219 = 54'h0; end end always @(posedge clk) begin if (cyc==2) begin if ((W0161) != (32'hFFFFFFFF)) if (check) $stop; if (((- (W0161)) & ((W0217[62:31]) & ({25'h0,(W0219[53:47])}))) != (32'h00000000)) if (check) $stop; end end //============================================================ reg [119:0] W0592; //=000000000000000000000000000000 reg [ 7:0] W0593; //=70 always @(posedge clk) begin if (cyc==1) begin W0593 = (((8'h90)) * ((8'hFF))); W0592 = 120'h000000000000000000000000000000; end end always @(posedge clk) begin if (cyc==2) begin if (((W0592[119:9]) >> ((W0593))) != (111'h0000000000000000000000000000)) if (check) $stop; end end //============================================================ reg [127:0] WA1063 ; //=00000000000000000000000000000001 reg [ 34:0] WA1064 /*verilator public*/; //=7FFFFFFFF reg [ 62:0] WA1065 ; //=0000000000000000 reg [ 89:0] WA1066 /*verilator public*/; //=00000000000000000000001 reg [ 34:0] WA1067 ; //=7FFFFFFFF reg [111:0] WA1068; always @(check) begin WA1067 = (~ (35'h0)); WA1066 = (90'h00000000000000000000001); WA1065 = (WA1066[89:27]); WA1064 = (WA1067); WA1063 = (~ ((~ (128'hffffffffffffffffffffffffffffffff)) ^ (~ (128'h00000000000000000000000000000001)))); end always @(posedge clk) begin if (cyc==2) begin if ((WA1063[(WA1064[(WA1065[((5'h04) | (5'h0))+:4])+:3])+:112]) != 112'h0) if (check) $stop; end end //============================================================ reg [127:0] WB1063 ; //=00000000000000000000000000000001 reg [ 34:0] WB1064 /*verilator public*/; //=7FFFFFFFF reg [ 62:0] WB1065 ; //=0000000000000000 reg [ 89:0] WB1066 /*verilator public*/; //=00000000000000000000001 reg [ 34:0] WB1067 ; //=7FFFFFFFF reg [111:0] WB1068; always @(posedge clk) begin if (cyc==1) begin WB1067 = (~ (35'h0)); WB1066 = (90'h00000000000000000000001); end if (cyc==2) WB1065 <= (WB1066[89:27]); if (cyc==3) WB1064 <= (WB1067); if (cyc==4) WB1063 <= (~ ((~ (128'hffffffffffffffffffffffffffffffff)) ^ (~ (128'h00000000000000000000000000000001)))); if (cyc==5) WB1068 <= (WB1063[(WB1064[(WB1065[((5'h04) | (5'h0))+:4])+:3])+:112]); end always @(posedge clk) begin if (cyc==9) begin if (WB1068 != 112'h0) if (check) $stop; if ((WB1063[(WB1064[(WB1065[((5'h04) | (5'h0))+:4])+:3])+:112]) != 112'h0) if (check) $stop; end end //============================================================ reg signed [ 60:0] WC0064 ; //=1FFFFFFFFFFFFFFF reg signed [ 6:0] WC0065 ; //=00 reg signed [ 62:0] WC0067 /*verilator public*/; //=33250A3BFFFFFFFF always @(check) begin WC0064 = 61'sh1FFFFFFFFFFFFFFF; WC0065 = 7'sh0; if (((WC0064) >>> (WC0065)) != 61'sh1fffffffffffffff) if (check) $stop; end //============================================================ reg signed [ 76:0] W0234 ; //=00000000000000000000 reg signed [ 7:0] W0235 /*verilator public*/; //=B6 always @(check) begin W0235 = 8'shb6; W0234 = ((77'sh0001ffffffffffffffff) >>> (W0235)); if ((W0234) != 77'sh0) if (check) $stop; end //============================================================ reg signed [ 30:0] W0146 ; //=00000001 always @(check) begin : Block71 W0146 = (31'sh00000001); if ((W0146 >>> 6'sh3f) != 31'sh0) if (check) $stop; end //============================================================ reg signed [ 54:0] W0857 /*verilator public*/; //=7FFFFFFFFFFFFF always @(check) begin : Block405 W0857 = 55'sh7fffffffffffff; if ((63'sh7fffffffffffffff >>> (W0857[54:54] ? 7'sh56 : 7'sh7f)) != 63'sh7fffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((((122'sh3ffffffffffffffd3e48e0900000001 >>> 8'shff) >>> 8'b1) ) != 122'sh3ffffffffffffffffffffffffffffff) if (check) $stop; if (((95'sh7fff_ffff_ffffffff_ffffffff < 95'sh4a76_3d8b_0f4e3995_1146e342) != 1'h0)) if (check) $stop; end //============================================================ reg signed [ 82:0] W0226 ; //=47A4301EE3FB4133EE3DA always @* begin : Block144 W0226 = 83'sh47A4301EE3FB4133EE3DA; if ((W0226 >>> 8'sh1a) != 83'sh7ffffff1e90c07b8fed04) if (check) $stop; end //============================================================ reg signed [ 68:0] W0792 /*verilator public*/; //=169351569551247E0C reg signed [ 68:0] W0793 ; //=1FFFFFFFFF4EB1A91A always @(posedge clk) begin W0793 <= 69'sh1f_ffffffff_4eb1a91a; W0792 <= (W0793 * 69'sh1F_0E989F3E_F15F509E); if (W0792 != 69'sh16_93515695_51247E0C) if (check) $stop; end //============================================================ reg signed [ 2:0] DW0515 /*verilator public*/; //=7 always @(posedge clk) begin DW0515 <= 3'sh7; if ($signed({62'h0,DW0515[1'h1]}) != 63'sh0000000000000001) if (check) $stop; end //============================================================ reg signed [ 62:0] W0753 ; //=004E20004ED93E26 reg [ 2:0] W0772 /*verilator public*/; //=7 always @(posedge clk) begin W0753 <= 63'sh004E20004ED93E26; //(63'sh7fffffffffffffff + (63'sh464eac8c4ed93e27 & (63'sh08cf6243ffffffff))); W0772 <= 3'h7; if ((W0772[(W0753 < 63'sh0876c66a7e29fabf)]) != 1'h1) if (check) $stop; if ((W0772[(63'sh004E20004ED93E26 < 63'sh0876c66a7e29fabf)]) != 1'h1) if (check) $stop; end //============================================================ reg [ 98:0] W1027 ; //=7FFFFFFFFFFFFFFFFFFFFFFFF always @(posedge clk) begin W1027 <= ~99'h0; // verilator lint_off CMPCONST if (((1'sb1 < (95'sh7fffffffffffffffffffffff >= 95'sh09deb904ffffffffe062d44c))) != 1'h0) if (check) $stop; // verilator lint_on CMPCONST end //============================================================ reg signed [ 5:0] W123_is_3f ; //=3F always @(posedge clk) begin W123_is_3f <= 6'sh3f; end always @(posedge clk) begin if (((~ ((32'sh088d1bcb) <<< W123_is_3f)) >>> 6'sh3f) != 32'shffffffff) if (check) $stop; end //============================================================ reg signed [105: 0] W0032 /*verilator public*/; //=106'h3ff0000000100000000bd597bb1 always @(check) begin : Block237 W0032 = 106'sh3ff0000000100000000bd597bb1; if ((106'sh1ca0000000000000000b96b8dc2 / 106'sh3ff0000000100000000bd597bb1) != 106'sh3fffffffffffffffffffffffe36) if (check) $stop; if ((106'sh1ca0000000000000000b96b8dc2 / W0032) != 106'sh3fffffffffffffffffffffffe36) if (check) $stop; end //============================================================ reg signed [ 83: 0] W0024 ; //=84'h0000000000000e1fe9094 reg signed [ 83: 0] W0025 ; //=84'h0f66afffffffe308b3d7c always @(posedge clk) begin W0024 <= 84'h0000000000000e1fe9094; W0025 <= 84'h0f66afffffffe308b3d7c; if ((W0024 % W0025) != 84'sh0000000000000e1fe9094) if (check) $stop; end //============================================================ always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==18) begin check <= 1'b1; end if (cyc==20) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_math_divw.pl0000775000177100017500000000071712473477707021373 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_packed_assign.v0000664000177100017500000000147312473477707022671 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); /* verilator lint_off WIDTH */ input clk; integer cyc; initial cyc = 0; logic [31:0] arr_c; initial arr_c = 0; logic [7:0] [3:0] arr; logic [31:0] arr2_c; initial arr2_c = 0; logic [7:0] [3:0] arr2; assign arr2_c = arr2; always @ (posedge clk) begin cyc <= cyc + 1; arr_c <= arr_c + 1; arr2 <= arr2 + 1; `ifdef TEST_VERBOSE $write("cyc%0d c:%0x a0:%0x a1:%0x a2:%0x a3:%0x\n", cyc, arr_c, arr[0], arr[1], arr[2], arr[3]); `endif if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end /* verilator lint_on WIDTH */ endmodule verilator-3.874/test_regress/t/t_vlcov_rank.pl0000775000177100017500000000141312473477707021547 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); $Self->_run(cmd=>["../bin/verilator_coverage", "--rank", "t/t_vlcov_data_a.dat", "t/t_vlcov_data_b.dat", "t/t_vlcov_data_c.dat", "t/t_vlcov_data_d.dat", ], logfile=>"$Self->{obj_dir}/vlcov.log", tee => 0, ); ok(files_identical("$Self->{obj_dir}/vlcov.log", "t/$Self->{name}.out")); 1; verilator-3.874/test_regress/t/t_package_param.pl0000775000177100017500000000072212473477707022160 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gate_array.pl0000775000177100017500000000072212473477707021523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_graph.pl0000775000177100017500000000067512473477707021373 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # Compile only test compile ( ); ok(1); 1; verilator-3.874/test_regress/t/t_case_inside.v0000664000177100017500000000313312473477707021501 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; reg [63:0] sum; reg out1; reg [4:0] out2; sub sub (.in(crc[23:0]), .out1(out1), .out2(out2)); always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x sum=%x in[3:0]=%x out=%x,%x\n",$time, cyc, crc, sum, crc[3:0], out1,out2); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= {sum[62:0], sum[63]^sum[2]^sum[0]} ^ {58'h0,out1,out2}; if (cyc==0) begin // Setup crc <= 64'h00000000_00000097; sum <= 64'h0; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); `define EXPECTED_SUM 64'h10204fa5567c8a4b if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub (/*AUTOARG*/ // Outputs out1, out2, // Inputs in ); input [23:0] in; output reg out1; output reg [4:0] out2; always @* begin case (in[3:0]) inside default: {out1,out2} = {1'b0,5'h0F}; // Note not last item 4'h1, 4'h2, 4'h3: {out1,out2} = {1'b1,5'h01}; 4'h4: {out1,out2} = {1'b1,5'h04}; [4'h6:4'h5]: {out1,out2} = {1'b1,5'h05}; // order backwards, will not match 4'b100?:/*8,9*/ {out1,out2} = {1'b1,5'h08}; [4'hc:4'hf]: {out1,out2} = {1'b1,5'h0C}; endcase end endmodule verilator-3.874/test_regress/t/t_hierarchy_identifier_bad.pl0000775000177100017500000000220512473477707024371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Warning-ENDLABEL: t/t_hierarchy_identifier_bad.v:\d+: End label 'if_cnt_finish_bad' does not match begin label 'if_cnt_finish' %Warning-ENDLABEL: Use .* %Warning-ENDLABEL: t/t_hierarchy_identifier_bad.v:\d+: End label 'generate_for_bad' does not match begin label 'generate_for' %Warning-ENDLABEL: t/t_hierarchy_identifier_bad.v:\d+: End label 'generate_if_if_bad' does not match begin label 'generate_if_if' %Warning-ENDLABEL: t/t_hierarchy_identifier_bad.v:\d+: End label 'generate_if_else_bad' does not match begin label 'generate_if_else' %Warning-ENDLABEL: t/t_hierarchy_identifier_bad.v:\d+: End label 't_bad' does not match begin label 't' %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_ena_cc.pl0000775000177100017500000000155412473477707021777 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_trace_ena.v"); compile ( verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/V$Self->{name}__Trace__Slow.cpp", qr/c_trace_on\"/x); file_grep_not ("$Self->{obj_dir}/V$Self->{name}__Trace__Slow.cpp", qr/_trace_off\"/x); file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x); file_grep_not ("$Self->{obj_dir}/simx.vcd", qr/inside_sub/x); } ok(1); 1; verilator-3.874/test_regress/t/t_select_index.pl0000775000177100017500000000072012473477707022051 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_mp_func.v0000664000177100017500000000115612473477707022705 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. interface pads_if(); modport mp_dig( import fIn, import fOut ); integer exists[8]; function automatic integer fIn (integer i); fIn = exists[i]; endfunction task automatic fOut (integer i); exists[i] = 33; endtask endinterface module t(); pads_if padsif(); initial begin padsif.fOut(3); if (padsif.fIn(3) != 33) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_unpacked_array_order.pl0000775000177100017500000000071212525171734023554 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_complex_params.pl0000775000177100017500000000127712473477707023603 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t_trace_complex.v"); compile ( verilator_flags2 => ['--cc --trace --no-trace-structs --trace-params'], ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ PARAM /); vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out"); ok(1); 1; verilator-3.874/test_regress/t/t_package.v0000664000177100017500000000255712473477707020637 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. typedef int unit_type_t; function [3:0] unit_plusone(input [3:0] i); unit_plusone = i+1; endfunction package p; typedef int package_type_t; integer pi = 123; function [3:0] plusone(input [3:0] i); plusone = i+1; endfunction endpackage package p2; typedef int package2_type_t; function [3:0] plustwo(input [3:0] i); plustwo = i+2; endfunction endpackage module t (/*AUTOARG*/ // Inputs clk ); input clk; unit_type_t vu; $unit::unit_type_t vdu; p::package_type_t vp; t2 t2 (); initial begin if (unit_plusone(1) !== 2) $stop; if ($unit::unit_plusone(1) !== 2) $stop; if (p::plusone(1) !== 2) $stop; p::pi = 124; if (p::pi !== 124) $stop; $write("*-* All Finished *-*\n"); $finish; end always @ (posedge clk) begin p::pi += 1; if (p::pi < 124) $stop; end endmodule module t2; import p::*; import p2::plustwo; import p2::package2_type_t; package_type_t vp; package2_type_t vp2; initial begin if (plusone(1) !== 2) $stop; if (plustwo(1) !== 3) $stop; if (p::pi !== 123 && p::pi !== 124) $stop; // may race with other initial, so either value end endmodule verilator-3.874/test_regress/t/t_sys_sformat.v0000664000177100017500000000271312525171734021574 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. `include "verilated.v" module t; // Note $sscanf already tested elsewhere reg [3:0] n; reg [63:0] q; reg [16*8:1] wide; reg [8:1] char; reg [48*8:1] str; reg [48*8:1] str2; real r; initial begin n = 4'b1100; q = 64'h1234_5678_abcd_0123; wide = "hello-there12345"; $sformat(str, "n=%b q=%d w=%s", n, q, wide); `ifdef TEST_VERBOSE $display("str=%0s",str); `endif if (str !== "n=1100 q= 1311768467750060323 w=hello-there12345") $stop; q = {q[62:0],1'b1}; $swrite(str2, "n=%b q=%d w=%s", n, q, wide); `ifdef TEST_VERBOSE $display("str2=%0s",str2); `endif if (str2 !== "n=1100 q= 2623536935500120647 w=hello-there12345") $stop; $swrite(str2, "e=%e", r); $swrite(str2, "e=%f", r); $swrite(str2, "e=%g", r); r = 0.01; $swrite(str2, "e=%e f=%f g=%g", r, r, r); `ifdef TEST_VERBOSE $display("str2=%0s",str2); `endif if (str2 !== "e=1.000000e-02 f=0.010000 g=0.01") $stop; $swrite(str2, "mod=%m"); `ifdef TEST_VERBOSE $display("str2=%0s",str2); `endif `ifdef verilator if (str2 !== "mod=top.v") $stop; `else if (str2 !== "mod=top.t") $stop; `endif $sformat(char,"%s","c"); if (char != "c") $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_param_while.v0000664000177100017500000000126012473477707021522 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. //bug505 module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter WIDTH = 33; localparam MAX_WIDTH = 11; localparam NUM_OUT = num_out(WIDTH); wire [NUM_OUT-1:0] z; function integer num_out; input integer width; num_out = 1; while ((width + num_out - 1) / num_out > MAX_WIDTH) num_out = num_out * 2; endfunction initial begin if (NUM_OUT != 4) $stop; if ($bits(z) != 4) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_interface_mp_func.pl0000775000177100017500000000072212473477707023054 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dedupe_seq_logic.pl0000775000177100017500000000106712473477707022703 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--stats"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 6); } ok(1); 1; verilator-3.874/test_regress/t/t_select_bad_tri.v0000664000177100017500000000044712473477707022203 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/); reg [72:1] in; initial begin if (in[( (1'h0 / 1'b0) )+:71] != 71'h0) $stop; end endmodule verilator-3.874/test_regress/t/t_cover_line_sc.pl0000775000177100017500000000115712473477707022222 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_cover_line.v"); compile ( verilator_flags2 => ['--sc --coverage-line'], ); execute ( check_finished=>1, ); # Read the input .v file and do any CHECK_COVER requests inline_checks(); ok(1); 1; verilator-3.874/test_regress/t/t_pp_lib_inc.vh0000664000177100017500000000026112473477707021500 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. `define WIDTH 10 verilator-3.874/test_regress/t/t_inst_implicit.v0000664000177100017500000000201412525172076022064 0ustar wsnyderwsnyder// DESCRIPTION:tor:ilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [31:0] o; wire [31:0] oe; Test test (/*AUTOINST*/ // Outputs .o (o[31:0]), .oe (oe[31:0])); // Test loop always @ (posedge clk) begin if (o !== 32'h00000001) $stop; if (oe !== 32'h00000001) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module subimp(o,oe); output [31:0] o; assign o = 32'h12345679; output [31:0] oe; assign oe = 32'hab345679; endmodule module Test(o,oe); output [31:0] o; output [31:0] oe; wire [31:0] xe; assign xe[31:1] = 0; // verilator lint_off IMPLICIT // verilator lint_off WIDTH subimp subimp(x, // x is implicit and one bit xe[0]); // xe explicit one bit assign o = x; assign oe = xe; // verilator lint_on WIDTH // verilator lint_on IMPLICIT endmodule verilator-3.874/test_regress/t/t_inst_port_array.pl0000775000177100017500000000072212473477707022624 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vpi_unimpl.cpp0000664000177100017500000001271412525171734021724 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "Vt_vpi_unimpl.h" #include "verilated.h" #include "svdpi.h" #include "Vt_vpi_unimpl__Dpi.h" #include "verilated_vpi.h" #include "verilated_vpi.cpp" #include "verilated_vcd_c.h" #include #include "TestVpi.h" // __FILE__ is too long #define FILENM "t_vpi_unimpl.cpp" #define DEBUG if (0) printf unsigned int main_time = false; unsigned int callback_count = false; //====================================================================== #define CHECK_RESULT_VH(got, exp) \ if ((got) != (exp)) { \ printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \ FILENM,__LINE__, (got), (exp)); \ return __LINE__; \ } #define CHECK_RESULT_NZ(got) \ if (!(got)) { \ printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \ return __LINE__; \ } // Use cout to avoid issues with %d/%lx etc #define CHECK_RESULT(got, exp) \ if ((got != exp)) { \ cout<", (exp)?(exp):""); \ return __LINE__; \ } #define CHECK_RESULT_CSTR_STRIP(got, exp) \ CHECK_RESULT_CSTR(got+strspn(got, " "), exp) int _mon_check_unimpl(p_cb_data cb_data) { static TestVpiHandle cb, clk_h; if (cb_data) { // this is the callback s_vpi_error_info info; vpi_chk_error(&info); callback_count++; printf("%%Info: got pli message %s\n", info.message); } else { // setup and install static t_cb_data cb_data; clk_h = vpi_handle_by_name((PLI_BYTE8*)"t.clk", NULL); cb_data.reason = cbPLIError; cb_data.cb_rtn = _mon_check_unimpl; // this function cb = vpi_register_cb(&cb_data); CHECK_RESULT_NZ(cb); // now exercise unimplemented fns vpi_get_cb_info(cb, NULL); CHECK_RESULT(callback_count, 1); vpi_register_systf(NULL); CHECK_RESULT(callback_count, 2); vpi_get_systf_info(NULL, NULL); CHECK_RESULT(callback_count, 3); vpi_handle_multi(0, NULL, NULL); CHECK_RESULT(callback_count, 4); vpi_get64(0, NULL); CHECK_RESULT(callback_count, 5); vpi_get_delays(NULL, NULL); CHECK_RESULT(callback_count, 6); vpi_put_delays(NULL, NULL); CHECK_RESULT(callback_count, 7); vpi_get_value_array(NULL, NULL, NULL, 0); CHECK_RESULT(callback_count, 8); vpi_put_value_array(NULL, NULL, NULL, 0); CHECK_RESULT(callback_count, 9); vpi_get_time(NULL, NULL); CHECK_RESULT(callback_count, 10); vpi_mcd_name(0); CHECK_RESULT(callback_count, 11); vpi_compare_objects(NULL, NULL); CHECK_RESULT(callback_count, 12); vpi_get_data(0, NULL, 0); CHECK_RESULT(callback_count, 13); vpi_put_data(0, NULL, 0); CHECK_RESULT(callback_count, 14); vpi_get_userdata(NULL); CHECK_RESULT(callback_count, 15); vpi_put_userdata(NULL, NULL); CHECK_RESULT(callback_count, 16); vpi_handle_by_multi_index(NULL, 0, NULL); CHECK_RESULT(callback_count, 17); } return 0; // Ok } int mon_check() { // Callback from initial block in monitor if (int status = _mon_check_unimpl(NULL)) return status; return 0; // Ok } //====================================================================== double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { double sim_time = 1100; Verilated::commandArgs(argc, argv); Verilated::debug(0); Verilated::fatalOnVpiError(0); // we're going to be checking for these errors do don't crash out VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out #ifdef VERILATOR # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif #endif #if VM_TRACE Verilated::traceEverOn(true); VL_PRINTF("Enabling waves...\n"); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_vpi_var/simx.vcd"); #endif topp->eval(); topp->clk = 0; main_time += 10; while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += 1; topp->eval(); VerilatedVpi::callValueCbs(); topp->clk = !topp->clk; //mon_do(); #if VM_TRACE if (tfp) tfp->dump (main_time); #endif } CHECK_RESULT(callback_count, 17); if (!Verilated::gotFinish()) { vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish"); } topp->final(); #if VM_TRACE if (tfp) tfp->close(); #endif delete topp; topp=NULL; exit(0L); } verilator-3.874/test_regress/t/t_math_equal.v0000664000177100017500000000272712473477707021363 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer _mode; reg _guard1; reg [127:0] r_wide0; reg _guard2; wire [63:0] r_wide1; reg _guard3; reg _guard4; reg _guard5; reg _guard6; assign r_wide1 = r_wide0[127:64]; // surefire lint_off STMINI initial _mode = 0; always @ (posedge clk) begin if (_mode==0) begin $write("[%0t] t_equal: Running\n", $time); _guard1 <= 0; _guard2 <= 0; _guard3 <= 0; _guard4 <= 0; _guard5 <= 0; _guard6 <= 0; _mode<=1; r_wide0 <= {32'h aa111111,32'hbb222222,32'hcc333333,32'hdd444444}; end else if (_mode==1) begin _mode<=2; // if (5'd10 != 5'b1010) $stop; if (5'd10 != 5'd10) $stop; if (5'd10 != 5'ha) $stop; if (5'd10 != 5'o12) $stop; if (5'd10 != 5'B 1010) $stop; if (5'd10 != 5'D10) $stop; if (5'd10 != 5'H a) $stop; if (5'd10 != 5 'O 12) $stop; // if (r_wide0 !== {32'haa111111,32'hbb222222,32'hcc333333,32'hdd444444}) $stop; if (r_wide1 !== {32'haa111111,32'hbb222222}) $stop; if (|{_guard1,_guard2,_guard3,_guard4,_guard5,_guard6}) begin $write("Guard error %x %x %x %x %x\n",_guard1,_guard2,_guard3,_guard4,_guard5); $stop; end $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_func_wide.pl0000775000177100017500000000071712473477707021354 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_context_noopt.pl0000775000177100017500000000111212473477707023136 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_dpi_context.v"); compile ( v_flags2 => ["t/t_dpi_context_c.cpp"], verilator_flags2 => [$Self->{v3}?"-O0":""], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_readmem_bad_digit.pl0000775000177100017500000000107412473477707023704 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( fails=>$Self->{v3}, expect=> '%Error: t/t_sys_readmem_bad_digit.mem:\d+: \$readmemb \(binary\) file contains hex characters', ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_complex_params.out0000664000177100017500000000612512473477707023771 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Tue Apr 15 19:42:37 2014 $end $timescale 1ns $end $scope module top $end $var wire 1 9 clk $end $scope module $unit $end $var wire 1 # global_bit $end $upscope $end $scope module v $end $var wire 1 9 clk $end $var wire 32 $ cyc [31:0] $end $var real 64 3 v_arr_real(0) $end $var real 64 5 v_arr_real(1) $end $var wire 2 * v_arrp [2:1] $end $var wire 4 + v_arrp_arrp [3:0] $end $var wire 4 , v_arrp_strp [3:0] $end $var wire 1 : v_arru(1) $end $var wire 1 ; v_arru(2) $end $var wire 2 - v_arru_arrp(3) [2:1] $end $var wire 2 . v_arru_arrp(4) [2:1] $end $var wire 1 < v_arru_arru(3)(1) $end $var wire 1 = v_arru_arru(3)(2) $end $var wire 1 > v_arru_arru(4)(1) $end $var wire 1 ? v_arru_arru(4)(2) $end $var wire 2 / v_arru_strp(3) [1:0] $end $var wire 2 0 v_arru_strp(4) [1:0] $end $var real 64 1 v_real $end $var wire 64 % v_str32x2 [63:0] $end $var wire 2 ' v_strp [1:0] $end $var wire 4 ( v_strp_strp [3:0] $end $var wire 2 ) v_unip_strp [1:0] $end $scope module p2 $end $var wire 32 @ PARAM [31:0] $end $upscope $end $scope module p3 $end $var wire 32 A PARAM [31:0] $end $upscope $end $scope module unnamedblk1 $end $var wire 32 7 b [31:0] $end $scope module unnamedblk2 $end $var wire 32 8 a [31:0] $end $upscope $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 1# b00000000000000000000000000000000 $ b0000000000000000000000000000000000000000000000000000000011111111 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0 1 r0 3 r0 5 b00000000000000000000000000000000 7 b00000000000000000000000000000000 8 09 0: 0; 0< 0= 0> 0? b00000000000000000000000000000010 @ b00000000000000000000000000000011 A #10 b00000000000000000000000000000001 $ b0000000000000000000000000000000100000000000000000000000011111110 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.1 1 r0.2 3 r0.3 5 b00000000000000000000000000000101 7 b00000000000000000000000000000101 8 19 #15 09 #20 b00000000000000000000000000000010 $ b0000000000000000000000000000001000000000000000000000000011111101 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.2 1 r0.4 3 r0.6 5 19 #25 09 #30 b00000000000000000000000000000011 $ b0000000000000000000000000000001100000000000000000000000011111100 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.3 1 r0.6000000000000001 3 r0.8999999999999999 5 19 #35 09 #40 b00000000000000000000000000000100 $ b0000000000000000000000000000010000000000000000000000000011111011 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.4 1 r0.8 3 r1.2 5 19 #45 09 #50 b00000000000000000000000000000101 $ b0000000000000000000000000000010100000000000000000000000011111010 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.5 1 r1 3 r1.5 5 19 #55 09 #60 b00000000000000000000000000000110 $ b0000000000000000000000000000011000000000000000000000000011111001 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.6 1 r1.2 3 r1.8 5 19 verilator-3.874/test_regress/t/t_interface_gen4.v0000664000177100017500000000210012525171734022066 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // bug789 generates module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc #(1) itopa(); ifc #(2) itopb(); sub #(1) ca (.isub(itopa), .i_value(4)); sub #(2) cb (.isub(itopb), .i_value(5)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==1) begin if (itopa.MODE != 1) $stop; if (itopb.MODE != 2) $stop; end if (cyc==20) begin if (itopa.i != 4) $stop; if (itopb.i != 5) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub #(parameter MODE = 0) ( ifc isub, input integer i_value ); // Commercial unsupported Xmrs into scopes within interfaces generate always_comb isub.i = i_value; endgenerate endmodule interface ifc; parameter MODE = 0; // Commercial unsupported Xmrs into scopes within interfaces generate integer i; endgenerate endinterface verilator-3.874/test_regress/t/t_param_sel.pl0000775000177100017500000000071712473477707021354 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_array_partial.v0000664000177100017500000000423012473477707023121 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [19:10] bitout; wire [29:24] short_bitout; wire [7:0] allbits; wire [15:0] twobits; sub i_sub1 [7:4] (.allbits (allbits), .twobits (twobits[15:8]), .bitout (bitout[17:14])), i_sub2 [3:0] (.allbits (allbits), .twobits (twobits[7:0]), .bitout (bitout[13:10])); sub i_sub3 [7:4] (.allbits (allbits), .twobits (twobits[15:8]), .bitout (bitout[17:14])); sub i_sub4 [7:4] (.allbits (allbits), .twobits (twobits[15:8]), .bitout (short_bitout[27:24])); sub i_sub5 [7:0] (.allbits (allbits), .twobits (twobits), .bitout (bitout[17:10])); sub i_sub6 [7:4] (.allbits (allbits), .twobits (twobits[15:8]), .bitout ({bitout[18+:2],short_bitout[28+:2]})); integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Signals under test assign allbits = crc[7:0]; assign twobits = crc[15:0]; wire [63:0] result = {48'h0, short_bitout, bitout}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'ha1da9ff8082a4ff6 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule // t module sub ( input wire [7:0] allbits, input wire [1:0] twobits, output wire bitout); assign bitout = (^ twobits) ^ (^ allbits); endmodule // sub verilator-3.874/test_regress/t/t_lint_implicit.v0000664000177100017500000000052712473477707022077 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (a,z); input a; output z; assign b = 1'b1; or OR0 (nt0, a, b); logic [1:0] dummy_ip; assign {dummy1, dummy2} = dummy_ip; assign z = nt0; endmodule verilator-3.874/test_regress/t/t_flag_f.v0000664000177100017500000000123612473477707020453 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module `include "t_flag_f_tsub_inc.v" module t; initial begin `ifndef GOT_DEF1 $write("%%Error: NO GOT_DEF1\n"); $stop; `endif `ifndef GOT_DEF2 $write("%%Error: NO GOT_DEF2\n"); $stop; `endif `ifndef GOT_DEF3 $write("%%Error: NO GOT_DEF3\n"); $stop; `endif `ifndef GOT_DEF4 $write("%%Error: NO GOT_DEF4\n"); $stop; `endif `ifndef GOT_DEF5 $write("%%Error: NO GOT_DEF5\n"); $stop; `endif `ifndef GOT_DEF6 $write("%%Error: NO GOT_DEF6\n"); $stop; `endif `ifdef NON_DEF $write("%%Error: NON_DEF\n"); $stop; `endif $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_mem_multiwire.v0000664000177100017500000000344212473477707022115 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // verilator lint_off LITENDIAN wire [7:0] array [2:0][1:3]; wire [7:0] arrayNoColon [2][3]; // verilator lint_on LITENDIAN integer cyc; initial cyc=0; integer i0,i1,i2; genvar g0,g1,g2; generate for (g0=0; g0<3; g0=g0+1) begin for (g1=1; g1<4; g1=g1+1) begin inst inst (.q(array[g0[1:0]] [g1[1:0]]), .cyc(cyc), .i0(g0[1:0]), .i1(g1[1:0])); end end endgenerate always @ (posedge clk) begin //$write("cyc==%0d\n",cyc); cyc <= cyc + 1; if (cyc==2) begin if (array[2][1] !== 8'h92) $stop; for (i0=0; i0<3; i0=i0+1) begin for (i1=1; i1<4; i1=i1+1) begin //$write(" array[%0d][%0d] == 8'h%x\n",i0,i1,array[i0[1:0]] [i1[1:0]]); if (array[i0[1:0]] [i1[1:0]] != {i0[1:0], i1[1:0], cyc[3:0]}) $stop; end end end else if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module inst (/*AUTOARG*/ // Outputs q, // Inputs cyc, i0, i1 ); output reg [7:0] q; input [31:0] cyc; input [1:0] i0; input [1:0] i1; inst2 inst2 (/*AUTOINST*/ // Inputs .cyc (cyc[31:0]), .i0 (i0[1:0]), .i1 (i1[1:0])); always @* begin q = {i0, i1, cyc[3:0]}; end endmodule module inst2 (/*AUTOARG*/ // Inputs cyc, i0, i1 ); /*verilator no_inline_module*/ // So we'll get a CELL under a GENFOR, without inlining input [31:0] cyc; input [1:0] i0; input [1:0] i1; initial begin if (cyc==32'h1) $write("[%0t] i0=%d i1=%d\n", $time, i0, i1); end endmodule verilator-3.874/test_regress/t/t_func_public.pl0000775000177100017500000000103012473477707021667 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ['+define+VERILATOR_PUBLIC_TASKS'], fails => $fail, ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_mismodport_bad.pl0000775000177100017500000000130012473477707024421 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, fails => 1, expect=> '%Error: t/t_interface_mismodport_bad.v:\d+: Can\'t find definition of \'bad\' in dotted signal: isub.bad .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_for1.v0000664000177100017500000000276512473477707020745 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire b; reg reset; integer cyc=0; Testit testit (/*AUTOINST*/ // Outputs .b (b), // Inputs .clk (clk), .reset (reset)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin reset <= 1'b0; end else if (cyc<10) begin reset <= 1'b1; end else if (cyc<90) begin reset <= 1'b0; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module Testit (clk, reset, b); input clk; input reset; output b; wire [0:0] c; wire my_sig; wire [0:0] d; genvar i; generate for(i = 0; i >= 0; i = i-1) begin: fnxtclk1 fnxtclk fnxtclk1 (.u(c[i]), .reset(reset), .clk(clk), .w(d[i]) ); end endgenerate assign b = d[0]; assign c[0] = my_sig; assign my_sig = 1'b1; endmodule module fnxtclk (u, reset, clk, w ); input u; input reset; input clk; output reg w; always @ (posedge clk or posedge reset) begin if (reset == 1'b1) begin w <= 1'b0; end else begin w <= u; end end endmodule verilator-3.874/test_regress/t/t_bitsel_wire_array_bad.v0000664000177100017500000000076112473477707023553 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test of select from constant // // This tests issue 509, bit select of constant fails // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; // a and b are arrays of length 1. wire a[0:0]; // Array of nets wire b[0:0]; assign a = 1'b0; // Only net assignment allowed assign b = a[0]; // Only net assignment allowed endmodule verilator-3.874/test_regress/t/t_func.pl0000775000177100017500000000071712473477707020344 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_outfirst.v0000664000177100017500000000532712473477707022134 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. `define DDIFF_BITS 9 `define AOA_BITS 8 `define HALF_DDIFF `DDIFF_BITS'd256 `define MAX_AOA `AOA_BITS'd255 `define BURP_DIVIDER 9'd16 module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [`DDIFF_BITS-1:0] DDIFF_B = crc[`DDIFF_BITS-1:0]; wire reset = (cyc<7); /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [`AOA_BITS-1:0] AOA_B; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .AOA_B (AOA_B[`AOA_BITS-1:0]), // Inputs .DDIFF_B (DDIFF_B[`DDIFF_BITS-1:0]), .reset (reset), .clk (clk)); // Aggregate outputs into a single result vector wire [63:0] result = {56'h0, AOA_B}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h3a74e9d34771ad93 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs AOA_B, // Inputs DDIFF_B, reset, clk ); input [`DDIFF_BITS-1:0] DDIFF_B; input reset; input clk; output reg [`AOA_BITS-1:0] AOA_B; reg [`AOA_BITS-1:0] AOA_NEXT_B; reg [`AOA_BITS-1:0] tmp; always @(posedge clk) begin if (reset) begin AOA_B <= 8'h80; end else begin AOA_B <= AOA_NEXT_B; end end always @* begin // verilator lint_off WIDTH tmp = ((`HALF_DDIFF-DDIFF_B)/`BURP_DIVIDER); t_aoa_update(AOA_NEXT_B, AOA_B, ((`HALF_DDIFF-DDIFF_B)/`BURP_DIVIDER)); // verilator lint_on WIDTH end task t_aoa_update; output [`AOA_BITS-1:0] aoa_reg_next; input [`AOA_BITS-1:0] aoa_reg; input [`AOA_BITS-1:0] aoa_delta_update; begin if ((`MAX_AOA-aoa_reg)1, ); ok(1); 1; verilator-3.874/test_regress/t/t_parse_delay.pl0000775000177100017500000000072212473477707021675 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_shift.v0000664000177100017500000000546612473477707021374 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs ign, // Inputs clk ); input clk; output [31:0] ign; reg [31:0] right; reg [31:0] left; reg [63:0] qright; reg [63:0] qleft; reg [31:0] amt; assign ign = {31'h0, clk} >>> 4'bx; // bug760 always @* begin right = 32'h819b018a >> amt; left = 32'h819b018a << amt; qright = 64'hf784bf8f_12734089 >> amt; qleft = 64'hf784bf8f_12734089 >> amt; end integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("%d %x %x %x %x\n", cyc, left, right, qleft, qright); `endif if (cyc==1) begin amt <= 32'd0; if (5'b10110>>2 != 5'b00101) $stop; if (5'b10110>>>2 != 5'b00101) $stop; // Note it cares about sign-ness if (5'b10110<<2 != 5'b11000) $stop; if (5'b10110<<<2 != 5'b11000) $stop; if (5'sb10110>>2 != 5'sb00101) $stop; if (5'sb10110>>>2 != 5'sb11101) $stop; if (5'sb10110<<2 != 5'sb11000) $stop; if (5'sb10110<<<2 != 5'sb11000) $stop; // Allow >64 bit shifts if the shift amount is a constant if ((64'sh458c2de282e30f8b >> 68'sh4) !== 64'sh0458c2de282e30f8) $stop; end if (cyc==2) begin amt <= 32'd28; if (left != 32'h819b018a) $stop; if (right != 32'h819b018a) $stop; if (qleft != 64'hf784bf8f_12734089) $stop; if (qright != 64'hf784bf8f_12734089) $stop; end if (cyc==3) begin amt <= 32'd31; if (left != 32'ha0000000) $stop; if (right != 32'h8) $stop; if (qleft != 64'h0000000f784bf8f1) $stop; if (qright != 64'h0000000f784bf8f1) $stop; end if (cyc==4) begin amt <= 32'd32; if (left != 32'h0) $stop; if (right != 32'h1) $stop; if (qleft != 64'h00000001ef097f1e) $stop; if (qright != 64'h00000001ef097f1e) $stop; end if (cyc==5) begin amt <= 32'd33; if (left != 32'h0) $stop; if (right != 32'h0) $stop; if (qleft != 64'h00000000f784bf8f) $stop; if (qright != 64'h00000000f784bf8f) $stop; end if (cyc==6) begin amt <= 32'd64; if (left != 32'h0) $stop; if (right != 32'h0) $stop; if (qleft != 64'h000000007bc25fc7) $stop; if (qright != 64'h000000007bc25fc7) $stop; end if (cyc==7) begin amt <= 32'd128; if (left != 32'h0) $stop; if (right != 32'h0) $stop; if (qleft != 64'h0) $stop; if (qright != 64'h0) $stop; end if (cyc==8) begin if (left != 32'h0) $stop; if (right != 32'h0) $stop; if (qleft != 64'h0) $stop; if (qright != 64'h0) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_stream3.v0000664000177100017500000000441012473477707020610 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; /*AUTOWIRE*/ generate for (genvar width=1; width<=16; width++) begin for (genvar amt=1; amt<=width; amt++) begin Test #(.WIDTH(width), .AMT(amt)) test (.ins(crc[width-1:0])); end end endgenerate // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x\n", $time, cyc, crc); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h0 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Inputs ins ); parameter WIDTH = 1; parameter AMT = 1; input [WIDTH-1:0] ins; reg [WIDTH-1:0] got; reg [WIDTH-1:0] expec; int istart; int bitn; int ostart; always @* begin got = { << AMT {ins}}; // Note always starts with right-most bit expec = 0; for (istart=0; istart= 0 && (ostart+bitn) < WIDTH && (ostart+bitn) >= 0) begin expec[ostart+bitn] = ins[istart+bitn]; end end end `ifdef TEST_VERBOSE $write("[%0t] exp %0d'b%b got %0d'b%b = { << %0d { %0d'b%b }}\n", $time, WIDTH, expec, WIDTH, got, AMT, WIDTH, ins); `endif `checkh(got, expec); end endmodule verilator-3.874/test_regress/t/t_interface1.pl0000775000177100017500000000072712473477707021433 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_multi_io3_cc.pl0000775000177100017500000000122412525171734022577 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_mem_multi_io3.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io3.cpp -Oi"], verilator_flags3 => [], ); ok(1); 1; verilator-3.874/test_regress/t/t_enum.v0000664000177100017500000000327512473477707020206 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. typedef enum logic [4:0] { BIT0 = 5'd0, BIT1 = 5'd1, BIT2 = 5'd2 } three_t; module t (/*AUTOARG*/); localparam FIVE = 5; enum { e0, e1, e3=3, e5=FIVE, e10_[2] = 10, e20_[5:7] = 25, e20_z, e30_[7:5] = 30, e30_z } EN; enum { z5 = e5 } ZN; typedef enum [2:0] { ONES=~0 } three_t; three_t three = ONES; var logic [ONES:0] sized_based_on_enum; var enum logic [3:0] { QINVALID='1, QSEND={2'b0,2'h0}, QOP={2'b0,2'h1}, QCL={2'b0,2'h2}, QPR={2'b0,2'h3 }, QACK, QRSP } inv; initial begin if (e0 !== 0) $stop; if (e1 !== 1) $stop; if (e3 !== 3) $stop; if (e5 !== 5) $stop; if (e10_0 !== 10) $stop; if (e10_1 !== 11) $stop; if (e20_5 !== 25) $stop; if (e20_6 !== 26) $stop; if (e20_7 !== 27) $stop; if (e20_z !== 28) $stop; if (e30_7 !== 30) $stop; if (e30_6 !== 31) $stop; if (e30_5 !== 32) $stop; if (e30_z !== 33) $stop; if (z5 !== 5) $stop; if (three != 3'b111) $stop; if ($bits(sized_based_on_enum) != 8) $stop; if ($bits(three_t) != 3) $stop; if (FIVE[BIT0] != 1'b1) $stop; if (FIVE[BIT1] != 1'b0) $stop; if (FIVE[BIT2] != 1'b1) $stop; if (QINVALID != 15) $stop; if (QSEND != 0) $stop; if (QOP != 1) $stop; if (QCL != 2) $stop; if (QPR != 3) $stop; if (QACK != 4) $stop; if (QRSP != 5) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_flag_wfatal.v0000664000177100017500000000036712473477707021510 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/); // Width error below wire [3:0] foo = 6'h2e; endmodule verilator-3.874/test_regress/t/t_inst_misarray_bad.pl0000775000177100017500000000113112525171734023057 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_inst_misarray_bad.v:\d+: Illegal assignment of constant to unpacked array %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_alw.v0000664000177100017500000000330612473477707020651 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [9:0] in = crc[9:0]; /*AUTOWIRE*/ Test test (/*AUTOINST*/ // Inputs .clk (clk), .in (in[9:0])); // Aggregate outputs into a single result vector wire [63:0] result = {64'h0}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h0 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Inputs clk, in ); input clk; input [9:0] in; reg a [9:0]; integer ai; always @* begin for (ai=0;ai<10;ai=ai+1) begin a[ai]=in[ai]; end end reg [1:0] b [9:0]; integer j; generate genvar i; for (i=0; i<2; i=i+1) begin always @(posedge clk) begin for (j=0; j<10; j=j+1) begin if (a[j]) b[i][j] <= 1'b0; else b[i][j] <= 1'b1; end end end endgenerate endmodule verilator-3.874/test_regress/t/t_vpi_var.v0000664000177100017500000000650212473477707020704 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2010 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. `ifdef USE_VPI_NOT_DPI //We call it via $c so we can verify DPI isn't required - see bug572 `else import "DPI-C" context function integer mon_check(); `endif module t (/*AUTOARG*/ // Inputs clk ); `ifdef VERILATOR `systemc_header extern "C" int mon_check(); `verilog `endif input clk; reg onebit /*verilator public_flat_rw @(posedge clk) */; reg [2:1] twoone /*verilator public_flat_rw @(posedge clk) */; reg [2:1] fourthreetwoone[4:3] /*verilator public_flat_rw @(posedge clk) */; reg [61:0] quads[3:2] /*verilator public_flat_rw @(posedge clk) */; reg [31:0] count /*verilator public_flat_rd */; reg [31:0] half_count /*verilator public_flat_rd */; reg [7:0] text_byte /*verilator public_flat_rw @(posedge clk) */; reg [15:0] text_half /*verilator public_flat_rw @(posedge clk) */; reg [31:0] text_word /*verilator public_flat_rw @(posedge clk) */; reg [63:0] text_long /*verilator public_flat_rw @(posedge clk) */; reg [511:0] text /*verilator public_flat_rw @(posedge clk) */; integer status; sub sub(); // Test loop initial begin count = 0; onebit = 1'b0; fourthreetwoone[3] = 0; // stop icarus optimizing away text_byte = "B"; text_half = "Hf"; text_word = "Word"; text_long = "Long64b"; text = "Verilog Test module"; `ifdef VERILATOR status = $c32("mon_check()"); `endif `ifdef iverilog status = $mon_check(); `endif `ifndef USE_VPI_NOT_DPI status = mon_check(); `endif if (status!=0) begin $write("%%Error: t_vpi_var.cpp:%0d: C Test failed\n", status); $stop; end $write("%%Info: Checking results\n"); if (onebit != 1'b1) $stop; if (quads[2] != 62'h12819213_abd31a1c) $stop; if (quads[3] != 62'h1c77bb9b_3784ea09) $stop; if (text_byte != "A") $stop; if (text_half != "T2") $stop; if (text_word != "Tree") $stop; if (text_long != "44Four44") $stop; if (text != "lorem ipsum") $stop; end always @(posedge clk) begin count <= count + 2; if (count[1]) half_count <= half_count + 2; if (count == 1000) begin $write("*-* All Finished *-*\n"); $finish; end end genvar i; generate for (i=1; i<=128; i=i+1) begin : arr arr #(.LENGTH(i)) arr(); end endgenerate endmodule : t module sub; reg subsig1 /*verilator public_flat_rd*/; reg subsig2 /*verilator public_flat_rd*/; `ifdef iverilog // stop icarus optimizing signals away wire redundant = subsig1 | subsig2; `endif endmodule : sub module arr; parameter LENGTH = 1; reg [LENGTH-1:0] sig /*verilator public_flat_rw*/; reg [LENGTH-1:0] rfr /*verilator public_flat_rw*/; reg check /*verilator public_flat_rw*/; reg verbose /*verilator public_flat_rw*/; initial begin sig = {LENGTH{1'b0}}; rfr = {LENGTH{1'b0}}; end always @(posedge check) begin if (verbose) $display("%m : %x %x", sig, rfr); if (check && sig != rfr) $stop; check <= 0; end endmodule : arr verilator-3.874/test_regress/t/t_case_write1_tasks.v0000664000177100017500000030173612473477707022660 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. `include "verilated.v" module t_case_write1_tasks (); // verilator lint_off WIDTH // verilator lint_off CASEINCOMPLETE parameter STRLEN = 78; task ozonerab; input [6:0] rab; inout [STRLEN*8:1] foobar; // verilator no_inline_task begin case (rab[6:0]) 7'h00 : foobar = {foobar, " 0"}; 7'h01 : foobar = {foobar, " 1"}; 7'h02 : foobar = {foobar, " 2"}; 7'h03 : foobar = {foobar, " 3"}; 7'h04 : foobar = {foobar, " 4"}; 7'h05 : foobar = {foobar, " 5"}; 7'h06 : foobar = {foobar, " 6"}; 7'h07 : foobar = {foobar, " 7"}; 7'h08 : foobar = {foobar, " 8"}; 7'h09 : foobar = {foobar, " 9"}; 7'h0a : foobar = {foobar, " 10"}; 7'h0b : foobar = {foobar, " 11"}; 7'h0c : foobar = {foobar, " 12"}; 7'h0d : foobar = {foobar, " 13"}; 7'h0e : foobar = {foobar, " 14"}; 7'h0f : foobar = {foobar, " 15"}; 7'h10 : foobar = {foobar, " 16"}; 7'h11 : foobar = {foobar, " 17"}; 7'h12 : foobar = {foobar, " 18"}; 7'h13 : foobar = {foobar, " 19"}; 7'h14 : foobar = {foobar, " 20"}; 7'h15 : foobar = {foobar, " 21"}; 7'h16 : foobar = {foobar, " 22"}; 7'h17 : foobar = {foobar, " 23"}; 7'h18 : foobar = {foobar, " 24"}; 7'h19 : foobar = {foobar, " 25"}; 7'h1a : foobar = {foobar, " 26"}; 7'h1b : foobar = {foobar, " 27"}; 7'h1c : foobar = {foobar, " 28"}; 7'h1d : foobar = {foobar, " 29"}; 7'h1e : foobar = {foobar, " 30"}; 7'h1f : foobar = {foobar, " 31"}; 7'h20 : foobar = {foobar, " 32"}; 7'h21 : foobar = {foobar, " 33"}; 7'h22 : foobar = {foobar, " 34"}; 7'h23 : foobar = {foobar, " 35"}; 7'h24 : foobar = {foobar, " 36"}; 7'h25 : foobar = {foobar, " 37"}; 7'h26 : foobar = {foobar, " 38"}; 7'h27 : foobar = {foobar, " 39"}; 7'h28 : foobar = {foobar, " 40"}; 7'h29 : foobar = {foobar, " 41"}; 7'h2a : foobar = {foobar, " 42"}; 7'h2b : foobar = {foobar, " 43"}; 7'h2c : foobar = {foobar, " 44"}; 7'h2d : foobar = {foobar, " 45"}; 7'h2e : foobar = {foobar, " 46"}; 7'h2f : foobar = {foobar, " 47"}; 7'h30 : foobar = {foobar, " 48"}; 7'h31 : foobar = {foobar, " 49"}; 7'h32 : foobar = {foobar, " 50"}; 7'h33 : foobar = {foobar, " 51"}; 7'h34 : foobar = {foobar, " 52"}; 7'h35 : foobar = {foobar, " 53"}; 7'h36 : foobar = {foobar, " 54"}; 7'h37 : foobar = {foobar, " 55"}; 7'h38 : foobar = {foobar, " 56"}; 7'h39 : foobar = {foobar, " 57"}; 7'h3a : foobar = {foobar, " 58"}; 7'h3b : foobar = {foobar, " 59"}; 7'h3c : foobar = {foobar, " 60"}; 7'h3d : foobar = {foobar, " 61"}; 7'h3e : foobar = {foobar, " 62"}; 7'h3f : foobar = {foobar, " 63"}; 7'h40 : foobar = {foobar, " 64"}; 7'h41 : foobar = {foobar, " 65"}; 7'h42 : foobar = {foobar, " 66"}; 7'h43 : foobar = {foobar, " 67"}; 7'h44 : foobar = {foobar, " 68"}; 7'h45 : foobar = {foobar, " 69"}; 7'h46 : foobar = {foobar, " 70"}; 7'h47 : foobar = {foobar, " 71"}; 7'h48 : foobar = {foobar, " 72"}; 7'h49 : foobar = {foobar, " 73"}; 7'h4a : foobar = {foobar, " 74"}; 7'h4b : foobar = {foobar, " 75"}; 7'h4c : foobar = {foobar, " 76"}; 7'h4d : foobar = {foobar, " 77"}; 7'h4e : foobar = {foobar, " 78"}; 7'h4f : foobar = {foobar, " 79"}; 7'h50 : foobar = {foobar, " 80"}; 7'h51 : foobar = {foobar, " 81"}; 7'h52 : foobar = {foobar, " 82"}; 7'h53 : foobar = {foobar, " 83"}; 7'h54 : foobar = {foobar, " 84"}; 7'h55 : foobar = {foobar, " 85"}; 7'h56 : foobar = {foobar, " 86"}; 7'h57 : foobar = {foobar, " 87"}; 7'h58 : foobar = {foobar, " 88"}; 7'h59 : foobar = {foobar, " 89"}; 7'h5a : foobar = {foobar, " 90"}; 7'h5b : foobar = {foobar, " 91"}; 7'h5c : foobar = {foobar, " 92"}; 7'h5d : foobar = {foobar, " 93"}; 7'h5e : foobar = {foobar, " 94"}; 7'h5f : foobar = {foobar, " 95"}; 7'h60 : foobar = {foobar, " 96"}; 7'h61 : foobar = {foobar, " 97"}; 7'h62 : foobar = {foobar, " 98"}; 7'h63 : foobar = {foobar, " 99"}; 7'h64 : foobar = {foobar, " 100"}; 7'h65 : foobar = {foobar, " 101"}; 7'h66 : foobar = {foobar, " 102"}; 7'h67 : foobar = {foobar, " 103"}; 7'h68 : foobar = {foobar, " 104"}; 7'h69 : foobar = {foobar, " 105"}; 7'h6a : foobar = {foobar, " 106"}; 7'h6b : foobar = {foobar, " 107"}; 7'h6c : foobar = {foobar, " 108"}; 7'h6d : foobar = {foobar, " 109"}; 7'h6e : foobar = {foobar, " 110"}; 7'h6f : foobar = {foobar, " 111"}; 7'h70 : foobar = {foobar, " 112"}; 7'h71 : foobar = {foobar, " 113"}; 7'h72 : foobar = {foobar, " 114"}; 7'h73 : foobar = {foobar, " 115"}; 7'h74 : foobar = {foobar, " 116"}; 7'h75 : foobar = {foobar, " 117"}; 7'h76 : foobar = {foobar, " 118"}; 7'h77 : foobar = {foobar, " 119"}; 7'h78 : foobar = {foobar, " 120"}; 7'h79 : foobar = {foobar, " 121"}; 7'h7a : foobar = {foobar, " 122"}; 7'h7b : foobar = {foobar, " 123"}; 7'h7c : foobar = {foobar, " 124"}; 7'h7d : foobar = {foobar, " 125"}; 7'h7e : foobar = {foobar, " 126"}; 7'h7f : foobar = {foobar, " 127"}; default:foobar = {foobar, " 128"}; endcase end endtask task ozonerb; input [5:0] rb; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (rb[5:0]) 6'h10, 6'h17, 6'h1e, 6'h1f: foobar = {foobar, " 129"}; default: ozonerab({1'b1, rb}, foobar); endcase end endtask task ozonef3f4_iext; input [1:0] foo; input [15:0] im16; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo) 2'h0 : begin skyway({4{im16[15]}}, foobar); skyway({4{im16[15]}}, foobar); skyway(im16[15:12], foobar); skyway(im16[11: 8], foobar); skyway(im16[ 7: 4], foobar); skyway(im16[ 3:0], foobar); foobar = {foobar, " 130"}; end 2'h1 : begin foobar = {foobar, " 131"}; skyway(im16[15:12], foobar); skyway(im16[11: 8], foobar); skyway(im16[ 7: 4], foobar); skyway(im16[ 3:0], foobar); end 2'h2 : begin skyway({4{im16[15]}}, foobar); skyway({4{im16[15]}}, foobar); skyway(im16[15:12], foobar); skyway(im16[11: 8], foobar); skyway(im16[ 7: 4], foobar); skyway(im16[ 3:0], foobar); foobar = {foobar, " 132"}; end 2'h3 : begin foobar = {foobar, " 133"}; skyway(im16[15:12], foobar); skyway(im16[11: 8], foobar); skyway(im16[ 7: 4], foobar); skyway(im16[ 3:0], foobar); end endcase end endtask task skyway; input [ 3:0] hex; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (hex) 4'h0 : foobar = {foobar, " 134"}; 4'h1 : foobar = {foobar, " 135"}; 4'h2 : foobar = {foobar, " 136"}; 4'h3 : foobar = {foobar, " 137"}; 4'h4 : foobar = {foobar, " 138"}; 4'h5 : foobar = {foobar, " 139"}; 4'h6 : foobar = {foobar, " 140"}; 4'h7 : foobar = {foobar, " 141"}; 4'h8 : foobar = {foobar, " 142"}; 4'h9 : foobar = {foobar, " 143"}; 4'ha : foobar = {foobar, " 144"}; 4'hb : foobar = {foobar, " 145"}; 4'hc : foobar = {foobar, " 146"}; 4'hd : foobar = {foobar, " 147"}; 4'he : foobar = {foobar, " 148"}; 4'hf : foobar = {foobar, " 149"}; endcase end endtask task ozonesr; input [ 15:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo[11: 9]) 3'h0 : foobar = {foobar, " 158"}; 3'h1 : foobar = {foobar, " 159"}; 3'h2 : foobar = {foobar, " 160"}; 3'h3 : foobar = {foobar, " 161"}; 3'h4 : foobar = {foobar, " 162"}; 3'h5 : foobar = {foobar, " 163"}; 3'h6 : foobar = {foobar, " 164"}; 3'h7 : foobar = {foobar, " 165"}; endcase end endtask task ozonejk; input k; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin if (k) foobar = {foobar, " 166"}; else foobar = {foobar, " 167"}; end endtask task ozoneae; input [ 2:0] ae; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (ae) 3'b000 : foobar = {foobar, " 168"}; 3'b001 : foobar = {foobar, " 169"}; 3'b010 : foobar = {foobar, " 170"}; 3'b011 : foobar = {foobar, " 171"}; 3'b100 : foobar = {foobar, " 172"}; 3'b101 : foobar = {foobar, " 173"}; 3'b110 : foobar = {foobar, " 174"}; 3'b111 : foobar = {foobar, " 175"}; endcase end endtask task ozoneaee; input [ 2:0] aee; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (aee) 3'b001, 3'b011, 3'b101, 3'b111 : foobar = {foobar, " 176"}; 3'b000 : foobar = {foobar, " 177"}; 3'b010 : foobar = {foobar, " 178"}; 3'b100 : foobar = {foobar, " 179"}; 3'b110 : foobar = {foobar, " 180"}; endcase end endtask task ozoneape; input [ 2:0] ape; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (ape) 3'b001, 3'b011, 3'b101, 3'b111 : foobar = {foobar, " 181"}; 3'b000 : foobar = {foobar, " 182"}; 3'b010 : foobar = {foobar, " 183"}; 3'b100 : foobar = {foobar, " 184"}; 3'b110 : foobar = {foobar, " 185"}; endcase end endtask task ozonef1; input [ 31:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo[24:21]) 4'h0 : if (foo[26]) foobar = {foobar, " 186"}; else foobar = {foobar, " 187"}; 4'h1 : case (foo[26:25]) 2'b00 : foobar = {foobar, " 188"}; 2'b01 : foobar = {foobar, " 189"}; 2'b10 : foobar = {foobar, " 190"}; 2'b11 : foobar = {foobar, " 191"}; endcase 4'h2 : foobar = {foobar, " 192"}; 4'h3 : case (foo[26:25]) 2'b00 : foobar = {foobar, " 193"}; 2'b01 : foobar = {foobar, " 194"}; 2'b10 : foobar = {foobar, " 195"}; 2'b11 : foobar = {foobar, " 196"}; endcase 4'h4 : if (foo[26]) foobar = {foobar, " 197"}; else foobar = {foobar, " 198"}; 4'h5 : case (foo[26:25]) 2'b00 : foobar = {foobar, " 199"}; 2'b01 : foobar = {foobar, " 200"}; 2'b10 : foobar = {foobar, " 201"}; 2'b11 : foobar = {foobar, " 202"}; endcase 4'h6 : foobar = {foobar, " 203"}; 4'h7 : case (foo[26:25]) 2'b00 : foobar = {foobar, " 204"}; 2'b01 : foobar = {foobar, " 205"}; 2'b10 : foobar = {foobar, " 206"}; 2'b11 : foobar = {foobar, " 207"}; endcase 4'h8 : case (foo[26:25]) 2'b00 : foobar = {foobar, " 208"}; 2'b01 : foobar = {foobar, " 209"}; 2'b10 : foobar = {foobar, " 210"}; 2'b11 : foobar = {foobar, " 211"}; endcase 4'h9 : case (foo[26:25]) 2'b00 : foobar = {foobar, " 212"}; 2'b01 : foobar = {foobar, " 213"}; 2'b10 : foobar = {foobar, " 214"}; 2'b11 : foobar = {foobar, " 215"}; endcase 4'ha : if (foo[25]) foobar = {foobar, " 216"}; else foobar = {foobar, " 217"}; 4'hb : if (foo[25]) foobar = {foobar, " 218"}; else foobar = {foobar, " 219"}; 4'hc : if (foo[26]) foobar = {foobar, " 220"}; else foobar = {foobar, " 221"}; 4'hd : case (foo[26:25]) 2'b00 : foobar = {foobar, " 222"}; 2'b01 : foobar = {foobar, " 223"}; 2'b10 : foobar = {foobar, " 224"}; 2'b11 : foobar = {foobar, " 225"}; endcase 4'he : case (foo[26:25]) 2'b00 : foobar = {foobar, " 226"}; 2'b01 : foobar = {foobar, " 227"}; 2'b10 : foobar = {foobar, " 228"}; 2'b11 : foobar = {foobar, " 229"}; endcase 4'hf : case (foo[26:25]) 2'b00 : foobar = {foobar, " 230"}; 2'b01 : foobar = {foobar, " 231"}; 2'b10 : foobar = {foobar, " 232"}; 2'b11 : foobar = {foobar, " 233"}; endcase endcase end endtask task ozonef1e; input [ 31:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo[27:21]) 7'h00: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 234"}; foobar = {foobar, " 235"}; end 7'h01: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 236"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 237"}; foobar = {foobar, " 238"}; end 7'h02: foobar = {foobar, " 239"}; 7'h03: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 240"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 241"}; foobar = {foobar, " 242"}; end 7'h04: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 243"}; foobar = {foobar," 244"}; end 7'h05: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 245"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 246"}; end 7'h06: foobar = {foobar, " 247"}; 7'h07: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 248"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 249"}; end 7'h08: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 250"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 251"}; end 7'h09: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 252"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 253"}; end 7'h0a: begin ozoneae(foo[17:15], foobar); foobar = {foobar," 254"}; end 7'h0b: begin ozoneae(foo[17:15], foobar); foobar = {foobar," 255"}; end 7'h0c: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 256"}; end 7'h0d: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 257"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 258"}; end 7'h0e: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 259"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 260"}; end 7'h0f: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 261"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 262"}; end 7'h10: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 263"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 264"}; foobar = {foobar, " 265"}; foobar = {foobar, " 266"}; end 7'h11: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 267"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 268"}; foobar = {foobar, " 269"}; foobar = {foobar, " 270"}; end 7'h12: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 271"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 272"}; foobar = {foobar, " 273"}; foobar = {foobar, " 274"}; end 7'h13: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 275"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 276"}; foobar = {foobar, " 277"}; foobar = {foobar, " 278"}; end 7'h14: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 279"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 280"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 281"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 282"}; foobar = {foobar, " 283"}; foobar = {foobar, " 284"}; end 7'h15: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 285"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 286"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 287"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 288"}; foobar = {foobar, " 289"}; foobar = {foobar, " 290"}; end 7'h16: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 291"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 292"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 293"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 294"}; foobar = {foobar, " 295"}; foobar = {foobar, " 296"}; end 7'h17: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 297"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 298"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 299"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 300"}; foobar = {foobar, " 301"}; foobar = {foobar, " 302"}; end 7'h18: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 303"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 304"}; foobar = {foobar, " 305"}; foobar = {foobar, " 306"}; end 7'h19: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 307"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 308"}; foobar = {foobar, " 309"}; foobar = {foobar, " 310"}; end 7'h1a: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 311"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 312"}; foobar = {foobar, " 313"}; foobar = {foobar, " 314"}; end 7'h1b: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 315"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 316"}; foobar = {foobar, " 317"}; foobar = {foobar, " 318"}; end 7'h1c: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 319"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 320"}; foobar = {foobar, " 321"}; foobar = {foobar, " 322"}; end 7'h1d: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 323"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 324"}; foobar = {foobar, " 325"}; foobar = {foobar, " 326"}; end 7'h1e: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 327"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 328"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 329"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 330"}; foobar = {foobar, " 331"}; foobar = {foobar, " 332"}; end 7'h1f: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 333"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 334"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 335"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 336"}; foobar = {foobar, " 337"}; foobar = {foobar, " 338"}; end 7'h20: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 339"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 340"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 341"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 342"}; foobar = {foobar, " 343"}; foobar = {foobar, " 344"}; end 7'h21: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 345"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 346"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 347"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 348"}; foobar = {foobar, " 349"}; foobar = {foobar, " 350"}; end 7'h22: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 351"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 352"}; foobar = {foobar, " 353"}; foobar = {foobar, " 354"}; end 7'h23: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 355"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 356"}; foobar = {foobar, " 357"}; foobar = {foobar, " 358"}; end 7'h24: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 359"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 360"}; foobar = {foobar, " 361"}; foobar = {foobar, " 362"}; end 7'h25: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 363"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 364"}; foobar = {foobar, " 365"}; foobar = {foobar, " 366"}; end 7'h26: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 367"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 368"}; foobar = {foobar, " 369"}; foobar = {foobar, " 370"}; end 7'h27: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 371"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 372"}; foobar = {foobar, " 373"}; foobar = {foobar, " 374"}; end 7'h28: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 375"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 376"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 377"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 378"}; foobar = {foobar, " 379"}; foobar = {foobar, " 380"}; end 7'h29: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 381"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 382"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 383"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 384"}; foobar = {foobar, " 385"}; foobar = {foobar, " 386"}; end 7'h2a: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 387"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 388"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 389"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 390"}; foobar = {foobar, " 391"}; foobar = {foobar, " 392"}; end 7'h2b: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 393"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 394"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 395"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 396"}; foobar = {foobar, " 397"}; foobar = {foobar, " 398"}; end 7'h2c: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 399"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 400"}; foobar = {foobar, " 401"}; foobar = {foobar, " 402"}; end 7'h2d: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 403"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 404"}; foobar = {foobar, " 405"}; foobar = {foobar, " 406"}; end 7'h2e: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 407"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 408"}; foobar = {foobar, " 409"}; foobar = {foobar, " 410"}; end 7'h2f: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 411"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 412"}; foobar = {foobar, " 413"}; foobar = {foobar, " 414"}; end 7'h30: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 415"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 416"}; foobar = {foobar, " 417"}; foobar = {foobar, " 418"}; end 7'h31: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 419"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 420"}; foobar = {foobar, " 421"}; foobar = {foobar, " 422"}; end 7'h32: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 423"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 424"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 425"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 426"}; foobar = {foobar, " 427"}; foobar = {foobar, " 428"}; end 7'h33: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 429"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 430"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 431"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 432"}; foobar = {foobar, " 433"}; foobar = {foobar, " 434"}; end 7'h34: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 435"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 436"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 437"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 438"}; foobar = {foobar, " 439"}; foobar = {foobar, " 440"}; end 7'h35: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 441"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 442"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 443"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 444"}; foobar = {foobar, " 445"}; foobar = {foobar, " 446"}; end 7'h36: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 447"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 448"}; foobar = {foobar, " 449"}; foobar = {foobar, " 450"}; end 7'h37: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 451"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 452"}; foobar = {foobar, " 453"}; foobar = {foobar, " 454"}; end 7'h38: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 455"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 456"}; foobar = {foobar, " 457"}; end 7'h39: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 458"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 459"}; foobar = {foobar, " 460"}; end 7'h3a: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 461"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 462"}; foobar = {foobar, " 463"}; end 7'h3b: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 464"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 465"}; foobar = {foobar, " 466"}; end 7'h3c: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 467"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 468"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 469"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 470"}; foobar = {foobar, " 471"}; end 7'h3d: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 472"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 473"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 474"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 475"}; foobar = {foobar, " 476"}; end 7'h3e: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 477"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 478"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 479"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 480"}; foobar = {foobar, " 481"}; end 7'h3f: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 482"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 483"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 484"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 485"}; foobar = {foobar, " 486"}; end 7'h40: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 487"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 488"}; foobar = {foobar, " 489"}; foobar = {foobar, " 490"}; end 7'h41: begin foobar = {foobar, " 491"}; foobar = {foobar, " 492"}; end 7'h42: begin foobar = {foobar, " 493"}; foobar = {foobar, " 494"}; end 7'h43: begin foobar = {foobar, " 495"}; foobar = {foobar, " 496"}; end 7'h44: begin foobar = {foobar, " 497"}; foobar = {foobar, " 498"}; end 7'h45: foobar = {foobar, " 499"}; 7'h46: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 500"}; foobar = {foobar, " 501"}; foobar = {foobar, " 502"}; end 7'h47: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 503"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 504"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 505"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 506"}; foobar = {foobar, " 507"}; foobar = {foobar, " 508"}; end 7'h48: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 509"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 510"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 511"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 512"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 513"}; end 7'h49: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 514"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 515"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 516"}; end 7'h4a: foobar = {foobar," 517"}; 7'h4b: foobar = {foobar, " 518"}; 7'h4c: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 519"}; foobar = {foobar, " 520"}; foobar = {foobar, " 521"}; end 7'h4d: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 522"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 523"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 524"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 525"}; foobar = {foobar, " 526"}; foobar = {foobar, " 527"}; end 7'h4e: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 528"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 529"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 530"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 531"}; end 7'h4f: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 532"}; end 7'h50: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 533"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 534"}; ozoneaee(foo[20:18], foobar); foobar = {foobar," 535"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 536"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 537"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 538"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 539"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 540"}; end 7'h51: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 541"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 542"}; ozoneaee(foo[20:18], foobar); foobar = {foobar," 543"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 544"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 545"}; end 7'h52: foobar = {foobar, " 546"}; 7'h53: begin ozoneae(foo[20:18], foobar); foobar = {foobar, " 547"}; end 7'h54: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 548"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 549"}; end 7'h55: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 550"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 551"}; end 7'h56: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 552"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 553"}; foobar = {foobar, " 554"}; end 7'h57: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 555"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 556"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 557"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 558"}; end 7'h58: begin ozoneae(foo[20:18], foobar); foobar = {foobar, " 559"}; end 7'h59: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 560"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 561"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 562"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 563"}; end 7'h5a: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 564"}; ozoneae(foo[17:15], foobar); foobar = {foobar, " 565"}; end 7'h5b: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 566"}; ozoneae(foo[17:15], foobar); foobar = {foobar, " 567"}; end 7'h5c: begin foobar = {foobar," 568"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 569"}; foobar = {foobar," 570"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 571"}; ozoneae(foo[20:18], foobar); foobar = {foobar," 572"}; ozoneaee(foo[17:15], foobar); foobar = {foobar, " 573"}; end 7'h5d: begin foobar = {foobar," 574"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 575"}; foobar = {foobar," 576"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 577"}; ozoneae(foo[20:18], foobar); foobar = {foobar," 578"}; ozoneaee(foo[17:15], foobar); foobar = {foobar, " 579"}; end 7'h5e: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 580"}; ozoneae(foo[17:15], foobar); foobar = {foobar, " 581"}; end 7'h5f: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 582"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 583"}; ozoneaee(foo[20:18], foobar); foobar = {foobar," 584"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 585"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 586"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 587"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 588"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 589"}; end 7'h60: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 590"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 591"}; end 7'h61: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 592"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 593"}; end 7'h62: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 594"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 595"}; end 7'h63: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 596"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 597"}; end 7'h64: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 598"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 599"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 600"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 601"}; end 7'h65: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 602"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 603"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 604"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 605"}; end 7'h66: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 606"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 607"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 608"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 609"}; end 7'h67: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 610"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 611"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 612"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 613"}; end 7'h68: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 614"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 615"}; ozoneaee(foo[20:18], foobar); foobar = {foobar," 616"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 617"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 618"}; ozoneape(foo[17:15], foobar); end 7'h69: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 619"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 620"}; ozoneae(foo[20:18], foobar); foobar = {foobar," 621"}; end 7'h6a: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 622"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 623"}; ozoneaee(foo[20:18], foobar); foobar = {foobar," 624"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 625"}; ozoneaee(foo[20:18], foobar); foobar = {foobar," 626"}; ozoneae(foo[17:15], foobar); end 7'h6b: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 627"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 628"}; ozoneae(foo[20:18], foobar); foobar = {foobar," 629"}; end 7'h6c: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 630"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 631"}; ozoneaee(foo[20:18], foobar); foobar = {foobar," 632"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 633"}; ozoneaee(foo[20:18], foobar); foobar = {foobar," 634"}; ozoneae(foo[17:15], foobar); end 7'h6d: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 635"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 636"}; ozoneae(foo[20:18], foobar); foobar = {foobar," 637"}; end 7'h6e: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 638"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 639"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 640"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 641"}; end 7'h6f: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 642"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 643"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 644"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 645"}; end 7'h70: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 646"}; ozoneae(foo[20:18], foobar); foobar = {foobar," 647"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 648"}; ozoneae(foo[17:15], foobar); foobar = {foobar, " 649"}; end 7'h71: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 650"}; ozoneae(foo[17:15], foobar); foobar = {foobar, " 651"}; end 7'h72: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 652"}; ozoneae(foo[17:15], foobar); foobar = {foobar, " 653"}; end 7'h73: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 654"}; ozoneae(foo[20:18], foobar); foobar = {foobar," 655"}; ozoneae(foo[17:15], foobar); end 7'h74: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 656"}; ozoneae(foo[20:18], foobar); foobar = {foobar," 657"}; ozoneae(foo[17:15], foobar); end 7'h75: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 658"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 659"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 660"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 661"}; foobar = {foobar, " 662"}; foobar = {foobar, " 663"}; end 7'h76: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 664"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 665"}; ozoneaee(foo[20:18], foobar); foobar = {foobar," 666"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 667"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 668"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 669"}; end 7'h77: begin ozoneaee(foo[20:18], foobar); foobar = {foobar," 670"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 671"}; ozoneaee(foo[17:15], foobar); foobar = {foobar," 672"}; ozoneape(foo[20:18], foobar); foobar = {foobar," 673"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 674"}; ozoneape(foo[17:15], foobar); foobar = {foobar," 675"}; end 7'h78, 7'h79, 7'h7a, 7'h7b, 7'h7c, 7'h7d, 7'h7e, 7'h7f: foobar = {foobar," 676"}; endcase end endtask task ozonef2; input [ 31:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo[24:21]) 4'h0 : case (foo[26:25]) 2'b00 : foobar = {foobar," 677"}; 2'b01 : foobar = {foobar," 678"}; 2'b10 : foobar = {foobar," 679"}; 2'b11 : foobar = {foobar," 680"}; endcase 4'h1 : case (foo[26:25]) 2'b00 : foobar = {foobar," 681"}; 2'b01 : foobar = {foobar," 682"}; 2'b10 : foobar = {foobar," 683"}; 2'b11 : foobar = {foobar," 684"}; endcase 4'h2 : case (foo[26:25]) 2'b00 : foobar = {foobar," 685"}; 2'b01 : foobar = {foobar," 686"}; 2'b10 : foobar = {foobar," 687"}; 2'b11 : foobar = {foobar," 688"}; endcase 4'h3 : case (foo[26:25]) 2'b00 : foobar = {foobar," 689"}; 2'b01 : foobar = {foobar," 690"}; 2'b10 : foobar = {foobar," 691"}; 2'b11 : foobar = {foobar," 692"}; endcase 4'h4 : case (foo[26:25]) 2'b00 : foobar = {foobar," 693"}; 2'b01 : foobar = {foobar," 694"}; 2'b10 : foobar = {foobar," 695"}; 2'b11 : foobar = {foobar," 696"}; endcase 4'h5 : case (foo[26:25]) 2'b00 : foobar = {foobar," 697"}; 2'b01 : foobar = {foobar," 698"}; 2'b10 : foobar = {foobar," 699"}; 2'b11 : foobar = {foobar," 700"}; endcase 4'h6 : case (foo[26:25]) 2'b00 : foobar = {foobar," 701"}; 2'b01 : foobar = {foobar," 702"}; 2'b10 : foobar = {foobar," 703"}; 2'b11 : foobar = {foobar," 704"}; endcase 4'h7 : case (foo[26:25]) 2'b00 : foobar = {foobar," 705"}; 2'b01 : foobar = {foobar," 706"}; 2'b10 : foobar = {foobar," 707"}; 2'b11 : foobar = {foobar," 708"}; endcase 4'h8 : if (foo[26]) foobar = {foobar," 709"}; else foobar = {foobar," 710"}; 4'h9 : case (foo[26:25]) 2'b00 : foobar = {foobar," 711"}; 2'b01 : foobar = {foobar," 712"}; 2'b10 : foobar = {foobar," 713"}; 2'b11 : foobar = {foobar," 714"}; endcase 4'ha : case (foo[26:25]) 2'b00 : foobar = {foobar," 715"}; 2'b01 : foobar = {foobar," 716"}; 2'b10 : foobar = {foobar," 717"}; 2'b11 : foobar = {foobar," 718"}; endcase 4'hb : case (foo[26:25]) 2'b00 : foobar = {foobar," 719"}; 2'b01 : foobar = {foobar," 720"}; 2'b10 : foobar = {foobar," 721"}; 2'b11 : foobar = {foobar," 722"}; endcase 4'hc : if (foo[26]) foobar = {foobar," 723"}; else foobar = {foobar," 724"}; 4'hd : case (foo[26:25]) 2'b00 : foobar = {foobar," 725"}; 2'b01 : foobar = {foobar," 726"}; 2'b10 : foobar = {foobar," 727"}; 2'b11 : foobar = {foobar," 728"}; endcase 4'he : case (foo[26:25]) 2'b00 : foobar = {foobar," 729"}; 2'b01 : foobar = {foobar," 730"}; 2'b10 : foobar = {foobar," 731"}; 2'b11 : foobar = {foobar," 732"}; endcase 4'hf : case (foo[26:25]) 2'b00 : foobar = {foobar," 733"}; 2'b01 : foobar = {foobar," 734"}; 2'b10 : foobar = {foobar," 735"}; 2'b11 : foobar = {foobar," 736"}; endcase endcase end endtask task ozonef2e; input [ 31:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin casez (foo[25:21]) 5'h00 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 737"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 738"}; end 5'h01 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 739"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 740"}; end 5'h02 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 741"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 742"}; end 5'h03 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 743"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 744"}; end 5'h04 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 745"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 746"}; end 5'h05 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 747"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 748"}; end 5'h06 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 749"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 750"}; end 5'h07 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 751"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 752"}; end 5'h08 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 753"}; if (foo[ 6]) foobar = {foobar," 754"}; else foobar = {foobar," 755"}; end 5'h09 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 756"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 757"}; end 5'h0a : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 758"}; ozoneae(foo[17:15], foobar); end 5'h0b : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 759"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 760"}; end 5'h0c : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 761"}; end 5'h0d : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 762"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 763"}; end 5'h0e : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 764"}; ozoneae(foo[17:15], foobar); end 5'h0f : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 765"}; ozoneae(foo[17:15], foobar); end 5'h10 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 766"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 767"}; end 5'h11 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 768"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 769"}; end 5'h18 : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 770"}; if (foo[ 6]) foobar = {foobar," 771"}; else foobar = {foobar," 772"}; end 5'h1a : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 773"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 774"}; end 5'h1b : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 775"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 776"}; if (foo[ 6]) foobar = {foobar," 777"}; else foobar = {foobar," 778"}; foobar = {foobar," 779"}; end 5'h1c : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 780"}; end 5'h1d : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 781"}; if (foo[ 6]) foobar = {foobar," 782"}; else foobar = {foobar," 783"}; foobar = {foobar," 784"}; end 5'h1e : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 785"}; if (foo[ 6]) foobar = {foobar," 786"}; else foobar = {foobar," 787"}; foobar = {foobar," 788"}; end 5'h1f : begin ozoneae(foo[20:18], foobar); foobar = {foobar," 789"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 790"}; if (foo[ 6]) foobar = {foobar," 791"}; else foobar = {foobar," 792"}; foobar = {foobar," 793"}; end default : foobar = {foobar," 794"}; endcase end endtask task ozonef3e; input [ 31:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo[25:21]) 5'h00, 5'h01, 5'h02: begin ozoneae(foo[20:18], foobar); case (foo[22:21]) 2'h0: foobar = {foobar," 795"}; 2'h1: foobar = {foobar," 796"}; 2'h2: foobar = {foobar," 797"}; endcase ozoneae(foo[17:15], foobar); foobar = {foobar," 798"}; if (foo[ 9]) ozoneae(foo[ 8: 6], foobar); else ozonef3e_te(foo[ 8: 6], foobar); foobar = {foobar," 799"}; end 5'h08, 5'h09, 5'h0d, 5'h0e, 5'h0f: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 800"}; ozoneae(foo[17:15], foobar); case (foo[23:21]) 3'h0: foobar = {foobar," 801"}; 3'h1: foobar = {foobar," 802"}; 3'h5: foobar = {foobar," 803"}; 3'h6: foobar = {foobar," 804"}; 3'h7: foobar = {foobar," 805"}; endcase if (foo[ 9]) ozoneae(foo[ 8: 6], foobar); else ozonef3e_te(foo[ 8: 6], foobar); end 5'h0a, 5'h0b: begin ozoneae(foo[17:15], foobar); if (foo[21]) foobar = {foobar," 806"}; else foobar = {foobar," 807"}; if (foo[ 9]) ozoneae(foo[ 8: 6], foobar); else ozonef3e_te(foo[ 8: 6], foobar); end 5'h0c: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 808"}; if (foo[ 9]) ozoneae(foo[ 8: 6], foobar); else ozonef3e_te(foo[ 8: 6], foobar); foobar = {foobar," 809"}; ozoneae(foo[17:15], foobar); end 5'h10, 5'h11, 5'h12, 5'h13: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 810"}; ozoneae(foo[17:15], foobar); case (foo[22:21]) 2'h0, 2'h2: foobar = {foobar," 811"}; 2'h1, 2'h3: foobar = {foobar," 812"}; endcase ozoneae(foo[ 8: 6], foobar); foobar = {foobar," 813"}; ozoneae((foo[20:18]+1), foobar); foobar = {foobar," 814"}; ozoneae((foo[17:15]+1), foobar); case (foo[22:21]) 2'h0, 2'h3: foobar = {foobar," 815"}; 2'h1, 2'h2: foobar = {foobar," 816"}; endcase ozoneae((foo[ 8: 6]+1), foobar); end 5'h18: begin ozoneae(foo[20:18], foobar); foobar = {foobar," 817"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 818"}; ozoneae(foo[ 8: 6], foobar); foobar = {foobar," 819"}; ozoneae(foo[20:18], foobar); foobar = {foobar," 820"}; ozoneae(foo[17:15], foobar); foobar = {foobar," 821"}; ozoneae(foo[ 8: 6], foobar); end default : foobar = {foobar," 822"}; endcase end endtask task ozonef3e_te; input [ 2:0] te; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (te) 3'b100 : foobar = {foobar, " 823"}; 3'b101 : foobar = {foobar, " 824"}; 3'b110 : foobar = {foobar, " 825"}; default: foobar = {foobar, " 826"}; endcase end endtask task ozonearm; input [ 2:0] ate; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (ate) 3'b000 : foobar = {foobar, " 827"}; 3'b001 : foobar = {foobar, " 828"}; 3'b010 : foobar = {foobar, " 829"}; 3'b011 : foobar = {foobar, " 830"}; 3'b100 : foobar = {foobar, " 831"}; 3'b101 : foobar = {foobar, " 832"}; 3'b110 : foobar = {foobar, " 833"}; 3'b111 : foobar = {foobar, " 834"}; endcase end endtask task ozonebmuop; input [ 4:0] f4; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (f4[ 4:0]) 5'h00, 5'h04 : foobar = {foobar, " 835"}; 5'h01, 5'h05 : foobar = {foobar, " 836"}; 5'h02, 5'h06 : foobar = {foobar, " 837"}; 5'h03, 5'h07 : foobar = {foobar, " 838"}; 5'h08, 5'h18 : foobar = {foobar, " 839"}; 5'h09, 5'h19 : foobar = {foobar, " 840"}; 5'h0a, 5'h1a : foobar = {foobar, " 841"}; 5'h0b : foobar = {foobar, " 842"}; 5'h1b : foobar = {foobar, " 843"}; 5'h0c, 5'h1c : foobar = {foobar, " 844"}; 5'h0d, 5'h1d : foobar = {foobar, " 845"}; 5'h1e : foobar = {foobar, " 846"}; endcase end endtask task ozonef3; input [ 31:0] foo; inout [STRLEN*8: 1] foobar; reg nacho; // verilator no_inline_task begin : f3_body nacho = 1'b0; case (foo[24:21]) 4'h0: case (foo[26:25]) 2'b00 : foobar = {foobar, " 847"}; 2'b01 : foobar = {foobar, " 848"}; 2'b10 : foobar = {foobar, " 849"}; 2'b11 : foobar = {foobar, " 850"}; endcase 4'h1: case (foo[26:25]) 2'b00 : foobar = {foobar, " 851"}; 2'b01 : foobar = {foobar, " 852"}; 2'b10 : foobar = {foobar, " 853"}; 2'b11 : foobar = {foobar, " 854"}; endcase 4'h2: case (foo[26:25]) 2'b00 : foobar = {foobar, " 855"}; 2'b01 : foobar = {foobar, " 856"}; 2'b10 : foobar = {foobar, " 857"}; 2'b11 : foobar = {foobar, " 858"}; endcase 4'h8, 4'h9, 4'hd, 4'he, 4'hf : case (foo[26:25]) 2'b00 : foobar = {foobar, " 859"}; 2'b01 : foobar = {foobar, " 860"}; 2'b10 : foobar = {foobar, " 861"}; 2'b11 : foobar = {foobar, " 862"}; endcase 4'ha, 4'hb : if (foo[25]) foobar = {foobar, " 863"}; else foobar = {foobar, " 864"}; 4'hc : if (foo[26]) foobar = {foobar, " 865"}; else foobar = {foobar, " 866"}; default : begin foobar = {foobar, " 867"}; nacho = 1'b1; end endcase if (~nacho) begin case (foo[24:21]) 4'h8 : foobar = {foobar, " 868"}; 4'h9 : foobar = {foobar, " 869"}; 4'ha, 4'he : foobar = {foobar, " 870"}; 4'hb, 4'hf : foobar = {foobar, " 871"}; 4'hd : foobar = {foobar, " 872"}; endcase if (foo[20]) case (foo[18:16]) 3'b000 : foobar = {foobar, " 873"}; 3'b100 : foobar = {foobar, " 874"}; default: foobar = {foobar, " 875"}; endcase else ozoneae(foo[18:16], foobar); if (foo[24:21] === 4'hc) if (foo[25]) foobar = {foobar, " 876"}; else foobar = {foobar, " 877"}; case (foo[24:21]) 4'h0, 4'h1, 4'h2: foobar = {foobar, " 878"}; endcase end end endtask task ozonerx; input [ 31:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo[19:18]) 2'h0 : foobar = {foobar, " 879"}; 2'h1 : foobar = {foobar, " 880"}; 2'h2 : foobar = {foobar, " 881"}; 2'h3 : foobar = {foobar, " 882"}; endcase case (foo[17:16]) 2'h1 : foobar = {foobar, " 883"}; 2'h2 : foobar = {foobar, " 884"}; 2'h3 : foobar = {foobar, " 885"}; endcase end endtask task ozonerme; input [ 2:0] rme; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (rme) 3'h0 : foobar = {foobar, " 886"}; 3'h1 : foobar = {foobar, " 887"}; 3'h2 : foobar = {foobar, " 888"}; 3'h3 : foobar = {foobar, " 889"}; 3'h4 : foobar = {foobar, " 890"}; 3'h5 : foobar = {foobar, " 891"}; 3'h6 : foobar = {foobar, " 892"}; 3'h7 : foobar = {foobar, " 893"}; endcase end endtask task ozoneye; input [5:0] ye; input l; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin foobar = {foobar, " 894"}; ozonerme(ye[5:3],foobar); case ({ye[ 2:0], l}) 4'h2, 4'ha: foobar = {foobar, " 895"}; 4'h4, 4'hb: foobar = {foobar, " 896"}; 4'h6, 4'he: foobar = {foobar, " 897"}; 4'h8, 4'hc: foobar = {foobar, " 898"}; endcase end endtask task ozonef1e_ye; input [5:0] ye; input l; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin foobar = {foobar, " 899"}; ozonerme(ye[5:3],foobar); ozonef1e_inc_dec(ye[5:0], l ,foobar); end endtask task ozonef1e_h; input [ 2:0] e; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin if (e[ 2:0] <= 3'h4) foobar = {foobar, " 900"}; end endtask task ozonef1e_inc_dec; input [5:0] ye; input l; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case ({ye[ 2:0], l}) 4'h2, 4'h3, 4'ha: foobar = {foobar, " 901"}; 4'h4, 4'h5, 4'hb: foobar = {foobar, " 902"}; 4'h6, 4'h7, 4'he: foobar = {foobar, " 903"}; 4'h8, 4'h9, 4'hc: foobar = {foobar, " 904"}; 4'hf: foobar = {foobar, " 905"}; endcase end endtask task ozonef1e_hl; input [ 2:0] e; input l; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case ({e[ 2:0], l}) 4'h0, 4'h2, 4'h4, 4'h6, 4'h8: foobar = {foobar, " 906"}; 4'h1, 4'h3, 4'h5, 4'h7, 4'h9: foobar = {foobar, " 907"}; endcase end endtask task ozonexe; input [ 3:0] xe; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (xe[3]) 1'b0 : foobar = {foobar, " 908"}; 1'b1 : foobar = {foobar, " 909"}; endcase case (xe[ 2:0]) 3'h1, 3'h5: foobar = {foobar, " 910"}; 3'h2, 3'h6: foobar = {foobar, " 911"}; 3'h3, 3'h7: foobar = {foobar, " 912"}; 3'h4: foobar = {foobar, " 913"}; endcase end endtask task ozonerp; input [ 2:0] rp; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (rp) 3'h0 : foobar = {foobar, " 914"}; 3'h1 : foobar = {foobar, " 915"}; 3'h2 : foobar = {foobar, " 916"}; 3'h3 : foobar = {foobar, " 917"}; 3'h4 : foobar = {foobar, " 918"}; 3'h5 : foobar = {foobar, " 919"}; 3'h6 : foobar = {foobar, " 920"}; 3'h7 : foobar = {foobar, " 921"}; endcase end endtask task ozonery; input [ 3:0] ry; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (ry) 4'h0 : foobar = {foobar, " 922"}; 4'h1 : foobar = {foobar, " 923"}; 4'h2 : foobar = {foobar, " 924"}; 4'h3 : foobar = {foobar, " 925"}; 4'h4 : foobar = {foobar, " 926"}; 4'h5 : foobar = {foobar, " 927"}; 4'h6 : foobar = {foobar, " 928"}; 4'h7 : foobar = {foobar, " 929"}; 4'h8 : foobar = {foobar, " 930"}; 4'h9 : foobar = {foobar, " 931"}; 4'ha : foobar = {foobar, " 932"}; 4'hb : foobar = {foobar, " 933"}; 4'hc : foobar = {foobar, " 934"}; 4'hd : foobar = {foobar, " 935"}; 4'he : foobar = {foobar, " 936"}; 4'hf : foobar = {foobar, " 937"}; endcase end endtask task ozonearx; input [ 15:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo[1:0]) 2'h0 : foobar = {foobar, " 938"}; 2'h1 : foobar = {foobar, " 939"}; 2'h2 : foobar = {foobar, " 940"}; 2'h3 : foobar = {foobar, " 941"}; endcase end endtask task ozonef3f4imop; input [ 4:0] f3f4iml; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin casez (f3f4iml) 5'b000??: foobar = {foobar, " 942"}; 5'b001??: foobar = {foobar, " 943"}; 5'b?10??: foobar = {foobar, " 944"}; 5'b0110?: foobar = {foobar, " 945"}; 5'b01110: foobar = {foobar, " 946"}; 5'b01111: foobar = {foobar, " 947"}; 5'b10???: foobar = {foobar, " 948"}; 5'b11100: foobar = {foobar, " 949"}; 5'b11101: foobar = {foobar, " 950"}; 5'b11110: foobar = {foobar, " 951"}; 5'b11111: foobar = {foobar, " 952"}; endcase end endtask task ozonecon; input [ 4:0] con; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (con) 5'h00 : foobar = {foobar, " 953"}; 5'h01 : foobar = {foobar, " 954"}; 5'h02 : foobar = {foobar, " 955"}; 5'h03 : foobar = {foobar, " 956"}; 5'h04 : foobar = {foobar, " 957"}; 5'h05 : foobar = {foobar, " 958"}; 5'h06 : foobar = {foobar, " 959"}; 5'h07 : foobar = {foobar, " 960"}; 5'h08 : foobar = {foobar, " 961"}; 5'h09 : foobar = {foobar, " 962"}; 5'h0a : foobar = {foobar, " 963"}; 5'h0b : foobar = {foobar, " 964"}; 5'h0c : foobar = {foobar, " 965"}; 5'h0d : foobar = {foobar, " 966"}; 5'h0e : foobar = {foobar, " 967"}; 5'h0f : foobar = {foobar, " 968"}; 5'h10 : foobar = {foobar, " 969"}; 5'h11 : foobar = {foobar, " 970"}; 5'h12 : foobar = {foobar, " 971"}; 5'h13 : foobar = {foobar, " 972"}; 5'h14 : foobar = {foobar, " 973"}; 5'h15 : foobar = {foobar, " 974"}; 5'h16 : foobar = {foobar, " 975"}; 5'h17 : foobar = {foobar, " 976"}; 5'h18 : foobar = {foobar, " 977"}; 5'h19 : foobar = {foobar, " 978"}; 5'h1a : foobar = {foobar, " 979"}; 5'h1b : foobar = {foobar, " 980"}; 5'h1c : foobar = {foobar, " 981"}; 5'h1d : foobar = {foobar, " 982"}; 5'h1e : foobar = {foobar, " 983"}; 5'h1f : foobar = {foobar, " 984"}; endcase end endtask task ozonedr; input [ 15:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo[ 9: 6]) 4'h0 : foobar = {foobar, " 985"}; 4'h1 : foobar = {foobar, " 986"}; 4'h2 : foobar = {foobar, " 987"}; 4'h3 : foobar = {foobar, " 988"}; 4'h4 : foobar = {foobar, " 989"}; 4'h5 : foobar = {foobar, " 990"}; 4'h6 : foobar = {foobar, " 991"}; 4'h7 : foobar = {foobar, " 992"}; 4'h8 : foobar = {foobar, " 993"}; 4'h9 : foobar = {foobar, " 994"}; 4'ha : foobar = {foobar, " 995"}; 4'hb : foobar = {foobar, " 996"}; 4'hc : foobar = {foobar, " 997"}; 4'hd : foobar = {foobar, " 998"}; 4'he : foobar = {foobar, " 999"}; 4'hf : foobar = {foobar, " 1000"}; endcase end endtask task ozoneshift; input [ 15:0] foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo[ 4: 3]) 2'h0 : foobar = {foobar, " 1001"}; 2'h1 : foobar = {foobar, " 1002"}; 2'h2 : foobar = {foobar, " 1003"}; 2'h3 : foobar = {foobar, " 1004"}; endcase end endtask task ozoneacc; input foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo) 2'h0 : foobar = {foobar, " 1005"}; 2'h1 : foobar = {foobar, " 1006"}; endcase end endtask task ozonehl; input foo; inout [STRLEN*8: 1] foobar; // verilator no_inline_task begin case (foo) 2'h0 : foobar = {foobar, " 1007"}; 2'h1 : foobar = {foobar, " 1008"}; endcase end endtask task dude; inout [STRLEN*8: 1] foobar; reg [ 7:0] temp; integer i; reg nacho; // verilator no_inline_task begin : justify_block nacho = 1'b0; for (i=STRLEN-1; i>1; i=i-1) begin temp = foobar>>((STRLEN-1)*8); if (temp || nacho) nacho = 1'b1; else begin foobar = foobar<<8; foobar[8:1] = 32; end end end endtask task big_case; input [ 31:0] fd; input [ 31:0] foo; reg [STRLEN*8: 1] foobar; // verilator no_inline_task begin foobar = " 1009"; if (&foo === 1'bx) $fwrite(fd, " 1010"); else casez ( {foo[31:26], foo[19:15], foo[5:0]} ) 17'b00_111?_?_????_??_???? : begin ozonef1(foo, foobar); foobar = {foobar, " 1011"}; ozoneacc(~foo[26], foobar); ozonehl(foo[20], foobar); foobar = {foobar, " 1012"}; ozonerx(foo, foobar); dude(foobar); $fwrite (fd, " 1013:%s", foobar); end 17'b01_001?_?_????_??_???? : begin ozonef1(foo, foobar); foobar = {foobar, " 1014"}; ozonerx(foo, foobar); foobar = {foobar, " 1015"}; foobar = {foobar, " 1016"}; ozonehl(foo[20], foobar); dude(foobar); $fwrite (fd, " 1017:%s", foobar); end 17'b10_100?_?_????_??_???? : begin ozonef1(foo, foobar); foobar = {foobar, " 1018"}; ozonerx(foo, foobar); foobar = {foobar, " 1019"}; foobar = {foobar, " 1020"}; ozonehl(foo[20], foobar); dude(foobar); $fwrite (fd, " 1021:%s", foobar); end 17'b10_101?_?_????_??_???? : begin ozonef1(foo, foobar); foobar = {foobar, " 1022"}; if (foo[20]) begin foobar = {foobar, " 1023"}; ozoneacc(foo[18], foobar); foobar = {foobar, " 1024"}; foobar = {foobar, " 1025"}; if (foo[19]) foobar = {foobar, " 1026"}; else foobar = {foobar, " 1027"}; end else ozonerx(foo, foobar); dude(foobar); $fwrite (fd, " 1028:%s", foobar); end 17'b10_110?_?_????_??_???? : begin ozonef1(foo, foobar); foobar = {foobar, " 1029"}; foobar = {foobar, " 1030"}; ozonehl(foo[20], foobar); foobar = {foobar, " 1031"}; ozonerx(foo, foobar); dude(foobar); $fwrite (fd, " 1032:%s", foobar); end 17'b10_111?_?_????_??_???? : begin ozonef1(foo, foobar); foobar = {foobar, " 1033"}; foobar = {foobar, " 1034"}; ozonehl(foo[20], foobar); foobar = {foobar, " 1035"}; ozonerx(foo, foobar); dude(foobar); $fwrite (fd, " 1036:%s", foobar); end 17'b11_001?_?_????_??_???? : begin ozonef1(foo, foobar); foobar = {foobar, " 1037"}; ozonerx(foo, foobar); foobar = {foobar, " 1038"}; foobar = {foobar, " 1039"}; ozonehl(foo[20], foobar); dude(foobar); $fwrite (fd, " 1040:%s", foobar); end 17'b11_111?_?_????_??_???? : begin ozonef1(foo, foobar); foobar = {foobar, " 1041"}; foobar = {foobar, " 1042"}; ozonerx(foo, foobar); foobar = {foobar, " 1043"}; if (foo[20]) foobar = {foobar, " 1044"}; else foobar = {foobar, " 1045"}; dude(foobar); $fwrite (fd, " 1046:%s", foobar); end 17'b00_10??_?_????_?1_1111 : casez (foo[11: 5]) 7'b??_0_010_0: begin foobar = " 1047"; ozonecon(foo[14:10], foobar); foobar = {foobar, " 1048"}; ozonef1e(foo, foobar); dude(foobar); $fwrite (fd, " 1049:%s", foobar); end 7'b00_?_110_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1050"}; case ({foo[ 9],foo[ 5]}) 2'b00: begin foobar = {foobar, " 1051"}; ozoneae(foo[14:12], foobar); ozonehl(foo[ 5], foobar); end 2'b01: begin foobar = {foobar, " 1052"}; ozoneae(foo[14:12], foobar); ozonehl(foo[ 5], foobar); end 2'b10: begin foobar = {foobar, " 1053"}; ozoneae(foo[14:12], foobar); end 2'b11: foobar = {foobar, " 1054"}; endcase dude(foobar); $fwrite (fd, " 1055:%s", foobar); end 7'b01_?_110_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1056"}; case ({foo[ 9],foo[ 5]}) 2'b00: begin ozoneae(foo[14:12], foobar); ozonehl(foo[ 5], foobar); foobar = {foobar, " 1057"}; end 2'b01: begin ozoneae(foo[14:12], foobar); ozonehl(foo[ 5], foobar); foobar = {foobar, " 1058"}; end 2'b10: begin ozoneae(foo[14:12], foobar); foobar = {foobar, " 1059"}; end 2'b11: foobar = {foobar, " 1060"}; endcase dude(foobar); $fwrite (fd, " 1061:%s", foobar); end 7'b10_0_110_0: begin ozonef1e(foo, foobar); foobar = {foobar, " 1062"}; foobar = {foobar, " 1063"}; if (foo[12]) foobar = {foobar, " 1064"}; else ozonerab({4'b1001, foo[14:12]}, foobar); dude(foobar); $fwrite (fd, " 1065:%s", foobar); end 7'b10_0_110_1: begin ozonef1e(foo, foobar); foobar = {foobar, " 1066"}; if (foo[12]) foobar = {foobar, " 1067"}; else ozonerab({4'b1001, foo[14:12]}, foobar); foobar = {foobar, " 1068"}; dude(foobar); $fwrite (fd, " 1069:%s", foobar); end 7'b??_?_000_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1070"}; foobar = {foobar, " 1071"}; ozonef1e_hl(foo[11:9],foo[ 5],foobar); foobar = {foobar, " 1072"}; ozonef1e_ye(foo[14:9],foo[ 5],foobar); dude(foobar); $fwrite (fd, " 1073:%s", foobar); end 7'b??_?_100_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1074"}; foobar = {foobar, " 1075"}; ozonef1e_hl(foo[11:9],foo[ 5],foobar); foobar = {foobar, " 1076"}; ozonef1e_ye(foo[14:9],foo[ 5],foobar); dude(foobar); $fwrite (fd, " 1077:%s", foobar); end 7'b??_?_001_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1078"}; ozonef1e_ye(foo[14:9],foo[ 5],foobar); foobar = {foobar, " 1079"}; foobar = {foobar, " 1080"}; ozonef1e_hl(foo[11:9],foo[ 5],foobar); dude(foobar); $fwrite (fd, " 1081:%s", foobar); end 7'b??_?_011_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1082"}; ozonef1e_ye(foo[14:9],foo[ 5],foobar); foobar = {foobar, " 1083"}; foobar = {foobar, " 1084"}; ozonef1e_hl(foo[11:9],foo[ 5],foobar); dude(foobar); $fwrite (fd, " 1085:%s", foobar); end 7'b??_?_101_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1086"}; ozonef1e_ye(foo[14:9],foo[ 5],foobar); dude(foobar); $fwrite (fd, " 1087:%s", foobar); end endcase 17'b00_10??_?_????_?0_0110 : begin ozonef1e(foo, foobar); foobar = {foobar, " 1088"}; ozoneae(foo[ 8: 6], foobar); ozonef1e_hl(foo[11:9],foo[ 5],foobar); foobar = {foobar, " 1089"}; ozonef1e_ye(foo[14:9],foo[ 5],foobar); dude(foobar); $fwrite (fd, " 1090:%s", foobar); end 17'b00_10??_?_????_00_0111 : begin ozonef1e(foo, foobar); foobar = {foobar, " 1091"}; if (foo[ 6]) foobar = {foobar, " 1092"}; else ozonerab({4'b1001, foo[ 8: 6]}, foobar); foobar = {foobar, " 1093"}; foobar = {foobar, " 1094"}; ozonerme(foo[14:12],foobar); case (foo[11: 9]) 3'h2, 3'h5, 3'h6, 3'h7: ozonef1e_inc_dec(foo[14:9],1'b0,foobar); 3'h1, 3'h3, 3'h4: foobar = {foobar, " 1095"}; endcase dude(foobar); $fwrite (fd, " 1096:%s", foobar); end 17'b00_10??_?_????_?0_0100 : begin ozonef1e(foo, foobar); foobar = {foobar, " 1097"}; ozonef1e_ye(foo[14:9],foo[ 5],foobar); foobar = {foobar, " 1098"}; ozoneae(foo[ 8: 6], foobar); ozonef1e_hl(foo[11:9],foo[ 5],foobar); dude(foobar); $fwrite (fd, " 1099:%s", foobar); end 17'b00_10??_?_????_10_0111 : begin ozonef1e(foo, foobar); foobar = {foobar, " 1100"}; foobar = {foobar, " 1101"}; ozonerme(foo[14:12],foobar); case (foo[11: 9]) 3'h2, 3'h5, 3'h6, 3'h7: ozonef1e_inc_dec(foo[14:9],1'b0,foobar); 3'h1, 3'h3, 3'h4: foobar = {foobar, " 1102"}; endcase foobar = {foobar, " 1103"}; if (foo[ 6]) foobar = {foobar, " 1104"}; else ozonerab({4'b1001, foo[ 8: 6]}, foobar); dude(foobar); $fwrite (fd, " 1105:%s", foobar); end 17'b00_10??_?_????_?0_1110 : begin ozonef1e(foo, foobar); foobar = {foobar, " 1106"}; case (foo[11:9]) 3'h2: begin foobar = {foobar, " 1107"}; if (foo[14:12] == 3'h0) foobar = {foobar, " 1108"}; else ozonerme(foo[14:12],foobar); foobar = {foobar, " 1109"}; end 3'h6: begin foobar = {foobar, " 1110"}; if (foo[14:12] == 3'h0) foobar = {foobar, " 1111"}; else ozonerme(foo[14:12],foobar); foobar = {foobar, " 1112"}; end 3'h0: begin foobar = {foobar, " 1113"}; if (foo[14:12] == 3'h0) foobar = {foobar, " 1114"}; else ozonerme(foo[14:12],foobar); foobar = {foobar, " 1115"}; if (foo[ 7: 5] >= 3'h5) foobar = {foobar, " 1116"}; else ozonexe(foo[ 8: 5], foobar); end 3'h1: begin foobar = {foobar, " 1117"}; if (foo[14:12] == 3'h0) foobar = {foobar, " 1118"}; else ozonerme(foo[14:12],foobar); foobar = {foobar, " 1119"}; if (foo[ 7: 5] >= 3'h5) foobar = {foobar, " 1120"}; else ozonexe(foo[ 8: 5], foobar); end 3'h4: begin foobar = {foobar, " 1121"}; if (foo[14:12] == 3'h0) foobar = {foobar, " 1122"}; else ozonerme(foo[14:12],foobar); foobar = {foobar, " 1123"}; if (foo[ 7: 5] >= 3'h5) foobar = {foobar, " 1124"}; else ozonexe(foo[ 8: 5], foobar); end 3'h5: begin foobar = {foobar, " 1125"}; if (foo[14:12] == 3'h0) foobar = {foobar, " 1126"}; else ozonerme(foo[14:12],foobar); foobar = {foobar, " 1127"}; if (foo[ 7: 5] >= 3'h5) foobar = {foobar, " 1128"}; else ozonexe(foo[ 8: 5], foobar); end endcase dude(foobar); $fwrite (fd, " 1129:%s", foobar); end 17'b00_10??_?_????_?0_1111 : casez (foo[14: 9]) 6'b001_10_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1130"}; foobar = {foobar, " 1131"}; ozonef1e_hl(foo[ 7: 5],foo[ 9],foobar); foobar = {foobar, " 1132"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1133:%s", foobar); end 6'b???_11_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1134"}; ozoneae(foo[14:12], foobar); ozonef1e_hl(foo[ 7: 5],foo[ 9],foobar); foobar = {foobar, " 1135"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1136:%s", foobar); end 6'b000_10_1, 6'b010_10_1, 6'b100_10_1, 6'b110_10_1: begin ozonef1e(foo, foobar); foobar = {foobar, " 1137"}; ozonerab({4'b1001, foo[14:12]}, foobar); foobar = {foobar, " 1138"}; if ((foo[ 7: 5] >= 3'h1) & (foo[ 7: 5] <= 3'h3)) foobar = {foobar, " 1139"}; else ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1140:%s", foobar); end 6'b000_10_0, 6'b010_10_0, 6'b100_10_0, 6'b110_10_0: begin ozonef1e(foo, foobar); foobar = {foobar, " 1141"}; foobar = {foobar, " 1142"}; ozonerab({4'b1001, foo[14:12]}, foobar); foobar = {foobar, " 1143"}; foobar = {foobar, " 1144"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1145"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1146:%s", foobar); end 6'b???_00_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1147"}; if (foo[ 9]) begin foobar = {foobar, " 1148"}; ozoneae(foo[14:12], foobar); end else begin foobar = {foobar, " 1149"}; ozoneae(foo[14:12], foobar); foobar = {foobar, " 1150"}; end foobar = {foobar, " 1151"}; foobar = {foobar, " 1152"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1153"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1154:%s", foobar); end 6'b???_01_?: begin ozonef1e(foo, foobar); foobar = {foobar, " 1155"}; ozoneae(foo[14:12], foobar); if (foo[ 9]) foobar = {foobar, " 1156"}; else foobar = {foobar, " 1157"}; foobar = {foobar, " 1158"}; foobar = {foobar, " 1159"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1160"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1161:%s", foobar); end 6'b011_10_0: begin ozonef1e(foo, foobar); foobar = {foobar, " 1162"}; case (foo[ 8: 5]) 4'h0: foobar = {foobar, " 1163"}; 4'h1: foobar = {foobar, " 1164"}; 4'h2: foobar = {foobar, " 1165"}; 4'h3: foobar = {foobar, " 1166"}; 4'h4: foobar = {foobar, " 1167"}; 4'h5: foobar = {foobar, " 1168"}; 4'h8: foobar = {foobar, " 1169"}; 4'h9: foobar = {foobar, " 1170"}; 4'ha: foobar = {foobar, " 1171"}; 4'hb: foobar = {foobar, " 1172"}; 4'hc: foobar = {foobar, " 1173"}; 4'hd: foobar = {foobar, " 1174"}; default: foobar = {foobar, " 1175"}; endcase dude(foobar); $fwrite (fd, " 1176:%s", foobar); end default: foobar = {foobar, " 1177"}; endcase 17'b00_10??_?_????_?0_110? : begin ozonef1e(foo, foobar); foobar = {foobar, " 1178"}; foobar = {foobar, " 1179"}; ozonef1e_hl(foo[11:9], foo[0], foobar); foobar = {foobar, " 1180"}; ozonef1e_ye(foo[14:9],1'b0,foobar); foobar = {foobar, " 1181"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1182"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1183:%s", foobar); end 17'b00_10??_?_????_?1_110? : begin ozonef1e(foo, foobar); foobar = {foobar, " 1184"}; foobar = {foobar, " 1185"}; ozonef1e_hl(foo[11:9],foo[0],foobar); foobar = {foobar, " 1186"}; ozonef1e_ye(foo[14:9],foo[ 0],foobar); foobar = {foobar, " 1187"}; foobar = {foobar, " 1188"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1189"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1190:%s", foobar); end 17'b00_10??_?_????_?0_101? : begin ozonef1e(foo, foobar); foobar = {foobar, " 1191"}; ozonef1e_ye(foo[14:9],foo[ 0],foobar); foobar = {foobar, " 1192"}; foobar = {foobar, " 1193"}; ozonef1e_hl(foo[11:9],foo[0],foobar); foobar = {foobar, " 1194"}; foobar = {foobar, " 1195"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1196"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1197:%s", foobar); end 17'b00_10??_?_????_?0_1001 : begin ozonef1e(foo, foobar); foobar = {foobar, " 1198"}; foobar = {foobar, " 1199"}; ozonef1e_h(foo[11:9],foobar); foobar = {foobar, " 1200"}; ozonef1e_ye(foo[14:9],1'b0,foobar); foobar = {foobar, " 1201"}; case (foo[ 7: 5]) 3'h1, 3'h2, 3'h3: foobar = {foobar, " 1202"}; default: begin foobar = {foobar, " 1203"}; foobar = {foobar, " 1204"}; ozonexe(foo[ 8: 5], foobar); end endcase dude(foobar); $fwrite (fd, " 1205:%s", foobar); end 17'b00_10??_?_????_?0_0101 : begin ozonef1e(foo, foobar); foobar = {foobar, " 1206"}; case (foo[11: 9]) 3'h1, 3'h3, 3'h4: foobar = {foobar, " 1207"}; default: begin ozonef1e_ye(foo[14:9],1'b0,foobar); foobar = {foobar, " 1208"}; foobar = {foobar, " 1209"}; end endcase foobar = {foobar, " 1210"}; foobar = {foobar, " 1211"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1212"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1213:%s", foobar); end 17'b00_10??_?_????_?1_1110 : begin ozonef1e(foo, foobar); foobar = {foobar, " 1214"}; ozonef1e_ye(foo[14:9],1'b0,foobar); foobar = {foobar, " 1215"}; foobar = {foobar, " 1216"}; ozonef1e_h(foo[11: 9],foobar); foobar = {foobar, " 1217"}; foobar = {foobar, " 1218"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1219"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1220:%s", foobar); end 17'b00_10??_?_????_?0_1000 : begin ozonef1e(foo, foobar); foobar = {foobar, " 1221"}; ozonef1e_ye(foo[14:9],1'b0,foobar); foobar = {foobar, " 1222"}; foobar = {foobar, " 1223"}; ozonef1e_h(foo[11: 9],foobar); foobar = {foobar, " 1224"}; foobar = {foobar, " 1225"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1226"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite (fd, " 1227:%s", foobar); end 17'b10_01??_?_????_??_???? : begin if (foo[27]) foobar = " 1228"; else foobar = " 1229"; ozonecon(foo[20:16], foobar); foobar = {foobar, " 1230"}; ozonef2(foo[31:0], foobar); dude(foobar); $fwrite (fd, " 1231:%s", foobar); end 17'b00_1000_?_????_01_0011 : if (~|foo[ 9: 8]) begin if (foo[ 7]) foobar = " 1232"; else foobar = " 1233"; ozonecon(foo[14:10], foobar); foobar = {foobar, " 1234"}; ozonef2e(foo[31:0], foobar); dude(foobar); $fwrite (fd, " 1235:%s", foobar); end else begin foobar = " 1236"; ozonecon(foo[14:10], foobar); foobar = {foobar, " 1237"}; ozonef3e(foo[31:0], foobar); dude(foobar); $fwrite (fd, " 1238:%s", foobar); end 17'b11_110?_1_????_??_???? : begin ozonef3(foo[31:0], foobar); dude(foobar); $fwrite(fd, " 1239:%s", foobar); end 17'b11_110?_0_????_??_???? : begin : f4_body casez (foo[24:20]) 5'b0_1110, 5'b1_0???, 5'b1_1111: begin $fwrite (fd, " 1240"); end 5'b0_00??: begin ozoneacc(foo[26], foobar); foobar = {foobar, " 1241"}; ozoneacc(foo[25], foobar); ozonebmuop(foo[24:20], foobar); ozoneae(foo[18:16], foobar); foobar = {foobar, " 1242"}; dude(foobar); $fwrite(fd, " 1243:%s", foobar); end 5'b0_01??: begin ozoneacc(foo[26], foobar); foobar = {foobar, " 1244"}; ozoneacc(foo[25], foobar); ozonebmuop(foo[24:20], foobar); ozonearm(foo[18:16], foobar); dude(foobar); $fwrite(fd, " 1245:%s", foobar); end 5'b0_1011: begin ozoneacc(foo[26], foobar); foobar = {foobar, " 1246"}; ozonebmuop(foo[24:20], foobar); foobar = {foobar, " 1247"}; ozoneae(foo[18:16], foobar); foobar = {foobar, " 1248"}; dude(foobar); $fwrite(fd, " 1249:%s", foobar); end 5'b0_100?, 5'b0_1010, 5'b0_110? : begin ozoneacc(foo[26], foobar); foobar = {foobar, " 1250"}; ozonebmuop(foo[24:20], foobar); foobar = {foobar, " 1251"}; ozoneacc(foo[25], foobar); foobar = {foobar, " 1252"}; ozoneae(foo[18:16], foobar); foobar = {foobar, " 1253"}; dude(foobar); $fwrite(fd, " 1254:%s", foobar); end 5'b0_1111 : begin ozoneacc(foo[26], foobar); foobar = {foobar, " 1255"}; ozoneacc(foo[25], foobar); foobar = {foobar, " 1256"}; ozoneae(foo[18:16], foobar); dude(foobar); $fwrite(fd, " 1257:%s", foobar); end 5'b1_10??, 5'b1_110?, 5'b1_1110 : begin ozoneacc(foo[26], foobar); foobar = {foobar, " 1258"}; ozonebmuop(foo[24:20], foobar); foobar = {foobar, " 1259"}; ozoneacc(foo[25], foobar); foobar = {foobar, " 1260"}; ozonearm(foo[18:16], foobar); foobar = {foobar, " 1261"}; dude(foobar); $fwrite(fd, " 1262:%s", foobar); end endcase end 17'b11_100?_?_????_??_???? : casez (foo[23:19]) 5'b111??, 5'b0111?: begin ozoneae(foo[26:24], foobar); foobar = {foobar, " 1263"}; ozonef3f4imop(foo[23:19], foobar); foobar = {foobar, " 1264"}; ozoneae(foo[18:16], foobar); foobar = {foobar, " 1265"}; skyway(foo[15:12], foobar); skyway(foo[11: 8], foobar); skyway(foo[ 7: 4], foobar); skyway(foo[ 3:0], foobar); foobar = {foobar, " 1266"}; dude(foobar); $fwrite(fd, " 1267:%s", foobar); end 5'b?0???, 5'b110??: begin ozoneae(foo[26:24], foobar); foobar = {foobar, " 1268"}; if (foo[23:21] == 3'b100) foobar = {foobar, " 1269"}; ozoneae(foo[18:16], foobar); if (foo[19]) foobar = {foobar, " 1270"}; else foobar = {foobar, " 1271"}; ozonef3f4imop(foo[23:19], foobar); foobar = {foobar, " 1272"}; ozonef3f4_iext(foo[20:19], foo[15:0], foobar); dude(foobar); $fwrite(fd, " 1273:%s", foobar); end 5'b010??, 5'b0110?: begin ozoneae(foo[18:16], foobar); if (foo[19]) foobar = {foobar, " 1274"}; else foobar = {foobar, " 1275"}; ozonef3f4imop(foo[23:19], foobar); foobar = {foobar, " 1276"}; ozonef3f4_iext(foo[20:19], foo[15:0], foobar); dude(foobar); $fwrite(fd, " 1277:%s", foobar); end endcase 17'b00_1000_?_????_11_0011 : begin foobar = " 1278"; ozonecon(foo[14:10], foobar); foobar = {foobar, " 1279"}; casez (foo[25:21]) 5'b0_1110, 5'b1_0???, 5'b1_1111: begin $fwrite(fd, " 1280"); end 5'b0_00??: begin ozoneae(foo[20:18], foobar); foobar = {foobar, " 1281"}; ozoneae(foo[17:15], foobar); ozonebmuop(foo[25:21], foobar); ozoneae(foo[ 8: 6], foobar); foobar = {foobar, " 1282"}; dude(foobar); $fwrite(fd, " 1283:%s", foobar); end 5'b0_01??: begin ozoneae(foo[20:18], foobar); foobar = {foobar, " 1284"}; ozoneae(foo[17:15], foobar); ozonebmuop(foo[25:21], foobar); ozonearm(foo[ 8: 6], foobar); dude(foobar); $fwrite(fd, " 1285:%s", foobar); end 5'b0_1011: begin ozoneae(foo[20:18], foobar); foobar = {foobar, " 1286"}; ozonebmuop(foo[25:21], foobar); foobar = {foobar, " 1287"}; ozoneae(foo[ 8: 6], foobar); foobar = {foobar, " 1288"}; dude(foobar); $fwrite(fd, " 1289:%s", foobar); end 5'b0_100?, 5'b0_1010, 5'b0_110? : begin ozoneae(foo[20:18], foobar); foobar = {foobar, " 1290"}; ozonebmuop(foo[25:21], foobar); foobar = {foobar, " 1291"}; ozoneae(foo[17:15], foobar); foobar = {foobar, " 1292"}; ozoneae(foo[ 8: 6], foobar); foobar = {foobar, " 1293"}; dude(foobar); $fwrite(fd, " 1294:%s", foobar); end 5'b0_1111 : begin ozoneae(foo[20:18], foobar); foobar = {foobar, " 1295"}; ozoneae(foo[17:15], foobar); foobar = {foobar, " 1296"}; ozoneae(foo[ 8: 6], foobar); dude(foobar); $fwrite(fd, " 1297:%s", foobar); end 5'b1_10??, 5'b1_110?, 5'b1_1110 : begin ozoneae(foo[20:18], foobar); foobar = {foobar, " 1298"}; ozonebmuop(foo[25:21], foobar); foobar = {foobar, " 1299"}; ozoneae(foo[17:15], foobar); foobar = {foobar, " 1300"}; ozonearm(foo[ 8: 6], foobar); foobar = {foobar, " 1301"}; dude(foobar); $fwrite(fd, " 1302:%s", foobar); end endcase end 17'b00_0010_?_????_??_???? : begin $fwrite(fd, " 1304a:%x;%x", foobar, foo[25:20]); ozonerab({1'b0, foo[25:20]}, foobar); $fwrite(fd, " 1304b:%x", foobar); foobar = {foobar, " 1303"}; $fwrite(fd, " 1304c:%x;%x", foobar, foo[19:16]); skyway(foo[19:16], foobar); $fwrite(fd, " 1304d:%x", foobar); dude(foobar); $fwrite(fd, " 1304e:%x", foobar); $fwrite(fd, " 1304:%s", foobar); end 17'b00_01??_?_????_??_???? : begin if (foo[27]) begin foobar = {foobar, " 1305"}; if (foo[26]) foobar = {foobar, " 1306"}; else foobar = {foobar, " 1307"}; skyway(foo[19:16], foobar); foobar = {foobar, " 1308"}; ozonerab({1'b0, foo[25:20]}, foobar); end else begin ozonerab({1'b0, foo[25:20]}, foobar); foobar = {foobar, " 1309"}; if (foo[26]) foobar = {foobar, " 1310"}; else foobar = {foobar, " 1311"}; skyway(foo[19:16], foobar); foobar = {foobar, " 1312"}; end dude(foobar); $fwrite(fd, " 1313:%s", foobar); end 17'b01_000?_?_????_??_???? : begin if (foo[26]) begin ozonerb(foo[25:20], foobar); foobar = {foobar, " 1314"}; ozoneae(foo[18:16], foobar); ozonehl(foo[19], foobar); end else begin ozoneae(foo[18:16], foobar); ozonehl(foo[19], foobar); foobar = {foobar, " 1315"}; ozonerb(foo[25:20], foobar); end dude(foobar); $fwrite(fd, " 1316:%s", foobar); end 17'b01_10??_?_????_??_???? : begin if (foo[27]) begin ozonerab({1'b0, foo[25:20]}, foobar); foobar = {foobar, " 1317"}; ozonerx(foo, foobar); end else begin ozonerx(foo, foobar); foobar = {foobar, " 1318"}; ozonerab({1'b0, foo[25:20]}, foobar); end dude(foobar); $fwrite(fd, " 1319:%s", foobar); end 17'b11_101?_?_????_??_???? : begin ozonerab (foo[26:20], foobar); foobar = {foobar, " 1320"}; skyway(foo[19:16], foobar); skyway(foo[15:12], foobar); skyway(foo[11: 8], foobar); skyway(foo[ 7: 4], foobar); skyway(foo[ 3: 0], foobar); dude(foobar); $fwrite(fd, " 1321:%s", foobar); end 17'b11_0000_?_????_??_???? : begin casez (foo[25:23]) 3'b00?: begin ozonerab(foo[22:16], foobar); foobar = {foobar, " 1322"}; end 3'b01?: begin foobar = {foobar, " 1323"}; if (foo[22:16]>=7'h60) foobar = {foobar, " 1324"}; else ozonerab(foo[22:16], foobar); end 3'b110: foobar = {foobar, " 1325"}; 3'b10?: begin foobar = {foobar, " 1326"}; if (foo[22:16]>=7'h60) foobar = {foobar, " 1327"}; else ozonerab(foo[22:16], foobar); end 3'b111: begin foobar = {foobar, " 1328"}; ozonerab(foo[22:16], foobar); foobar = {foobar, " 1329"}; end endcase dude(foobar); $fwrite(fd, " 1330:%s", foobar); end 17'b00_10??_?_????_?1_0000 : begin if (foo[27]) begin foobar = {foobar, " 1331"}; ozonerp(foo[14:12], foobar); foobar = {foobar, " 1332"}; skyway(foo[19:16], foobar); skyway({foo[15],foo[11: 9]}, foobar); skyway(foo[ 8: 5], foobar); foobar = {foobar, " 1333"}; if (foo[26:20]>=7'h60) foobar = {foobar, " 1334"}; else ozonerab(foo[26:20], foobar); end else begin ozonerab(foo[26:20], foobar); foobar = {foobar, " 1335"}; foobar = {foobar, " 1336"}; ozonerp(foo[14:12], foobar); foobar = {foobar, " 1337"}; skyway(foo[19:16], foobar); skyway({foo[15],foo[11: 9]}, foobar); skyway(foo[ 8: 5], foobar); foobar = {foobar, " 1338"}; end dude(foobar); $fwrite(fd, " 1339:%s", foobar); end 17'b00_101?_1_0000_?1_0010 : if (~|foo[11: 7]) begin if (foo[ 6]) begin foobar = {foobar, " 1340"}; ozonerp(foo[14:12], foobar); foobar = {foobar, " 1341"}; ozonejk(foo[ 5], foobar); foobar = {foobar, " 1342"}; if (foo[26:20]>=7'h60) foobar = {foobar, " 1343"}; else ozonerab(foo[26:20], foobar); end else begin ozonerab(foo[26:20], foobar); foobar = {foobar, " 1344"}; foobar = {foobar, " 1345"}; ozonerp(foo[14:12], foobar); foobar = {foobar, " 1346"}; ozonejk(foo[ 5], foobar); foobar = {foobar, " 1347"}; end dude(foobar); $fwrite(fd, " 1348:%s", foobar); end else $fwrite(fd, " 1349"); 17'b00_100?_0_0011_?1_0101 : if (~|foo[ 8: 7]) begin if (foo[6]) begin ozonerab(foo[26:20], foobar); foobar = {foobar, " 1350"}; ozoneye(foo[14: 9],foo[ 5], foobar); end else begin ozoneye(foo[14: 9],foo[ 5], foobar); foobar = {foobar, " 1351"}; if (foo[26:20]>=7'h60) foobar = {foobar, " 1352"}; else ozonerab(foo[26:20], foobar); end dude(foobar); $fwrite(fd, " 1353:%s", foobar); end else $fwrite(fd, " 1354"); 17'b00_1001_0_0000_?1_0010 : if (~|foo[25:20]) begin ozoneye(foo[14: 9],1'b0, foobar); foobar = {foobar, " 1355"}; ozonef1e_h(foo[11: 9],foobar); foobar = {foobar, " 1356"}; ozonef1e_h(foo[ 7: 5],foobar); foobar = {foobar, " 1357"}; ozonexe(foo[ 8: 5], foobar); dude(foobar); $fwrite(fd, " 1358:%s", foobar); end else $fwrite(fd, " 1359"); 17'b00_101?_0_????_?1_0010 : if (~foo[13]) begin if (foo[12]) begin foobar = {foobar, " 1360"}; if (foo[26:20]>=7'h60) foobar = {foobar, " 1361"}; else ozonerab(foo[26:20], foobar); foobar = {foobar, " 1362"}; foobar = {foobar, " 1363"}; skyway({1'b0,foo[18:16]}, foobar); skyway({foo[15],foo[11: 9]}, foobar); skyway(foo[ 8: 5], foobar); dude(foobar); $fwrite(fd, " 1364:%s", foobar); end else begin ozonerab(foo[26:20], foobar); foobar = {foobar, " 1365"}; foobar = {foobar, " 1366"}; skyway({1'b0,foo[18:16]}, foobar); skyway({foo[15],foo[11: 9]}, foobar); skyway(foo[ 8: 5], foobar); dude(foobar); $fwrite(fd, " 1367:%s", foobar); end end else $fwrite(fd, " 1368"); 17'b01_01??_?_????_??_???? : begin ozonerab({1'b0,foo[27:26],foo[19:16]}, foobar); foobar = {foobar, " 1369"}; ozonerab({1'b0,foo[25:20]}, foobar); dude(foobar); $fwrite(fd, " 1370:%s", foobar); end 17'b00_100?_?_???0_11_0101 : if (~foo[6]) begin foobar = " 1371"; ozonecon(foo[14:10], foobar); foobar = {foobar, " 1372"}; ozonerab({foo[ 9: 7],foo[19:16]}, foobar); foobar = {foobar, " 1373"}; ozonerab({foo[26:20]}, foobar); dude(foobar); $fwrite(fd, " 1374:%s", foobar); end else $fwrite(fd, " 1375"); 17'b00_1000_?_????_?1_0010 : if (~|foo[25:24]) begin ozonery(foo[23:20], foobar); foobar = {foobar, " 1376"}; ozonerp(foo[14:12], foobar); foobar = {foobar, " 1377"}; skyway(foo[19:16], foobar); skyway({foo[15],foo[11: 9]}, foobar); skyway(foo[ 8: 5], foobar); dude(foobar); $fwrite(fd, " 1378:%s", foobar); end else if ((foo[25:24] == 2'b10) & ~|foo[19:15] & ~|foo[11: 6]) begin ozonery(foo[23:20], foobar); foobar = {foobar, " 1379"}; ozonerp(foo[14:12], foobar); foobar = {foobar, " 1380"}; ozonejk(foo[ 5], foobar); dude(foobar); $fwrite(fd, " 1381:%s", foobar); end else $fwrite(fd, " 1382"); 17'b11_01??_?_????_??_????, 17'b10_00??_?_????_??_???? : if (foo[30]) $fwrite(fd, " 1383:%s", foo[27:16]); else $fwrite(fd, " 1384:%s", foo[27:16]); 17'b00_10??_?_????_01_1000 : if (~foo[6]) begin if (foo[7]) $fwrite(fd, " 1385:%s", foo[27: 8]); else $fwrite(fd, " 1386:%s", foo[27: 8]); end else $fwrite(fd, " 1387"); 17'b00_10??_?_????_11_1000 : begin foobar = " 1388"; ozonecon(foo[14:10], foobar); foobar = {foobar, " 1389"}; if (foo[15]) foobar = {foobar, " 1390"}; else foobar = {foobar, " 1391"}; skyway(foo[27:24], foobar); skyway(foo[23:20], foobar); skyway(foo[19:16], foobar); skyway(foo[ 9: 6], foobar); dude(foobar); $fwrite(fd, " 1392:%s", foobar); end 17'b11_0001_?_????_??_???? : casez (foo[25:22]) 4'b01?? : begin foobar = " 1393"; ozonecon(foo[20:16], foobar); case (foo[23:21]) 3'h0 : foobar = {foobar, " 1394"}; 3'h1 : foobar = {foobar, " 1395"}; 3'h2 : foobar = {foobar, " 1396"}; 3'h3 : foobar = {foobar, " 1397"}; 3'h4 : foobar = {foobar, " 1398"}; 3'h5 : foobar = {foobar, " 1399"}; 3'h6 : foobar = {foobar, " 1400"}; 3'h7 : foobar = {foobar, " 1401"}; endcase dude(foobar); $fwrite(fd, " 1402:%s", foobar); end 4'b0000 : $fwrite(fd, " 1403:%s", foo[21:16]); 4'b0010 : if (~|foo[21:16]) $fwrite(fd, " 1404"); 4'b1010 : if (~|foo[21:17]) begin if (foo[16]) $fwrite(fd, " 1405"); else $fwrite(fd, " 1406"); end default : $fwrite(fd, " 1407"); endcase 17'b01_11??_?_????_??_???? : if (foo[27:23] === 5'h00) $fwrite(fd, " 1408:%s", foo[22:16]); else $fwrite(fd, " 1409:%s", foo[22:16]); default: $fwrite(fd, " 1410"); endcase end endtask //(query-replace-regexp "\\([a-z0-9_]+\\) *( *\\([][a-z0-9_~': ]+\\) *, *\\([][a-z0-9'~: ]+\\) *, *\\([][a-z0-9'~: ]+\\) *);" "$c(\"\\1(\",\\2,\",\",\\3,\",\",\\4,\");\");" nil nil nil) //(query-replace-regexp "\\([a-z0-9_]+\\) *( *\\([][a-z0-9_~': ]+\\) *, *\\([][a-z0-9'~: ]+\\) *);" "$c(\"\\1(\",\\2,\",\",\\3,\");\");" nil nil nil) endmodule verilator-3.874/test_regress/t/t_select_plus.v0000664000177100017500000000625412473477707021564 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [83:4] from; reg [83:4] to; reg [6:0] bitn; reg [3:0] nibblep; reg [3:0] nibblem; reg [7:0] cyc; initial cyc=0; always @* begin nibblep = from[bitn +: 4]; nibblem = from[bitn -: 4]; to = from; to[bitn +: 4] = cyc[3:0]; to[bitn -: 4] = cyc[3:0]; end always @ (posedge clk) begin //$write("[%0t] cyc==%d nibblep==%b nibblem==%b to^from==%x\n",$time, cyc, nibblep, nibblem, from^to); cyc <= cyc + 8'd1; case (cyc) 8'd00: begin from<=80'h7bea9d779b67e48f67da; bitn<=7'd7; end 8'd01: begin from<=80'hefddce326b11ca5dc448; bitn<=7'd8; end 8'd02: begin from<=80'h3f99c5f34168401e210d; bitn<=7'd4; end // truncate -: 8'd03: begin from<=80'hc90635f0a7757614ce3f; bitn<=7'd79; end 8'd04: begin from<=80'hc761feca3820331370ec; bitn<=7'd83; end // truncate +: 8'd05: begin from<=80'hd6e36077bf28244f84b5; bitn<=7'd6; end // half trunc 8'd06: begin from<=80'h90118c5d3d285a1f3252; bitn<=7'd81; end // half trunc 8'd07: begin from<=80'h38305da3d46b5859fe16; bitn<=7'd67; end 8'd08: begin from<=80'h4b9ade23a8f5cc5b3111; bitn<=7'd127; end // truncate 8'd09: begin $write("*-* All Finished *-*\n"); $finish; end default: ; endcase case (cyc) 8'd00: ; 8'd01: begin if ((nibblep & 4'b1111)!==4'b1011) $stop; if ((nibblem & 4'b1111)!==4'b1010) $stop; end 8'd02: begin if ((nibblep & 4'b1111)!==4'b0100) $stop; if ((nibblem & 4'b1111)!==4'b0100) $stop; end 8'd03: begin if ((nibblep & 4'b1111)!==4'b1101) $stop; if ((nibblem & 4'b0000)!==4'b0000) $stop; end 8'd04: begin if ((nibblep & 4'b1111)!==4'b1001) $stop; if ((nibblem & 4'b1111)!==4'b1001) $stop; end 8'd05: begin if ((nibblep & 4'b0000)!==4'b0000) $stop; if ((nibblem & 4'b1111)!==4'b1100) $stop; end 8'd06: begin if ((nibblep & 4'b1111)!==4'b1101) $stop; if ((nibblem & 4'b0000)!==4'b0000) $stop; end 8'd07: begin if ((nibblep & 4'b0000)!==4'b0000) $stop; if ((nibblem & 4'b1111)!==4'b0100) $stop; end 8'd08: begin if ((nibblep & 4'b1111)!==4'b0000) $stop; if ((nibblem & 4'b1111)!==4'b0101) $stop; end 8'd09: begin if ((nibblep & 4'b0000)!==4'b0000) $stop; if ((nibblem & 4'b0000)!==4'b0000) $stop; end default: $stop; endcase case (cyc) 8'd00: ; 8'd01: begin if ((to^from)!==80'h0000000000000000005b) $stop; end 8'd02: begin if ((to^from)!==80'h0000000000000000006c) $stop; end 8'd03: begin if ((to^from)!==80'h0000000000000000000e) $stop; end 8'd04: begin if ((to^from)!==80'h6d000000000000000000) $stop; end 8'd05: begin if (((to^from)&~80'hf)!==80'h90000000000000000000) $stop; end // Exceed bounds, verilator may write index 0 8'd06: begin if (((to^from)&~80'hf)!==80'h00000000000000000020) $stop; end // Exceed bounds, verilator may write index 0 8'd07: begin if (((to^from)&~80'hf)!==80'h4c000000000000000000) $stop; end 8'd08: begin if ((to^from)!==80'h0004d000000000000000) $stop; end 8'd09: begin if (((to^from)&~80'hf)!==80'h00000000000000000000) $stop; end default: $stop; endcase end endmodule verilator-3.874/test_regress/t/t_pp_lib.pl0000775000177100017500000000077612473477707020663 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ['-v', 't/t_pp_lib_library.v'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_bind2.pl0000775000177100017500000000072212473477707020403 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_shift.pl0000775000177100017500000000077012525171734021523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["-Wno-CLKDATA"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_skipidentical.v0000664000177100017500000000030312473477707023043 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/); endmodule verilator-3.874/test_regress/t/t_case_66bits.pl0000775000177100017500000000025012473477707021511 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_2in.v0000664000177100017500000000703212473477707020556 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. `ifndef VERILATOR module t; /*AUTOREGINPUT*/ // Beginning of automatic reg inputs (for undeclared instantiated-module inputs) reg c0; // To t2 of t2.v reg c1; // To t2 of t2.v reg check; // To t2 of t2.v reg [1:0] clks; // To t2 of t2.v // End of automatics t2 t2 (/*AUTOINST*/ // Inputs .clks (clks[1:0]), .c0 (c0), .c1 (c1), .check (check)); task clockit (input v1, v0); c1 = v1; c0 = v0; clks[1] = v1; clks[0] = v0; `ifdef TEST_VERBOSE $write("[%0t] c1=%x c0=%x\n", $time,v0,v1); `endif #1; endtask initial begin check = '0; c0 = '0; c1 = '0; clks = '0; #1 t2.clear(); #10; for (int i=0; i<2; i++) begin clockit(0, 0); clockit(0, 0); clockit(0, 1); clockit(1, 1); clockit(0, 0); clockit(1, 1); clockit(1, 0); clockit(0, 0); clockit(1, 0); clockit(0, 1); clockit(0, 0); end check = 1; clockit(0, 0); end endmodule `endif `ifdef VERILATOR `define t2 t `else `define t2 t2 `endif module `t2 ( input [1:0] clks, input c0, input c1, input check ); `ifdef T_CLK_2IN_VEC wire clk0 = clks[0]; wire clk1 = clks[1]; `else wire clk0 = c0; wire clk1 = c1; `endif integer p0 = 0; integer p1 = 0; integer p01 = 0; integer n0 = 0; integer n1 = 0; integer n01 = 0; integer vp = 0; integer vn = 0; integer vpn = 0; task clear; `ifdef TEST_VERBOSE $display("[%0t] clear\n",$time); `endif p0 = 0; p1 = 0; p01 = 0; n0 = 0; n1 = 0; n01 = 0; vp = 0; vn = 0; vpn = 0; endtask `define display_counts(text) begin \ $write("[%0t] ",$time); \ `ifdef T_CLK_2IN_VEC $write(" 2v "); `endif \ $write(text); \ $write(": %0d %0d %0d %0d %0d %0d %0d %0d %0d\n", p0, p1, p01, n0, n1, n01, vp, vn, vpn); \ end always @ (posedge clk0) begin p0 = p0 + 1; // Want blocking, so don't miss clock counts `ifdef TEST_VERBOSE `display_counts("posedge 0"); `endif end always @ (posedge clk1) begin p1 = p1 + 1; `ifdef TEST_VERBOSE `display_counts("posedge 1"); `endif end always @ (posedge clk0 or posedge clk1) begin p01 = p01 + 1; `ifdef TEST_VERBOSE `display_counts("posedge *"); `endif end always @ (negedge clk0) begin n0 = n0 + 1; `ifdef TEST_VERBOSE `display_counts("negedge 0"); `endif end always @ (negedge clk1) begin n1 = n1 + 1; `ifdef TEST_VERBOSE `display_counts("negedge 1"); `endif end always @ (negedge clk0 or negedge clk1) begin n01 = n01 + 1; `ifdef TEST_VERBOSE `display_counts("negedge *"); `endif end `ifndef VERILATOR always @ (posedge clks) begin vp = vp + 1; `ifdef TEST_VERBOSE `display_counts("pos vec"); `endif end always @ (negedge clks) begin vn = vn + 1; `ifdef TEST_VERBOSE `display_counts("neg vec"); `endif end always @ (posedge clks or negedge clks) begin vpn = vpn + 1; `ifdef TEST_VERBOSE `display_counts("or vec"); `endif end `endif always @ (posedge check) begin if (p0!=6) $stop; if (p1!=6) $stop; if (p01!=10) $stop; if (n0!=6) $stop; if (n1!=6) $stop; if (n01!=10) $stop; `ifndef VERILATOR if (vp!=6) $stop; if (vn!=6) $stop; if (vpn!=12) $stop; `endif $write("*-* All Finished *-*\n"); end endmodule verilator-3.874/test_regress/t/t_enum_name2.v0000664000177100017500000000115312525171734021246 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jonathon Donaldson. package our_pkg; typedef enum logic [8-1:0] { ADC_IN2IN = 8'h99, ADC_IMMED = 8'h88, ADC_INDIR = 8'h86, ADC_INIDX = 8'h97 } T_Opcode; endpackage : our_pkg module t (); our our (); endmodule module our import our_pkg::*; (); T_Opcode IR = ADC_IN2IN; initial begin $write ("%s (%t)\n", IR.name, $realtime); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_math_svl.v0000664000177100017500000000677112473477707021063 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [15:0] l; reg [49:0] q; reg [79:0] w; reg [4:0] lc; reg lo; reg l0; reg [5:0] qc; reg qo; reg q0; reg [6:0] wc; reg wo; reg w0; always @* begin lc = $countones(l); lo = $onehot(l); l0 = $onehot0(l); wc = $countones(w); wo = $onehot(w); w0 = $onehot0(w); qc = $countones(q); qo = $onehot(q); q0 = $onehot0(q); end integer cyc; initial cyc=1; integer cyc_com; always_comb begin cyc_com = cyc; end integer cyc_d1; always_ff @ (posedge clk) begin cyc_d1 <= cyc_com; end always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; //$write("%d %x %d %x %x %x %d %x %x %x %d %x %x\n", // cyc, l, lc, lo, l0, q,qc,qo,q0, w,wc,wo,w0); if (cyc_com != cyc_com) $stop; if (cyc_d1 != cyc-1) $stop; if (cyc==0) begin // Constification check if ($countones(32'b11001011101) != 7) $stop; if ($countones(32'b0) != 0) $stop; if ($isunknown(32'b11101x11111) != 1) $stop; if ($isunknown(32'b11101011111) != 0) $stop; if ($isunknown(32'b10zzzzzzzzz) != 0) $stop; if ($bits(0) != 32'd32) $stop; if ($bits(lc) != 5) $stop; if ($onehot(32'b00000001000000) != 1'b1) $stop; if ($onehot(32'b00001001000000) != 1'b0) $stop; if ($onehot(32'b0) != 1'b0) $stop; if ($onehot0(32'b00000001000000) != 1'b1) $stop; if ($onehot0(32'b00001001000000) != 1'b0) $stop; if ($onehot0(32'b0) != 1'b1) $stop; end if (cyc==1) begin l <= 16'b0; q <= 50'h0; w <= 80'h0; end if (cyc==2) begin l <= ~16'b0; q <= ~50'h0; w <= ~80'h0; // if ({lc,lo,l0} != {5'd0,1'b0,1'b1}) $stop; if ({qc,qo,q0} != {6'd0,1'b0,1'b1}) $stop; if ({wc,wo,w0} != {7'd0,1'b0,1'b1}) $stop; end if (cyc==3) begin l <= 16'b0010110010110111; q <= 50'h01_1111_0001; w <= 80'h0100_0000_0f00_00f0_0000; // if ({lc,lo,l0} != {5'd16,1'b0,1'b0}) $stop; if ({qc,qo,q0} != {6'd50,1'b0,1'b0}) $stop; if ({wc,wo,w0} != {7'd80,1'b0,1'b0}) $stop; end if (cyc==4) begin l <= 16'b0000010000000000; q <= 50'h1_0000_0000; w <= 80'h010_00000000_00000000; // if ({lc,lo,l0} != {5'd9,1'b0,1'b0}) $stop; if ({qc,qo,q0} != {6'd6,1'b0,1'b0}) $stop; if ({wc,wo,w0} != {7'd9,1'b0,1'b0}) $stop; end if (cyc==5) begin l <= 16'b0000000100000000; q <= 50'h8000_0000_0000; w <= 80'h10_00000000_00000000; // if ({lc,lo,l0} != {5'd1,1'b1,1'b1}) $stop; if ({qc,qo,q0} != {6'd1,1'b1,1'b1}) $stop; if ({wc,wo,w0} != {7'd1,1'b1,1'b1}) $stop; end if (cyc==6) begin l <= 16'b0000100100000000; q <= 50'h01_00000100; w <= 80'h01_00000100_00000000; // if ({lc,lo,l0} != {5'd1,1'b1,1'b1}) $stop; if ({qc,qo,q0} != {6'd1,1'b1,1'b1}) $stop; if ({wc,wo,w0} != {7'd1,1'b1,1'b1}) $stop; end if (cyc==7) begin // if ({lc,lo,l0} != {5'd2,1'b0,1'b0}) $stop; if ({qc,qo,q0} != {6'd2,1'b0,1'b0}) $stop; if ({wc,wo,w0} != {7'd2,1'b0,1'b0}) $stop; end if (cyc==8) begin end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end final begin $write("Goodbye world, at cycle %0d\n", cyc); end endmodule verilator-3.874/test_regress/t/t_func_begin2.pl0000775000177100017500000000104212473477707021562 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only --inline-mult 1"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_first.pl0000775000177100017500000000072212473477707021714 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_readmem.v0000664000177100017500000000371212473477707021546 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; // verilator lint_off LITENDIAN reg [5:0] binary_nostart [2:15]; reg [5:0] binary_start [0:15]; reg [175:0] hex [0:15]; // verilator lint_on LITENDIAN integer i; initial begin begin $readmemb("t/t_sys_readmem_b.mem", binary_nostart); `ifdef TEST_VERBOSE for (i=0; i<16; i=i+1) $write(" @%x = %x\n", i, binary_nostart[i]); `endif if (binary_nostart['h2] != 6'h02) $stop; if (binary_nostart['h3] != 6'h03) $stop; if (binary_nostart['h4] != 6'h04) $stop; if (binary_nostart['h5] != 6'h05) $stop; if (binary_nostart['h6] != 6'h06) $stop; if (binary_nostart['h7] != 6'h07) $stop; if (binary_nostart['h8] != 6'h10) $stop; if (binary_nostart['hc] != 6'h14) $stop; if (binary_nostart['hd] != 6'h15) $stop; end begin $readmemb("t/t_sys_readmem_b_8.mem", binary_start, 4, 4+7); `ifdef TEST_VERBOSE for (i=0; i<16; i=i+1) $write(" @%x = %x\n", i, binary_start[i]); `endif if (binary_start['h04] != 6'h10) $stop; if (binary_start['h05] != 6'h11) $stop; if (binary_start['h06] != 6'h12) $stop; if (binary_start['h07] != 6'h13) $stop; if (binary_start['h08] != 6'h14) $stop; if (binary_start['h09] != 6'h15) $stop; if (binary_start['h0a] != 6'h16) $stop; if (binary_start['h0b] != 6'h17) $stop; end begin $readmemh("t/t_sys_readmem_h.mem", hex, 0); `ifdef TEST_VERBOSE for (i=0; i<16; i=i+1) $write(" @%x = %x\n", i, hex[i]); `endif if (hex['h04] != 176'h400437654321276543211765432107654321abcdef10) $stop; if (hex['h0a] != 176'h400a37654321276543211765432107654321abcdef11) $stop; if (hex['h0b] != 176'h400b37654321276543211765432107654321abcdef12) $stop; if (hex['h0c] != 176'h400c37654321276543211765432107654321abcdef13) $stop; end $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_flag_libinc.v0000664000177100017500000000077012473477707021470 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module liblib_a (/*AUTOARG*/); liblib_b b (); endmodule module liblib_b (/*AUTOARG*/); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule module liblib_c (/*AUTOARG*/); // Unused initial $stop; liblib_d d (); endmodule module liblib_d (/*AUTOARG*/); // Unused initial $stop; endmodule verilator-3.874/test_regress/t/t_case_x_bad.pl0000775000177100017500000000133012473477707021451 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Warning-CASEX: t/t_case_x_bad.v:\d+: Suggest casez \(with \?\'s\) in place of casex \(with X\'s\) .*%Warning-CASEWITHX: t/t_case_x_bad.v:\d+: Use of x/\? constant in case statement, \(perhaps intended casex/casez\) .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_file_scan.v0000664000177100017500000000173212473477707022057 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. `include "verilated.v" module t; `verilator_file_descriptor infile, outfile; integer count, a; initial begin infile = $fopen("t/t_sys_file_scan_input.dat", "r"); outfile = $fopen("obj_dir/t_sys_file_scan/t_sys_file_scan_test.log", "w"); count = 1234; `ifdef TEST_VERBOSE $display("-count == %0d, infile %d, outfile %d", count, infile, outfile); `endif count = $fscanf(infile, "%d\n", a); `ifdef TEST_VERBOSE // Ifdefing this out gave bug248 $display("-count == %0d, infile %d, outfile %d", count, infile, outfile); `endif if (count == 0) $stop; $fwrite(outfile, "# a\n"); $fwrite(outfile, "%d\n", a); $fclose(infile); $fclose(outfile); $write("*-* All Finished *-*\n"); $finish(0); // Test arguments to finish end endmodule verilator-3.874/test_regress/t/t_order_quad.cpp0000664000177100017500000000202312473477707021672 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. #include #include "Vt_order_quad.h" //====================================================================== unsigned int main_time = 0; double sc_time_stamp () { return main_time; } VM_PREFIX* topp = NULL; bool fail = false; void check (QData got, QData exp) { if (got != exp) { VL_PRINTF("%%Error: got=0x%" VL_PRI64 "x exp=0x%" VL_PRI64 "x\n", got, exp); fail = true; } } int main (int argc, char *argv[]) { topp = new VM_PREFIX; Verilated::debug(0); topp->a0 = 0; topp->eval(); check (topp->y, VL_ULL(0x0)); topp->a0 = 15; topp->eval(); check (topp->y, VL_ULL(0x3c00000000)); topp->final(); if (!fail) { VL_PRINTF("*-* All Finished *-*\n"); topp->final(); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results\n"); } return 0; } verilator-3.874/test_regress/t/t_tri_ifbegin.v0000664000177100017500000000172112473477707021515 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module module t (/*AUTOARG*/ // Inputs clk ); input clk; tri pad_io_h; tri pad_io_l; sub sub (.*); endmodule module sub (/*AUTOARG*/ // Inouts pad_io_h, pad_io_l ); parameter USE = 1'b1; parameter DIFFERENTIAL = 1'b1; parameter BIDIR = 1'b1; inout pad_io_h; inout pad_io_l; wire [31:0] dqs_out_dtap_delay; generate if (USE) begin: output_strobe wire aligned_os_oe; wire aligned_strobe; if (BIDIR) begin reg sig_h_r = 1'b0; reg sig_l_r = 1'b0; always @* begin sig_h_r = ~aligned_os_oe ? aligned_strobe : 1'bz; if (DIFFERENTIAL) sig_l_r = ~aligned_os_oe ? ~aligned_strobe : 1'bz; end assign pad_io_h = sig_h_r; if (DIFFERENTIAL) assign pad_io_l = sig_l_r; end end endgenerate endmodule verilator-3.874/test_regress/t/t_math_equal.pl0000775000177100017500000000071712473477707021531 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vlcov_merge.pl0000775000177100017500000000136512473477707021721 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); $Self->_run(cmd=>["../bin/verilator_coverage", "--write", "$Self->{obj_dir}/coverage.dat", "t/t_vlcov_data_a.dat", "t/t_vlcov_data_b.dat", "t/t_vlcov_data_c.dat", "t/t_vlcov_data_d.dat", ], ); ok(files_identical("$Self->{obj_dir}/coverage.dat", "t/$Self->{name}.out")); 1; verilator-3.874/test_regress/t/t_string.v0000664000177100017500000000456312525171734020536 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); `define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=\"%s\" exp=\"%s\"\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [4*8:1] vstr; const string s = "a"; // Check static assignment string s2; string s3; reg eq; // Operators == != < <= > >= {a,b} {a{b}} a[b] // a.len, a.putc, a.getc, a.toupper, a.tolower, a.compare, a.icompare, a.substr // a.atoi, a.atohex, a.atooct, a.atobin, a.atoreal, // a.itoa, a.hextoa, a.octoa, a.bintoa, a.realtoa initial begin $sformat(vstr, "s=%s", s); `checks(vstr, "s=a"); `checks(s, "a"); `checks({s,s,s}, "aaa"); `checks({4{s}}, "aaaa"); // Constification `checkh(s == "a", 1'b1); `checkh(s == "b", 1'b0); `checkh(s != "a", 1'b0); `checkh(s != "b", 1'b1); `checkh(s > " ", 1'b1); `checkh(s > "a", 1'b0); `checkh(s >= "a", 1'b1); `checkh(s >= "b", 1'b0); `checkh(s < "a", 1'b0); `checkh(s < "b", 1'b1); `checkh(s <= " ", 1'b0); `checkh(s <= "a", 1'b1); end // Test loop always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin // Setup s2 = "c0"; end else if (cyc==1) begin $sformat(vstr, "s2%s", s2); `checks(vstr, "s2c0"); end else if (cyc==2) begin s3 = s2; $sformat(vstr, "s2%s", s3); `checks(vstr, "s2c0"); end else if (cyc==3) begin s2 = "a"; s3 = "b"; end else if (cyc==4) begin `checks({s2,s3}, "ab"); `checks({3{s3}}, "bbb"); `checkh(s == "a", 1'b1); `checkh(s == "b", 1'b0); `checkh(s != "a", 1'b0); `checkh(s != "b", 1'b1); `checkh(s > " ", 1'b1); `checkh(s > "a", 1'b0); `checkh(s >= "a", 1'b1); `checkh(s >= "b", 1'b0); `checkh(s < "a", 1'b0); `checkh(s < "b", 1'b1); `checkh(s <= " ", 1'b0); `checkh(s <= "a", 1'b1); end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_func_const_bad.v0000664000177100017500000000234412473477707022205 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; // Speced ignored: system calls. I think this is nasty, so we error instead. // Speced Illegal: inout/output/ref not allowed localparam B1 = f_bad_output(1,2); function integer f_bad_output(input [31:0] a, output [31:0] o); f_bad_output = 0; endfunction // Speced Illegal: void // Speced Illegal: dotted localparam EIGHT = 8; localparam B2 = f_bad_dotted(2); function integer f_bad_dotted(input [31:0] a); f_bad_dotted = t.EIGHT; endfunction // Speced Illegal: ref to non-local var integer modvar; localparam B3 = f_bad_nonparam(3); function integer f_bad_nonparam(input [31:0] a); f_bad_nonparam = modvar; endfunction // Speced Illegal: needs constant function itself // Our own - infinite loop localparam B4 = f_bad_infinite(3); function integer f_bad_infinite(input [31:0] a); while (1) begin f_bad_infinite = 0; end endfunction // Our own - stop localparam BSTOP = f_bad_stop(3); function integer f_bad_stop(input [31:0] a); $stop; endfunction endmodule verilator-3.874/test_regress/t/t_case_write2.pl0000775000177100017500000000121412473477707021611 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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->{golden_out} ||= "t/$Self->{name}.out"; compile ( verilator_flags2 => ["--stats --O3 -x-assign fast"], ); execute ( check_finished=>1, ); ok(files_identical("$Self->{obj_dir}/$Self->{name}_logger.log", $Self->{golden_out})); 1; verilator-3.874/test_regress/t/t_func_const.v0000664000177100017500000000370012473477707021374 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; localparam P4 = f_add(P3,1); localparam P8 = f_add2(P3,P3,f_add(1,1)); localparam P5 = f_while(7); localparam P16 = f_for(P4); localparam P18 = f_case(P4); localparam P6 = f_return(P4); localparam P3 = 3; initial begin `ifdef TEST_VERBOSE $display("P5=%0d P8=%0d P16=%0d P18=%0d",P5,P8,P16,P18); `endif if (P3 !== 3) $stop; if (P4 !== 4) $stop; if (P5 !== 5) $stop; if (P6 !== 6) $stop; if (P8 !== 8) $stop; if (P16 !== 16) $stop; if (P18 !== 18) $stop; $write("*-* All Finished *-*\n"); $finish; end function integer f_add(input [31:0] a, input [31:0] b); f_add = a+b; endfunction // Speced ok: function called from function function integer f_add2(input [31:0] a, input [31:0] b, input [31:0] c); f_add2 = f_add(a,b)+c; endfunction // Speced ok: local variables function integer f_for(input [31:0] a); integer i; integer times; begin times = 1; for (i=0; i1) break; end while (1) begin out = out+1; if (a>1) return 2+out; end f_return = 0; endfunction endmodule verilator-3.874/test_regress/t/t_select_bad_range2.v0000664000177100017500000000207212473477707022557 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [1:0] in; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [1:0] out10; // From test of Test.v wire [1:0] out32; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out32 (out32[1:0]), .out10 (out10[1:0]), // Inputs .in (in[1:0])); // Test loop always @ (posedge clk) begin in <= in + 1; `ifdef TEST_VERBOSE $write("[%0t] in=%d out32=%d out10=%d\n",$time, in, out32, out10); `endif if (in==3) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out32, out10, // Inputs in ); input [1:0] in; output [1:0] out32; output [1:0] out10; assign out32 = in[3:2]; assign out10 = in[1:0]; endmodule verilator-3.874/test_regress/t/t_mem_slice.pl0000775000177100017500000000071712473477707021346 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_program.pl0000775000177100017500000000071712473477707021060 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_if.pl0000775000177100017500000000073412473477707020637 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( ); ok(1); 1; verilator-3.874/test_regress/t/t_math_pow2.pl0000775000177100017500000000072212473477707021305 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_twod.pl0000775000177100017500000000072712473477707022407 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_declfilename.pl0000775000177100017500000000111212473477707023035 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( v_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_bad.pl0000775000177100017500000000222512473477707021146 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_func_bad.v:\d+: Missing argument on non-defaulted argument 'from2' in function call to FUNC 'add' %Error: t/t_func_bad.v:\d+: Too many arguments in function call to FUNC 'add' %Error: t/t_func_bad.v:\d+: Missing argument on non-defaulted argument 'y' in function call to TASK 'x' %Error: t/t_func_bad.v:\d+: Unsupported: Function output argument 'y' requires 1 bits, but connection's CONST '.*' generates 32 bits. %Error: t/t_func_bad.v:\d+: No such argument 'no_such' in function call to FUNC 'f' %Error: t/t_func_bad.v:\d+: Duplicate argument 'dup' in function call to FUNC 'f' %Error: t/t_func_bad.v:\d+: Too many arguments in function call to FUNC 'f' %Error: Exiting due to}, ); ok(1); 1; verilator-3.874/test_regress/t/t_cast.v0000664000177100017500000000336712534630412020154 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t; typedef logic [3:0] mc_t; typedef mc_t tocast_t; mc_t o; logic [15:0] allones = 16'hffff; parameter FOUR = 4; // bug925 localparam [6:0] RESULT = 7'((6*9+92)%96); logic signed [14:0] samp0 = 15'h0000; logic signed [14:0] samp1 = 15'h0000; logic signed [14:0] samp2 = 15'h6000; logic signed [11:0] coeff0 = 12'h009; logic signed [11:0] coeff1 = 12'h280; logic signed [11:0] coeff2 = 12'h4C5; logic signed [26:0] mida = ((27'(coeff2 * samp2) >>> 11)); // verilator lint_off WIDTH logic signed [26:0] midb = 15'((27'(coeff2 * samp2) >>> 11)); // verilator lint_on WIDTH logic signed [14:0] outa = 15'((27'(coeff0 * samp0) >>> 11) + // 27' size casting in order for intermediate result to not be truncated to the width of LHS vector (27'(coeff1 * samp1) >>> 11) + (27'(coeff2 * samp2) >>> 11)); // 15' size casting to avoid synthesis/simulator warnings initial begin if (4'shf > 4'sh0) $stop; if (signed'(4'hf) > 4'sh0) $stop; if (4'hf < 4'h0) $stop; if (unsigned'(4'shf) < 4'h0) $stop; if (4'(allones) !== 4'hf) $stop; if (6'(allones) !== 6'h3f) $stop; if ((4)'(allones) !== 4'hf) $stop; if ((4+2)'(allones) !== 6'h3f) $stop; if ((4-2)'(allones) !== 2'h3) $stop; if ((FOUR+2)'(allones) !== 6'h3f) $stop; if (50 !== RESULT) $stop; o = tocast_t'(4'b1); if (o != 4'b1) $stop; if (15'h6cec != outa) $stop; if (27'h7ffecec != mida) $stop; if (27'h7ffecec != midb) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_sv_bus_mux_demux/0000775000177100017500000000000012534632371022424 5ustar wsnyderwsnyderverilator-3.874/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_wrap.sv0000664000177100017500000000646412473477707027451 0ustar wsnyderwsnyder//////////////////////////////////////////////////////////////////////////////// // // // This file is placed into the Public Domain, for any use, without warranty. // // 2012 by Iztok Jeras // // // //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // // This wrapper contains a bus multiplexer and a bus demultiplexer. Both // // modules have all ports exposed an there are no signals connecting them. // // // // --------------------- // // | wrap | // // | | // // | ----------- | // // bsi -> | -> | mux | -> | -> sto // // | ----------- | // // | | // // | ----------- | // // bso <- | <- | demux | <- | <- sto // // | ----------- | // // | | // // --------------------- // // // //////////////////////////////////////////////////////////////////////////////// module sv_bus_mux_demux_wrap ( // system signals input logic clk, input logic rst, // input bus input logic bsi_vld, // valid (chip select) input logic [31:0] bsi_adr, // address input logic [31:0] bsi_dat, // data output logic bsi_rdy, // ready (acknowledge) // output stream output logic sto_vld, output logic [7:0] sto_bus, input logic sto_rdy, // input stream input logic sti_vld, input logic [7:0] sti_bus, output logic sti_rdy, // output bus output logic bso_vld, // valid (chip select) output logic [31:0] bso_adr, // address output logic [31:0] bso_dat, // data input logic bso_rdy // ready (acknowledge) ); sv_bus_mux_demux_mux mux ( // system signals .clk (clk), .rst (rst), // input bus .bus_vld (bsi_vld), .bus_adr (bsi_adr), .bus_dat (bsi_dat), .bus_rdy (bsi_rdy), // output stream .str_vld (sto_vld), .str_bus (sto_bus), .str_rdy (sto_rdy) ); sv_bus_mux_demux_demux demux ( // system signals .clk (clk), .rst (rst), // input stream .str_vld (sti_vld), .str_bus (sti_bus), .str_rdy (sti_rdy), // output bus .bus_vld (bso_vld), .bus_adr (bso_adr), .bus_dat (bso_dat), .bus_rdy (bso_rdy) ); endmodule : sv_bus_mux_demux_wrap verilator-3.874/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_demux.sv0000664000177100017500000000435612473477707027620 0ustar wsnyderwsnyder//////////////////////////////////////////////////////////////////////////////// // // // This file is placed into the Public Domain, for any use, without warranty. // // 2012 by Iztok Jeras // // // //////////////////////////////////////////////////////////////////////////////// import package_bus::*; import package_str::*; module sv_bus_mux_demux_demux ( // system signals input logic clk, // clock input logic rst, // reset // output stream input logic str_vld, // valid (chip select) input logic [7:0] str_bus, // byte data bus output logic str_rdy, // ready (acknowledge) // input bus output logic bus_vld, // valid (chip select) output logic [31:0] bus_adr, // address output logic [31:0] bus_dat, // data input logic bus_rdy // ready (acknowledge) ); logic bus_trn; // bus data transfer logic str_trn; // stream data transfer logic [2:0] pkt_cnt; // packet byte counter logic pkt_end; // packet byte counter end t_str pkt_str; // transfer packet as a structure t_bus pkt_bus; // transfer packet as an array // stream data transfer assign str_trn = str_vld & str_rdy; // ready if pipe is empty or output is ready assign str_rdy = ~bus_vld | bus_rdy; // packet byte counter always @ (posedge clk, posedge rst) if (rst) pkt_cnt <= 3'd0; else if (str_trn) pkt_cnt <= pkt_cnt + 3'd1; // packet byte counter end assign pkt_end = (&pkt_cnt); always @ (posedge clk) if (str_trn) pkt_str [pkt_cnt] <= str_bus; // the input packed array is mapped onto the output structure assign pkt_bus = pkt_str; // the output structure is mapped onto address/data outputs assign bus_adr = pkt_bus.adr; assign bus_dat = pkt_bus.dat; // output valid is set on the last input packed byte // or cleared by each output transfer always @ (posedge clk, posedge rst) if (rst) bus_vld <= 1'b0; else bus_vld <= str_trn & pkt_end | bus_vld & ~bus_rdy; // bus data transfer assign bus_trn = bus_vld & bus_rdy; endmodule : sv_bus_mux_demux_demux verilator-3.874/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_mux.sv0000664000177100017500000000444212473477707027303 0ustar wsnyderwsnyder//////////////////////////////////////////////////////////////////////////////// // // // This file is placed into the Public Domain, for any use, without warranty. // // 2012 by Iztok Jeras // // // //////////////////////////////////////////////////////////////////////////////// import package_bus::*; import package_str::*; import package_uni::*; module sv_bus_mux_demux_mux ( // system signals input logic clk, // clock input logic rst, // reset // input bus input logic bus_vld, // valid (chip select) input logic [31:0] bus_adr, // address input logic [31:0] bus_dat, // data output logic bus_rdy, // ready (acknowledge) // output stream output logic str_vld, // valid (chip select) output logic [7:0] str_bus, // byte data bus input logic str_rdy // ready (acknowledge) ); logic bus_trn; // bus data transfer logic str_trn; // stream data transfer logic [2:0] pkt_cnt; // packet byte counter logic pkt_end; // packet byte counter end //t_bus pkt_bus; // transfer packet as a structure //t_str pkt_str; // transfer packet as an array t_uni pkt_uni; // transfer packet as an union // bus data transfer assign bus_trn = bus_vld & bus_rdy; // ready if pipe is empty or output is ready assign bus_rdy = ~str_vld | pkt_end; // writing input address/data into a structure always @ (posedge clk) if (bus_trn) begin pkt_uni.bus.adr <= bus_adr; pkt_uni.bus.dat <= bus_dat; end // output valid is set by an input transfer // or cleared by the last output transfer always @ (posedge clk, posedge rst) if (rst) str_vld <= 1'b0; else str_vld <= bus_trn | (str_vld & ~pkt_end); // packet byte counter always @ (posedge clk, posedge rst) if (rst) pkt_cnt <= 4'd0; else if (str_trn) pkt_cnt <= pkt_cnt + 3'd1; // packet byte counter end assign pkt_end = str_rdy & (&pkt_cnt); // TODO, this should be a registered signal assign str_bus = pkt_uni.str [pkt_cnt]; // stream data transfer assign str_trn = str_vld & str_rdy; endmodule : sv_bus_mux_demux_mux verilator-3.874/test_regress/t/t_sv_bus_mux_demux/sv_bus_mux_demux_def.sv0000664000177100017500000000200212473477707027216 0ustar wsnyderwsnyder//////////////////////////////////////////////////////////////////////////////// // // // This file is placed into the Public Domain, for any use, without warranty. // // 2012 by Iztok Jeras // // // //////////////////////////////////////////////////////////////////////////////// // definition of data bus structure package package_bus; typedef struct packed { logic [3:0] [7:0] adr; // address logic [3:0] [7:0] dat; // data } t_bus; endpackage : package_bus // definition of streaming bus packet as an array package package_str; typedef logic [7:0][7:0] t_str; endpackage : package_str // union of the structure and array representation package package_uni; import package_bus::*; import package_str::*; typedef union packed { t_bus bus; t_str str; } t_uni; endpackage : package_uni verilator-3.874/test_regress/t/t_inst_comma.v0000664000177100017500000000307112525171734021352 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; parameter ONE = 1; wire [17:10] bitout; reg [7:0] allbits; reg [15:0] onebit; sub #(1) sub0 (allbits, onebit[1:0], bitout[10]), sub1 (allbits, onebit[3:2], bitout[11]), sub2 (allbits, onebit[5:4], bitout[12]), sub3 (allbits, onebit[7:6], bitout[13]), sub4 (allbits, onebit[9:8], bitout[14]), sub5 (allbits, onebit[11:10], bitout[15]), sub6 (allbits, onebit[13:12], bitout[16]), sub7 (allbits, onebit[15:14], bitout[17]); integer x; always @ (posedge clk) begin //$write("%x\n", bitout); if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin allbits <= 8'hac; onebit <= 16'hc01a; end if (cyc==2) begin if (bitout !== 8'h07) $stop; allbits <= 8'hca; onebit <= 16'h1f01; end if (cyc==3) begin if (bitout !== 8'h41) $stop; if (sub0.bitout !== 1'b1) $stop; if (sub1.bitout !== 1'b0) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule `ifdef USE_INLINE `define INLINE_MODULE /*verilator inline_module*/ `else `define INLINE_MODULE /*verilator public_module*/ `endif module sub (input [7:0] allbits, input [1:0] onebit, output bitout); `INLINE_MODULE parameter integer P = 0; initial if (P != 1) $stop; wire bitout = (^ onebit) ^ (^ allbits); endmodule verilator-3.874/test_regress/t/t_var_bad_hide2.v0000664000177100017500000000067512473477707021714 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; // Arguable, but we won't throw a hidden warning on tcp_port parameter tcp_port = 5678; import "DPI-C" function int dpii_func ( input integer tcp_port, output longint obj ); // 't' is hidden: integer t; endmodule verilator-3.874/test_regress/t/t_EXAMPLE.v0000664000177100017500000000454412525171734020322 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Use this file as a template for submitting bugs, etc. // This module takes a single clock input, and should either // $write("*-* All Finished *-*\n"); // $finish; // on success, or $stop. // // The code as shown applies a random vector to the Test // module, then calculates a CRC on the Test module's outputs. // // **If you do not wish for your code to be released to the public // please note it here, otherwise:** // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by ____YOUR_NAME_HERE____. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[31:0]), // Inputs .clk (clk), .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h4afe43fb79d7b71e if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); // Replace this module with the device under test. // // Change the code in the t module to apply values to the inputs and // merge the output values into the result vector. input clk; input [31:0] in; output reg [31:0] out; always @(posedge clk) begin out <= in; end endmodule verilator-3.874/test_regress/t/t_gen_for0.pl0000775000177100017500000000071712473477707021110 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_no_parentheses.v0000664000177100017500000000266112473477707023435 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. // // This is a copy of t_param.v with the parentheses around the module parameters // removed. module t (/*AUTOARG*/ // Inputs clk ); parameter PAR = 3; m1 #PAR m1(); m3 #PAR m3(); mnooverride #10 mno(); input clk; integer cyc=1; reg [4:0] bitsel; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin bitsel = 0; if (PAR[bitsel]!==1'b1) $stop; bitsel = 1; if (PAR[bitsel]!==1'b1) $stop; bitsel = 2; if (PAR[bitsel]!==1'b0) $stop; end if (cyc==1) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module m1; localparam PAR1MINUS1 = PAR1DUP-2-1; localparam PAR1DUP = PAR1+2; // Check we propagate parameters properly parameter PAR1 = 0; m2 #PAR1MINUS1 m2 (); endmodule module m2; parameter PAR2 = 10; initial begin $display("%x",PAR2); if (PAR2 !== 2) $stop; end endmodule module m3; localparam LOC = 13; parameter PAR = 10; initial begin $display("%x %x",LOC,PAR); if (LOC !== 13) $stop; if (PAR !== 3) $stop; end endmodule module mnooverride; localparam LOC = 13; parameter PAR = 10; initial begin $display("%x %x",LOC,PAR); if (LOC !== 13) $stop; if (PAR !== 10) $stop; end endmodule verilator-3.874/test_regress/t/t_math_reverse.v0000664000177100017500000000411712473477707021722 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [7:0] crc; // Build up assignments wire [7:0] bitrev; assign bitrev[7] = crc[0]; assign bitrev[6] = crc[1]; assign bitrev[5] = crc[2]; assign bitrev[4] = crc[3]; assign bitrev[0] = crc[7]; assign bitrev[1] = crc[6]; assign bitrev[2] = crc[5]; assign bitrev[3] = crc[4]; // Build up always assignments reg [7:0] bitrevb; always @ (/*AS*/crc) begin bitrevb[7] = crc[0]; bitrevb[6] = crc[1]; bitrevb[5] = crc[2]; bitrevb[4] = crc[3]; bitrevb[0] = crc[7]; bitrevb[1] = crc[6]; bitrevb[2] = crc[5]; bitrevb[3] = crc[4]; end // Build up always assignments reg [7:0] bitrevr; always @ (posedge clk) begin bitrevr[7] <= crc[0]; bitrevr[6] <= crc[1]; bitrevr[5] <= crc[2]; bitrevr[4] <= crc[3]; bitrevr[0] <= crc[7]; bitrevr[1] <= crc[6]; bitrevr[2] <= crc[5]; bitrevr[3] <= crc[4]; end always @ (posedge clk) begin if (cyc!=0) begin cyc<=cyc+1; //$write("cyc=%0d crc=%x r=%x\n", cyc, crc, bitrev); crc <= {crc[6:0], ~^ {crc[7],crc[5],crc[4],crc[3]}}; if (cyc==1) begin crc <= 8'hed; end if (cyc==2 && bitrev!=8'hb7) $stop; if (cyc==3 && bitrev!=8'h5b) $stop; if (cyc==4 && bitrev!=8'h2d) $stop; if (cyc==5 && bitrev!=8'h16) $stop; if (cyc==6 && bitrev!=8'h8b) $stop; if (cyc==7 && bitrev!=8'hc5) $stop; if (cyc==8 && bitrev!=8'he2) $stop; if (cyc==9 && bitrev!=8'hf1) $stop; if (bitrevb != bitrev) $stop; if (cyc==3 && bitrevr!=8'hb7) $stop; if (cyc==4 && bitrevr!=8'h5b) $stop; if (cyc==5 && bitrevr!=8'h2d) $stop; if (cyc==6 && bitrevr!=8'h16) $stop; if (cyc==7 && bitrevr!=8'h8b) $stop; if (cyc==8 && bitrevr!=8'hc5) $stop; if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_tri_various.v0000664000177100017500000001076612473477707021613 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks module t (clk); input clk; reg [31:0] state; initial state=0; wire A = state[0]; wire OE = state[1]; wire Z1, Z2, Z3, Z4, Z5, Z6, Z7, Z8, Z9; wire [3:0] Z10; wire Z11; Test1 test1(/*AUTOINST*/ // Inouts .Z1 (Z1), // Inputs .OE (OE), .A (A)); Test2 test2(/*AUTOINST*/ // Inouts .Z2 (Z2), // Inputs .OE (OE), .A (A)); Test3 test3(/*AUTOINST*/ // Inouts .Z3 (Z3), // Inputs .OE (OE), .A (A)); Test4 test4(/*AUTOINST*/ // Outputs .Z4 (Z4), // Inouts .Z5 (Z5)); Test5 test5(/*AUTOINST*/ // Inouts .Z6 (Z6), .Z7 (Z7), .Z8 (Z8), .Z9 (Z9), // Inputs .OE (OE)); Test6 test6(/*AUTOINST*/ // Inouts .Z10 (Z10[3:0]), // Inputs .OE (OE)); Test7 test7(/*AUTOINST*/ // Outputs .Z11 (Z11), // Inputs .state (state[2:0])); always @(posedge clk) begin state <= state + 1; `ifdef TEST_VERBOSE $write("[%0t] state=%d Z1=%b 2=%b 3=%b 4=%b 5=%b 6=%b 7=%b 8=%b 9=%b 10=%b 11=%b\n", $time, state, Z1,Z2,Z3,Z4,Z5,Z6,Z7,Z8,Z9,Z10,Z11); `endif if(state == 0) begin if(Z1 !== 1'b1) $stop; // tests pullups if(Z2 !== 1'b1) $stop; if(Z3 !== 1'b1) $stop; `ifndef VERILATOR if(Z4 !== 1'b1) $stop; `endif if(Z5 !== 1'b1) $stop; if(Z6 !== 1'b1) $stop; if(Z7 !== 1'b0) $stop; if(Z8 !== 1'b0) $stop; if(Z9 !== 1'b1) $stop; if(Z10 !== 4'b0001) $stop; if(Z11 !== 1'b0) $stop; end else if(state == 1) begin if(Z1 !== 1'b1) $stop; // tests pullup if(Z2 !== 1'b1) $stop; if(Z3 !== 1'b1) $stop; `ifndef VERILATOR if(Z4 !== 1'b1) $stop; `endif if(Z5 !== 1'b1) $stop; if(Z6 !== 1'b1) $stop; if(Z7 !== 1'b0) $stop; if(Z8 !== 1'b0) $stop; if(Z9 !== 1'b1) $stop; if(Z10 !== 4'b0001) $stop; if(Z11 !== 1'b1) $stop; end else if(state == 2) begin if(Z1 !== 1'b0) $stop; // tests output driver low if(Z2 !== 1'b0) $stop; if(Z3 !== 1'b1 && Z3 !== 1'bx) $stop; // Conflicts `ifndef VERILATOR if(Z4 !== 1'b1) $stop; `endif if(Z5 !== 1'b1) $stop; if(Z6 !== 1'b0) $stop; if(Z7 !== 1'b1) $stop; if(Z8 !== 1'b1) $stop; if(Z9 !== 1'b0) $stop; if(Z10 !== 4'b0010) $stop; //if(Z11 !== 1'bx) $stop; // Doesn't matter end else if(state == 3) begin if(Z1 !== 1'b1) $stop; // tests output driver high if(Z2 !== 1'b1) $stop; if(Z3 !== 1'b1) $stop; `ifndef VERILATOR if(Z4 !== 1'b1) $stop; `endif if(Z5 !== 1'b1) $stop; if(Z6 !== 1'b0) $stop; if(Z7 !== 1'b1) $stop; if(Z8 !== 1'b1) $stop; if(Z9 !== 1'b0) $stop; if(Z10 !== 4'b0010) $stop; if(Z11 !== 1'b1) $stop; end else if(state == 4) begin $write("*-* All Finished *-*\n"); $finish; end end pullup(Z1); pullup(Z2); pullup(Z3); pullup(Z4); pullup(Z5); pullup(Z6); pulldown(Z7); pullup(Z8); pulldown(Z9); pulldown pd10[3:0] (Z10); endmodule module Test1(input OE, input A, inout Z1); assign Z1 = (OE) ? A : 1'bz; endmodule module Test2(input OE, input A, inout Z2); assign Z2 = (OE) ? A : 1'bz; endmodule // mixed low-Z and tristate module Test3(input OE, input A, inout Z3); assign Z3 = (OE) ? A : 1'bz; assign Z3 = 1'b1; endmodule // floating output and inout `ifndef VERILATOR // Note verilator doesn't know to make Z4 a tristate unless marked an inout `endif module Test4(output Z4, inout Z5); endmodule // AND gate tristates module Test5(input OE, inout Z6, inout Z7, inout Z8, inout Z9); assign Z6 = (OE) ? 1'b0 : 1'bz; assign Z7 = (OE) ? 1'b1 : 1'bz; assign Z8 = (OE) ? 1'bz : 1'b0; assign Z9 = (OE) ? 1'bz : 1'b1; endmodule // AND gate tristates module Test6(input OE, inout [3:0] Z10); wire [1:0] i; Test6a a (.OE(OE), .Z({Z10[0],Z10[1]})); Test6a b (.OE(~OE), .Z({Z10[2],Z10[0]})); endmodule module Test6a(input OE, inout [1:0] Z); assign Z = (OE) ? 2'b01 : 2'bzz; endmodule module Test7(input [2:0] state, output reg Z11); always @(*) begin casez (state) 3'b000: Z11 = 1'b0; 3'b0?1: Z11 = 1'b1; default: Z11 = 1'bx; endcase end endmodule // This is not implemented yet //module Test3(input OE, input A, inout Z3); // always @(*) begin // if(OE) begin // Z3 = A; // end else begin // Z3 = 1'bz; // end // end //endmodule verilator-3.874/test_regress/t/t_sys_readmem_bad_addr.v0000664000177100017500000000052512473477707023345 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; reg [175:0] hex [15:0]; initial begin $readmemh("t/t_sys_readmem_bad_addr.mem", hex); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_lint_syncasyncnet_bad.pl0000775000177100017500000000200412473477707023755 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME --if-depth 10"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: Signal flopped as both synchronous and async: rst_both_l %Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: ... Location of async usage %Warning-SYNCASYNCNET: t/t_lint_syncasyncnet_bad.v:\d+: ... Location of sync usage %Warning-SYNCASYNCNET: Use .* around source to disable this message. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_param_ddeep_width.pl0000775000177100017500000000103412473477707023042 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_crc.v0000664000177100017500000002117312473477707021021 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [63:0] d; reg [31:0] c; wire [31:0] q = crc (d, c); reg [31:0] q_r; integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; q_r <= q; c <= q; d <= {d[62:0], ^d[63:48]}; //$write("%d crc(%x,%x)=%x\n", cyc, d, c, q); if (cyc==1) begin // Assign inputs randomly q_r <= 32'h12345678; c <= 32'h12345678; d <= 64'hffffffff_ffffffff; end if (cyc==2) begin d <= 64'hffffffff_ffffffff; end if (cyc==3) begin d <= 64'hffffffff_ffffffff; end if (cyc==4) begin d <= 64'h50183721_81a04b1a; end if (cyc==5) begin end if (cyc==9) begin if (q !== 32'h38295e96) $stop; $write("*-* All Finished *-*\n"); $finish; end end end function [31:0] crc; input [63:0] di; input [31:0] ci; reg [63:0] drev; begin drev = reverse(di); crc = newcrc(drev, ci); end endfunction function [63:0] reverse; input [63:0] di; integer i; begin reverse = 64'b0; for (i=0; i<64; i=i+1) reverse[i] = di[63-i]; end endfunction function [31:0] newcrc; input [63:0] D; input [31:0] C; reg [31:0] N; reg [31:0] DT; begin N = 32'b0; // Note this isn't a real CRC code; it's been munged for privacy N[0] = D[59]^D[53]^D[52]^D[49]^D[44]^D[41]^D[40]^D[39]^D[37]^D[32]^D[29]^D[26]^D[22]^D[21]^D[20]^D[16]^D[15]^D[14]^D[9]^D[7]^D[0] ^C[29]^C[27]^C[24]^C[23]^C[22]^C[21]^C[19]^C[15]^C[13]^C[10]^C[8]^C[3]^C[1]; N[1] = D[61]^D[57]^D[51]^D[47]^D[43]^D[37]^D[35]^D[32]^D[28]^D[24]^D[22]^D[21]^D[20]^D[16]^D[12]^D[11]^D[10]^D[8]^D[7]^D[6]^D[1]^D[0] ^C[30]^C[27]^C[26]^C[20]^C[16]^C[14]^C[13]^C[11]^C[10]^C[8]^C[5]^C[0]; N[2] = D[63]^D[62]^D[61]^D[60]^D[55]^D[54]^D[52]^D[44]^D[43]^D[42]^D[37]^D[34]^D[33]^D[29]^D[28]^D[25]^D[24]^D[23]^D[22]^D[18]^D[16]^D[15]^D[13]^D[12]^D[11] ^C[31]^C[30]^C[27]^C[22]^C[21]^C[18]^C[15]^C[12]^C[11]^C[10]^C[7]; N[3] = D[62]^D[54]^D[50]^D[47]^D[46]^D[38]^D[36]^D[35]^D[34]^D[33]^D[32]^D[30]^D[27]^D[25]^D[21]^D[20]^D[19]^D[17]^D[15]^D[11]^D[8]^D[5]^D[3]^D[1]^D[0] ^C[28]^C[25]^C[24]^C[13]^C[11]^C[9]^C[8]^C[7]^C[3]^C[1]; N[4] = D[57]^D[54]^D[53]^D[52]^D[45]^D[44]^D[43]^D[39]^D[37]^D[34]^D[33]^D[32]^D[31]^D[28]^D[24]^D[23]^D[20]^D[19]^D[15]^D[14]^D[10]^D[6]^D[1]^D[0] ^C[30]^C[24]^C[20]^C[16]^C[14]^C[11]^C[8]^C[7]^C[6]^C[5]^C[2]; N[5] = D[58]^D[57]^D[50]^D[49]^D[48]^D[47]^D[43]^D[39]^D[29]^D[26]^D[23]^D[22]^D[20]^D[18]^D[14]^D[10]^D[9]^D[6]^D[5]^D[4]^D[1] ^C[27]^C[24]^C[20]^C[19]^C[18]^C[14]^C[13]^C[12]^C[11]^C[8]^C[7]^C[1]; N[6] = D[63]^D[62]^D[61]^D[57]^D[51]^D[50]^D[47]^D[38]^D[37]^D[34]^D[30]^D[28]^D[27]^D[25]^D[21]^D[16]^D[15]^D[10]^D[9]^D[6]^D[5]^D[2]^D[1] ^C[31]^C[27]^C[25]^C[16]^C[13]^C[9]^C[8]^C[7]^C[0]; N[7] = ^D[62]^D[61]^D[59]^D[54]^D[52]^D[51]^D[49]^D[46]^D[45]^D[42]^D[41]^D[38]^D[35]^D[29]^D[26]^D[24]^D[15]^D[12]^D[11]^D[9]^D[2]^D[0] ^C[28]^C[27]^C[26]^C[20]^C[19]^C[18]^C[15]^C[12]^C[7]^C[4]; N[8] = D[62]^D[61]^D[60]^D[59]^D[52]^D[50]^D[48]^D[47]^D[46]^D[45]^D[44]^D[42]^D[41]^D[40]^D[30]^D[24]^D[23]^D[22]^D[19]^D[17]^D[11]^D[10]^D[7]^D[6]^D[2] ^C[31]^C[29]^C[27]^C[22]^C[21]^C[19]^C[17]^C[11]^C[9]^C[7]^C[6]; N[9] = D[62]^D[59]^D[58]^D[57]^D[54]^D[51]^D[50]^D[43]^D[41]^D[39]^D[28]^D[25]^D[24]^D[23]^D[22]^D[21]^D[18]^D[16]^D[15]^D[7] ^C[30]^C[29]^C[27]^C[25]^C[23]^C[22]^C[13]^C[12]^C[7]^C[6]^C[5]^C[1]; N[10] = D[61]^D[60]^D[58]^D[56]^D[54]^D[53]^D[51]^D[48]^D[46]^D[43]^D[42]^D[38]^D[37]^D[35]^D[33]^D[31]^D[30]^D[27]^D[26]^D[24]^D[19]^D[10]^D[8]^D[6]^D[1] ^C[31]^C[30]^C[26]^C[25]^C[24]^C[21]^C[16]^C[12]^C[3]^C[2]; N[11] = D[59]^D[57]^D[56]^D[50]^D[49]^D[48]^D[47]^D[46]^D[45]^D[42]^D[41]^D[40]^D[33]^D[32]^D[30]^D[25]^D[21]^D[15]^D[14]^D[13]^D[12]^D[11]^D[5]^D[1] ^C[27]^C[25]^C[24]^C[21]^C[16]^C[12]^C[7]^C[3]^C[2]^C[1]; N[12] = D[62]^D[61]^D[59]^D[58]^D[56]^D[55]^D[53]^D[48]^D[47]^D[44]^D[43]^D[35]^D[31]^D[30]^D[28]^D[24]^D[23]^D[21]^D[14]^D[5]^D[2] ^C[28]^C[26]^C[25]^C[23]^C[22]^C[18]^C[16]^C[15]^C[6]; N[13] = D[63]^D[60]^D[58]^D[57]^D[55]^D[54]^D[53]^D[51]^D[47]^D[45]^D[42]^D[41]^D[38]^D[28]^D[26]^D[25]^D[22]^D[20]^D[18]^D[17]^D[15]^D[13]^D[12]^D[11] ^C[29]^C[28]^C[25]^C[22]^C[19]^C[17]^C[16]^C[15]^C[14]^C[12]^C[10]^C[9]; N[14] = D[58]^D[56]^D[55]^D[52]^D[47]^D[43]^D[41]^D[40]^D[39]^D[38]^D[30]^D[26]^D[25]^D[22]^D[19]^D[17]^D[13]^D[11]^D[10]^D[9]^D[8]^D[3]^D[2]^D[0] ^C[31]^C[28]^C[20]^C[18]^C[17]^C[16]^C[15]^C[13]^C[11]^C[4]^C[2]^C[1]; N[15] = D[63]^D[62]^D[61]^D[59]^D[58]^D[48]^D[47]^D[43]^D[42]^D[35]^D[28]^D[26]^D[25]^D[24]^D[23]^D[22]^D[21]^D[20]^D[19]^D[17]^D[11]^D[7]^D[2] ^C[30]^C[29]^C[27]^C[24]^C[20]^C[17]^C[16]^C[15]^C[11]^C[9]^C[5]; N[16] = D[60]^D[57]^D[49]^D[46]^D[45]^D[43]^D[39]^D[36]^D[32]^D[30]^D[29]^D[28]^D[27]^D[26]^D[23]^D[20]^D[19]^D[17]^D[11]^D[8]^D[5]^D[1] ^C[28]^C[26]^C[23]^C[22]^C[18]^C[16]^C[13]^C[12]^C[10]^C[9]^C[6]; N[17] = D[63]^D[62]^D[61]^D[60]^D[58]^D[54]^D[53]^D[51]^D[48]^D[42]^D[41]^D[37]^D[36]^D[34]^D[28]^D[27]^D[26]^D[24]^D[13]^D[12]^D[9]^D[7]^D[4]^D[0] ^C[31]^C[30]^C[27]^C[23]^C[20]^C[17]^C[14]^C[9]^C[6]^C[4]^C[3]^C[0]; N[18] = D[63]^D[61]^D[59]^D[56]^D[52]^D[50]^D[47]^D[42]^D[37]^D[35]^D[34]^D[31]^D[30]^D[29]^D[22]^D[19]^D[17]^D[16]^D[11]^D[9]^D[8]^D[7] ^C[26]^C[22]^C[20]^C[19]^C[16]^C[11]^C[8]^C[6]^C[5]^C[0]; N[19] = D[62]^D[60]^D[52]^D[49]^D[44]^D[43]^D[42]^D[37]^D[33]^D[32]^D[29]^D[26]^D[19]^D[17]^D[16]^D[12]^D[10]^D[7]^D[6]^D[4]^D[3]^D[2] ^C[30]^C[29]^C[26]^C[25]^C[22]^C[19]^C[14]^C[7]^C[6]^C[5]^C[2]^C[0]; N[20] = D[63]^D[58]^D[54]^D[48]^D[47]^D[40]^D[39]^D[35]^D[34]^D[32]^D[31]^D[28]^D[27]^D[25]^D[18]^D[12]^D[9]^D[7]^D[5]^D[4]^D[3]^D[2]^D[1] ^C[31]^C[29]^C[28]^C[25]^C[19]^C[18]^C[17]^C[15]^C[10]^C[9]^C[6]^C[4]; N[21] = D[61]^D[59]^D[57]^D[56]^D[53]^D[48]^D[44]^D[43]^D[41]^D[35]^D[29]^D[26]^D[25]^D[20]^D[18]^D[17]^D[16]^D[12]^D[9]^D[6]^D[5]^D[3]^D[1] ^C[30]^C[27]^C[24]^C[23]^C[22]^C[21]^C[20]^C[13]^C[9]^C[3]^C[2]; N[22] = D[63]^D[62]^D[60]^D[57]^D[53]^D[51]^D[45]^D[44]^D[42]^D[34]^D[33]^D[27]^D[20]^D[19]^D[18]^D[15]^D[10]^D[9]^D[8]^D[4]^D[3] ^C[24]^C[23]^C[18]^C[17]^C[16]^C[14]^C[12]^C[11]^C[10]^C[9]^C[6]^C[5]; N[23] = D[58]^D[56]^D[54]^D[51]^D[47]^D[43]^D[42]^D[40]^D[37]^D[36]^D[33]^D[25]^D[23]^D[20]^D[18]^D[16]^D[15]^D[12]^D[10]^D[8]^D[7]^D[5]^D[3] ^C[31]^C[27]^C[26]^C[23]^C[21]^C[18]^C[15]^C[11]^C[10]^C[8]^C[7]^C[1]; N[24] = D[60]^D[59]^D[52]^D[50]^D[48]^D[44]^D[39]^D[36]^D[35]^D[31]^D[30]^D[28]^D[27]^D[23]^D[22]^D[21]^D[19]^D[14]^D[13]^D[12]^D[9]^D[4]^D[1]^D[0] ^C[27]^C[25]^C[23]^C[21]^C[17]^C[11]^C[10]^C[4]^C[0]; N[25] = D[61]^D[60]^D[56]^D[54]^D[51]^D[46]^D[43]^D[41]^D[40]^D[38]^D[37]^D[36]^D[29]^D[28]^D[27]^D[22]^D[17]^D[15]^D[10]^D[7]^D[4]^D[2] ^C[29]^C[28]^C[26]^C[23]^C[18]^C[14]^C[13]^C[12]^C[11]^C[9]^C[8]^C[6]; N[26] = D[63]^D[62]^D[58]^D[55]^D[54]^D[52]^D[50]^D[39]^D[37]^D[36]^D[35]^D[33]^D[31]^D[29]^D[27]^D[18]^D[14]^D[10]^D[3]^D[2]^D[0] ^C[31]^C[27]^C[26]^C[25]^C[24]^C[21]^C[13]^C[12]^C[10]^C[1]; N[27] = D[62]^D[60]^D[58]^D[56]^D[55]^D[54]^D[51]^D[44]^D[41]^D[36]^D[34]^D[32]^D[31]^D[29]^D[28]^D[27]^D[23]^D[17]^D[12]^D[11]^D[8]^D[6]^D[4]^D[2] ^C[31]^C[30]^C[28]^C[27]^C[23]^C[19]^C[17]^C[16]^C[14]^C[12]^C[11]^C[10]^C[3]; N[28] = D[57]^D[54]^D[53]^D[51]^D[50]^D[48]^D[40]^D[38]^D[34]^D[33]^D[31]^D[30]^D[29]^D[27]^D[23]^D[21]^D[14]^D[9]^D[7]^D[6]^D[5]^D[4]^D[0] ^C[31]^C[30]^C[26]^C[24]^C[15]^C[14]^C[13]^C[7]^C[6]^C[4]^C[3]^C[0]; N[29] = D[62]^D[60]^D[55]^D[46]^D[45]^D[44]^D[43]^D[41]^D[40]^D[35]^D[33]^D[32]^D[30]^D[28]^D[25]^D[23]^D[22]^D[13]^D[8]^D[7]^D[6]^D[5]^D[4]^D[3]^D[1]^D[0] ^C[31]^C[28]^C[27]^C[18]^C[11]^C[8]^C[6]^C[4]^C[2]^C[1]^C[0]; N[30] = D[63]^D[62]^D[59]^D[58]^D[55]^D[52]^D[47]^D[44]^D[36]^D[35]^D[34]^D[31]^D[29]^D[22]^D[21]^D[20]^D[19]^D[15]^D[14]^D[10]^D[6]^D[3]^D[2]^D[0] ^C[28]^C[25]^C[24]^C[22]^C[20]^C[15]^C[14]^C[12]^C[10]^C[9]^C[4]^C[0]; N[31] = D[61]^D[58]^D[56]^D[55]^D[54]^D[52]^D[51]^D[50]^D[49]^D[42]^D[38]^D[37]^D[36]^D[34]^D[31]^D[30]^D[27]^D[26]^D[23]^D[22]^D[21]^D[19]^D[18]^D[12]^D[0] ^C[28]^C[26]^C[24]^C[21]^C[17]^C[16]^C[14]^C[13]^C[10]^C[8]^C[2]; newcrc = N; end endfunction endmodule verilator-3.874/test_regress/t/t_dpi_var.cpp0000664000177100017500000001132112473477707021172 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "Vt_dpi_var.h" #include "verilated.h" #include "svdpi.h" #include "verilated_syms.h" //====================================================================== struct MyMon { vluint32_t* sigsp[2]; MyMon() { sigsp[0]=NULL; sigsp[1]=NULL; } }; MyMon mons[2]; void mon_register_a(const char* namep, void* sigp, bool isOut) { // Callback from initial block in monitor #ifdef TEST_VERBOSE VL_PRINTF("- mon_register_a(\"%s\", %p, %d);\n", namep, sigp, isOut); #endif mons[0].sigsp[isOut] = (vluint32_t*)sigp; } void mon_do(MyMon* monp) { if (!monp->sigsp[0]) vl_fatal(__FILE__,__LINE__,"","never registered"); if (!monp->sigsp[1]) vl_fatal(__FILE__,__LINE__,"","never registered"); *monp->sigsp[1] = (*(monp->sigsp[0]))+1; #ifdef TEST_VERBOSE VL_PRINTF("- mon_do(%08x(&%p) -> %08x(&%p));\n", *(monp->sigsp[0]), monp->sigsp[0], *(monp->sigsp[1]), monp->sigsp[1]); #endif } void mon_class_name(const char* namep) { #ifdef TEST_VERBOSE VL_PRINTF("- mon_class_name(\"%s\");\n", namep); #endif // Check the C's calling name of "" doesn't lead to extra dots in the name() if (namep && namep[0]=='.') vl_fatal(__FILE__,__LINE__,"", (string("Unexp class name ")+namep).c_str()); } extern "C" void mon_scope_name(const char* namep); void mon_scope_name(const char* namep) { const char* modp = svGetNameFromScope(svGetScope()); #ifdef TEST_VERBOSE VL_PRINTF("- mon_scope_name('%s', \"%s\");\n", modp, namep); #endif if (strcmp(namep,"t.sub")) vl_fatal(__FILE__,__LINE__,"", (string("Unexp scope name ")+namep).c_str()); if (strcmp(modp,"t.sub")) vl_fatal(__FILE__,__LINE__,"", (string("Unexp dpiscope name ")+modp).c_str()); } extern "C" void mon_register_b(const char* namep, int isOut); void mon_register_b(const char* namep, int isOut) { const char* modp = svGetNameFromScope(svGetScope()); #ifdef TEST_VERBOSE VL_PRINTF("- mon_register_b('%s', \"%s\", %d);\n", modp, namep, isOut); #endif // Use scope to get pointer and size of signal const VerilatedScope* scopep = Verilated::dpiScope(); const VerilatedVar* varp = scopep->varFind(namep); if (!varp) { VL_PRINTF("%%Warning: mon_register_b signal not found: \"%s\"\n", namep); } else if (varp->vltype() != VLVT_UINT32) { VL_PRINTF("%%Warning: wrong type for signal: \"%s\"\n", namep); } else { vluint32_t* datap = (vluint32_t*)(varp->datap()); VL_PRINTF("- mon_register_b('%s', \"%s\", %p, %d);\n", modp, namep, datap, isOut); mons[1].sigsp[isOut] = (vluint32_t*)(varp->datap()); } } extern "C" void mon_register_done(); void mon_register_done() { const char* modp = svGetNameFromScope(svGetScope()); #ifdef TEST_VERBOSE VL_PRINTF("- mon_register_done('%s');\n", modp); #endif // Print list of all signals - if we didn't register2 anything we'd pick them off here const VerilatedScope* scopep = Verilated::dpiScope(); if (VerilatedVarNameMap* varsp = scopep->varsp()) { for (VerilatedVarNameMap::const_iterator it = varsp->begin(); it != varsp->end(); ++it) { VL_PRINTF("- mon2: %s\n", it->first); } } } extern "C" void mon_eval(); void mon_eval() { // Callback from always@ negedge mon_do(&mons[0]); mon_do(&mons[1]); } //====================================================================== unsigned int main_time = false; double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { double sim_time = 1100; Verilated::commandArgs(argc, argv); Verilated::debug(0); VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out #ifdef VERILATOR # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif #endif topp->eval(); topp->clk = 0; main_time += 10; while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += 1; topp->eval(); topp->clk = !topp->clk; //mon_do(); } if (!Verilated::gotFinish()) { vl_fatal(__FILE__,__LINE__,"main", "%Error: Timeout; never got a $finish"); } topp->final(); delete topp; topp=NULL; exit(0L); } verilator-3.874/test_regress/t/t_langext_3.v0000664000177100017500000000075412473477707021125 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // A test of the +verilog2001ext+ and +verilog2005ext+ flags. // // This source code uses the uwire declaration, which is only valid in Verilog // 2005. // // Compile only test, so no need for "All Finished" output. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; uwire w; // Only in Verilog 2005 endmodule verilator-3.874/test_regress/t/t_math_tri.pl0000775000177100017500000000071712473477707021220 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_attr_parenstar.pl0000775000177100017500000000071712473477707022442 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_notfound_bad.pl0000775000177100017500000000105412473477707023452 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( fails=>1, expect=> '%Error: t/t_struct_notfound_bad.v:\d+: Member \'nfmember\' not found in structure %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_for_local.pl0000775000177100017500000000071712473477707021351 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_notunsized.v0000664000177100017500000000460012473477707022472 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [71:0] muxed; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .muxed (muxed[71:0]), // Inputs .clk (clk), .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {muxed[63:0]}; wire [5:0] width_check = cyc[5:0] + 1; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h20050a66e7b253d1 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs muxed, // Inputs clk, in ); input clk; input [31:0] in; output [71:0] muxed; wire [71:0] a = {in[7:0],~in[31:0],in[31:0]}; wire [71:0] b = {~in[7:0],in[31:0],~in[31:0]}; /*AUTOWIRE*/ Muxer muxer ( .sa (0), .sb (in[0]), /*AUTOINST*/ // Outputs .muxed (muxed[71:0]), // Inputs .a (a[71:0]), .b (b[71:0])); endmodule module Muxer (/*AUTOARG*/ // Outputs muxed, // Inputs sa, sb, a, b ); input sa; input sb; output wire [71:0] muxed; input [71:0] a; input [71:0] b; // Constification wasn't sizing with inlining and gave // unsized error on below // v assign muxed = (({72{sa}} & a) | ({72{sb}} & b)); endmodule verilator-3.874/test_regress/t/t_mem_slice_bad.pl0000775000177100017500000000210112473477707022141 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions %Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions %Error: t/t_mem_slice_bad.v:\d+: Unsupported: Slices in a non-delayed assignment with the same Var on both sides %Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions %Error: t/t_mem_slice_bad.v:\d+: Slices of arrays in assignments must have the same unpacked dimensions %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_order_first.pl0000775000177100017500000000072212473477707021727 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_for.v0000664000177100017500000000712612473477707020660 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [7:0] crc; genvar g; wire [7:0] out_p1; wire [15:0] out_p2; wire [7:0] out_p3; wire [7:0] out_p4; paramed #(.WIDTH(8), .MODE(0)) p1 (.in(crc), .out(out_p1)); paramed #(.WIDTH(16), .MODE(1)) p2 (.in({crc,crc}), .out(out_p2)); paramed #(.WIDTH(8), .MODE(2)) p3 (.in(crc), .out(out_p3)); gencase #(.MODE(3)) p4 (.in(crc), .out(out_p4)); wire [7:0] out_ef; enflop #(.WIDTH(8)) enf (.a(crc), .q(out_ef), .oe_e1(1'b1), .clk(clk)); always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%b %x %x %x %x %x\n",$time, cyc, crc, out_p1, out_p2, out_p3, out_p4, out_ef); cyc <= cyc + 1; crc <= {crc[6:0], ~^ {crc[7],crc[5],crc[4],crc[3]}}; if (cyc==0) begin // Setup crc <= 8'hed; end else if (cyc==1) begin end else if (cyc==3) begin if (out_p1 !== 8'h2d) $stop; if (out_p2 !== 16'h2d2d) $stop; if (out_p3 !== 8'h78) $stop; if (out_p4 !== 8'h44) $stop; if (out_ef !== 8'hda) $stop; end else if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module gencase (/*AUTOARG*/ // Outputs out, // Inputs in ); parameter MODE = 0; input [7:0] in; output [7:0] out; generate // : genblk1 begin case (MODE) 2: mbuf mc [7:0] (.q(out[7:0]), .a({in[5:0],in[7:6]})); default: mbuf mc [7:0] (.q(out[7:0]), .a({in[3:0],in[3:0]})); endcase end endgenerate endmodule module paramed (/*AUTOARG*/ // Outputs out, // Inputs in ); parameter WIDTH = 1; parameter MODE = 0; input [WIDTH-1:0] in; output [WIDTH-1:0] out; generate if (MODE==0) initial $write("Mode=0\n"); // No else endgenerate `ifndef NC // for(genvar) unsupported `ifndef ATSIM // for(genvar) unsupported generate // Empty loop body, local genvar for (genvar j=0; j<3; j=j+1) begin end // Ditto to make sure j has new scope for (genvar j=0; j<5; j=j+1) begin end endgenerate `endif `endif generate endgenerate genvar i; generate if (MODE==0) begin // Flip bitorder, direct assign method for (i=0; i1, ); ok(1); 1; verilator-3.874/test_regress/t/t_display_time.pl0000775000177100017500000000157612473477707022100 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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->{vl_time_multiplier} = 1000; compile ( verilator_flags2 => ['-DVL_TIME_MULTIPLER=1000'], ); execute ( check_finished=>1, expect=> quotemeta( 'default: [0.000] 0t time [ 0.000] No0 time ' # Unsupported: #'default: [0] 0t time [ 0] No0 time #-9,0,,0: [0] 0t time [0] No0 time #-9,0,,10: [0] 0t time [ 0] No0 time #-9,0,ns,5: [0ns] 0t time [ 0ns] No0 time #-9,3,ns,8: [0.000ns] 0t time [ 0.000ns] No0 time #' ), ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_gen.v0000664000177100017500000000133312473477707020662 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; tri z0; tri z1; updown #(0) updown0 (.z(z0)); updown #(1) updown1 (.z(z1)); always @ (posedge clk) begin if (z0 !== 0) $stop; if (z1 !== 1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module updown #(parameter UP=0) (inout z); generate if (UP) begin t_up sub (.z); end else begin t_down sub (.z); end endgenerate endmodule module t_up (inout tri1 z); endmodule module t_down (inout tri0 z); endmodule verilator-3.874/test_regress/t/t_interface_down_inlac.pl0000775000177100017500000000112412473477707023537 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_A +define+INLINE_C'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_set.pl0000775000177100017500000000072012473477707021535 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_index.v0000664000177100017500000000262312473477707021176 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test generate index usage. // // The code illustrates a problem in Verilator's handling of constant // expressions inside generate indexes. // // This is a regression test against issue 517. // // **If you do not wish for your code to be released to the public // please note it here, otherwise:** // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett. `define START 8 `define SIZE 4 `define END (`START + `SIZE) module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [`END-1:0] y; wire [`END-1:0] x; foo foo_i (.y (y), .x (x), .clk (clk)); always @(posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule // t module foo(output wire [`END-1:0] y, input wire [`END-1:0] x, input wire clk); function peek_bar; peek_bar = bar_inst[`START].i_bar.r; // this is ok peek_bar = bar_inst[`START + 1].i_bar.r; // this fails, should not. endfunction genvar g; generate for (g = `START; g < `END; g = g + 1) begin: bar_inst bar i_bar(.x (x[g]), .y (y[g]), .clk (clk)); end endgenerate endmodule : foo module bar(output wire y, input wire x, input wire clk); reg r = 0; assign y = r; always @(posedge clk) begin r = x ? ~x : y; end endmodule : bar verilator-3.874/test_regress/t/t_flag_csplit.pl0000775000177100017500000000271312473477707021676 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( v_flags2 => ["--trace --output-split 1 --output-split-cfuncs 1"], ); execute ( check_finished=>1, ); my $got1; foreach my $file (glob("$Self->{obj_dir}/*.cpp")) { $got1 = 1 if $file =~ /__1/; check($file); } $got1 or $Self->error("No __1 split file found"); ok(1); 1; sub check { my $filename = shift; my $size = -s $filename; printf " File %6d %s\n", $size, $filename if $Self->{verbose}; my $fh = IO::File->new("<$filename") or $Self->error("$! $filenme"); my @funcs; while (defined (my $line = $fh->getline)) { if ($line =~ /^(void|IData)\s+(.*::.*)/) { my $func = $2; $func =~ s/\(.*$//; print "\tFunc $func\n" if $Self->{verbose}; if ($func !~ /::_eval_initial_loop$/ && $func !~ /::__Vconfigure$/ && $func !~ /::trace$/ && $func !~ /::traceInit$/ && $func !~ /::traceFull$/ ) { push @funcs, $func; } } } if ($#funcs > 0) { $Self->error("Split had multiple functions in $filename\n\t".join("\n\t",@funcs)); } } verilator-3.874/test_regress/t/t_sv_bus_mux_demux.pl0000775000177100017500000000102612473477707022777 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug181"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_in_assign.pl0000775000177100017500000000071712473477707022233 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_real.pl0000775000177100017500000000071712473477707021345 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_x.pl0000775000177100017500000000077412473477707020656 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ["--x-assign 0"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_circ_bad.v0000664000177100017500000000042612473477707022143 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/); sub sub (); endmodule module sub #(parameter WIDTH=X, parameter X=WIDTH) (); endmodule verilator-3.874/test_regress/t/t_func_named.pl0000775000177100017500000000072212473477707021504 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_assert_synth.v0000664000177100017500000000370312473477707021764 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg a; initial a = 1'b1; reg b_fc; initial b_fc = 1'b0; reg b_pc; initial b_pc = 1'b0; reg b_oh; initial b_oh = 1'b0; reg b_oc; initial b_oc = 1'b0; wire a_l = ~a; wire b_oc_l = ~b_oc; // Note we must insure that full, parallel, etc, only fire during // edges (not mid-cycle), and must provide a way to turn them off. // SystemVerilog provides: $asserton and $assertoff. // verilator lint_off CASEINCOMPLETE always @* begin // Note not all tools support directives on casez's case ({a,b_fc}) // synopsys full_case 2'b0_0: ; 2'b0_1: ; 2'b1_0: ; // Note no default endcase priority case ({a,b_fc}) 2'b0_0: ; 2'b0_1: ; 2'b1_0: ; // Note no default endcase end always @* begin case (1'b1) // synopsys full_case parallel_case a: ; b_pc: ; endcase end `ifdef NOT_YET_VERILATOR // Unsupported // ambit synthesis one_hot "a, b_oh" // cadence one_cold "a_l, b_oc_l" `endif integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin a <= 1'b1; b_fc <= 1'b0; b_pc <= 1'b0; b_oh <= 1'b0; b_oc <= 1'b0; end if (cyc==2) begin a <= 1'b0; b_fc <= 1'b1; b_pc <= 1'b1; b_oh <= 1'b1; b_oc <= 1'b1; end if (cyc==3) begin a <= 1'b1; b_fc <= 1'b0; b_pc <= 1'b0; b_oh <= 1'b0; b_oc <= 1'b0; end if (cyc==4) begin `ifdef FAILING_FULL b_fc <= 1'b1; `endif `ifdef FAILING_PARALLEL b_pc <= 1'b1; `endif `ifdef FAILING_OH b_oh <= 1'b1; `endif `ifdef FAILING_OC b_oc <= 1'b1; `endif end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_langext_1.pl0000775000177100017500000000075712473477707021277 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # This is a compile only test. compile ( v_flags2 => ["+verilog2001ext+v"], ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_for_overlap.v0000664000177100017500000000203612473477707022403 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. // bug749 module t (/*AUTOARG*/ // Inputs clk ); input clk; genvar g; for (g=1; g<3; ++g) begin : gblk sub2 #(.IN(g)) u (); //sub #(.IN(g)) u2 (); end sub1 #(.IN(0)) u (); always @ (posedge clk) begin if (t.u.IN != 0) $stop; if (t.u.FLAVOR != 1) $stop; //if (t.u2.IN != 0) $stop; // This should be not found if (t.gblk[1].u.IN != 1) $stop; if (t.gblk[2].u.IN != 2) $stop; if (t.gblk[1].u.FLAVOR != 2) $stop; if (t.gblk[2].u.FLAVOR != 2) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module sub1 (/*AUTOARG*/); parameter [31:0] IN = 99; parameter FLAVOR = 1; `ifdef TEST_VERBOSE initial $display("%m"); `endif endmodule module sub2 (/*AUTOARG*/); parameter [31:0] IN = 99; parameter FLAVOR = 2; `ifdef TEST_VERBOSE initial $display("%m"); `endif endmodule verilator-3.874/test_regress/t/t_case_huge_sub4.v0000664000177100017500000000333412473477707022116 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t_case_huge_sub4 (/*AUTOARG*/ // Outputs outq, // Inputs index ); input [7:0] index; output [9:0] outq; // ============================= /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [9:0] outq; // End of automatics // ============================= always @(/*AS*/index) begin case (index) // default below: no change 8'h00: begin outq = 10'h001; end 8'he0: begin outq = 10'h05b; end 8'he1: begin outq = 10'h126; end 8'he2: begin outq = 10'h369; end 8'he3: begin outq = 10'h291; end 8'he4: begin outq = 10'h2ca; end 8'he5: begin outq = 10'h25b; end 8'he6: begin outq = 10'h106; end 8'he7: begin outq = 10'h172; end 8'he8: begin outq = 10'h2f7; end 8'he9: begin outq = 10'h2d3; end 8'hea: begin outq = 10'h182; end 8'heb: begin outq = 10'h327; end 8'hec: begin outq = 10'h1d0; end 8'hed: begin outq = 10'h204; end 8'hee: begin outq = 10'h11f; end 8'hef: begin outq = 10'h365; end 8'hf0: begin outq = 10'h2c2; end 8'hf1: begin outq = 10'h2b5; end 8'hf2: begin outq = 10'h1f8; end 8'hf3: begin outq = 10'h2a7; end 8'hf4: begin outq = 10'h1be; end 8'hf5: begin outq = 10'h25e; end 8'hf6: begin outq = 10'h032; end 8'hf7: begin outq = 10'h2ef; end 8'hf8: begin outq = 10'h02f; end 8'hf9: begin outq = 10'h201; end 8'hfa: begin outq = 10'h054; end 8'hfb: begin outq = 10'h013; end 8'hfc: begin outq = 10'h249; end 8'hfd: begin outq = 10'h09a; end 8'hfe: begin outq = 10'h012; end 8'hff: begin outq = 10'h114; end default: ; // No change endcase end endmodule verilator-3.874/test_regress/t/t_array_packed_write_read.pl0000775000177100017500000000102612473477707024235 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug446"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_graphcirc.pl0000775000177100017500000000071712473477707022366 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_order_multidriven.v0000664000177100017500000001101512473477707022766 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Ted Campbell. //With MULTI_CLK defined shows bug, without it is hidden `define MULTI_CLK //bug634 module t ( input i_clk_wr, input i_clk_rd ); wire wr$wen; wire [7:0] wr$addr; wire [7:0] wr$wdata; wire [7:0] wr$rdata; wire rd$wen; wire [7:0] rd$addr; wire [7:0] rd$wdata; wire [7:0] rd$rdata; wire clk_wr; wire clk_rd; `ifdef MULTI_CLK assign clk_wr = i_clk_wr; assign clk_rd = i_clk_rd; `else assign clk_wr = i_clk_wr; assign clk_rd = i_clk_wr; `endif FooWr u_wr ( .i_clk ( clk_wr ), .o_wen ( wr$wen ), .o_addr ( wr$addr ), .o_wdata ( wr$wdata ), .i_rdata ( wr$rdata ) ); FooRd u_rd ( .i_clk ( clk_rd ), .o_wen ( rd$wen ), .o_addr ( rd$addr ), .o_wdata ( rd$wdata ), .i_rdata ( rd$rdata ) ); FooMem u_mem ( .iv_clk ( {clk_wr, clk_rd } ), .iv_wen ( {wr$wen, rd$wen } ), .iv_addr ( {wr$addr, rd$addr } ), .iv_wdata ( {wr$wdata,rd$wdata} ), .ov_rdata ( {wr$rdata,rd$rdata} ) ); endmodule // Memory Writer module FooWr( input i_clk, output o_wen, output [7:0] o_addr, output [7:0] o_wdata, input [7:0] i_rdata ); reg [7:0] cnt = 0; // Count [0,200] always @( posedge i_clk ) if ( cnt < 8'd50 ) cnt <= cnt + 8'd1; // Write addr in (10,30) if even assign o_wen = ( cnt > 8'd10 ) && ( cnt < 8'd30 ) && ( cnt[0] == 1'b0 ); assign o_addr = cnt; assign o_wdata = cnt; endmodule // Memory Reader module FooRd( input i_clk, output o_wen, output [7:0] o_addr, output [7:0] o_wdata, input [7:0] i_rdata ); reg [7:0] cnt = 0; reg [7:0] addr_r; reg en_r; // Count [0,200] always @( posedge i_clk ) if ( cnt < 8'd200 ) cnt <= cnt + 8'd1; // Read data assign o_wen = 0; assign o_addr = cnt - 8'd100; // Track issued read always @( posedge i_clk ) begin addr_r <= o_addr; en_r <= ( cnt > 8'd110 ) && ( cnt < 8'd130 ) && ( cnt[0] == 1'b0 ); end // Display to console 100 cycles after writer always @( negedge i_clk ) if ( en_r ) begin `ifdef TEST_VERBOSE $display( "MEM[%x] == %x", addr_r, i_rdata ); `endif if (addr_r != i_rdata) $stop; end endmodule // Multi-port memory abstraction module FooMem( input [2 -1:0] iv_clk, input [2 -1:0] iv_wen, input [2*8-1:0] iv_addr, input [2*8-1:0] iv_wdata, output [2*8-1:0] ov_rdata ); FooMemImpl u_impl ( .a_clk ( iv_clk [0*1+:1] ), .a_wen ( iv_wen [0*1+:1] ), .a_addr ( iv_addr [0*8+:8] ), .a_wdata ( iv_wdata[0*8+:8] ), .a_rdata ( ov_rdata[0*8+:8] ), .b_clk ( iv_clk [1*1+:1] ), .b_wen ( iv_wen [1*1+:1] ), .b_addr ( iv_addr [1*8+:8] ), .b_wdata ( iv_wdata[1*8+:8] ), .b_rdata ( ov_rdata[1*8+:8] ) ); endmodule // Dual-Port L1 Memory Implementation module FooMemImpl( input a_clk, input a_wen, input [7:0] a_addr, input [7:0] a_wdata, output [7:0] a_rdata, input b_clk, input b_wen, input [7:0] b_addr, input [7:0] b_wdata, output [7:0] b_rdata ); /* verilator lint_off MULTIDRIVEN */ reg [7:0] mem[0:255]; /* verilator lint_on MULTIDRIVEN */ always @( posedge a_clk ) if ( a_wen ) mem[a_addr] <= a_wdata; always @( posedge b_clk ) if ( b_wen ) mem[b_addr] <= b_wdata; always @( posedge a_clk ) a_rdata <= mem[a_addr]; always @( posedge b_clk ) b_rdata <= mem[b_addr]; endmodule verilator-3.874/test_regress/t/t_lint_declfilename_bad.pl0000775000177100017500000000153112473477707023650 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. top_filename("t/t_lint_declfilename.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only -Wall"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning-DECLFILENAME: t/t_lint_declfilename.v:6: Filename \'t_lint_declfilename\' does not match MODULE name: t %Warning-DECLFILENAME: Use .* to disable this message. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_gate_unsup.pl0000775000177100017500000000110712473477707021555 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( # Unsupported: UDP Tables make_top_shell => 0, make_main => 0, verilator_flags2 => ["--lint-only --bbox-unsup"], verilator_make_gcc => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_bad_range.v0000664000177100017500000000063212473477707022475 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (clk); input clk; reg [43:0] mi; reg sel; reg [3:0] sel2; always @ (posedge clk) begin mi = 44'h123; sel = mi[44]; sel2 = mi[44:41]; $write ("Bad select %x %x\n", sel, sel2); end endmodule verilator-3.874/test_regress/t/t_pp_lib.v0000664000177100017500000000040012473477707020472 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. `include "t_pp_lib_inc.vh" module t(); wire [`WIDTH-1:0] a; library_cell n1(a); endmodule verilator-3.874/test_regress/t/t_flag_woff.pl0000775000177100017500000000112412473477707021334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only -Wno-WIDTH"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_vpi_var.cpp0000664000177100017500000004720312525171734021211 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifdef IS_VPI #include "vpi_user.h" #else #include "Vt_vpi_var.h" #include "verilated.h" #include "svdpi.h" #include "Vt_vpi_var__Dpi.h" #include "verilated_vpi.h" #include "verilated_vpi.cpp" #include "verilated_vcd_c.h" #endif #include #include #include #include using namespace std; #include "TestSimulator.h" #include "TestVpi.h" // __FILE__ is too long #define FILENM "t_vpi_var.cpp" #define TEST_MSG if (0) printf unsigned int main_time = false; unsigned int callback_count = false; unsigned int callback_count_half = false; unsigned int callback_count_quad = false; unsigned int callback_count_strs = false; unsigned int callback_count_strs_max = 500; //====================================================================== #define CHECK_RESULT_VH(got, exp) \ if ((got) != (exp)) { \ printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \ FILENM,__LINE__, (got), (exp)); \ return __LINE__; \ } #define CHECK_RESULT_NZ(got) \ if (!(got)) { \ printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \ return __LINE__; \ } // Use cout to avoid issues with %d/%lx etc #define CHECK_RESULT(got, exp) \ if ((got) != (exp)) { \ cout<", (exp)?(exp):""); \ return __LINE__; \ } #define CHECK_RESULT_CSTR_STRIP(got, exp) \ CHECK_RESULT_CSTR(got+strspn(got, " "), exp) int _mon_check_mcd() { PLI_INT32 status; PLI_UINT32 mcd; PLI_BYTE8* filename = (PLI_BYTE8*)"obj_dir/t_vpi_var/mcd_open.tmp"; mcd = vpi_mcd_open(filename); CHECK_RESULT_NZ(mcd); { // Check it got written FILE* fp = fopen(filename,"r"); CHECK_RESULT_NZ(fp); fclose(fp); } status = vpi_mcd_printf(mcd, (PLI_BYTE8*)"hello %s", "vpi_mcd_printf"); CHECK_RESULT(status, strlen("hello vpi_mcd_printf")); status = vpi_mcd_flush(mcd); CHECK_RESULT(status, 0); status = vpi_mcd_close(mcd); // Icarus says 'error' on ones we're not using, so check only used ones return 0. CHECK_RESULT(status & mcd, 0); status = vpi_flush(); CHECK_RESULT(status, 0); return 0; } int _mon_check_callbacks_error(p_cb_data cb_data) { vpi_printf((PLI_BYTE8*)"%%Error: callback should not be executed\n"); return 1; } int _mon_check_callbacks() { t_cb_data cb_data; cb_data.reason = cbEndOfSimulation; cb_data.cb_rtn = _mon_check_callbacks_error; cb_data.user_data = 0; cb_data.value = NULL; cb_data.time = NULL; vpiHandle vh = vpi_register_cb(&cb_data); CHECK_RESULT_NZ(vh); PLI_INT32 status = vpi_remove_cb(vh); CHECK_RESULT_NZ(status); return 0; } int _value_callback(p_cb_data cb_data) { if (TestSimulator::is_verilator()) { // this check only makes sense in Verilator CHECK_RESULT(cb_data->value->value.integer+10, main_time); } callback_count++; return 0; } int _value_callback_half(p_cb_data cb_data) { if (TestSimulator::is_verilator()) { // this check only makes sense in Verilator CHECK_RESULT(cb_data->value->value.integer*2+10, main_time); } callback_count_half++; return 0; } int _value_callback_quad(p_cb_data cb_data) { for (int index=0;index<2;index++) { CHECK_RESULT_HEX(cb_data->value->value.vector[1].aval, (unsigned long)((index==2)?0x1c77bb9bUL:0x12819213UL)); CHECK_RESULT_HEX(cb_data->value->value.vector[0].aval, (unsigned long)((index==2)?0x3784ea09UL:0xabd31a1cUL)); } callback_count_quad++; return 0; } int _mon_check_value_callbacks() { vpiHandle vh1 = VPI_HANDLE("count"); CHECK_RESULT_NZ(vh1); s_vpi_value v; v.format = vpiIntVal; vpi_get_value(vh1, &v); t_cb_data cb_data; cb_data.reason = cbValueChange; cb_data.cb_rtn = _value_callback; cb_data.obj = vh1; cb_data.value = &v; cb_data.time = NULL; vpiHandle vh = vpi_register_cb(&cb_data); CHECK_RESULT_NZ(vh); vh1 = VPI_HANDLE("half_count"); CHECK_RESULT_NZ(vh1); cb_data.obj = vh1; cb_data.cb_rtn = _value_callback_half; vh = vpi_register_cb(&cb_data); CHECK_RESULT_NZ(vh); vh1 = VPI_HANDLE("quads"); CHECK_RESULT_NZ(vh1); v.format = vpiVectorVal; cb_data.obj = vh1; cb_data.cb_rtn = _value_callback_quad; vh = vpi_register_cb(&cb_data); CHECK_RESULT_NZ(vh); vh1 = vpi_handle_by_index(vh1, 2); CHECK_RESULT_NZ(vh1); cb_data.obj = vh1; cb_data.cb_rtn = _value_callback_quad; vh = vpi_register_cb(&cb_data); CHECK_RESULT_NZ(vh); return 0; } int _mon_check_var() { TestVpiHandle vh1 = VPI_HANDLE("onebit"); CHECK_RESULT_NZ(vh1); TestVpiHandle vh2 = vpi_handle_by_name((PLI_BYTE8*)TestSimulator::top(), NULL); CHECK_RESULT_NZ(vh2); // scope attributes const char* p; p = vpi_get_str(vpiName, vh2); CHECK_RESULT_CSTR(p, "t"); p = vpi_get_str(vpiFullName, vh2); CHECK_RESULT_CSTR(p, TestSimulator::top()); TestVpiHandle vh3 = vpi_handle_by_name((PLI_BYTE8*)"onebit", vh2); CHECK_RESULT_NZ(vh3); // onebit attributes PLI_INT32 d; d = vpi_get(vpiType, vh3); CHECK_RESULT(d, vpiReg); if (TestSimulator::has_get_scalar()) { d = vpi_get(vpiVector, vh3); CHECK_RESULT(d, 0); } p = vpi_get_str(vpiName, vh3); CHECK_RESULT_CSTR(p, "onebit"); p = vpi_get_str(vpiFullName, vh3); CHECK_RESULT_CSTR(p, TestSimulator::rooted("onebit")); // array attributes TestVpiHandle vh4 = VPI_HANDLE("fourthreetwoone"); CHECK_RESULT_NZ(vh4); if (TestSimulator::has_get_scalar()) { d = vpi_get(vpiVector, vh4); CHECK_RESULT(d, 1); } t_vpi_value tmpValue; tmpValue.format = vpiIntVal; { TestVpiHandle vh10 = vpi_handle(vpiLeftRange, vh4); CHECK_RESULT_NZ(vh10); vpi_get_value(vh10, &tmpValue); CHECK_RESULT(tmpValue.value.integer,4); } { TestVpiHandle vh10 = vpi_handle(vpiRightRange, vh4); CHECK_RESULT_NZ(vh10); vpi_get_value(vh10, &tmpValue); CHECK_RESULT(tmpValue.value.integer,3); } { TestVpiHandle vh10 = vpi_iterate(vpiMemoryWord, vh4); CHECK_RESULT_NZ(vh10); TestVpiHandle vh11 = vpi_scan(vh10); CHECK_RESULT_NZ(vh11); TestVpiHandle vh12 = vpi_handle(vpiLeftRange, vh11); CHECK_RESULT_NZ(vh12); vpi_get_value(vh12, &tmpValue); CHECK_RESULT(tmpValue.value.integer,2); TestVpiHandle vh13 = vpi_handle(vpiRightRange, vh11); CHECK_RESULT_NZ(vh13); vpi_get_value(vh13, &tmpValue); CHECK_RESULT(tmpValue.value.integer,1); } return 0; } int _mon_check_varlist() { const char* p; TestVpiHandle vh2 = VPI_HANDLE("sub"); CHECK_RESULT_NZ(vh2); TestVpiHandle vh10 = vpi_iterate(vpiReg, vh2); CHECK_RESULT_NZ(vh10.nofree()); TestVpiHandle vh11 = vpi_scan(vh10); CHECK_RESULT_NZ(vh11); p = vpi_get_str(vpiFullName, vh11); CHECK_RESULT_CSTR(p, TestSimulator::rooted("sub.subsig1")); TestVpiHandle vh12 = vpi_scan(vh10); CHECK_RESULT_NZ(vh12); p = vpi_get_str(vpiFullName, vh12); CHECK_RESULT_CSTR(p, TestSimulator::rooted("sub.subsig2")); TestVpiHandle vh13 = vpi_scan(vh10); CHECK_RESULT(vh13,0); return 0; } int _mon_check_getput() { TestVpiHandle vh2 = VPI_HANDLE("onebit"); CHECK_RESULT_NZ(vh2); s_vpi_value v; v.format = vpiIntVal; vpi_get_value(vh2, &v); CHECK_RESULT(v.value.integer, 0); s_vpi_time t; t.type = vpiSimTime; t.high = 0; t.low = 0; v.value.integer = 1; vpi_put_value(vh2, &v, &t, vpiNoDelay); vpi_get_value(vh2, &v); CHECK_RESULT(v.value.integer, 1); return 0; } int _mon_check_quad() { TestVpiHandle vh2 = VPI_HANDLE("quads"); CHECK_RESULT_NZ(vh2); s_vpi_value v; t_vpi_vecval vv[2]; bzero(&vv,sizeof(vv)); s_vpi_time t; t.type = vpiSimTime; t.high = 0; t.low = 0; TestVpiHandle vhidx2 = vpi_handle_by_index(vh2, 2); CHECK_RESULT_NZ(vhidx2); TestVpiHandle vhidx3 = vpi_handle_by_index(vh2, 3); CHECK_RESULT_NZ(vhidx2); v.format = vpiVectorVal; v.value.vector = vv; v.value.vector[1].aval = 0x12819213UL; v.value.vector[0].aval = 0xabd31a1cUL; vpi_put_value(vhidx2, &v, &t, vpiNoDelay); v.format = vpiVectorVal; v.value.vector = vv; v.value.vector[1].aval = 0x1c77bb9bUL; v.value.vector[0].aval = 0x3784ea09UL; vpi_put_value(vhidx3, &v, &t, vpiNoDelay); vpi_get_value(vhidx2, &v); CHECK_RESULT(v.value.vector[1].aval, 0x12819213UL); CHECK_RESULT(v.value.vector[1].bval, 0); vpi_get_value(vhidx3, &v); CHECK_RESULT(v.value.vector[1].aval, 0x1c77bb9bUL); CHECK_RESULT(v.value.vector[1].bval, 0); return 0; } int _mon_check_string() { static struct { const char *name; const char *initial; const char *value; } text_test_obs[] = { {"text_byte", "B", "xxA"}, // x's dropped {"text_half", "Hf", "xxT2"}, // x's dropped {"text_word", "Word", "Tree"}, {"text_long", "Long64b", "44Four44"}, {"text" , "Verilog Test module", "lorem ipsum"}, }; for (int i=0; i<5; i++) { TestVpiHandle vh1 = VPI_HANDLE(text_test_obs[i].name); CHECK_RESULT_NZ(vh1); s_vpi_value v; s_vpi_time t = { vpiSimTime, 0, 0}; s_vpi_error_info e; v.format = vpiStringVal; vpi_get_value(vh1, &v); if (vpi_chk_error(&e)) { printf("%%vpi_chk_error : %s\n", e.message); } CHECK_RESULT_CSTR_STRIP(v.value.str, text_test_obs[i].initial); v.value.str = (PLI_BYTE8*)text_test_obs[i].value; vpi_put_value(vh1, &v, &t, vpiNoDelay); } return 0; } int _mon_check_putget_str(p_cb_data cb_data) { static TestVpiHandle cb; static struct { TestVpiHandle scope, sig, rfr, check, verbose; char str[128+1]; // char per bit plus null terminator int type; // value type in .str union { PLI_INT32 integer; s_vpi_vecval vector[4]; } value; // reference } data[129]; if (cb_data) { // this is the callback static unsigned int seed = 1; s_vpi_time t; t.type = vpiSimTime; t.high = 0; t.low = 0; for (int i=2; i<=128; i++) { static s_vpi_value v; int words = (i+31)>>5; TEST_MSG("========== %d ==========\n", i); if (callback_count_strs) { // check persistance if (data[i].type) { v.format = data[i].type; } else { static PLI_INT32 vals[] = {vpiBinStrVal, vpiOctStrVal, vpiHexStrVal, vpiDecStrVal}; v.format = vals[rand_r(&seed) % ((words>2)?3:4)]; TEST_MSG("new format %d\n", v.format); } vpi_get_value(data[i].sig, &v); TEST_MSG("%s\n", v.value.str); if (data[i].type) { CHECK_RESULT_CSTR(v.value.str, data[i].str); } else { data[i].type = v.format; strcpy(data[i].str, v.value.str); } } // check for corruption v.format = (words==1)?vpiIntVal:vpiVectorVal; vpi_get_value(data[i].sig, &v); if (v.format == vpiIntVal) { TEST_MSG("%08x %08x\n", v.value.integer, data[i].value.integer); CHECK_RESULT(v.value.integer, data[i].value.integer); } else { for (int k=0; k < words; k++) { TEST_MSG("%d %08x %08x\n", k, v.value.vector[k].aval, data[i].value.vector[k].aval); CHECK_RESULT_HEX(v.value.vector[k].aval, data[i].value.vector[k].aval); } } if (callback_count_strs & 7) { // put same value back - checking encoding/decoding equivalent v.format = data[i].type; v.value.str = data[i].str; vpi_put_value(data[i].sig, &v, &t, vpiNoDelay); v.format = vpiIntVal; v.value.integer = 1; //vpi_put_value(data[i].verbose, &v, &t, vpiNoDelay); vpi_put_value(data[i].check, &v, &t, vpiNoDelay); } else { // stick a new random value in unsigned int mask = ((i&31)?(1<<(i&31)):0)-1; if (words == 1) { v.value.integer = rand_r(&seed); data[i].value.integer = v.value.integer &= mask; v.format = vpiIntVal; TEST_MSG("new value %08x\n", data[i].value.integer); } else { TEST_MSG("new value\n"); for (int j=0; j<4; j++) { data[i].value.vector[j].aval = rand_r(&seed); if (j==(words-1)) { data[i].value.vector[j].aval &= mask; } TEST_MSG(" %08x\n", data[i].value.vector[j].aval); } v.value.vector = data[i].value.vector; v.format = vpiVectorVal; } vpi_put_value(data[i].sig, &v, &t, vpiNoDelay); vpi_put_value(data[i].rfr, &v, &t, vpiNoDelay); } if ((callback_count_strs & 1) == 0) data[i].type = 0; } if (++callback_count_strs == callback_count_strs_max) { int success = vpi_remove_cb(cb); CHECK_RESULT_NZ(success); }; } else { // setup and install for (int i=1; i<=128; i++) { char buf[32]; snprintf(buf, sizeof(buf), TestSimulator::rooted("arr[%d].arr"), i); CHECK_RESULT_NZ(data[i].scope = vpi_handle_by_name((PLI_BYTE8*)buf, NULL)); CHECK_RESULT_NZ(data[i].sig = vpi_handle_by_name((PLI_BYTE8*)"sig", data[i].scope)); CHECK_RESULT_NZ(data[i].rfr = vpi_handle_by_name((PLI_BYTE8*)"rfr", data[i].scope)); CHECK_RESULT_NZ(data[i].check = vpi_handle_by_name((PLI_BYTE8*)"check", data[i].scope)); CHECK_RESULT_NZ(data[i].verbose = vpi_handle_by_name((PLI_BYTE8*)"verbose", data[i].scope)); } static t_cb_data cb_data; static s_vpi_value v; static TestVpiHandle count_h = VPI_HANDLE("count"); cb_data.reason = cbValueChange; cb_data.cb_rtn = _mon_check_putget_str; // this function cb_data.obj = count_h; cb_data.value = &v; cb_data.time = NULL; v.format = vpiIntVal; cb = vpi_register_cb(&cb_data); CHECK_RESULT_NZ(cb); } return 0; } int _mon_check_vlog_info() { s_vpi_vlog_info vlog_info; PLI_INT32 rtn = vpi_get_vlog_info(&vlog_info); CHECK_RESULT(rtn, 1); CHECK_RESULT(vlog_info.argc, 4); CHECK_RESULT_CSTR(vlog_info.argv[1], "+PLUS"); CHECK_RESULT_CSTR(vlog_info.argv[2], "+INT=1234"); CHECK_RESULT_CSTR(vlog_info.argv[3], "+STRSTR"); if (TestSimulator::is_verilator()) { CHECK_RESULT_CSTR(vlog_info.product, "Verilator"); CHECK_RESULT(strlen(vlog_info.version) > 0, 1); } return 0; } #ifndef IS_VPI #define CHECK_ENUM_STR(fn, enum) \ do { \ const char* strVal = VerilatedVpiError::fn(enum); \ CHECK_RESULT_CSTR(strVal, #enum); \ } while (0) int _mon_check_vl_str() { CHECK_ENUM_STR(strFromVpiVal, vpiBinStrVal); CHECK_ENUM_STR(strFromVpiVal, vpiRawFourStateVal); CHECK_ENUM_STR(strFromVpiObjType, vpiAlways); CHECK_ENUM_STR(strFromVpiObjType, vpiWhile); CHECK_ENUM_STR(strFromVpiObjType, vpiAttribute); CHECK_ENUM_STR(strFromVpiObjType, vpiUdpArray); CHECK_ENUM_STR(strFromVpiObjType, vpiContAssignBit); CHECK_ENUM_STR(strFromVpiObjType, vpiGenVar); CHECK_ENUM_STR(strFromVpiMethod, vpiCondition); CHECK_ENUM_STR(strFromVpiMethod, vpiStmt); CHECK_ENUM_STR(strFromVpiCallbackReason, cbValueChange); CHECK_ENUM_STR(strFromVpiCallbackReason, cbAtEndOfSimTime); CHECK_ENUM_STR(strFromVpiProp, vpiType); CHECK_ENUM_STR(strFromVpiProp, vpiProtected); CHECK_ENUM_STR(strFromVpiProp, vpiDirection); CHECK_ENUM_STR(strFromVpiProp, vpiTermIndex); CHECK_ENUM_STR(strFromVpiProp, vpiConstType); CHECK_ENUM_STR(strFromVpiProp, vpiAutomatic); CHECK_ENUM_STR(strFromVpiProp, vpiOffset); CHECK_ENUM_STR(strFromVpiProp, vpiStop); CHECK_ENUM_STR(strFromVpiProp, vpiIsProtected); return 0; } #endif int mon_check() { // Callback from initial block in monitor if (int status = _mon_check_mcd()) return status; if (int status = _mon_check_callbacks()) return status; if (int status = _mon_check_value_callbacks()) return status; if (int status = _mon_check_var()) return status; if (int status = _mon_check_varlist()) return status; if (int status = _mon_check_getput()) return status; if (int status = _mon_check_quad()) return status; if (int status = _mon_check_string()) return status; if (int status = _mon_check_putget_str(NULL)) return status; if (int status = _mon_check_vlog_info()) return status; #ifndef IS_VPI if (int status = _mon_check_vl_str()) return status; #endif return 0; // Ok } //====================================================================== #ifdef IS_VPI static int mon_check_vpi() { vpiHandle href = vpi_handle(vpiSysTfCall, 0); s_vpi_value vpi_value; vpi_value.format = vpiIntVal; vpi_value.value.integer = mon_check(); vpi_put_value(href, &vpi_value, NULL, vpiNoDelay); return 0; } static s_vpi_systf_data vpi_systf_data[] = { {vpiSysFunc, vpiIntFunc, (PLI_BYTE8*)"$mon_check", (PLI_INT32(*)(PLI_BYTE8*))mon_check_vpi, 0, 0, 0}, 0 }; // cver entry void vpi_compat_bootstrap(void) { p_vpi_systf_data systf_data_p; systf_data_p = &(vpi_systf_data[0]); while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++); } // icarus entry void (*vlog_startup_routines[])() = { vpi_compat_bootstrap, 0 }; #else double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { double sim_time = 1100; Verilated::commandArgs(argc, argv); Verilated::debug(0); VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out #ifdef VERILATOR # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif #endif #if VM_TRACE Verilated::traceEverOn(true); VL_PRINTF("Enabling waves...\n"); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_vpi_var/simx.vcd"); #endif topp->eval(); topp->clk = 0; main_time += 10; while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += 1; topp->eval(); VerilatedVpi::callValueCbs(); topp->clk = !topp->clk; //mon_do(); #if VM_TRACE if (tfp) tfp->dump (main_time); #endif } CHECK_RESULT(callback_count, 501); CHECK_RESULT(callback_count_half, 250); CHECK_RESULT(callback_count_quad, 2); CHECK_RESULT(callback_count_strs, callback_count_strs_max); if (!Verilated::gotFinish()) { vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish"); } topp->final(); #if VM_TRACE if (tfp) tfp->close(); #endif delete topp; topp=NULL; exit(0L); } #endif verilator-3.874/test_regress/t/t_struct_init.pl0000775000177100017500000000072312473477707021755 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_bad_msb.pl0000775000177100017500000000117012473477707022331 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( fails=>1, expect=> '%Warning-LITENDIAN: t/t_select_bad_msb.v:\d+: Little bit endian vector: MSB < LSB of bit range: 0:22 .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_cond_bitrange.v0000664000177100017500000000557512473477707022676 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test for short-circuiting in generate "if" // // The given generate loops should only access valid bits of mask, since that // is defined by SIZE. However since the loop range is larger, this only works // if short-circuited evaluation of the generate loop is in place. // This file ONLY is placed into the Public Domain, for any use, without // warranty, 2012 by Jeremy Bennett. `define MAX_SIZE 4 module t (/*AUTOARG*/ // Inputs clk ); input clk; // Set the parameters, so that we use a size less than MAX_SIZE test_gen #(.SIZE (2), .MASK (2'b11)) i_test_gen (.clk (clk)); // This is only a compilation test, but for good measure we do one clock // cycle. integer count; initial begin count = 0; end always @(posedge clk) begin if (count == 1) begin $write("*-* All Finished *-*\n"); $finish; end else begin count = count + 1; end end endmodule // t module test_gen #( parameter SIZE = `MAX_SIZE, MASK = `MAX_SIZE'b0) (/*AUTOARG*/ // Inputs clk ); input clk; // Generate blocks that rely on short-circuiting of the logic to avoid errors. generate genvar g; for (g = 0; g < `MAX_SIZE; g = g + 1) begin if ((g < SIZE) && MASK[g]) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Logical AND generate if MASK [%1d] = %d\n", g, MASK[g]); `endif if (g >= SIZE) begin $stop; end end end end endgenerate generate for (g = 0; g < `MAX_SIZE; g = g + 1) begin if (!((g >= SIZE) || ~MASK[g])) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Logical OR generate if MASK [%1d] = %d\n", g, MASK[g]); `endif if (g >= SIZE) begin $stop; end end end end endgenerate generate for (g = 0; g < `MAX_SIZE; g = g + 1) begin if (!((g < SIZE) -> ~MASK[g])) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Logical infer generate if MASK [%1d] = %d\n", g, MASK[g]); `endif if (g >= SIZE) begin $stop; end end end end endgenerate generate for (g = 0; g < `MAX_SIZE; g = g + 1) begin if ( g < SIZE ? MASK[g] : 1'b0) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Conditional generate if MASK [%1d] = %d\n", g, MASK[g]); `endif if (g >= SIZE) begin $stop; end end end end endgenerate // The other way round generate for (g = 0; g < `MAX_SIZE; g = g + 1) begin if ( g >= SIZE ? 1'b0 : MASK[g]) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Conditional generate if MASK [%1d] = %d\n", g, MASK[g]); `endif if (g >= SIZE) begin $stop; end end end end endgenerate endmodule verilator-3.874/test_regress/t/t_embed1_child.v0000664000177100017500000000167712473477707021546 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t_embed1_child (/*AUTOARG*/ // Outputs bit_out, vec_out, wide_out, did_init_out, // Inputs clk, bit_in, vec_in, wide_in, is_ref ); input clk; input bit_in; output bit_out; input [30:0] vec_in; output [30:0] vec_out; input [123:0] wide_in; output [123:0] wide_out; output did_init_out; input is_ref; reg did_init; initial did_init = 0; initial begin did_init = 1; end reg did_final; initial did_final = 0; final begin did_final = 1; if (!is_ref) $write("*-* All Finished *-*\n"); //$finish is in parent end // Note async use! wire bit_out = bit_in; wire did_init_out = did_init; always @ (posedge clk) begin vec_out <= vec_in; wide_out <= wide_in; end endmodule verilator-3.874/test_regress/t/t_gen_assign.v0000664000177100017500000000234112473477707021350 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty. `timescale 1ns / 1ps module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; reg [31:0] sum; wire [8:0] Output; wire [8:0] Input = crc[8:0]; assigns assigns (/*AUTOINST*/ // Outputs .Output (Output[8:0]), // Inputs .Input (Input[8:0])); always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x q=%x\n",$time, cyc, crc, sum); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 32'h0; end else if (cyc>10 && cyc<90) begin sum <= {sum[30:0],sum[31]} ^ {23'h0, crc[8:0]}; end else if (cyc==99) begin if (sum !== 32'he8bbd130) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module assigns(Input, Output); input [8:0] Input; output [8:0] Output; genvar i; generate for (i = 0; i < 8; i = i + 1) begin : ap assign Output[(i>0) ? i-1 : 8] = Input[(i>0) ? i-1 : 8]; end endgenerate endmodule verilator-3.874/test_regress/t/t_sys_readmem_b_8.mem0000664000177100017500000000066512473477707022613 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test data file // // Copyright 2006 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. // ** Note this file has DOS CR's so we can test them! 10000 10001 10010 10011 /* multi line ignored */ 10100 10101 10110 10111 verilator-3.874/test_regress/t/t_vpi_var.pl0000775000177100017500000000145312473477707021055 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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. compile ( make_top_shell => 0, make_main => 0, make_pli => 1, sim_time => 2100, iv_flags2 => ["-g2005-sv -D USE_VPI_NOT_DPI -DWAVES"], v_flags2 => ["+define+USE_VPI_NOT_DPI"], verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --no-l2name $Self->{t_dir}/t_vpi_var.cpp"], ); execute ( iv_pli => 1, check_finished=>1, all_run_flags => ['+PLUS +INT=1234 +STRSTR'] ); ok(1); 1; verilator-3.874/test_regress/t/t_package_param.v0000664000177100017500000000141112473477707022003 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // IEEE 1800-2009 requires that any local definitions take precedence over // definitions in wildcard imported packages (section 26.3). Thus the code // below is valid SystemVerilog. // // This file ONLY is placed into the Public Domain, for any use, without // warranty, 2013 by Jie Xu package defs; parameter NUMBER = 8; localparam NUM = NUMBER; endpackage module t(/*AUTOARG*/ // Inputs clk ); input clk; import defs::*; // This also fails if we use localparam parameter NUM = 32; // Check we have the right definition always @(posedge clk) begin if (NUM == 32) begin $write("*-* All Finished *-*\n"); $finish; end else begin $stop; end end endmodule verilator-3.874/test_regress/t/t_preproc_inc_inc_bad.vh0000664000177100017500000000032312473477707023343 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module xx; xx // intentional error endmodule verilator-3.874/test_regress/t/t_mod_recurse.v0000664000177100017500000000523712473477707021551 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Sean Moore. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [7:0] tripline = crc[7:0]; /*AUTOWIRE*/ wire valid; wire [3-1:0] value; PriorityChoice #(.OCODEWIDTH(3)) pe (.out(valid), .outN(value[2:0]), .tripline(tripline)); // Aggregate outputs into a single result vector wire [63:0] result = {59'h0, valid, value}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hc5fc632f816568fb if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module PriorityChoice (out, outN, tripline); parameter OCODEWIDTH = 1; localparam CODEWIDTH=OCODEWIDTH-1; localparam SCODEWIDTH= (CODEWIDTH<1) ? 1 : CODEWIDTH; output reg out; output reg [OCODEWIDTH-1:0] outN; input wire [(1<1, ); ok(1); 1; verilator-3.874/test_regress/t/t_cover_line.v0000664000177100017500000000607712473477707021372 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg toggle; initial toggle=0; integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; alpha a1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); alpha a2 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); beta b1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); beta b2 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); tsk t1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); off o1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; toggle <= '0; if (cyc==3) begin toggle <= '1; end else if (cyc==5) begin `ifdef VERILATOR $c("call_task();"); `else call_task(); `endif end else if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end task call_task; /* verilator public */ t1.center_task(1'b1); endtask endmodule module alpha (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; always @ (posedge clk) begin if (toggle) begin // CHECK_COVER(-1,"top.v.a*",2) // t.a1 and t.a2 collapse to a count of 2 end if (toggle) begin // CHECK_COVER_MISSING(-1) // This doesn't even get added // verilator coverage_block_off $write(""); end end endmodule module beta (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; /* verilator public_module */ always @ (posedge clk) begin if (0) begin // CHECK_COVER(-1,"top.v.b*",0) // Make sure that we don't optimize away zero buckets end if (toggle) begin // CHECK_COVER(-1,"top.v.b*",2) // t.b1 and t.b2 collapse to a count of 2 end if (toggle) begin // CHECK_COVER_MISSING(-1) // This doesn't // verilator coverage_block_off $write(""); end end endmodule module tsk (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; /* verilator public_module */ always @ (posedge clk) begin center_task(1'b0); end task center_task; input external; begin if (toggle) begin // CHECK_COVER(-1,"top.v.t1",1) end if (external) begin // CHECK_COVER(-1,"top.v.t1",1) $write("[%0t] Got external pulse\n", $time); end end endtask endmodule module off (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; // verilator coverage_off always @ (posedge clk) begin if (toggle) begin // CHECK_COVER_MISSING(-1) // because under coverage_module_off end end // verilator coverage_on always @ (posedge clk) begin if (toggle) begin // CHECK_COVER(-1,"top.v.o1",1) // because under coverage_module_off end end endmodule verilator-3.874/test_regress/t/t_math_arith.pl0000775000177100017500000000071712473477707021531 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_gate_notif1.pl0000775000177100017500000000134312473477707022463 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_tri_gate.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ['+define+T_NOTIF1',], make_flags => 'CPPFLAGS_ADD=-DT_NOTIF1', verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_tieout.v0000664000177100017500000000205012473477707021411 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. // bug291 module t (/*AUTOARG*/ // Inputs clk ); input clk; integer out18; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire out1; // From test of Test.v wire out19; // From test of Test.v wire out1b; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out1 (out1), .out18 (out18), .out1b (out1b), .out19 (out19)); // Test loop always @ (posedge clk) begin if (out1 !== 1'b1) $stop; if (out18 !== 32'h18) $stop; if (out1b !== 1'b1) $stop; if (out19 !== 1'b1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module Test ( output wire out1 = 1'b1, output integer out18 = 32'h18, output var out1b = 1'b1, output var logic out19 = 1'b1 ); endmodule verilator-3.874/test_regress/t/t_display.pl0000775000177100017500000000253112473477707021052 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, expect=>quotemeta(dequote( '[0] In top.v: Hi [0] In top.v.sub [0] In top.v.sub.subblock [0] In top.v.sub2 [0] In top.v.sub2.subblock2 [0] Back \ Quote " [0] %X=00c %0X=c %0O=14 %B=000001100 [0] %x=00c %0x=c %0o=14 %b=000001100 [0] %D= 12 %d= 12 %01d=12 %06d=000012 %6d= 12 [0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100 [0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 [0] %t= 0 %03t= 0 %0t=0 [0] %s=! %s= what! %s= hmmm!1234 [0] hello, from a very long string. Percent %s are literally substituted in. [0] Embedded <#013> return [0] Embedded multiline *-* All Finished *-* ')), ); ok(1); # Don't put control chars into our source repository, pre-compress instead sub dequote { my $s = shift; $s =~ s/<#013>/\r/g; $s; } 1; verilator-3.874/test_regress/t/t_lint_only.pl0000775000177100017500000000155012473477707021414 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["--lint-only"], verilator_make_gcc => 0, ); foreach my $file (glob("$Self->{obj_dir}/*t_lint_only*")) { next if $file =~ /simx_compile.log/; # Made by driver.pl, not Verilator next if $file =~ /\.status/; # Made by driver.pl, not Verilator $Self->error("%Error: Created $file, but --lint-only shouldn't create files"); } ok(1); 1; verilator-3.874/test_regress/t/t_flag_ldflags_c.cpp0000664000177100017500000000226112473477707022460 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include "svdpi.h" //====================================================================== #if defined(VERILATOR) # include "Vt_flag_ldflags__Dpi.h" #else # error "Unknown simulator for DPI test" #endif //====================================================================== #ifndef CFLAGS_FROM_CMDLINE # error "CFLAGS_FROM_CMDLINE not set - not passed down?" #endif #ifndef CFLAGS2_FROM_CMDLINE # error "CFLAGS2_FROM_CMDLINE not set - not passed down?" #endif void dpii_c_library() {} verilator-3.874/test_regress/t/t_sys_readmem_bad_digit.v0000664000177100017500000000052712473477707023535 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; reg [175:0] hex [15:0]; initial begin $readmemb("t/t_sys_readmem_bad_digit.mem", hex); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_mem_func.pl0000775000177100017500000000071712473477707021202 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_order_comboclkloop.pl0000775000177100017500000000072312473477707023264 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished => 1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_inout.cpp0000664000177100017500000000222112473477707021561 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks #include "Vt_tri_inout.h" Vt_tri_inout *tb = NULL; double sc_time_stamp() { return 0; } bool check() { bool pass; int Z; if (tb->SEL) { Z = tb->A; } else { Z = tb->B; } if (tb->Z == tb->Y1 && tb->Z == tb->Y2 && tb->Z == Z) { printf("PASS: "); pass = true; } else { printf("FAIL: "); pass = false; } #ifdef TEST_VERBOSE printf ("SEL=%d A=%d B=%d Z=%d Y1=%d Y2=%d\n", tb->SEL, tb->A, tb->B, tb->Z, tb->Y1, tb->Y2); #endif return pass; } int main() { bool pass = true; Verilated::debug(0); tb = new Vt_tri_inout("tb"); // loop through every possibility and check the result for (tb->SEL=0; tb->SEL<2; tb->SEL++) { for (tb->A=0; tb->A<2; tb->A++) { for (tb->B=0; tb->B<2; tb->B++) { tb->eval(); if (!check()) { pass = false; } } } } if(pass) { VL_PRINTF("*-* All Finished *-*\n"); tb->final(); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from inout test\n"); } return 0; } verilator-3.874/test_regress/t/t_sys_readmem_b.mem0000664000177100017500000000055012473477707022355 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test data file // // Copyright 2006 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. 010 0_1_1 100/*Space*/101// Space 110 111 @00_0_8 10000 @c 10100 10101 verilator-3.874/test_regress/t/t_var_const_bad.v0000664000177100017500000000063712473477707022045 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; const logic [2:0] five = 3'd5; always @ (posedge clk) begin five = 3'd4; if (five !== 3'd5) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_order.v0000664000177100017500000000565612473477707020362 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); // surefire lint_off ASWEBB // surefire lint_off ASWEMB // surefire lint_off STMINI // surefire lint_off CSEBEQ input clk; reg [7:0] a_to_clk_levm3; reg [7:0] b_to_clk_levm1; reg [7:0] c_com_levs10; reg [7:0] d_to_clk_levm2; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [7:0] m_from_clk_lev1_r; // From a of t_order_a.v wire [7:0] n_from_clk_lev2; // From a of t_order_a.v wire [7:0] o_from_com_levs11; // From a of t_order_a.v wire [7:0] o_from_comandclk_levs12;// From a of t_order_a.v wire [7:0] o_subfrom_clk_lev2; // From b of t_order_b.v // End of automatics reg [7:0] cyc; initial cyc=0; t_order_a a ( .one (8'h1), /*AUTOINST*/ // Outputs .m_from_clk_lev1_r (m_from_clk_lev1_r[7:0]), .n_from_clk_lev2 (n_from_clk_lev2[7:0]), .o_from_com_levs11 (o_from_com_levs11[7:0]), .o_from_comandclk_levs12(o_from_comandclk_levs12[7:0]), // Inputs .clk (clk), .a_to_clk_levm3 (a_to_clk_levm3[7:0]), .b_to_clk_levm1 (b_to_clk_levm1[7:0]), .c_com_levs10 (c_com_levs10[7:0]), .d_to_clk_levm2 (d_to_clk_levm2[7:0])); t_order_b b ( /*AUTOINST*/ // Outputs .o_subfrom_clk_lev2 (o_subfrom_clk_lev2[7:0]), // Inputs .m_from_clk_lev1_r (m_from_clk_lev1_r[7:0])); reg [7:0] o_from_com_levs12; reg [7:0] o_from_com_levs13; always @ (/*AS*/o_from_com_levs11) begin o_from_com_levs12 = o_from_com_levs11 + 8'h1; o_from_com_levs12 = o_from_com_levs12 + 8'h1; // Test we can add to self and optimize o_from_com_levs13 = o_from_com_levs12; end reg sepassign_in; // verilator lint_off UNOPTFLAT wire [3:0] sepassign; // verilator lint_on UNOPTFLAT // verilator lint_off UNOPT assign #0.1 sepassign[0] = 0, sepassign[1] = sepassign[2], sepassign[2] = sepassign[3], sepassign[3] = sepassign_in; wire [7:0] o_subfrom_clk_lev3 = o_subfrom_clk_lev2; // verilator lint_on UNOPT always @ (posedge clk) begin cyc <= cyc+8'd1; sepassign_in <= 0; if (cyc == 8'd1) begin a_to_clk_levm3 <= 0; d_to_clk_levm2 <= 1; b_to_clk_levm1 <= 1; c_com_levs10 <= 2; sepassign_in <= 1; end if (cyc == 8'd2) begin if (sepassign !== 4'b1110) $stop; end if (cyc == 8'd3) begin $display("%d %d %d %d",m_from_clk_lev1_r, n_from_clk_lev2, o_from_com_levs11, o_from_comandclk_levs12); if (m_from_clk_lev1_r !== 8'h2) $stop; if (o_subfrom_clk_lev3 !== 8'h2) $stop; if (n_from_clk_lev2 !== 8'h2) $stop; if (o_from_com_levs11 !== 8'h3) $stop; if (o_from_com_levs13 !== 8'h5) $stop; if (o_from_comandclk_levs12 !== 8'h5) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_tri_pull_bad.v0000664000177100017500000000031212473477707021667 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Lane Brooks. module t (clk); input clk; wire A; pullup p1(A); pulldown p2(A); endmodule verilator-3.874/test_regress/t/t_mem_multi_io3.cpp0000664000177100017500000000124112473477707022310 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // This file ONLY is placed into the Public Domain, for any use, // without warranty. #if defined(T_MEM_MULTI_IO3_CC) # include "Vt_mem_multi_io3_cc.h" #elif defined(T_MEM_MULTI_IO3_SC) # include "Vt_mem_multi_io3_sc.h" #else # error "Unknown test" #endif VM_PREFIX* tb = NULL; bool pass = true; double sc_time_stamp() { return 0; } int main() { Verilated::debug(0); tb = new VM_PREFIX ("tb"); // Just a constructor test bool pass = true; if (pass) { VL_PRINTF("*-* All Finished *-*\n"); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from test\n"); } return 0; } verilator-3.874/test_regress/t/t_trace_off_sc.pl0000775000177100017500000000120212473477707022014 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_trace_ena.v"); compile ( verilator_flags2 => ['-notrace -sc'], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { !-r "$Self->{obj_dir}/simx.vcd" or $Self->error("Tracing should be off\n"); } ok(1); 1; verilator-3.874/test_regress/t/t_cover_line.out0000664000177100017500000000652112473477707021726 0ustar wsnyderwsnyder // verilator_coverage annotation // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg toggle; initial toggle=0; integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; alpha a1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); alpha a2 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); beta b1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); beta b2 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); tsk t1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); off o1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); always @ (posedge clk) begin 000010 if (cyc!=0) begin cyc <= cyc + 1; toggle <= '0; %000001 if (cyc==3) begin toggle <= '1; end %000001 else if (cyc==5) begin `ifdef VERILATOR $c("call_task();"); `else call_task(); `endif end %000001 else if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end task call_task; /* verilator public */ t1.center_task(1'b1); endtask endmodule module alpha (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; always @ (posedge clk) begin %000002 if (toggle) begin // CHECK_COVER(-1,"top.v.a*",2) // t.a1 and t.a2 collapse to a count of 2 end if (toggle) begin // CHECK_COVER_MISSING(-1) // This doesn't even get added // verilator coverage_block_off $write(""); end end endmodule module beta (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; /* verilator public_module */ always @ (posedge clk) begin %000000 if (0) begin // CHECK_COVER(-1,"top.v.b*",0) // Make sure that we don't optimize away zero buckets end %000002 if (toggle) begin // CHECK_COVER(-1,"top.v.b*",2) // t.b1 and t.b2 collapse to a count of 2 end if (toggle) begin // CHECK_COVER_MISSING(-1) // This doesn't // verilator coverage_block_off $write(""); end end endmodule module tsk (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; /* verilator public_module */ always @ (posedge clk) begin center_task(1'b0); end task center_task; input external; begin %000001 if (toggle) begin // CHECK_COVER(-1,"top.v.t1",1) end %000001 if (external) begin // CHECK_COVER(-1,"top.v.t1",1) $write("[%0t] Got external pulse\n", $time); end end endtask endmodule module off (/*AUTOARG*/ // Inputs clk, toggle ); input clk; input toggle; // verilator coverage_off always @ (posedge clk) begin if (toggle) begin // CHECK_COVER_MISSING(-1) // because under coverage_module_off end end // verilator coverage_on always @ (posedge clk) begin %000001 if (toggle) begin // CHECK_COVER(-1,"top.v.o1",1) // because under coverage_module_off end end endmodule verilator-3.874/test_regress/t/t_flag_bboxsys.v0000664000177100017500000000065712473477707021725 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t; reg a; initial begin $unknown_sys_task_call_to_be_bbox("blah"); $unkown_sys_task_call_noarg; a = $unknown_sys_func_call(23); a = $unknown_sys_func_call_noarg; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_inst_signed.pl0000775000177100017500000000072212473477707021713 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_alw_dly.pl0000775000177100017500000000077112525171734021031 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["-Wno-CLKDATA"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_port_array.v0000664000177100017500000000205712473477707022456 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Alex Solomatnikov. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic [6-1:0] foo[4-1:0]; //initial $display("%m: %p\n", foo); //initial $display("%m: %p\n", foo[3:0]); // VCS not supported %p with slice //logic [6-1:0] foo2[4-1:0][5:6]; //initial $display("%m: %p\n", foo2[3:0][5:6]); // This is not legal dut #(.W(6), .D(4)) udut(.clk(clk), .foo(foo[4-1:0])); endmodule module dut #(parameter W = 1, parameter D = 1) (input logic clk, input logic [W-1:0] foo[D-1:0]); genvar i, j; generate for (j = 0; j < D; j++) begin for (i = 0; i < W; i++) begin suba ua(.clk(clk), .foo(foo[j][i])); end end endgenerate endmodule module suba (input logic clk, input logic foo); always @(posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_dpi_accessors.pl0000775000177100017500000000130312473477707022222 0ustar wsnyderwsnyder#!/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. # 8-Mar-2012: Modifications for this test contributed by Jeremy Bennett and # Jie Xu. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["-Wno-BLKANDNBLK -language 1800-2005 --exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_array_packed_sysfunct.v0000664000177100017500000001445212473477707023624 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); // parameters for array sizes localparam WA = 4; localparam WB = 6; localparam WC = 8; // 2D packed arrays logic [WA+1:2] [WB+1:2] [WC+1:2] array_bg; // big endian array /* verilator lint_off LITENDIAN */ logic [2:WA+1] [2:WB+1] [2:WC+1] array_lt; // little endian array /* verilator lint_on LITENDIAN */ logic [1:0] array_unpk [3:2][1:0]; integer cnt = 0; integer slc = 0; // slice type integer dim = 0; // dimension integer wdt = 0; // width initial begin `checkh($dimensions (array_unpk), 3); `ifndef VCS `checkh($unpacked_dimensions (array_unpk), 2); // IEEE 2009 `endif `checkh($bits (array_unpk), 2*2*2); `checkh($low (array_unpk), 2); `checkh($high (array_unpk), 3); `checkh($left (array_unpk), 3); `checkh($right(array_unpk), 2); `checkh($increment(array_unpk), 1); `checkh($size (array_unpk), 2); end // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if ( (cnt[30:4]==3) && (cnt[3:2]==2'd3) && (cnt[1:0]==2'd3) ) begin $write("*-* All Finished *-*\n"); $finish; end integer slc_next; // calculation of dimention sizes always @ (posedge clk) begin // slicing type counter case (cnt[3:2]) 2'd0 : begin slc_next = 0; end // full array 2'd1 : begin slc_next = 1; end // single array element 2'd2 : begin slc_next = 2; end // half array default: begin slc_next = 0; end endcase slc <= slc_next; // dimension counter case (cnt[1:0]) 2'd0 : begin dim <= 1; wdt <= (slc_next==1) ? WA/2 : (slc_next==2) ? WA/2 : WA; end 2'd1 : begin dim <= 2; wdt <= WB; end 2'd2 : begin dim <= 3; wdt <= WC; end default: begin dim <= 0; wdt <= 0; end endcase end always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("cnt[30:4]=%0d slc=%0d dim=%0d wdt=%0d\n", cnt[30:4], slc, dim, wdt); `endif if (cnt[30:4]==1) begin // big endian if (slc==0) begin // full array `checkh($dimensions (array_bg), 3); `checkh($bits (array_bg), WA*WB*WC); if ((dim>=1)&&(dim<=3)) begin `checkh($left (array_bg, dim), wdt+1); `checkh($right (array_bg, dim), 2 ); `checkh($low (array_bg, dim), 2 ); `checkh($high (array_bg, dim), wdt+1); `checkh($increment (array_bg, dim), 1 ); `checkh($size (array_bg, dim), wdt ); end end else if (slc==1) begin // single array element `checkh($dimensions (array_bg[2]), 2); `checkh($bits (array_bg[2]), WB*WC); if ((dim>=2)&&(dim<=3)) begin `checkh($left (array_bg[2], dim-1), wdt+1); `checkh($right (array_bg[2], dim-1), 2 ); `checkh($low (array_bg[2], dim-1), 2 ); `checkh($high (array_bg[2], dim-1), wdt+1); `checkh($increment (array_bg[2], dim-1), 1 ); `checkh($size (array_bg[2], dim-1), wdt ); end `ifndef VERILATOR // Unsupported slices don't maintain size correctly end else if (slc==2) begin // half array `checkh($dimensions (array_bg[WA/2+1:2]), 3); `checkh($bits (array_bg[WA/2+1:2]), WA/2*WB*WC); if ((dim>=1)&&(dim<=3)) begin `checkh($left (array_bg[WA/2+1:2], dim), wdt+1); `checkh($right (array_bg[WA/2+1:2], dim), 2 ); `checkh($low (array_bg[WA/2+1:2], dim), 2 ); `checkh($high (array_bg[WA/2+1:2], dim), wdt+1); `checkh($increment (array_bg[WA/2+1:2], dim), 1 ); `checkh($size (array_bg[WA/2+1:2], dim), wdt); end `endif end end else if (cnt[30:4]==2) begin // little endian if (slc==0) begin // full array `checkh($dimensions (array_lt), 3); `checkh($bits (array_lt), WA*WB*WC); if ((dim>=1)&&(dim<=3)) begin `checkh($left (array_lt, dim), 2 ); `checkh($right (array_lt, dim), wdt+1); `checkh($low (array_lt, dim), 2 ); `checkh($high (array_lt, dim), wdt+1); `checkh($increment (array_lt, dim), -1 ); `checkh($size (array_lt, dim), wdt ); end end else if (slc==1) begin // single array element `checkh($dimensions (array_lt[2]), 2); `checkh($bits (array_lt[2]), WB*WC); if ((dim>=2)&&(dim<=3)) begin `checkh($left (array_lt[2], dim-1), 2 ); `checkh($right (array_lt[2], dim-1), wdt+1); `checkh($low (array_lt[2], dim-1), 2 ); `checkh($high (array_lt[2], dim-1), wdt+1); `checkh($increment (array_lt[2], dim-1), -1 ); `checkh($size (array_lt[2], dim-1), wdt ); end `ifndef VERILATOR // Unsupported slices don't maintain size correctly end else if (slc==2) begin // half array `checkh($dimensions (array_lt[2:WA/2+1]), 3); `checkh($bits (array_lt[2:WA/2+1]), WA/2*WB*WC); if ((dim>=1)&&(dim<=3)) begin `checkh($left (array_lt[2:WA/2+1], dim), 2 ); `checkh($right (array_lt[2:WA/2+1], dim), wdt+1); `checkh($low (array_lt[2:WA/2+1], dim), 2 ); `checkh($high (array_lt[2:WA/2+1], dim), wdt+1); `checkh($increment (array_lt[2:WA/2+1], dim), -1 ); `checkh($size (array_lt[2:WA/2+1], dim), wdt ); end `endif end end end endmodule verilator-3.874/test_regress/t/t_detectarray_1.pl0000775000177100017500000000077312525171734022127 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["-Wno-CLKDATA"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_f.vc0000664000177100017500000000036312473477707020616 0ustar wsnyderwsnyder// Test that environment substitutions work -f $VERILATOR_ROOT/test_regress/t/t_flag_f__2.vc // Env var with .v file, and parens ${VERILATOR_ROOT}/test_regress/t/t_flag_f__3.v // Test -f -F $VERILATOR_ROOT/test_regress/t/tsub/t_flag_f_tsub.vc verilator-3.874/test_regress/t/t_vpi_unimpl.v0000664000177100017500000000154512473477707021422 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2010 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. `ifdef VERILATOR //We call it via $c so we can verify DPI isn't required - see bug572 `else import "DPI-C" context function integer mon_check(); `endif module t (/*AUTOARG*/ // Inputs clk ); `ifdef VERILATOR `systemc_header extern "C" int mon_check(); `verilog `endif input clk; reg onebit /*verilator public_flat_rw @(posedge clk) */; integer status; // Test loop initial begin `ifdef VERILATOR status = $c32("mon_check()"); `else status = mon_check(); `endif $write("*-* All Finished *-*\n"); $finish; end endmodule : t verilator-3.874/test_regress/t/t_array_pattern_unpacked.v0000664000177100017500000000354412473477707023766 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Iztok Jeras. module t (/*AUTOARG*/); logic [3:0] array_simp [1:0] [3:0]; // big endian array initial begin array_simp[0] = '{ 4'd3, 4'd2, 4'd1, 4'd0}; if ({array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 16'h3210) $stop; // verilator lint_off WIDTH array_simp[0] = '{ 3 ,2 ,1, 0 }; // verilator lint_on WIDTH if ({array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 16'h3210) $stop; // Doesn't seem to work for unpacked arrays in other simulators //array_simp[0] = '{ 1:4'd3, default:13 }; //if ({array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 16'hDD3D) $stop; array_simp = '{ '{ 4'd3, 4'd2, 4'd1, 4'd0 }, '{ 4'd1, 4'd2, 4'd3, 4'd4 }}; if ({array_simp[1][3],array_simp[1][2],array_simp[1][1],array_simp[1][0], array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 32'h3210_1234) $stop; // Doesn't seem to work for unpacked arrays in other simulators array_simp = '{2{ '{4'd3, 4'd2, 4'd1, 4'd0 } }}; if ({array_simp[1][3],array_simp[1][2],array_simp[1][1],array_simp[1][0], array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 32'h3210_3210) $stop; array_simp = '{2{ '{4{ 4'd3 }} }}; if ({array_simp[1][3],array_simp[1][2],array_simp[1][1],array_simp[1][0], array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 32'h3333_3333) $stop; // Not legal in other simulators - replication doesn't match // However IEEE suggests this is legal. //array_simp = '{2{ '{2{ 4'd3, 4'd2 }} }}; // Note it's not '{3,2} $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_order_quad.pl0000775000177100017500000000110512473477707021526 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe","$Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_cover_toggle.pl0000775000177100017500000000127012473477707022063 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ['--cc --coverage-toggle --stats'], ); execute ( check_finished=>1, ); # Read the input .v file and do any CHECK_COVER requests inline_checks(); file_grep ($Self->{stats}, qr/Coverage, Toggle points joined\s+(\d+)/i, 25) if $Self->{vlt}; ok(1); 1; verilator-3.874/test_regress/t/t_clk_vecgen3.pl0000775000177100017500000000103312473477707021564 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_clk_vecgen1.v"); compile ( v_flags2 => ['+define+T_TEST3',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_chain.v0000664000177100017500000000142212473477707021474 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t (/*AUTOARG*/); function integer max2; input integer x; input integer y; begin begin : blk automatic int temp; temp = x; end end max2 = ( x > y ) ? x : y; endfunction function integer max4; input integer x; input integer y; input integer z; input integer w; // MAX2 is used multiple times max4 = max2( max2( x, y ), max2( z, w ) ); endfunction localparam MAX4 = max4( 1, 1, 0, 0 ); initial begin if (MAX4 != 1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_math_cmp.pl0000775000177100017500000000071712473477707021201 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_array_bad.pl0000775000177100017500000000125712473477707022372 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_inst_array_bad.v:\d+: Input port connection 'onebit' as part of a module instance array requires 1 or 8 bits, but connection's VARREF 'onebitbad' generates 9 bits. %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_repeat.v0000664000177100017500000000133212473477707020512 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/); reg signed [2:0] negcnt; integer times; initial begin times = 0; repeat (1) begin repeat (0) $stop; repeat (-1) $stop; negcnt = 'sb111; // Not all commercial simulators agree on the below stopping or not // verilator lint_off WIDTH repeat (negcnt) $stop; // verilator lint_on WIDTH repeat (5) begin repeat (2) begin times = times + 1; end end end if (times != 10) $stop; // forever begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_interface_modport.v0000664000177100017500000000613012473477707022737 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. interface counter_if; logic [3:0] value; logic reset; modport counter_mp (input reset, output value); modport core_mp (output reset, input value); endinterface // Check can have inst module before top module module counter_ansi ( input clkm, counter_if c_data, input logic [3:0] i_value ); always @ (posedge clkm) begin c_data.value <= c_data.reset ? i_value : c_data.value + 1; end endmodule : counter_ansi module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; counter_if c1_data(); counter_if c2_data(); counter_if c3_data(); counter_if c4_data(); counter_ansi c1 (.clkm(clk), .c_data(c1_data.counter_mp), .i_value(4'h1)); `ifdef VERILATOR counter_ansi `else counter_nansi `endif /**/ c2 (.clkm(clk), .c_data(c2_data.counter_mp), .i_value(4'h2)); counter_ansi_m c3 (.clkm(clk), .c_data(c3_data), .i_value(4'h3)); `ifdef VERILATOR counter_ansi_m `else counter_nansi_m `endif /**/ c4 (.clkm(clk), .c_data(c4_data), .i_value(4'h4)); initial begin c1_data.value = 4'h4; c2_data.value = 4'h5; c3_data.value = 4'h6; c4_data.value = 4'h7; end always @ (posedge clk) begin cyc <= cyc + 1; if (cyc<2) begin c1_data.reset <= 1; c2_data.reset <= 1; c3_data.reset <= 1; c4_data.reset <= 1; end if (cyc==2) begin c1_data.reset <= 0; c2_data.reset <= 0; c3_data.reset <= 0; c4_data.reset <= 0; end if (cyc==20) begin $write("[%0t] cyc%0d: c1 %0x %0x c2 %0x %0x c3 %0x %0x c4 %0x %0x\n", $time, cyc, c1_data.value, c1_data.reset, c2_data.value, c2_data.reset, c3_data.value, c3_data.reset, c4_data.value, c4_data.reset); if (c1_data.value != 2) $stop; if (c2_data.value != 3) $stop; if (c3_data.value != 4) $stop; if (c4_data.value != 5) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule `ifndef VERILATOR // non-ansi modports not seen in the wild yet. Verilog-Perl needs parser improvement too. module counter_nansi (clkm, c_data, i_value); input clkm; counter_if c_data; input logic [3:0] i_value; always @ (posedge clkm) begin c_data.value <= c_data.reset ? i_value : c_data.value + 1; end endmodule : counter_nansi `endif module counter_ansi_m ( input clkm, counter_if.counter_mp c_data, input logic [3:0] i_value ); always @ (posedge clkm) begin c_data.value <= c_data.reset ? i_value : c_data.value + 1; end endmodule : counter_ansi_m `ifndef VERILATOR // non-ansi modports not seen in the wild yet. Verilog-Perl needs parser improvement too. module counter_nansi_m (clkm, c_data, i_value); input clkm; counter_if.counter_mp c_data; input logic [3:0] i_value; always @ (posedge clkm) begin c_data.value <= c_data.reset ? i_value : c_data.value + 1; end endmodule : counter_nansi_m `endif verilator-3.874/test_regress/t/t_enum_public.cpp0000664000177100017500000000122212473477707022047 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. #include #include "Vt_enum_public.h" #include "Vt_enum_public_p3.h" #include "Vt_enum_public_p62.h" int main (int argc, char *argv[]) { Vt_enum_public *topp = new Vt_enum_public; Verilated::debug(0); // Make sure public tag worked if (Vt_enum_public_p3::ZERO || Vt_enum_public_p3::ONE) {} if (Vt_enum_public_p62::ZERO || Vt_enum_public_p62::ALLONE) {} for (int i = 0; i < 10; i++) { topp->eval(); } } verilator-3.874/test_regress/t/t_inst_dtree_inlab.pl0000775000177100017500000000112012473477707022703 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_dtree.v"); compile ( v_flags2 => ['+define+INLINE_A +define+INLINE_B'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface1_modport_nansi.pl0000775000177100017500000000104512525171734024346 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_interface1_modport.v"); compile ( v_flags2 => ['+define+NANSI'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gated_clk_1.pl0000775000177100017500000000072212473477707021542 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_packed.v0000664000177100017500000001124412473477707021322 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; //Simple debug: //wire [1:1] wir_a [3:3] [2:2]; //11 //logic [1:1] log_a [3:3] [2:2]; //12 //wire [3:3] [2:2] [1:1] wir_p; //13 //logic [3:3] [2:2] [1:1] log_p; //14 integer cyc; initial cyc = 0; `ifdef iverilog reg [7:0] arr [3:0]; wire [7:0] arr_w [3:0]; `else reg [3:0] [7:0] arr; wire [3:0] [7:0] arr_w; `endif reg [7:0] sum; reg [7:0] sum_w; integer i0; initial begin for (i0=0; i0<5; i0=i0+1) begin arr[i0] = 1 << (i0[1:0]*2); end end assign arr_w = arr; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin // Setup sum <= 0; sum_w <= 0; end else if (cyc >= 10 && cyc < 14) begin sum <= sum + arr[cyc-10]; sum_w <= sum_w + arr_w[cyc-10]; end else if (cyc==99) begin $write("[%0t] cyc==%0d sum=%x\n",$time, cyc, sum); if (sum != 8'h55) $stop; if (sum != sum_w) $stop; $write("*-* All Finished *-*\n"); $finish; end end // Test ordering of packed dimensions logic [31:0] data_out; logic [31:0] data_out2; logic [0:0] [2:0] [31:0] data_in; logic [31:0] data_in2 [0:0] [2:0]; assign data_out = data_in[0][0] + data_in[0][1] + data_in[0][2]; assign data_out2 = data_in2[0][0] + data_in2[0][1] + data_in2[0][2]; logic [31:0] last_data_out; always @ (posedge clk) begin if (cyc <= 2) begin data_in[0][0] <= 0; data_in[0][1] <= 0; data_in[0][2] <= 0; data_in2[0][0] <= 0; data_in2[0][1] <= 0; data_in2[0][2] <= 0; end else if (cyc > 2 && cyc < 99) begin data_in[0][0] <= data_in[0][0] + 1; data_in[0][1] <= data_in[0][1] + 1; data_in[0][2] <= data_in[0][2] + 1; data_in2[0][0] <= data_in2[0][0] + 1; data_in2[0][1] <= data_in2[0][1] + 1; data_in2[0][2] <= data_in2[0][2] + 1; last_data_out <= data_out; `ifdef TEST_VERBOSE $write("data_out %0x %0x\n", data_out, last_data_out); `endif if (cyc > 4 && data_out != last_data_out + 3) $stop; if (cyc > 4 && data_out != data_out2) $stop; end end // Test for mixed implicit/explicit dimensions and all implicit packed bit [3:0][7:0][1:0] vld [1:0][1:0]; bit [3:0][7:0][1:0] vld2; // There are specific nodes for Or, Xor, Xnor and And logic vld_or; logic vld2_or; assign vld_or = |vld[0][0]; assign vld2_or = |vld2; logic vld_xor; logic vld2_xor; assign vld_xor = ^vld[0][0]; assign vld2_xor = ^vld2; logic vld_xnor; logic vld2_xnor; assign vld_xnor = ~^vld[0][0]; assign vld2_xnor = ~^vld2; logic vld_and; logic vld2_and; assign vld_and = &vld[0][0]; assign vld2_and = &vld2; // Bit reductions should be cloned, other unary operations should clone the // entire assign. bit [3:0][7:0][1:0] not_lhs; bit [3:0][7:0][1:0] not_rhs; assign not_lhs = ~not_rhs; // Test an AstNodeUniop that shouldn't be expanded bit [3:0][7:0][1:0] vld2_inv; assign vld2_inv = ~vld2; initial begin for (int i=0; i<4; i=i+2) begin for (int j=0; j<8; j=j+2) begin vld[0][0][i][j] = 2'b00; vld[0][0][i+1][j+1] = 2'b00; vld2[i][j] = 2'b00; vld2[i+1][j+1] = 2'b00; not_rhs[i][j] = i[1:0]; not_rhs[i+1][j+1] = i[1:0]; end end end logic [3:0] expect_cyc; initial expect_cyc = 'd15; always @(posedge clk) begin expect_cyc <= expect_cyc + 1; for (int i=0; i<4; i=i+1) begin for (int j=0; j<8; j=j+1) begin vld[0][0][i][j] <= vld[0][0][i][j] + 1; vld2[i][j] <= vld2[i][j] + 1; if (not_rhs[i][j] != ~not_lhs[i][j]) $stop; not_rhs[i][j] <= not_rhs[i][j] + 1; end end if (cyc % 8 == 0) begin vld[0][0][0][0] <= vld[0][0][0][0] - 1; vld2[0][0] <= vld2[0][0] - 1; end if (expect_cyc < 8 && !vld_xor) $stop; else if (expect_cyc > 7 && vld_xor) $stop; if (expect_cyc < 8 && vld_xnor) $stop; else if (expect_cyc > 7 && !vld_xnor) $stop; if (expect_cyc == 15 && vld_or) $stop; else if (expect_cyc == 11 && vld_or) $stop; else if (expect_cyc != 15 && expect_cyc != 11 && !vld_or) $stop; if (expect_cyc == 10 && !vld_and) $stop; else if (expect_cyc == 14 && !vld_and) $stop; else if (expect_cyc != 10 && expect_cyc != 14 && vld_and) $stop; if (vld_xor != vld2_xor) $stop; if (vld_xnor != vld2_xnor) $stop; if (vld_or != vld2_or) $stop; if (vld_and != vld2_and) $stop; end endmodule verilator-3.874/test_regress/t/t_select_negative.pl0000775000177100017500000000071712473477707022552 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_gate_pmos.pl0000775000177100017500000000133712473477707022244 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_tri_gate.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ['+define+T_PMOS',], make_flags => 'CPPFLAGS_ADD=-DT_PMOS', verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_pindup_bad.v0000664000177100017500000000063712473477707022374 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t ( output wire o, input wire i, input wire i2 ); sub #(, .P(2), .P(3)) sub (.o(o), .i(i), .i(i2), ); endmodule module sub #(parameter P=1) ( output wire o, input wire i ); assign o = ~i; endmodule verilator-3.874/test_regress/t/t_tri_gate_cond.pl0000775000177100017500000000133712473477707022211 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_tri_gate.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ['+define+T_COND',], make_flags => 'CPPFLAGS_ADD=-DT_COND', verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_itemwidth.v0000664000177100017500000000457712473477707022241 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // Some inputs we'll set to random values reg [6:0] addr; reg [6:0] e0; reg [5:0] e1; reg [5:0] e2; wire [7:0] data; reg [2:0] wrapcheck_a; reg [2:0] wrapcheck_b; test test (/*AUTOINST*/ // Outputs .data (data[7:0]), // Inputs .addr (addr[6:0]), .e0 (e0[6:0]), .e1 (e1[5:0]), .e2 (e2[5:0])); always @(/*AS*/addr) begin case(addr[2:0]) 3'd0+3'd0: wrapcheck_a = 3'h0; 3'd0+3'd1: wrapcheck_a = 3'h1; 3'd0+3'd2: wrapcheck_a = 3'h2; 3'd0+3'd3: wrapcheck_a = 3'h3; default: wrapcheck_a = 3'h4; endcase case(addr[2:0]) 3'd0+0: wrapcheck_b = 3'h0; 3'd1+1: wrapcheck_b = 3'h1; 3'd2+2: wrapcheck_b = 3'h2; 3'd3+3: wrapcheck_b = 3'h3; default: wrapcheck_b = 3'h4; endcase end integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; //$write("%d %x %x %x\n", cyc, data, wrapcheck_a, wrapcheck_b); if (cyc==1) begin addr <= 7'h28; e0 <= 7'h11; e1 <= 6'h02; e2 <= 6'h03; end if (cyc==2) begin addr <= 7'h2b; if (data != 8'h11) $stop; end if (cyc==3) begin addr <= 7'h2c; if (data != 8'h03) $stop; if (wrapcheck_a != 3'h3) $stop; if (wrapcheck_b != 3'h4) $stop; end if (cyc==4) begin addr <= 7'h0; if (data != 8'h00) $stop; if (wrapcheck_a != 3'h4) $stop; if (wrapcheck_b != 3'h2) $stop; end if (cyc==5) begin if (data != 8'h00) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule /* verilator lint_off WIDTH */ `define AI 7'h28 module test (/*AUTOARG*/ // Outputs data, // Inputs addr, e0, e1, e2 ); output [7:0] data; input [6:0] addr; input [6:0] e0; input [5:0] e1, e2; reg [7:0] data; always @(/*AS*/addr or e0 or e1 or e2) begin case (addr) `AI: data = {e0[6], 1'b0, e0[5:0]}; `AI+1: data = e1; `AI+2, `AI+3: data = e2; default: data = 0; endcase end endmodule // Local Variables: // eval:(verilog-read-defines) // verilog-auto-sense-defines-constant: t // End: verilator-3.874/test_regress/t/t_lint_unused_bad.pl0000775000177100017500000000236612473477707022552 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only --bbox-sys --bbox-unsup -Wall -Wno-DECLFILENAME"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning-UNUSED: t/t_lint_unused_bad.v:\d+: Bits of signal are not used: assunu1\[5:1\] %Warning-UNUSED: Use .* to disable this message. %Warning-UNDRIVEN: t/t_lint_unused_bad.v:\d+: Bits of signal are not driven: udrb2\[14:13,11\] %Warning-UNUSED: t/t_lint_unused_bad.v:\d+: Signal is not driven, nor used: unu3 %Warning-UNUSED: t/t_lint_unused_bad.v:\d+: Bits of signal are not driven, nor used: mixed\[3\] %Warning-UNUSED: t/t_lint_unused_bad.v:\d+: Bits of signal are not used: mixed\[2\] %Warning-UNDRIVEN: t/t_lint_unused_bad.v:\d+: Bits of signal are not driven: mixed\[1\] %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_extend_class_c.h0000664000177100017500000000073412473477707022177 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006-2009 by Wilson Snyder. class t_extend_class_c { public: // CONSTRUCTORS t_extend_class_c() {} ~t_extend_class_c() {} // METHODS // This function will be called from a instance created in Verilog inline vluint32_t my_math(vluint32_t in) { return in+1; } }; verilator-3.874/test_regress/t/t_struct_packed_write_read.v0000664000177100017500000001237412473477707024302 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; localparam NO = 10; // number of access events // packed structures struct packed { logic e0; logic [1:0] e1; logic [3:0] e2; logic [7:0] e3; } struct_bg; // big endian structure /* verilator lint_off LITENDIAN */ struct packed { logic e0; logic [0:1] e1; logic [0:3] e2; logic [0:7] e3; } struct_lt; // little endian structure /* verilator lint_on LITENDIAN */ localparam WS = 15; // $bits(struct_bg) integer cnt = 0; // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if ((cnt[30:2]==NO) && (cnt[1:0]==2'd0)) begin $write("*-* All Finished *-*\n"); $finish; end // big endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaaults (all bits to 0) if (cnt[30:2]==0) struct_bg <= '0; else if (cnt[30:2]==1) struct_bg <= '0; else if (cnt[30:2]==2) struct_bg <= '0; else if (cnt[30:2]==3) struct_bg <= '0; else if (cnt[30:2]==4) struct_bg <= '0; else if (cnt[30:2]==5) struct_bg <= '0; end else if (cnt[1:0]==2'd1) begin // write value to structure if (cnt[30:2]==0) begin end else if (cnt[30:2]==1) struct_bg <= '1; else if (cnt[30:2]==2) struct_bg.e0 <= '1; else if (cnt[30:2]==3) struct_bg.e1 <= '1; else if (cnt[30:2]==4) struct_bg.e2 <= '1; else if (cnt[30:2]==5) struct_bg.e3 <= '1; end else if (cnt[1:0]==2'd2) begin // check structure value if (cnt[30:2]==0) begin if (struct_bg !== 15'b000000000000000) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==1) begin if (struct_bg !== 15'b111111111111111) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==2) begin if (struct_bg !== 15'b100000000000000) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==3) begin if (struct_bg !== 15'b011000000000000) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==4) begin if (struct_bg !== 15'b000111100000000) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==5) begin if (struct_bg !== 15'b000000011111111) begin $display("%b", struct_bg); $stop(); end end end else if (cnt[1:0]==2'd3) begin // read value from structure (not a very good test for now) if (cnt[30:2]==0) begin if (struct_bg !== {WS{1'b0}}) $stop(); end else if (cnt[30:2]==1) begin if (struct_bg !== {WS{1'b1}}) $stop(); end else if (cnt[30:2]==2) begin if (struct_bg.e0 !== { 1{1'b1}}) $stop(); end else if (cnt[30:2]==3) begin if (struct_bg.e1 !== { 2{1'b1}}) $stop(); end else if (cnt[30:2]==4) begin if (struct_bg.e2 !== { 4{1'b1}}) $stop(); end else if (cnt[30:2]==5) begin if (struct_bg.e3 !== { 8{1'b1}}) $stop(); end end // little endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaaults (all bits to 0) if (cnt[30:2]==0) struct_lt <= '0; else if (cnt[30:2]==1) struct_lt <= '0; else if (cnt[30:2]==2) struct_lt <= '0; else if (cnt[30:2]==3) struct_lt <= '0; else if (cnt[30:2]==4) struct_lt <= '0; else if (cnt[30:2]==5) struct_lt <= '0; end else if (cnt[1:0]==2'd1) begin // write value to structure if (cnt[30:2]==0) begin end else if (cnt[30:2]==1) struct_lt <= '1; else if (cnt[30:2]==2) struct_lt.e0 <= '1; else if (cnt[30:2]==3) struct_lt.e1 <= '1; else if (cnt[30:2]==4) struct_lt.e2 <= '1; else if (cnt[30:2]==5) struct_lt.e3 <= '1; end else if (cnt[1:0]==2'd2) begin // check structure value if (cnt[30:2]==0) begin if (struct_lt !== 15'b000000000000000) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==1) begin if (struct_lt !== 15'b111111111111111) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==2) begin if (struct_lt !== 15'b100000000000000) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==3) begin if (struct_lt !== 15'b011000000000000) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==4) begin if (struct_lt !== 15'b000111100000000) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==5) begin if (struct_lt !== 15'b000000011111111) begin $display("%b", struct_lt); $stop(); end end end else if (cnt[1:0]==2'd3) begin // read value from structure (not a very good test for now) if (cnt[30:2]==0) begin if (struct_lt !== {WS{1'b0}}) $stop(); end else if (cnt[30:2]==1) begin if (struct_lt !== {WS{1'b1}}) $stop(); end else if (cnt[30:2]==2) begin if (struct_lt.e0 !== { 1{1'b1}}) $stop(); end else if (cnt[30:2]==3) begin if (struct_lt.e1 !== { 2{1'b1}}) $stop(); end else if (cnt[30:2]==4) begin if (struct_lt.e2 !== { 4{1'b1}}) $stop(); end else if (cnt[30:2]==5) begin if (struct_lt.e3 !== { 8{1'b1}}) $stop(); end end endmodule verilator-3.874/test_regress/t/t_dpi_shortcircuit.pl0000775000177100017500000000130412473477707022760 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug413 short circuit"); compile ( # Amazingly VCS, NC and Verilator all just accept the C file here! v_flags2 => ["t/t_dpi_shortcircuit_c.cpp"], verilator_flags2 => ["-Wno-DECLFILENAME"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_packed_value_list.v0000664000177100017500000001174112473477707024321 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; localparam NO = 7; // number of access events // packed structures struct packed { logic e0; logic [1:0] e1; logic [3:0] e2; logic [7:0] e3; } struct_bg; // big endian structure /* verilator lint_off LITENDIAN */ struct packed { logic e0; logic [0:1] e1; logic [0:3] e2; logic [0:7] e3; } struct_lt; // little endian structure /* verilator lint_on LITENDIAN */ localparam WS = 15; // $bits(struct_bg) integer cnt = 0; // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if ((cnt[30:2]==(NO-1)) && (cnt[1:0]==2'd3)) begin $write("*-* All Finished *-*\n"); $finish; end // big endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaults (all bits 1'b0) if (cnt[30:2]==0) struct_bg <= '0; else if (cnt[30:2]==1) struct_bg <= '0; else if (cnt[30:2]==2) struct_bg <= '0; else if (cnt[30:2]==3) struct_bg <= '0; else if (cnt[30:2]==4) struct_bg <= '0; else if (cnt[30:2]==5) struct_bg <= '0; else if (cnt[30:2]==6) struct_bg <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]==0) begin end else if (cnt[30:2]==1) struct_bg <= '{0 ,1 , 2, 3}; else if (cnt[30:2]==2) struct_bg <= '{e0:1, e1:2, e2:3, e3:4}; else if (cnt[30:2]==3) struct_bg <= '{e3:6, e2:4, e1:2, e0:0}; // verilator lint_off WIDTH else if (cnt[30:2]==4) struct_bg <= '{default:13}; else if (cnt[30:2]==5) struct_bg <= '{e2:8'haa, default:1}; else if (cnt[30:2]==6) struct_bg <= '{cnt+0 ,cnt+1 , cnt+2, cnt+3}; // verilator lint_on WIDTH end else if (cnt[1:0]==2'd2) begin // chack array agains expected value if (cnt[30:2]==0) begin if (struct_bg !== 15'b0_00_0000_00000000) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==1) begin if (struct_bg !== 15'b0_01_0010_00000011) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==2) begin if (struct_bg !== 15'b1_10_0011_00000100) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==3) begin if (struct_bg !== 15'b0_10_0100_00000110) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==4) begin if (struct_bg !== 15'b1_01_1101_00001101) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==5) begin if (struct_bg !== 15'b1_01_1010_00000001) begin $display("%b", struct_bg); $stop(); end end else if (cnt[30:2]==6) begin if (struct_bg !== 15'b1_10_1011_00011100) begin $display("%b", struct_bg); $stop(); end end end // little endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaults (all bits 1'b0) if (cnt[30:2]==0) struct_lt <= '0; else if (cnt[30:2]==1) struct_lt <= '0; else if (cnt[30:2]==2) struct_lt <= '0; else if (cnt[30:2]==3) struct_lt <= '0; else if (cnt[30:2]==4) struct_lt <= '0; else if (cnt[30:2]==5) struct_lt <= '0; else if (cnt[30:2]==6) struct_lt <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]==0) begin end else if (cnt[30:2]==1) struct_lt <= '{0 ,1 , 2, 3}; else if (cnt[30:2]==2) struct_lt <= '{e0:1, e1:2, e2:3, e3:4}; else if (cnt[30:2]==3) struct_lt <= '{e3:6, e2:4, e1:2, e0:0}; // verilator lint_off WIDTH else if (cnt[30:2]==4) struct_lt <= '{default:13}; else if (cnt[30:2]==5) struct_lt <= '{e2:8'haa, default:1}; else if (cnt[30:2]==6) struct_lt <= '{cnt+0 ,cnt+1 , cnt+2, cnt+3}; // verilator lint_on WIDTH end else if (cnt[1:0]==2'd2) begin // chack array agains expected value if (cnt[30:2]==0) begin if (struct_lt !== 15'b0_00_0000_00000000) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==1) begin if (struct_lt !== 15'b0_01_0010_00000011) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==2) begin if (struct_lt !== 15'b1_10_0011_00000100) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==3) begin if (struct_lt !== 15'b0_10_0100_00000110) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==4) begin if (struct_lt !== 15'b1_01_1101_00001101) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==5) begin if (struct_lt !== 15'b1_01_1010_00000001) begin $display("%b", struct_lt); $stop(); end end else if (cnt[30:2]==6) begin if (struct_lt !== 15'b1_10_1011_00011100) begin $display("%b", struct_lt); $stop(); end end end endmodule verilator-3.874/test_regress/t/t_inst_dtree_inld.pl0000775000177100017500000000107712473477707022557 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_dtree.v"); compile ( v_flags2 => ['+define+INLINE_D'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_ldflags_a.cpp0000664000177100017500000000133712473477707022461 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* extern "C" { void dpii_a_library() {} }; verilator-3.874/test_regress/t/t_var_outoforder.pl0000775000177100017500000000071712473477707022451 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem.v0000664000177100017500000000274212525171734020003 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // [16] is SV syntax for [0:15] reg [7:0] memory8_16 [16]; reg m_we; reg [3:1] m_addr; reg [15:0] m_data; always @ (posedge clk) begin // Load instructions from cache memory8_16[{m_addr,1'd0}] <= 8'hfe; if (m_we) begin {memory8_16[{m_addr,1'd1}], memory8_16[{m_addr,1'd0}]} <= m_data; end end reg [7:0] memory8_16_4; reg [7:0] memory8_16_5; // Test complicated sensitivity lists always @ (memory8_16[4][7:1] or memory8_16[5]) begin memory8_16_4 = memory8_16[4]; memory8_16_5 = memory8_16[5]; end always @ (posedge clk) begin m_we <= 0; if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin m_we <= 1'b1; m_addr <= 3'd2; m_data <= 16'h55_44; end if (cyc==2) begin m_we <= 1'b1; m_addr <= 3'd3; m_data <= 16'h77_66; end if (cyc==3) begin m_we <= 0; // Check we really don't write this m_addr <= 3'd3; m_data <= 16'h0bad; end if (cyc==5) begin if (memory8_16_4 != 8'h44) $stop; if (memory8_16_5 != 8'h55) $stop; if (memory8_16[6] != 8'hfe) $stop; if (memory8_16[7] != 8'h77) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_var_init.pl0000775000177100017500000000071712473477707021224 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_bitsel_struct.v0000664000177100017500000000125012473477707022117 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // A test case for struct signal bit selection. // // This test is to check that bit selection of multi-dimensional signal inside // of a struct works. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jie Xu. module t(/*AUTOARG*/ // Inputs clk ); input clk; typedef struct packed { logic [1:0][15:0] channel; logic others; } buss_t; buss_t b; reg [7:0] a; initial begin b = {16'h8765,16'h4321,1'b1}; a = b.channel[0][8+:8]; if (a != 8'h43) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_gen_var_bad.v0000664000177100017500000000044312473477707021463 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t; integer i; generate for (i=0; i<3; i=i+1) begin // Bad: i is not a genvar end endgenerate endmodule verilator-3.874/test_regress/t/t_assert_basic.pl0000775000177100017500000000102112473477707022040 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_vec_sel.pl0000775000177100017500000000104212473477707021671 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_swap.pl0000775000177100017500000000071712473477707021374 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_repl.pl0000775000177100017500000000071712473477707021533 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_select_unsized.v0000664000177100017500000000141512473477707023132 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test of selection with unsized Z. // // Test selecting Z when size is not explicit. Issue 510. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [1:0] b; wire [1:0] c; wire [0:0] d; // Explicit width due to issue 508 wire [0:0] e; // This works if we use 1'bz, or 1'bx, but not with just 'bz or 'bx. It // does require the tri-state Z. Since we get the same effect if b is // dimensioned [0:0], this may be connected to issue 508. assign b[1:0] = clk ? 2'bx : 'bz; assign c[1:0] = clk ? 2'bz : 'bx; assign d = clk ? 1'bx : 'bz; assign e = clk ? 1'bz : 'bx; endmodule // t verilator-3.874/test_regress/t/t_bitsel_struct.pl0000775000177100017500000000072212473477707022273 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_ccall.v0000664000177100017500000000241712473477707021352 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // verilator lint_on GENCLK reg [31:0] long; reg [63:0] quad; wire [31:0] longout; wire [63:0] quadout; wire [7:0] narrow = long[7:0]; sub sub (/*AUTOINST*/ // Outputs .longout (longout[31:0]), .quadout (quadout[63:0]), // Inputs .narrow (narrow[7:0]), .quad (quad[63:0])); always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin long <= 32'h12345678; quad <= 64'h12345678_abcdef12; end if (cyc==2) begin if (longout !== 32'h79) $stop; if (quadout !== 64'h12345678_abcdef13) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule module sub (input [7:0] narrow, input [63:0] quad, output [31:0] longout, output [63:0] quadout); // verilator public_module `ifdef verilator wire [31:0] longout = $c32("(",narrow,"+1)"); wire [63:0] quadout = $c64("(",quad,"+1)"); `else wire [31:0] longout = narrow + 8'd1; wire [63:0] quadout = quad + 64'd1; `endif endmodule verilator-3.874/test_regress/t/t_math_concat0.v0000664000177100017500000000411312473477707021572 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [15:0] in = crc[15:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [15:0] outa; // From test of Test.v wire [15:0] outb; // From test of Test.v wire [15:0] outc; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .outa (outa[15:0]), .outb (outb[15:0]), .outc (outc[15:0]), // Inputs .clk (clk), .in (in[15:0])); // Aggregate outputs into a single result vector wire [63:0] result = {16'h0, outa, outb, outc}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h09be74b1b0f8c35d if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs outa, outb, outc, // Inputs clk, in ); input clk; input [15:0] in; output reg [15:0] outa; output reg [15:0] outb; output reg [15:0] outc; parameter WIDTH = 0; always @(posedge clk) begin outa <= {in}; outb <= {{WIDTH{1'b0}}, in}; outc <= {in, {WIDTH{1'b0}}}; end endmodule verilator-3.874/test_regress/t/t_param.v0000664000177100017500000000275112473477707020340 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); parameter PAR = 3; m1 #(PAR) m1(); m3 #(PAR) m3(); mnooverride #(10) mno(); input clk; integer cyc=1; reg [4:0] bitsel; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin bitsel = 0; if (PAR[bitsel]!==1'b1) $stop; bitsel = 1; if (PAR[bitsel]!==1'b1) $stop; bitsel = 2; if (PAR[bitsel]!==1'b0) $stop; end if (cyc==1) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module m1; localparam PAR1MINUS1 = PAR1DUP-2-1; localparam PAR1DUP = PAR1+2; // Check we propagate parameters properly parameter PAR1 = 0; m2 #(PAR1MINUS1) m2 (); // Packed arrays localparam [1:0][3:0] PACKED_PARAM = { 4'h3, 4'h6 }; initial if (PACKED_PARAM != 8'h36) $stop; endmodule // bug 810 module m2 #(/*parameter*/ integer PAR2 = 10); initial begin $display("%x",PAR2); if (PAR2 !== 2) $stop; end endmodule module m3; localparam LOC = 13; parameter PAR = 10; initial begin $display("%x %x",LOC,PAR); if (LOC !== 13) $stop; if (PAR !== 3) $stop; end endmodule module mnooverride; localparam LOC = 13; parameter PAR = 10; initial begin $display("%x %x",LOC,PAR); if (LOC !== 13) $stop; if (PAR !== 10) $stop; end endmodule verilator-3.874/test_regress/t/t_sv_bus_mux_demux.v0000664000177100017500000001635112473477707022635 0ustar wsnyderwsnyder//////////////////////////////////////////////////////////////////////////////// // // // This file is placed into the Public Domain, for any use, without warranty. // // 2012 by Iztok Jeras // // // //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // // This testbench contains a bus source and a bus drain. The source creates // // address and data bus values, while the drain is the final destination of // // such pairs. All source and drain transfers are logged into memories, which // // are used at the end of simulation to check for data transfer correctness. // // Inside the RLT wrapper there is a multiplexer and a demultiplexer, they // // bus transfers into a 8bit data stream and back. Both stream input and // // output are exposed, they are connected together into a loopback. // // // // ----------- --------------------- // // | bso_mem | | wrap | // // ----------- | | // // ----------- | | ----------- | // // | bsi src | ------------> | -> | mux | -> | -> - sto // // ----------- | ----------- | \ // // | | | loopback // // ----------- | ----------- | / // // | bso drn | <------------ | <- | demux | <- | <- - sti // // ----------- | | ----------- | // // ----------- | | // // | bso_mem | | | // // ----------- --------------------- // // // // PROTOCOL: // // // // The 'vld' signal is driven by the source to indicate valid data is // // available, 'rdy' is used by the drain to indicate is is ready to accept // // valid data. A data transfer only happens if both 'vld' & 'rdy' are active. // // // //////////////////////////////////////////////////////////////////////////////// `timescale 1ns/1ps // include RTL files `include "t_sv_bus_mux_demux/sv_bus_mux_demux_def.sv" `include "t_sv_bus_mux_demux/sv_bus_mux_demux_demux.sv" `include "t_sv_bus_mux_demux/sv_bus_mux_demux_mux.sv" `include "t_sv_bus_mux_demux/sv_bus_mux_demux_wrap.sv" module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter SIZ = 10; // system signals //logic clk = 1'b1; // clock logic rst = 1'b1; // reset integer rst_cnt = 0; // input bus logic bsi_vld; // valid (chip select) logic [31:0] bsi_adr; // address logic [31:0] bsi_dat; // data logic bsi_rdy; // ready (acknowledge) logic bsi_trn; // data transfer logic [31:0] bsi_mem [SIZ]; // output stream logic sto_vld; // valid (chip select) logic [7:0] sto_bus; // data bus logic sto_rdy; // ready (acknowledge) // input stream logic sti_vld; // valid (chip select) logic [7:0] sti_bus; // data bus logic sti_rdy; // ready (acknowledge) // output bus logic bso_vld; // valid (chip select) logic [31:0] bso_adr; // address logic [31:0] bso_dat; // data logic bso_rdy; // ready (acknowledge) logic bso_trn; // data transfer logic [31:0] bso_mem [SIZ]; integer bso_cnt = 0; //////////////////////////////////////////////////////////////////////////////// // clock and reset //////////////////////////////////////////////////////////////////////////////// // clock toggling //always #5 clk = ~clk; // reset is removed after a delay always @ (posedge clk) begin rst_cnt <= rst_cnt + 1; rst <= rst_cnt <= 3; end // reset is removed after a delay always @ (posedge clk) if (bso_cnt == SIZ) begin if (bsi_mem === bso_mem) begin $write("*-* All Finished *-*\n"); $finish(); end else begin $display ("FAILED"); $stop(); end end //////////////////////////////////////////////////////////////////////////////// // input data generator //////////////////////////////////////////////////////////////////////////////// // input data transfer assign bsi_trn = bsi_vld & bsi_rdy; // valid (for SIZ transfers) always @ (posedge clk, posedge rst) if (rst) bsi_vld = 1'b0; else bsi_vld = (bsi_adr < SIZ); // address (increments every transfer) always @ (posedge clk, posedge rst) if (rst) bsi_adr <= 32'h00000000; else if (bsi_trn) bsi_adr <= bsi_adr + 'd1; // data (new random value generated after every transfer) always @ (posedge clk, posedge rst) if (rst) bsi_dat <= 32'h00000000; else if (bsi_trn) bsi_dat <= $random(); // storing transferred data into memory for final check always @ (posedge clk) if (bsi_trn) bsi_mem [bsi_adr] <= bsi_dat; //////////////////////////////////////////////////////////////////////////////// // RTL instance //////////////////////////////////////////////////////////////////////////////// sv_bus_mux_demux_wrap wrap ( // system signals .clk (clk), .rst (rst), // input bus .bsi_vld (bsi_vld), .bsi_adr (bsi_adr), .bsi_dat (bsi_dat), .bsi_rdy (bsi_rdy), // output stream .sto_vld (sto_vld), .sto_bus (sto_bus), .sto_rdy (sto_rdy), // input stream .sti_vld (sti_vld), .sti_bus (sti_bus), .sti_rdy (sti_rdy), // output bus .bso_vld (bso_vld), .bso_adr (bso_adr), .bso_dat (bso_dat), .bso_rdy (bso_rdy) ); // stream output from mux is looped back into stream input for demux assign sti_vld = sto_vld; assign sti_bus = sto_bus; assign sto_rdy = sti_rdy; //////////////////////////////////////////////////////////////////////////////// // output data monitor //////////////////////////////////////////////////////////////////////////////// // input data transfer assign bso_trn = bso_vld & bso_rdy; // output transfer counter used to end the test always @ (posedge clk, posedge rst) if (rst) bso_cnt <= 0; else if (bso_trn) bso_cnt <= bso_cnt + 1; // storing transferred data into memory for final check always @ (posedge clk) if (bso_trn) bso_mem [bso_adr] <= bso_dat; // every output transfer against expected value stored in memory always @ (posedge clk) if (bso_trn && (bsi_mem [bso_adr] !== bso_dat)) $display ("@%08h i:%08h o:%08h", bso_adr, bsi_mem [bso_adr], bso_dat); // ready is active for SIZ transfers always @ (posedge clk, posedge rst) if (rst) bso_rdy = 1'b0; else bso_rdy = 1'b1; endmodule : sv_bus_mux_demux_tb verilator-3.874/test_regress/t/t_assert_basic_fail.pl0000775000177100017500000000120212473477707023034 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_assert_basic.v"); compile ( v_flags2 => ['+define+FAILING_ASSERTIONS', $Self->{v3}?'--assert':($Self->{nc}?'+assert':'')], fails => $Self->{nc}, ); execute ( fails => $Self->{vlt}, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_width.v0000664000177100017500000000241712473477707021367 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (); // See also t_lint_width parameter A_ONE = '1; // verilator lint_off WIDTH parameter [3:0] A_W4 = A_ONE; // verilator lint_on WIDTH initial begin if ($bits(A_ONE) != 1 || A_ONE !== 1'b1) $stop; if ($bits(A_W4) != 4) $stop; if (A_W4 != 4'b0001) $stop; end b #(.B_WIDTH(48)) b (); reg [4:0] c; integer c_i; initial begin c_i = 3; c = 1'b1 << c_i; // No width warning when not embedded in expression, as is common syntax if (c != 5'b1000) $stop; end localparam D_TT = 32'd23; localparam D_SIX = 6; // verilator lint_off WIDTH localparam [5:0] D_SUB = D_TT - D_SIX; // verilator lint_on WIDTH initial begin if (D_SUB != 17) $stop; end initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule module b; parameter B_WIDTH = 1; localparam B_VALUE0 = {B_WIDTH{1'b0}}; localparam B_VALUE1 = {B_WIDTH{1'b1}}; reg [47:0] b_val; initial begin b_val = B_VALUE0; if (b_val != 48'b0) $stop; b_val = B_VALUE1; if (b_val != ~48'b0) $stop; end endmodule verilator-3.874/test_regress/t/t_gen_intdot2.v0000664000177100017500000001032712473477707021452 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg check; initial check = 1'b0; Genit g (.clk(clk), .check(check)); always @ (posedge clk) begin //$write("[%0t] cyc==%0d %x %x\n",$time, cyc, check, out); cyc <= cyc + 1; if (cyc==0) begin // Setup check <= 1'b0; end else if (cyc==1) begin check <= 1'b1; end else if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end //`define WAVES `ifdef WAVES initial begin $dumpfile("obj_dir/t_gen_intdot2/t_gen_intdot.vcd"); $dumpvars(12, t); end `endif endmodule module One; wire one = 1'b1; endmodule module Genit ( input clk, input check); // ARRAY One cellarray1[1:0] (); //cellarray[0..1][0..1] always @ (posedge clk) if (cellarray1[0].one !== 1'b1) $stop; always @ (posedge clk) if (cellarray1[1].one !== 1'b1) $stop; // IF generate // genblk1 refers to the if's name, not the "generate" itself. if (1'b1) // IMPLIED begin: genblk1 One ifcell1(); // genblk1.ifcell1 else One ifcell1(); // genblk1.ifcell1 endgenerate // On compliant simulators "Implicit name" not allowed here; IE we can't use "genblk1" etc `ifdef verilator always @ (posedge clk) if (genblk1.ifcell1.one !== 1'b1) $stop; //`else // NOT SUPPORTED accoring to spec - generic block references `endif generate begin : namedif2 if (1'b1) One ifcell2(); // namedif2.genblk1.ifcell2 end endgenerate `ifdef verilator always @ (posedge clk) if (namedif2.genblk1.ifcell2.one !== 1'b1) $stop; //`else // NOT SUPPORTED accoring to spec - generic block references `endif generate if (1'b1) begin : namedif3 One ifcell3(); // namedif3.ifcell3 end endgenerate always @ (posedge clk) if (namedif3.ifcell3.one !== 1'b1) $stop; // CASE generate case (1'b1) 1'b1 : One casecell10(); // genblk3.casecell10 endcase endgenerate `ifdef verilator always @ (posedge clk) if (genblk3.casecell10.one !== 1'b1) $stop; //`else // NOT SUPPORTED accoring to spec - generic block references `endif generate case (1'b1) 1'b1 : begin : namedcase11 One casecell11(); end endcase endgenerate always @ (posedge clk) if (namedcase11.casecell11.one !== 1'b1) $stop; genvar i; genvar j; // IF generate for (i = 0; i < 2; i = i + 1) One cellfor20 (); // genblk4[0..1].cellfor20 endgenerate `ifdef verilator always @ (posedge clk) if (genblk4[0].cellfor20.one !== 1'b1) $stop; always @ (posedge clk) if (genblk4[1].cellfor20.one !== 1'b1) $stop; //`else // NOT SUPPORTED accoring to spec - generic block references `endif // COMBO generate for (i = 0; i < 2; i = i + 1) begin : namedfor21 One cellfor21 (); // namedfor21[0..1].cellfor21 end endgenerate always @ (posedge clk) if (namedfor21[0].cellfor21.one !== 1'b1) $stop; always @ (posedge clk) if (namedfor21[1].cellfor21.one !== 1'b1) $stop; generate for (i = 0; i < 2; i = i + 1) begin : namedfor30 for (j = 0; j < 2; j = j + 1) begin : forb30 if (j == 0) begin : forif30 One cellfor30a (); // namedfor30[0..1].forb30[0].forif30.cellfor30a end else `ifdef verilator begin : forif30b `else begin : forif30 // forif30 seems to work on some simulators, not verilator yet `endif One cellfor30b (); // namedfor30[0..1].forb30[1].forif30.cellfor30b end end end endgenerate always @ (posedge clk) if (namedfor30[0].forb30[0].forif30.cellfor30a.one !== 1'b1) $stop; always @ (posedge clk) if (namedfor30[1].forb30[0].forif30.cellfor30a.one !== 1'b1) $stop; `ifdef verilator always @ (posedge clk) if (namedfor30[0].forb30[1].forif30b.cellfor30b.one !== 1'b1) $stop; always @ (posedge clk) if (namedfor30[1].forb30[1].forif30b.cellfor30b.one !== 1'b1) $stop; `else always @ (posedge clk) if (namedfor30[0].forb30[1].forif30.cellfor30b.one !== 1'b1) $stop; always @ (posedge clk) if (namedfor30[1].forb30[1].forif30.cellfor30b.one !== 1'b1) $stop; `endif endmodule verilator-3.874/test_regress/t/t_langext_2_bad.pl0000775000177100017500000000103612473477707022075 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_langext_2.v"); # This is a compile only test. compile ( v_flags2 => ["+1364-1995ext+v"], fails => 1 ); ok(1); 1; verilator-3.874/test_regress/t/t_math_svl.pl0000775000177100017500000000110612473477707021217 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2005 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. compile ( ); execute ( check_finished=>1, # Make sure we get the finish statement called expect=> '\*-\* All Finished \*-\* Goodbye world, at cycle \d+.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_gen3.v0000664000177100017500000000315612473477707022114 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // Very simple test for interface pathclearing module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc #(2) itopa(); ifc #(4) itopb(); sub ca (.isub(itopa.out_modport), .clk); sub cb (.isub(itopb.out_modport), .clk); always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d result=%b %b\n",$time, cyc, itopa.valueo, itopb.valueo); `endif cyc <= cyc + 1; itopa.valuei <= cyc[1:0]; itopb.valuei <= cyc[3:0]; if (cyc==1) begin if (itopa.WIDTH != 2) $stop; if (itopb.WIDTH != 4) $stop; if ($bits(itopa.valueo) != 2) $stop; if ($bits(itopb.valueo) != 4) $stop; if ($bits(itopa.out_modport.valueo) != 2) $stop; if ($bits(itopb.out_modport.valueo) != 4) $stop; end if (cyc==4) begin if (itopa.valueo != 2'b11) $stop; if (itopb.valueo != 4'b0011) $stop; end if (cyc==5) begin if (itopa.valueo != 2'b00) $stop; if (itopb.valueo != 4'b0100) $stop; end if (cyc==20) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule interface ifc #(parameter WIDTH = 1); // verilator lint_off MULTIDRIVEN logic [WIDTH-1:0] valuei; logic [WIDTH-1:0] valueo; // verilator lint_on MULTIDRIVEN modport out_modport (input valuei, output valueo); endinterface // Note not parameterized module sub ( ifc.out_modport isub, input clk ); always @(posedge clk) isub.valueo <= isub.valuei + 1; endmodule verilator-3.874/test_regress/t/t_unroll_signed.pl0000775000177100017500000000071712473477707022255 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_cond_const.v0000664000177100017500000000245212473477707022220 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test for generate IF constants // // The given generate loop should have a constant expression as argument. This // test checks it really does evaluate as constant. // This file ONLY is placed into the Public Domain, for any use, without // warranty, 2012 by Jeremy Bennett. `define MAX_SIZE 4 module t (/*AUTOARG*/ // Inputs clk ); input clk; // Set the parameters, so that we use a size less than MAX_SIZE test_gen #(.SIZE (2), .MASK (4'b1111)) i_test_gen (.clk (clk)); // This is only a compilation test, but for good measure we do one clock // cycle. integer count; initial begin count = 0; end always @(posedge clk) begin if (count == 1) begin $write("*-* All Finished *-*\n"); $finish; end else begin count = count + 1; end end endmodule // t module test_gen #( parameter SIZE = `MAX_SIZE, MASK = `MAX_SIZE'b0) (/*AUTOARG*/ // Inputs clk ); input clk; // Generate blocks that rely on short-circuiting of the logic to avoid // errors. generate if ((SIZE < 8'h04) && MASK[0]) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Generate IF MASK[0] = %d\n", MASK[0]); `endif end end endgenerate endmodule verilator-3.874/test_regress/t/t_case_huge_prof.pl0000775000177100017500000000264512473477707022364 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_case_huge.v"); compile ( verilator_flags2 => ["--stats --profile-cfuncs -CFLAGS '-pg' -LDFLAGS '-pg'"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10); file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10); } unlink $_ foreach (glob "$Self->{obj_dir}/gmon.out.*"); $ENV{GMON_OUT_PREFIX} = "$Self->{obj_dir}/gmon.out"; execute ( check_finished=>1, ); my $gmon_path; $gmon_path = $_ foreach (glob "$Self->{obj_dir}/gmon.out.*"); $gmon_path or $Self->error("Profiler did not create a gmon.out"); (my $gmon_base = $gmon_path) =~ s!.*[/\\]!!; $Self->_run(cmd=>["cd $Self->{obj_dir} && gprof $Self->{VM_PREFIX} $gmon_base > gprof.out"], check_finished=>0); $Self->_run(cmd=>["cd $Self->{obj_dir} && $ENV{VERILATOR_ROOT}/bin/verilator_profcfunc gprof.out > cfuncs.out"], check_finished=>0); file_grep ("$Self->{obj_dir}/cfuncs.out", qr/Overall summary by/); ok(1); 1; verilator-3.874/test_regress/t/t_savable.v0000664000177100017500000000366612525171734020650 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); /*verilator no_inline_module*/ // So we'll get hiearachy we can test input clk; sub sub (/*AUTOINST*/ // Inputs .clk (clk)); endmodule module sub (/*AUTOARG*/ // Inputs clk ); input clk; /*verilator no_inline_module*/ // So we'll get hiearachy we can test integer cyc=0; reg [127:0] save128; reg [47:0] save48; reg [1:0] save2; reg [255:0] cycdone; // Make sure each cycle executes exactly once reg [31:0] vec[2:1][2:1]; real r; string s,s2; string si; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d\n",$time, cyc); `endif si = "siimmed"; cyc <= cyc + 1; if (cycdone[cyc[7:0]]) $stop; cycdone[cyc[7:0]] <= '1; if (cyc==0) begin // Setup save128 <= 128'hc77bb9b3784ea0914afe43fb79d7b71e; save48 <= 48'h4afe43fb79d7; save2 <= 2'b10; vec[1][1] <= 32'h0101; vec[1][2] <= 32'h0102; vec[2][1] <= 32'h0201; vec[2][2] <= 32'h0202; r <= 1.234; s <= "hello"; end if (cyc==1) begin if ($test$plusargs("save_restore")!=0) begin // Don't allow the restored model to run from time 0, it must run from a restore $write("%%Error: didn't really restore\n"); $stop; end end else if (cyc==99) begin if (save128 !== 128'hc77bb9b3784ea0914afe43fb79d7b71e) $stop; if (save48 !== 48'h4afe43fb79d7) $stop; if (save2 !== 2'b10) $stop; if (cycdone !== {{(256-99){1'b0}}, {99{1'b1}}}) $stop; if (vec[1][1] !== 32'h0101) $stop; if (vec[1][2] !== 32'h0102) $stop; if (vec[2][1] !== 32'h0201) $stop; if (vec[2][2] !== 32'h0202) $stop; if (r != 1.234) $stop; $display("%s",s); $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_var_rsvd_port.pl0000775000177100017500000000073512473477707022303 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2=>["-Wno-SYMRSVDWORD"], ); execute(); ok(1); 1; verilator-3.874/test_regress/t/t_func_const_bad.pl0000775000177100017500000000355412473477707022362 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_output' %Error: t/t_func_const_bad.v:\d+: ... Location of non-constant VAR 'o': Language violation: Outputs not allowed in constant functions %Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_dotted' %Error: t/t_func_const_bad.v:\d+: ... Location of non-constant VARXREF 'EIGHT': Language violation: Dotted hierarchical references not allowed in constant functions %Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_nonparam' %Error: t/t_func_const_bad.v:\d+: ... Location of non-constant VARREF 'modvar': Language violation: reference to non-function-local variable %Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_infinite' %Error: t/t_func_const_bad.v:\d+: ... Location of non-constant WHILE: Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above 1024 %Error: t/t_func_const_bad.v:\d+: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_stop' %Error: t/t_func_const_bad.v:\d+: ... Location of non-constant STOP: .stop executed during function constification; maybe indicates assertion firing %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_enum_public.v0000664000177100017500000000114512473477707021536 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. package p3; typedef enum logic [2:0] { ZERO = 3'b0, ONE = 3'b1 } e3_t /*verilator public*/; endpackage package p62; typedef enum logic [62:0] { ZERO = '0, ALLONE = '1 } e62_t /*verilator public*/; endpackage module t (/*AUTOARG*/); enum integer { EI_A, EI_B, EI_C } m_state; initial begin m_state = EI_A; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_for_init_bug.pl0000775000177100017500000000066412473477707022060 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); #execute () ok(1); 1; verilator-3.874/test_regress/t/t_gen_mislevel.pl0000775000177100017500000000071712473477707022062 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_loop.pl0000775000177100017500000000071712473477707021721 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_rand.v0000664000177100017500000000131012473477707021165 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (clk, Rand); input clk; output reg [31:0] Rand; `ifdef verilator `systemc_interface unsigned int QxRandTbl (unsigned int tbl, unsigned int idx) { return 0xfeed0fad; } `verilog `endif function [31:0] QxRand32; /* verilator public */ input [7:0] tbl; input [7:0] idx; begin `ifdef verilator QxRand32 = $c ("QxRandTbl(",tbl,",",idx,")"); `else QxRand32 = 32'hfeed0fad; `endif end endfunction always @(posedge clk) begin Rand <= #1 QxRand32 (8'h0, 8'h7); end endmodule verilator-3.874/test_regress/t/t_udp_noname.pl0000775000177100017500000000103112473477707021524 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug468"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_gater.pl0000775000177100017500000000117412473477707021342 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--stats"], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { #Optimization is disabled #file_grep ($Self->{stats}, qr/Optimizations, Gaters inserted\s+(\d+)/i, 3); } ok(1); 1; verilator-3.874/test_regress/t/t_pp_dupdef.v0000664000177100017500000000050212473477707021176 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t; `define DUP fred `define DUP barney `define DUPP paramed(x) (x) `define DUPP paramed(x,z) (x*z) initial $stop; // Should have failed endmodule verilator-3.874/test_regress/t/t_bitsel_const_bad.pl0000775000177100017500000000117412473477707022705 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_bitsel_const_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is logic .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_enum.pl0000775000177100017500000000071712473477707020355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_cat_renew.pl0000775000177100017500000000151612473477707022534 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2013 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"); top_filename("t_trace_cat.v"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_cat.cpp"], ); execute ( check_finished=>1, ); vcd_identical ("$Self->{obj_dir}/simpart_0000.vcd", "t/$Self->{name}_0000.out"); vcd_identical ("$Self->{obj_dir}/simpart_0100.vcd", "t/$Self->{name}_0100.out"); ok(1); 1; verilator-3.874/test_regress/t/t_gen_var_bad.pl0000775000177100017500000000107512473477707021636 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '.*%Error: t/t_gen_var_bad.v:\d+: Non-genvar used in generate for: i %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_param_if_blk.v0000664000177100017500000000564312473477707021651 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013. // bug648 module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [7:0] datai = crc[7:0]; wire enable = crc[8]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) logic [7:0] datao; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .datao (datao[7:0]), // Inputs .clk (clk), .datai (datai[7:0]), .enable (enable)); // Aggregate outputs into a single result vector wire [63:0] result = {56'h0, datao}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h9d550d82d38926fa if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule `define FAIL 1 module Nested ( input logic clk, input logic x, output logic y ); logic t; always_comb t = x ^ 1'b1; always_ff @(posedge clk) begin if (clk) y <= t; end endmodule module Test ( input logic clk, input logic [7:0] datai, input logic enable, output logic [7:0] datao ); // verilator lint_off BLKANDNBLK logic [7:0] datat; // verilator lint_on BLKANDNBLK for (genvar i = 0; i < 8; i++) begin if (i%4 != 3) begin `ifndef FAIL logic t; always_comb begin t = datai[i] ^ 1'b1; end always_ff @(posedge clk) begin if (clk) datat[i] <= t; end `else Nested nested_i ( .clk(clk), .x(datai[i]), .y(datat[i]) //<== via Vcellout wire ); `endif always_comb begin casez (enable) 1'b1: datao[i] = datat[i]; 1'b0: datao[i] = '0; default: datao[i] = 'x; endcase end end else begin always_ff @(posedge clk) begin if (clk) datat[i] <= 0; //<== assign delayed end always_comb begin casez (enable) 1'b1: datao[i] = datat[i] ^ 1'b1; 1'b0: datao[i] = '1; default: datao[i] = 'x; endcase end end end endmodule verilator-3.874/test_regress/t/t_bench_mux4k.pl0000775000177100017500000000071712473477707021620 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_display.v0000664000177100017500000000443312473477707020704 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; reg [40:0] quad; initial quad = 41'ha_bbbb_cccc; reg [80:0] wide; initial wide = 81'habc_1234_5678_1234_5678; reg [31:0] str; initial str = "\000\277\021\n"; reg [47:0] str2; initial str2 = "\000what!"; reg [79:0] str3; initial str3 = "\000hmmm!1234"; reg [8:0] nine; sub sub (); sub2 sub2 (); initial begin $write("[%0t] In %m: Hi\n", $time); sub.write_m; sub2.write_m; // Escapes $display("[%0t] Back \\ Quote \"", $time); // Old bug when \" last on the line. // Display formatting nine = {3'd0,quad[5:0]}; $display("[%0t] %%X=%X %%0X=%0X %%0O=%0O %%B=%B", $time, nine, nine, nine, nine); $display("[%0t] %%x=%x %%0x=%0x %%0o=%0o %%b=%b", $time, nine, nine, nine, nine); $display("[%0t] %%D=%D %%d=%d %%01d=%01d %%06d=%06d %%6d=%6d", $time, nine, nine, nine, nine, nine); $display("[%0t] %%x=%x %%0x=%0x %%o=%o %%b=%b", $time, quad, quad, quad, quad); $display("[%0t] %%x=%x %%0x=%0x %%o=%o %%b=%b", $time, wide, wide, wide, wide); $display("[%0t] %%t=%t %%03t=%03t %%0t=%0t", $time, $time, $time, $time); $display; // Not testing %0s, it does different things in different simulators $display("[%0t] %%s=%s %%s=%s %%s=%s", $time, str2[7:0], str2, str3); $display("[%0t] %s%s%s", $time, "hel", "lo, fr", "om a very long string. Percent %s are literally substituted in."); $write("[%0t] Embedded \r return\n", $time); $display("[%0t] Embedded\ multiline", $time); // Str check `ifndef NC // NC-Verilog 5.3 chokes on this test if (str !== 32'h00_bf_11_0a) $stop; `endif $write("*-* All Finished *-*\n"); $finish; end endmodule module sub; task write_m; begin $write("[%0t] In %m\n", $time); begin : subblock $write("[%0t] In %M\n", $time); // Uppercase %M test end end endtask endmodule module sub2; // verilator no_inline_module task write_m; begin $write("[%0t] In %m\n", $time); begin : subblock2 $write("[%0t] In %m\n", $time); end end endtask endmodule verilator-3.874/test_regress/t/t_tri_inout.pl0000775000177100017500000000116512473477707021423 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_param.v0000664000177100017500000000134412473477707021513 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jonathon Donaldson. package my_funcs; function automatic int simple_func (input int value); begin simple_func = value; end endfunction endpackage package my_module_types; import my_funcs::*; localparam MY_PARAM = 3; localparam MY_PARAM2 /*verilator public*/ = simple_func(12); endpackage module t import my_module_types::*; ( input i_clk, input [MY_PARAM-1:0] i_d, output logic [MY_PARAM-1:0] o_q ); always_ff @(posedge i_clk) o_q <= i_d; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_preproc_ifdef.v0000664000177100017500000000145412473477707022046 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/); integer num; initial begin num = 0; `define EMPTY_TRUE `ifndef EMPTY_TRUE `error "Empty is still true" `endif `define A `ifdef A $display("1A"); num = num + 1; `ifdef C $stop; `elsif A $display("2A"); num = num + 1; `ifdef C $stop; `elsif B $stop; `else $display("3A"); num = num + 1; `endif `else $stop; `endif `elsif B $stop; `ifdef A $stop; `elsif A $stop; `else `endif `elsif C $stop; `else $stop; `endif if (num == 3) begin $write("*-* All Finished *-*\n"); $finish; end else begin $write("%%Error: Bad count: %d\n", num); $stop; end end endmodule verilator-3.874/test_regress/t/t_func_const.pl0000775000177100017500000000071712473477707021552 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_2in.cpp0000664000177100017500000000206712473477707021076 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. #include #ifdef T_CLK_2IN_VEC # include "Vt_clk_2in_vec.h" #else # include "Vt_clk_2in.h" #endif unsigned int main_time = false; double sc_time_stamp () { return main_time; } VM_PREFIX* topp = NULL; void clockit(int clk1, int clk0) { topp->clks = clk1<<1 | clk0; #ifndef T_CLK_2IN_VEC topp->c1 = clk1; topp->c0 = clk0; #endif #ifdef TEST_VERBOSE printf("[%d] c1=%d c0=%d\n", main_time, clk1, clk0); #endif topp->eval(); main_time++; } int main (int argc, char *argv[]) { topp = new VM_PREFIX; topp->check = 0; clockit(0,0); main_time+=10; Verilated::debug(0); for (int i = 0; i < 2; i++) { clockit(0, 0); clockit(0, 1); clockit(1, 1); clockit(0, 0); clockit(1, 1); clockit(1, 0); clockit(0, 0); clockit(0, 1); clockit(1, 0); clockit(0, 0); } topp->check = 1; clockit(0,0); } verilator-3.874/test_regress/t/t_extend_class.pl0000775000177100017500000000107712473477707022065 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( make_flags => "CPPFLAGS_ADD=-I$Self->{t_dir}", ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_shortcircuit_c.cpp0000664000177100017500000000353212473477707023433 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2011-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include "svdpi.h" //====================================================================== #if defined(VERILATOR) # include "Vt_dpi_shortcircuit__Dpi.h" #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef NEED_EXTERNS extern "C" { extern int dpii_clear (); extern int dpii_count (int idx); extern unsigned char dpii_inc0 (int idx); extern unsigned char dpii_inc1 (int idx); extern unsigned char dpii_incx (int idx, unsigned char value); } #endif //====================================================================== #define COUNTERS 16 static int global_count[COUNTERS]; int dpii_clear () { for (int i=0; i= 0 && idx= 0 && idx ['+define+INLINE_B'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_concat.pl0000775000177100017500000000071712473477707021671 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_for_funcbound.pl0000775000177100017500000000076412473477707022244 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, expect=> '[10] hello [20] world ', ); ok(1); 1; verilator-3.874/test_regress/t/t_gate_implicit.pl0000775000177100017500000000071712473477707022223 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clocker.v0000664000177100017500000000264212525171734020646 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Simple test of CLkDATA // // Trigger the CLKDATA detection // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Jie Xu. localparam ID_MSB = 1; module t (/*AUTOARG*/ // Inputs clk, res, res8, res16 ); input clk; output res; output [7:0] res8; output [15:0] res16; wire [7:0] clkSet; wire clk_1; wire [2:0] clk_3; wire [3:0] clk_4; wire clk_final; reg [7:0] count; assign clkSet = {8{clk}}; assign clk_4 = clkSet[7:4]; assign clk_1 = clk_4[0];; // arraysel assign clk_3 = {3{clk_1}}; assign clk_final = clk_3[0]; // the following two assignment triggers the CLKDATA warning // because on LHS there are a mix of signals both CLOCK and // DATA /* verilator lint_off CLKDATA */ assign res8 = {clk_3, 1'b0, clk_4}; assign res16 = {count, clk_3, clk_1, clk_4}; /* verilator lint_on CLKDATA */ initial count = 0; always @(posedge clk_final or negedge clk_final) begin count = count + 1; // the following assignment should trigger the CLKDATA warning // because CLOCK signal is used as DATA in sequential block /* verilator lint_off CLKDATA */ res <= clk_final; /* verilator lint_on CLKDATA */ if ( count == 8'hf) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_var_notfound_bad.v0000664000177100017500000000107212473477707022545 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/); integer i; integer a_var; sub sub (); initial begin nf = 0; // z not found sub.subsubz.inss = 0; // subsub not found i = nofunc(); // nofunc not found notask(); // notask not found a_var(); // Calling variable as task $finish; end endmodule module sub; subsub subsub (); endmodule module subsub; integer inss; endmodule verilator-3.874/test_regress/t/t_bitsel_slice.v0000664000177100017500000000344412473477707021701 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; logic [2:0] [1:0] in; always @* in = crc[5:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) logic [1:0] [1:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out/*[1:0][1:0]*/), // Inputs .clk (clk), .in (in/*[2:0][1:0]*/)); // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, out[1],out[0]}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hdc21e42d85441511 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); //bug717 input clk; input logic [2:0][1:0] in; output logic [1:0][1:0] out; always @(posedge clk) begin out <= in[2 -: 2]; end endmodule verilator-3.874/test_regress/t/t_assert_cover.pl0000775000177100017500000000272512473477707022111 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_assert_cover.v"); compile ( verilator_flags2 => ['--assert --cc --coverage-user'], nc_flags2 => ["+nccovoverwrite +nccoverage+all +nccovtest+$Self->{name}"] ); execute ( check_finished=>1, ); if ($Self->{nc}) { my $name = $Self->{name}; my $cf = "$Self->{obj_dir}/${name}__nccover.cf"; { my $fh = IO::File->new(">$cf") or die "%Error: $! writing $cf,"; $fh->printf("report_summary -module *\n"); $fh->printf("report_detail -both -instance *\n"); $fh->printf("report_html -both -instance * > $Self->{obj_dir}/${name}__nccover.html\n"); $fh->close; } $Self->_run (logfile=>"$Self->{obj_dir}/${name}__nccover.log", tee=>0, cmd=>[($ENV{VERILATOR_ICCR}||'iccr'), "-test ${name} ${cf}"]); } file_grep ($Self->{run_log_filename}, qr/COVER: Cyc==4/); file_grep ($Self->{run_log_filename}, qr/COVER: Cyc==5/); file_grep ($Self->{run_log_filename}, qr/COVER: Cyc==6/); # Allow old Perl format dump, or new binary dump file_grep ($Self->{coverage_filename}, qr/(cyc_eq_5.*,c=>[^0]|cyc_eq_5.* [1-9][0-9]*\n)/); ok(1); 1; verilator-3.874/test_regress/t/t_math_signed6.pl0000775000177100017500000000072212525171734021742 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_escape.out0000664000177100017500000000412212473477707021704 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Tue Jul 24 18:44:43 2012 $end $timescale 1ns $end $scope module top $end $var wire 1 * 9num $end $var wire 1 + bra[ket]slash/dash-colon:9backslash\done $end $var wire 1 ' clk $end $var wire 1 ) double__underscore $end $var wire 1 ( escaped_normal $end $scope module v $end $var wire 1 * 9num $end $var wire 32 & a0.cyc [31:0] $end $var wire 1 + bra[ket]slash/dash-colon:9backslash\done $end $var wire 1 $ check:alias $end $var wire 1 % check;alias $end $var wire 1 $ check_alias $end $var wire 1 ' clk $end $var wire 32 # cyc [31:0] $end $var wire 1 ) double__underscore $end $var wire 1 ( escaped_normal $end $var wire 32 & other.cyc [31:0] $end $var wire 1 $ wire $end $scope module a0 $end $var wire 32 # cyc [31:0] $end $upscope $end $scope module mod.with_dot $end $var wire 32 # cyc [31:0] $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 1$ 0% b11111111111111111111111111111110 & b00000000000000000000000000000001 # 0' 1( 1) 1* 1+ #10 0$ 1% b11111111111111111111111111111101 & b00000000000000000000000000000010 # 1' 0( 0) 0* 0+ #15 0' #20 1$ 0% b11111111111111111111111111111100 & b00000000000000000000000000000011 # 1' 1( 1) 1* 1+ #25 0' #30 0$ 1% b11111111111111111111111111111011 & b00000000000000000000000000000100 # 1' 0( 0) 0* 0+ #35 0' #40 1$ 0% b11111111111111111111111111111010 & b00000000000000000000000000000101 # 1' 1( 1) 1* 1+ #45 0' #50 0$ 1% b11111111111111111111111111111001 & b00000000000000000000000000000110 # 1' 0( 0) 0* 0+ #55 0' #60 1$ 0% b11111111111111111111111111111000 & b00000000000000000000000000000111 # 1' 1( 1) 1* 1+ #65 0' #70 0$ 1% b11111111111111111111111111110111 & b00000000000000000000000000001000 # 1' 0( 0) 0* 0+ #75 0' #80 1$ 0% b11111111111111111111111111110110 & b00000000000000000000000000001001 # 1' 1( 1) 1* 1+ #85 0' #90 0$ 1% b11111111111111111111111111110101 & b00000000000000000000000000001010 # 1' 0( 0) 0* 0+ #95 0' #100 1$ 0% b11111111111111111111111111110100 & b00000000000000000000000000001011 # 1' 1( 1) 1* 1+ verilator-3.874/test_regress/t/t_leak.v0000664000177100017500000000074212473477707020152 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (clk); sub sub (); input clk; integer cyc=1; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==2) begin // Not $finish; as we don't want a message to scroll by $c("Verilated::gotFinish(true);"); end end endmodule module sub; /* verilator public_module */ endmodule verilator-3.874/test_regress/t/t_struct_packed_sysfunct.v0000664000177100017500000000302312473477707024022 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; // packed structures struct packed { logic e0; logic [1:0] e1; logic [3:0] e2; logic [7:0] e3; } struct_bg; // big endian structure /* verilator lint_off LITENDIAN */ struct packed { logic e0; logic [0:1] e1; logic [0:3] e2; logic [0:7] e3; } struct_lt; // little endian structure /* verilator lint_on LITENDIAN */ integer cnt = 0; // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if (cnt==2) begin $write("*-* All Finished *-*\n"); $finish; end always @ (posedge clk) if (cnt==1) begin // big endian if ($bits (struct_bg ) != 15) $stop; if ($bits (struct_bg.e0) != 1) $stop; if ($bits (struct_bg.e1) != 2) $stop; if ($bits (struct_bg.e2) != 4) $stop; if ($bits (struct_bg.e3) != 8) $stop; if ($increment (struct_bg, 1) != 1) $stop; // little endian if ($bits (struct_lt ) != 15) $stop; if ($bits (struct_lt.e0) != 1) $stop; if ($bits (struct_lt.e1) != 2) $stop; if ($bits (struct_lt.e2) != 4) $stop; if ($bits (struct_lt.e3) != 8) $stop; if ($increment (struct_lt, 1) != 1) $stop; // Structure itself always big numbered end endmodule verilator-3.874/test_regress/t/t_table_fsm.v0000664000177100017500000000767212473477707021203 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; reg reset; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire myevent; // From test of Test.v wire myevent_pending; // From test of Test.v wire [1:0] state; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .state (state[1:0]), .myevent (myevent), .myevent_pending (myevent_pending), // Inputs .clk (clk), .reset (reset)); // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, myevent_pending,myevent,state}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x me=%0x mep=%x\n",$time, cyc, crc, result, myevent, myevent_pending); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; reset <= (cyc<2); if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h4e93a74bd97b25ef if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs state, myevent, myevent_pending, // Inputs clk, reset ); input clk; input reset; output [1:0] state; output myevent; output myevent_pending; reg [5:0] count = 0; always @ (posedge clk) if (reset) count <= 0; else count <= count + 1; reg myevent = 1'b0; always @ (posedge clk) myevent <= (count == 6'd27); reg myevent_done; reg hickup_ready; reg hickup_done; localparam STATE_ZERO = 0; localparam STATE_ONE = 1; localparam STATE_TWO = 2; reg [1:0] state = STATE_ZERO; reg state_start_myevent = 1'b0; reg state_start_hickup = 1'b0; reg myevent_pending = 1'b0; always @ (posedge clk) begin state <= state; myevent_pending <= myevent_pending || myevent; state_start_myevent <= 1'b0; state_start_hickup <= 1'b0; case (state) STATE_ZERO: if (myevent_pending) begin state <= STATE_ONE; myevent_pending <= 1'b0; state_start_myevent <= 1'b1; end else if (hickup_ready) begin state <= STATE_TWO; state_start_hickup <= 1'b1; end STATE_ONE: if (myevent_done) state <= STATE_ZERO; STATE_TWO: if (hickup_done) state <= STATE_ZERO; default: ; /* do nothing */ endcase end reg [3:0] myevent_count = 0; always @ (posedge clk) if (state_start_myevent) myevent_count <= 9; else if (myevent_count > 0) myevent_count <= myevent_count - 1; initial myevent_done = 1'b0; always @ (posedge clk) myevent_done <= (myevent_count == 0); reg [4:0] hickup_backlog = 2; always @ (posedge clk) if (state_start_myevent) hickup_backlog <= hickup_backlog - 1; else if (state_start_hickup) hickup_backlog <= hickup_backlog + 1; initial hickup_ready = 1'b1; always @ (posedge clk) hickup_ready <= (hickup_backlog < 3); reg [3:0] hickup_count = 0; always @ (posedge clk) if (state_start_hickup) hickup_count <= 10; else if (hickup_count > 0) hickup_count <= hickup_count - 1; initial hickup_done = 1'b0; always @ (posedge clk) hickup_done <= (hickup_count == 1); endmodule verilator-3.874/test_regress/t/t_display_real.v0000664000177100017500000000343212473477707021705 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; real n0; initial n0 = 0.0; real n1; initial n1 = 1.0; real n2; initial n2 = 0.1; real n3; initial n3 = 1.2345e-15; real n4; initial n4 = 2.579e+15; reg [7:0] r8; initial r8 = 3; initial begin // Display formatting $display("[%0t] e=%e e1=%1e e30=%3.0e e32=%3.2e", $time, n0,n0,n0,n0); $display("[%0t] f=%f f1=%1e f30=%3.0e f32=%3.2e", $time, n0,n0,n0,n0); $display("[%0t] g=%g g1=%1e g30=%3.0e g32=%3.2e", $time, n0,n0,n0,n0); $display; $display("[%0t] e=%e e1=%1e e30=%3.0e e32=%3.2e", $time, n1,n1,n1,n1); $display("[%0t] f=%f f1=%1e f30=%3.0e f32=%3.2e", $time, n1,n1,n1,n1); $display("[%0t] g=%g g1=%1e g30=%3.0e g32=%3.2e", $time, n1,n1,n1,n1); $display; $display("[%0t] e=%e e1=%1e e30=%3.0e e32=%3.2e", $time, n2,n2,n2,n2); $display("[%0t] f=%f f1=%1e f30=%3.0e f32=%3.2e", $time, n2,n2,n2,n2); $display("[%0t] g=%g g1=%1e g30=%3.0e g32=%3.2e", $time, n2,n2,n2,n2); $display; $display("[%0t] e=%e e1=%1e e30=%3.0e e32=%3.2e", $time, n3,n3,n3,n3); $display("[%0t] f=%f f1=%1e f30=%3.0e f32=%3.2e", $time, n3,n3,n3,n3); $display("[%0t] g=%g g1=%1e g30=%3.0e g32=%3.2e", $time, n3,n3,n3,n3); $display; $display("[%0t] e=%e e1=%1e e30=%3.0e e32=%3.2e", $time, n4,n4,n4,n4); $display("[%0t] f=%f f1=%1e f30=%3.0e f32=%3.2e", $time, n4,n4,n4,n4); $display("[%0t] g=%g g1=%1e g30=%3.0e g32=%3.2e", $time, n4,n4,n4,n4); $display; $display("r8=%d n1=%g n2=%g", r8, n1, n2); $display("n1=%g n2=%g r8=%d", n1, n2, r8); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_dos.pl0000775000177100017500000000071712473477707020176 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_pow4.v0000664000177100017500000000254612473477707021144 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Clifford Wolf. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; wire [31:0] y; reg a; test004 sub (/*AUTOINST*/ // Outputs .y (y[31:0]), // Inputs .a (a)); // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d a=%x y=%x\n",$time, cyc, a, y); `endif cyc <= cyc + 1; if (cyc==0) begin a <= 0; end else if (cyc==1) begin a <= 1; if (y != 32'h0) $stop; end else if (cyc==2) begin if (y != 32'h010000ff) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module test004(a, y); input a; output [31:0] y; wire [7:0] y0; wire [7:0] y1; wire [7:0] y2; wire [7:0] y3; assign y = {y0,y1,y2,y3}; localparam [7:0] v0 = +8'sd1 ** -8'sd2; //'h01 localparam [7:0] v1 = +8'sd2 ** -8'sd2; //'h00 localparam [7:0] v2 = -8'sd2 ** -8'sd3; //'h00 localparam [7:0] v3 = -8'sd1 ** -8'sd3; //'hff localparam [7:0] zero = 0; initial $display("v0=%x v1=%x v2=%x v3=%x", v0,v1,v2,v3); assign y0 = a ? v0 : zero; assign y1 = a ? v1 : zero; assign y2 = a ? v2 : zero; assign y3 = a ? v3 : zero; endmodule verilator-3.874/test_regress/t/t_enum_overlap_bad.pl0000775000177100017500000000130612473477707022706 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Error: t/t_enum_overlap_bad.v:\d+: Overlapping enumeration value: e1b %Error: t/t_enum_overlap_bad.v:\d+: ... Location of original declaration %Error: Exiting due to', ); ok(1); 1; verilator-3.874/test_regress/t/t_enum_type_pins.v0000664000177100017500000000614112525171734022260 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: System Verilog test of enumerated type methods // // This code exercises the various enumeration methods // // This file ONLY is placed into the Public Domain, for any use, without // warranty. // Contributed 2012 by M W Lund, Atmel Corporation and Jeremy Bennett, Embecosm. // **** Pin Identifiers **** typedef enum int { PINID_A0 = 32'd0, // MUST BE ZERO! // - Standard Ports - PINID_A1, PINID_A2, PINID_A3, PINID_A4, PINID_A5, PINID_A6, PINID_A7, PINID_B0, PINID_B1, PINID_B2, PINID_B3, PINID_B4, PINID_B5, PINID_B6, PINID_B7, PINID_C0, PINID_C1, PINID_C2, PINID_C3, PINID_C4, PINID_C5, PINID_C6, PINID_C7, PINID_D0, PINID_D1, PINID_D2, PINID_D3, PINID_D4, PINID_D5, PINID_D6, PINID_D7, PINID_E0, PINID_E1, PINID_E2, PINID_E3, PINID_E4, PINID_E5, PINID_E6, PINID_E7, PINID_F0, PINID_F1, PINID_F2, PINID_F3, PINID_F4, PINID_F5, PINID_F6, PINID_F7, PINID_G0, PINID_G1, PINID_G2, PINID_G3, PINID_G4, PINID_G5, PINID_G6, PINID_G7, PINID_H0, PINID_H1, PINID_H2, PINID_H3, PINID_H4, PINID_H5, PINID_H6, PINID_H7, // PINID_I0, PINID_I1, PINID_I2, PINID_I3, PINID_I4, PINID_I5, PINID_I6, PINID_I7,-> DO NOT USE!!!! I == 1 PINID_J0, PINID_J1, PINID_J2, PINID_J3, PINID_J4, PINID_J5, PINID_J6, PINID_J7, PINID_K0, PINID_K1, PINID_K2, PINID_K3, PINID_K4, PINID_K5, PINID_K6, PINID_K7, PINID_L0, PINID_L1, PINID_L2, PINID_L3, PINID_L4, PINID_L5, PINID_L6, PINID_L7, PINID_M0, PINID_M1, PINID_M2, PINID_M3, PINID_M4, PINID_M5, PINID_M6, PINID_M7, PINID_N0, PINID_N1, PINID_N2, PINID_N3, PINID_N4, PINID_N5, PINID_N6, PINID_N7, // PINID_O0, PINID_O1, PINID_O2, PINID_O3, PINID_O4, PINID_O5, PINID_O6, PINID_O7,-> DO NOT USE!!!! O == 0 PINID_P0, PINID_P1, PINID_P2, PINID_P3, PINID_P4, PINID_P5, PINID_P6, PINID_P7, PINID_Q0, PINID_Q1, PINID_Q2, PINID_Q3, PINID_Q4, PINID_Q5, PINID_Q6, PINID_Q7, PINID_R0, PINID_R1, PINID_R2, PINID_R3, PINID_R4, PINID_R5, PINID_R6, PINID_R7, // - AUX Port (Custom) - PINID_X0, PINID_X1, PINID_X2, PINID_X3, PINID_X4, PINID_X5, PINID_X6, PINID_X7, // - PDI Port - PINID_D2W_DAT, PINID_D2W_CLK, // - Power Pins - PINID_VDD0, PINID_VDD1, PINID_VDD2, PINID_VDD3, PINID_GND0, PINID_GND1, PINID_GND2, PINID_GND3, // - Maximum number of pins - PINID_MAX } t_pinid; module t (/*AUTOARG*/ // Inputs clk ); input clk; wire a = clk; wire b = 1'b0; reg c; test test_i (/*AUTOINST*/ // Inputs .clk (clk)); // This is a compile time only test. Immediately finish always @(posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule module test (/*AUTOARG*/ // Inputs clk ); input clk; // Use the enumeration size to initialize a dynamic array t_pinid e; int myarray1 [] = new [e.num]; always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Enumeration has %d members\n", e.num); `endif e = e.first; forever begin myarray1[e] <= e.prev; `ifdef TEST_VERBOSE $write ("myarray1[%d] (enum %s) = %d\n", e, e.name, myarray1[e]); `endif if (e == e.last) begin break; end else begin e = e.next; end end end endmodule verilator-3.874/test_regress/t/t_func_under2.pl0000775000177100017500000000072212473477707021617 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_array_pattern_unpacked.pl0000775000177100017500000000072212473477707024132 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_width_bad.v0000664000177100017500000000213612473477707022210 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (); // See also t_math_width // This shows the uglyness in width warnings across param modules // TODO: Would be nice to also show relevant parameter settings p #(.WIDTH(4)) p4 (.in(4'd0)); p #(.WIDTH(5)) p5 (.in(5'd0)); //==== localparam [3:0] XS = 'hx; // User presumably intended to use 'x //==== wire [4:0] c = 1'b1 << 2; // No width warning, as is common syntax wire [4:0] d = (1'b1 << 2) + 5'b1; // Has warning as not obvious what expression width is //==== localparam WIDTH = 6; wire one_bit; wire [2:0] shifter = 1; wire [WIDTH-1:0] masked = (({{(WIDTH){1'b0}}, one_bit}) << shifter); //==== // We presently warn here, in theory we could detect if the number of one bit additions could overflow the LHS wire one = 1; wire [2:0] cnt = (one + one + one + one); endmodule module p #(parameter WIDTH=64) (input [WIDTH-1:0] in); wire [4:0] out = in; endmodule verilator-3.874/test_regress/t/t_const_dec_mixed_bad.v0000664000177100017500000000035712473477707023175 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005-2007 by Wilson Snyder. module t (/*AUTOARG*/); parameter [200:0] MIXED = 32'dx_1; endmodule verilator-3.874/test_regress/t/t_select_index2.v0000664000177100017500000000152012473477707021761 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [7:0] x; wire [3:0] en; wire sel; wire a; // bug675 generate genvar g_k; for ( g_k = 0; g_k < 8; g_k = g_k + 1 ) begin: g_index always @* begin // Note this isn't a genif, but normal if // verilator lint_off SELRANGE if(g_k<4) begin x[g_k] = (sel == 1'b1) ? 1'b1 : (en[g_k] == 1'b0) ? 1'b1 : a; end else begin x[g_k] = (sel == 1'b0) ? 1'b1 : (en[g_k-4] == 1'b0) ? 1'b1 : a; end // verilator lint_on SELRANGE end end endgenerate endmodule verilator-3.874/test_regress/t/t_var_set_link.v0000664000177100017500000000100012473477707021702 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs state, // Inputs clk ); input clk; // Gave "Internal Error: V3Broken.cpp:: Broken link in node" output [1:0] state; reg [1:0] state = 2'b11; always @ (posedge clk) begin state <= state; end initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_param_mem_attr.pl0000775000177100017500000000067412473477707022403 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # Compile only test. compile ( ); ok(1); 1; verilator-3.874/test_regress/t/t_math_precedence.pl0000775000177100017500000000103212473477707022506 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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->{vcs} or $Self->unsupported("VCS does ** wrong, fixed in 2014"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_implicit.pl0000775000177100017500000000101212473477707022236 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( verilator_flags2 => ["-Wno-IMPLICIT"], ); ok(1); 1; verilator-3.874/test_regress/t/t_pp_misdef_bad.v0000664000177100017500000000046012473477707022007 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t; `define A B // NOTDEF isn't defined here: `NOTDEF //`include "notfound" initial $stop; // Should have failed endmodule verilator-3.874/test_regress/t/t_pipe_filter.pf0000664000177100017500000000316212473477707021677 0ustar wsnyderwsnyder#!/usr/bin/perl -w # DESCRIPTION: Verilator: Verilog Test example --pipe-filter script # # Copyright 2010 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. use IO::File; use strict; our $Debug = 0; autoflush STDOUT; print STDERR "t_pipe_filter.pf: Hello in Perl\n" if $Debug; while (defined(my $cmd = )) { print STDERR "t_pipe_filter.pf: gotcmd: $cmd" if $Debug; if ($cmd =~ /^read "(.*)"/) { my $filename = $1; open(my $fh, "<$filename") or die "t_pipe_filter.pf: %Error: $! $filename\n"; my $wholefile=""; # It's faster to slurp the whole file then scan (if needed), # then to read it into an array with getlines { local $/; undef $/; $wholefile = <$fh>; } close $fh; if ($wholefile =~ /example_lint/) { # else short circuit my $lineno = 1; my $pos=0; my @prefixes; while (1) { my $newpos=index($wholefile,"\n",$pos); last if $newpos<$pos; my $line = substr($wholefile,$pos,$newpos-$pos); if ($line =~ /example_lint/) { # We don't have a way to specify this yet, so just for now #print STDERR $line; push @prefixes, "int lint_off_line_${lineno} = 1;\n"; } $lineno++; $pos = $newpos+1; } #print STDERR "Line count: $lineno\n"; $wholefile = join('',@prefixes) . $wholefile; } print STDOUT "Content-Length: ".length($wholefile)."\n".$wholefile."\n"; } else { die "t_pipe_filter.pf: %Error: Unknown command: $cmd\n"; } } print STDOUT "t_pipe_filter.pf: Fin\n" if $Debug; exit(0); verilator-3.874/test_regress/t/t_trace_off_cc.pl0000775000177100017500000000117612473477707022006 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_trace_ena.v"); compile ( verilator_flags2 => ['-notrace'], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { !-r "$Self->{obj_dir}/simx.vcd" or $Self->error("Tracing should be off\n"); } ok(1); 1; verilator-3.874/test_regress/t/t_preproc.v0000664000177100017500000003736012525172076020703 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2000-2011 by Wilson Snyder. //=========================================================================== // Includes `include "t_preproc_inc2.vh" //=========================================================================== // Comments /* verilator pass_thru comment */ // verilator pass_thru_comment2 //=========================================================================== // Defines `define DEF_A3 `define DEF_A1 // DEF_A0 set by command line wire [3:0] q = { `ifdef DEF_A3 1'b1 `else 1'b0 `endif , `ifdef DEF_A2 1'b1 `else 1'b0 `endif , `ifdef DEF_A1 1'b1 `else 1'b0 `endif , `ifdef DEF_A0 1'b1 `else 1'b0 `endif }; text. `define FOOBAR foo /*this */ bar /* this too */ `define FOOBAR2 foobar2 // but not `FOOBAR `FOOBAR2 `define MULTILINE first part \ second part \ third part `define MOREMULTILINE {\ a,\ b,\ c} /*******COMMENT*****/ `MULTILINE `MOREMULTILINE Line_Preproc_Check `__LINE__ //=========================================================================== `define syn_negedge_reset_l or negedge reset_l `define DEEP deep `define DEEPER `DEEP `DEEP `DEEPER `define nosubst NOT_SUBSTITUTED `define WITHTICK "`nosubst" "Inside: `nosubst" `WITHTICK `define withparam(a, b) a b LLZZ a b `withparam(x,y) `withparam(`withparam(p,q),`withparam ( r , s )) `withparam(firstline , comma","line) `define withquote(a, bar) a bar LLZZ "a" bar `withquote( x , y) // Simulators disagree here; some substitute "a" others do not `define noparam (a,b) `noparam(a,b) `define msg(x,y) `"x: `\`"y`\`"`" $display(`msg(left side, right side)) `define foo(f) f``_suffix `foo(bar) more `define zap(which) \ $c("Zap(\"",which,"\");"); `zap(bug1); `zap("bug2"); /* Define inside comment: `DEEPER and `WITHTICK */ // More commentary: `zap(bug1); `zap("bug2"); //====================================================================== // display passthru `define ls left_side `define rs right_side `define noarg na `define thru(x) x `define thruthru `ls `rs // Doesn't expand `define msg(x,y) `"x: `\`"y`\`"`" initial begin //$display(`msg( \`, \`)); // Illegal $display(`msg(pre `thru(thrupre `thru(thrumid) thrupost) post,right side)); $display(`msg(left side,right side)); $display(`msg( left side , right side )); $display(`msg( `ls , `rs )); $display(`msg( `noarg , `rs )); $display(`msg( prep ( midp1 `ls midp2 ( outp ) ) , `rs )); $display(`msg(`noarg,`noarg`noarg)); $display(`msg( `thruthru , `thruthru )); // Results vary between simulators $display(`msg(`thru(),)); // Empty $display(`msg(`thru(left side),`thru(right side))); $display(`msg( `thru( left side ) , `thru( right side ) )); $display(`"standalone`"); // Unspecified when the stringification has multiple lines `define twoline first \ second $display(`msg(twoline, `twoline)); //$display(`msg(left side, \ right side \ )); // Not sure \{space} is legal. $write("*-* All Finished *-*\n"); $finish; end endmodule //====================================================================== // rt.cpan.org bug34429 `define ADD_UP(a,c) \ wire tmp_``a = a; \ wire tmp_``c = tmp_``a + 1; \ assign c = tmp_``c ; module add1 ( input wire d1, output wire o1); `ADD_UP(d1,o1) // expansion is OK endmodule module add2 ( input wire d2, output wire o2); `ADD_UP( d2 , o2 ) // expansion is bad endmodule `define check(mod, width, flopname, gate, path) \ generate for (i=0; i<(width); i=i+1) begin \ psl cover { path.d[i] & ~path.q[i] & !path.cond & (gate)} report `"fondNoRise: mod.flopname`"; \ psl cover { ~path.d[i] & path.q[i] & !path.cond & (gate)} report `"fondNoFall: mod.flopname`"; \ end endgenerate // parameterized macro with arguments that are macros `define MK m5k.f `define MF `MK .ctl `define CK_fr (`MF.alive & `MF.alive_m1) `check(m5kc_fcl, 3, _ctl_mvldx_m1, `CK_fr, `MF._ctl_mvldx_m1) // ignorecmt //====================================================================== // Quotes are legal in protected blocks. Grr. module prot(); `protected I!#r#e6<_Q{{E2+]I3<[3s)1@D|'E''i!O?]jD>Jo_![Cl) #nj1]p,3^1~,="E@QZB\T)eU\pC#C|7=\$J$##A[@-@{Qk] `endprotected endmodule //" //====================================================================== // macro call with define that has comma `define REG_H 6 `define REG_L 7 `define _H regs[`REG_H] `define _L regs[`REG_L] `define _HL {`_H, `_L} `define EX_WRITE(ad, da) begin addr <= (ad); wdata <= (da); wr <= 1; end `define EX_READ(ad) begin addr <= (ad); rd <= 1; end `EX_READ((`_HL + 1)) and `EX_WRITE((`_HL), rdata) `EX_READ(`_HL + 1) `EX_WRITE(`_HL, rdata) more //====================================================================== // include of parameterized file `define INCNAME "t_preproc_inc4.vh" `include `INCNAME `ifndef T_PREPROC_INC4 `error "No Inc4" `endif `undef T_PREPROC_INC4 `ifdef NOT_DEFINED_INC `include NOT_DEFINED_INC `endif //====================================================================== // macro call with , in {} `define xxerror(logfile, msg) $blah(logfile,msg) `xxerror("ab,cd","e,f"); `xxerror(this.logfile, vec); `xxerror(this.logfile, vec[1,2,3]); `xxerror(this.logfile, {blah.name(), " is not foo"}); //====================================================================== // pragma/default net type `pragma foo = 1 `default_nettype none `default_nettype uwire //====================================================================== // Ifdef `define EMPTY_TRUE `ifndef EMPTY_TRUE `error "Empty is still true" `endif Line_Preproc_Check `__LINE__ //====================================================================== // bug84 `define ARGPAR(a, // Hello, comments MIGHT not be legal /*more,,)cmts*/ b // But newlines ARE legal... who speced THAT? ) (a,b) `ARGPAR(p,q) `ARGPAR( //Here x, y //Too ) Line_Preproc_Check `__LINE__ //====================================================================== // defines split arguments `define BEGIN begin `define END end `define BEGINEND `BEGIN`END `define quoteit(x) `"x`" `BEGIN`END // 2001 spec doesn't require two tokens, so "beginend" ok `BEGINEND // 2001 spec doesn't require two tokens, so "beginend" ok `quoteit(`BEGIN`END) // No space "beginend" //====================================================================== // bug106 `define \esc`def got_escaped `ifdef \esc`def `\esc`def `endif Not a \`define //====================================================================== // misparsed comma in submacro `define sb bee `define appease_emacs_paren_matcher ( `define sa(l) x,y) `define sfoo(q,r) q--r `sfoo(`sa(el),`sb) submacro has comma paren //====================================================================== // bug191 `define bug191(bits) $display("bits %d %d", $bits(foo), bits); `bug191(10) //====================================================================== // 1800-2009 `define UDALL `ifndef PREDEF_COMMAND_LINE `error "Test setup error, PREDEF_COMMAND_LINE pre-missing" `endif `undefineall `ifdef UDALL `error "undefineall failed" `endif `ifndef PREDEF_COMMAND_LINE `error "Deleted too much, no PREDEF_COMMAND_LINE" `endif //====================================================================== // bug202 `define FC_INV3(out, in) \ `ifdef DC \ cell \inv_``out <$typeof(out)> (.a(), .o()); \ /* multi-line comment \ multi-line comment */ \ `else \ `ifdef MACRO_ATTRIBUTE \ (* macro_attribute = `"INV (out``,in``)`" *) \ `endif \ assign out = ~in ; \ `endif `FC_INV3(a3,b3) `define /* multi \ line1*/ \ bug202( i /*multi \ line2*/ \ ) \ /* multi \ line 3*/ \ def i \ `bug202(foo) //====================================================================== `define CMT1 // verilator NOT IN DEFINE `define CMT2 /* verilator PART OF DEFINE */ `define CMT3 /* verilator NOT PART OF DEFINE */ `define CMT4 /* verilator PART \ OF DEFINE */ `define CMT5 // CMT NOT \ also in // BUT TEXT IS \ also3 // CMT NOT 1 `CMT1 (nodef) 2 `CMT2 (hasdef) 3 `CMT3 (nodef) 4 `CMT4 (nodef) 5 `CMT5 (nodef) `define NL HAS a NEW \ LINE `NL //====================================================================== `define msg_fatal(log, msg) \ do \ /* synopsys translate_off */ \ `ifdef NEVER \ `error "WTF" \ `else \ if (start(`__FILE__, `__LINE__)) begin \ `endif \ message(msg); \ end \ /* synopsys translate_on */ \ while(0) `define msg_scen_(cl) cl``_scen `define MSG_MACRO_TO_STRING(x) `"x`" EXP: clxx_scen `msg_scen_(clxx) EXP: clxx_scen `MSG_MACRO_TO_STRING(`msg_scen_(clxx)) `define mf(clx) `msg_fatal(this.log, {"Blah-", `MSG_MACRO_TO_STRING(`msg_scen_(clx)), " end"}); EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", " end"}); end while(0); `mf(clx) //====================================================================== `define makedefine(name) \ `define def_``name This is name \ `define def_``name``_2 This is name``_2 \ `makedefine(fooed) `ifndef def_fooed `error "No def_fooed" `endif //`ifndef def_fooed_2 `error "No def_fooed_2" `endif EXP: This is fooed `def_fooed EXP: This is fooed_2 `def_fooed_2 //====================================================================== `define NOPARAM() np `NOPARAM() `NOPARAM( ) //====================================================================== // It's unclear if the spec allows this; is text_macro_idenitfier before or after substitution? `define NODS_DEFINED `define NODS_INDIRECT(x) x `ifndef `NODS_INDIRECT(NODS_DEFINED) `error "Indirect failed" `endif `ifdef `NODS_INDIRECT(NODS_UNDEFINED) `error "Indirect2 failed" `endif //====================================================================== // Metaprogramming `define REPEAT_0(d) `define REPEAT_1(d) d `define REPEAT_2(d) `REPEAT_1(d)d `define REPEAT_3(d) `REPEAT_2(d)d `define REPEAT_4(d) `REPEAT_3(d)d `define CONCAT(a, b) a``b `define REPEATC(n, d) `CONCAT(`REPEAT_, n)(d) `define REPEATT(n, d) `REPEAT_``n(d) `REPEATC(3, hello3 ) `REPEATT(4, hello4 ) //====================================================================== // Include from stringification `undef T_PREPROC_INC4 `define NODS_CONC_VH(m) `"m.vh`" `include `NODS_CONC_VH(t_preproc_inc4) `ifndef T_PREPROC_INC4 `error_here `endif //====================================================================== // Defines doing defines // Note the newline on the end - required to form the end of a define `define DEFINEIT(d) d \ `define _DEFIF_Z_0 1 `define DEFIF_NZ(d,n) `undef d `ifndef _DEFIF_Z_``n `DEFINEIT(`define d 1) `endif `DEFIF_NZ(TEMP,1) `ifndef TEMP `error "bad" `endif `DEFIF_NZ(TEMP,0) `ifdef TEMP `error "bad0" `endif Line_Preproc_Check `__LINE__ //====================================================================== // Quoted multiline - track line numbers, and insure \\n gets propagated `define MULQUOTE "FOO \ BAR " `define MULQUOTE2(mq) `MULQUOTE mq `MULQUOTE Line_Preproc_Check `__LINE__ `MULQUOTE2("arg_line1 \ arg_line2") Line_Preproc_Check `__LINE__ //====================================================================== // bug283 `define A a `define B b `define C c // EXP: abc `define C5 `A``b```C `C5 `undef A `undef B `undef C `define XTYPE sonet `define XJOIN(__arg1, __arg2) __arg1``__arg2 `define XACTION `XJOIN(`XTYPE, _frame) EXP: sonet_frame `XACTION // `define XFRAME frame `define XACTION2 `XJOIN(sonet_, `XFRAME) EXP: sonet_frame `XACTION2 // This result varies between simulators `define sonet_frame other_frame `define XACTION3 `XTYPE``_frame EXP: sonet_frame `XACTION3 // The existance of non-existance of a base define can make a difference `define QA_b zzz `define Q1 `QA``_b EXP: module zzz ; endmodule module `Q1 ; endmodule module `Q1 ; endmodule `define QA a EXP: module a_b ; endmodule module `Q1 ; endmodule module `Q1 ; endmodule //====================================================================== // bug311 integer/*NEED_SPACE*/foo; //====================================================================== // bug441 module t; //----- // case provided // note this does NOT escape as suggested in the mail `define LEX_CAT(lexem1, lexem2) lexem1``lexem2 `define LEX_ESC(name) \name \ initial begin : `LEX_ESC( `LEX_CAT(a[0],_assignment) ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`LEX_CAT(a[0],_assignment) "); end //----- // SHOULD(simulator-dependant): Backslash doesn't prevent arguments from // substituting and the \ staying in the expansion // Note space after name is important so when substitute it has ending whitespace `define ESC_CAT(name,name2) \name``_assignment_``name2 \ initial begin : `ESC_CAT( a[0],a[1] ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\a[0]_assignment_a[1] "); end `undef ESC_CAT //----- `define CAT(a,b) a``b `define ESC(name) \`CAT(name,suffix) // RULE: Ignoring backslash does NOT allow an additional expansion level // (Because ESC gets expanded then the \ has it's normal escape meaning) initial begin : `ESC(pp) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(pp,suffix) "); end `undef CAT `undef ESC //----- `define CAT(a,b) a``b `define ESC(name) \name \ // Similar to above; \ does not allow expansion after substitution initial begin : `ESC( `CAT(ff,bb) ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(ff,bb) "); end `undef CAT `undef ESC //----- `define ESC(name) \name \ // MUST: Unknown macro with backslash escape stays as escaped symbol name initial begin : `ESC( `zzz ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`zzz "); end `undef ESC //----- `define FOO bar `define ESC(name) \name \ // SHOULD(simulator-dependant): Known macro with backslash escape expands initial begin : `ESC( `FOO ) $write("GOT%%m='%m' OTHER_EXP='%s'\n OUR_EXP='%s'", "t.bar ","t.\\`FOO "); end // SHOULD(simulator-dependant): Prefix breaks the above initial begin : `ESC( xx`FOO ) $write("GOT%%m='%m' EXP='%s'\n", "t.\\xx`FOO "); end `undef FOO `undef ESC //----- // MUST: Unknown macro not under call with backslash escape doesn't expand `undef UNKNOWN initial begin : \`UNKNOWN $write("GOT%%m='%m' EXP='%s'\n", "t.\\`UNKNOWN "); end //----- // MUST: Unknown macro not under call doesn't expand `define DEF_NO_EXPAND error_dont_expand initial begin : \`DEF_NO_EXPAND $write("GOT%%m='%m' EXP='%s'\n", "t.\\`DEF_NO_EXPAND "); end `undef DEF_NO_EXPAND //----- // bug441 derivative // SHOULD(simulator-dependant): Quotes doesn't prevent arguments from expanding (like backslashes above) `define STR(name) "foo name baz" initial $write("GOT='%s' EXP='%s'\n", `STR(bar), "foo bar baz"); `undef STR //----- // RULE: Because there are quotes after substituting STR, the `A does NOT expand `define STR(name) "foo name baz" `define A(name) boo name hiss initial $write("GOT='%s' EXP='%s'\n", `STR(`A(bar)), "foo `A(bar) baz"); `undef A `undef STR //---- // bug845 `define SLASHED "1//2.3" initial $write("Slashed=`%s'\n", `SLASHED); //---- // bug915 `define BUG915(a,b,c) \ $display("%s%s",a,`"b``c``\n`") initial `BUG915("a1",b2,c3); endmodule //====================================================================== // IEEE mandated predefines `undefineall // undefineall should have no effect on these predef `SV_COV_START 0 predef `SV_COV_STOP 1 predef `SV_COV_RESET 2 predef `SV_COV_CHECK 3 predef `SV_COV_MODULE 10 predef `SV_COV_HIER 11 predef `SV_COV_ASSERTION 20 predef `SV_COV_FSM_STATE 21 predef `SV_COV_STATEMENT 22 predef `SV_COV_TOGGLE 23 predef `SV_COV_OVERFLOW -2 predef `SV_COV_ERROR -1 predef `SV_COV_NOCOV 0 predef `SV_COV_OK 1 predef `SV_COV_PARTIAL 2 //====================================================================== verilator-3.874/test_regress/t/t_tri_gate.v0000664000177100017500000000205412473477707021032 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks module top (input SEL, input[1:0] A, output W, output X, output Y, output Z); mux mux2 (.A(A), .SEL(SEL), .Z(W)); pass mux1 (.A(A), .SEL(SEL), .Z(X)); tbuf mux0[1:0] (.A(A), .OE({SEL,!SEL}), .Z(Y)); assign Z = ( SEL) ? A[1] : 1'bz; tbuf tbuf (.A(A[0]), .OE(!SEL), .Z(Z)); endmodule module pass (input[1:0] A, input SEL, output Z); tbuf tbuf1 (.A(A[1]), .OE(SEL), .Z(Z)); tbuf tbuf0 (.A(A[0]), .OE(!SEL),.Z(Z)); endmodule module tbuf (input A, input OE, output Z); `ifdef T_BUFIF0 bufif0 (Z, A, !OE); `elsif T_BUFIF1 bufif1 (Z, A, OE); `elsif T_NOTIF0 notif0 (Z, !A, !OE); `elsif T_NOTIF1 notif1 (Z, !A, OE); `elsif T_PMOS pmos (Z, A, !OE); `elsif T_NMOS nmos (Z, A, OE); `elsif T_COND assign Z = (OE) ? A : 1'bz; `else `error "Unknown test name" `endif endmodule module mux (input[1:0] A, input SEL, output Z); assign Z = (SEL) ? A[1] : 1'bz; assign Z = (!SEL)? A[0] : 1'bz; assign Z = 1'bz; endmodule verilator-3.874/test_regress/t/t_tri_select.v0000664000177100017500000000201612473477707021367 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks `define WIDTH 2 module top ( input OE1, input OE2, input [`WIDTH-1:0] A1, input [`WIDTH-1:0] A2, output [`WIDTH-1:0] Y1, output [`WIDTH-1:0] Y2, output [`WIDTH-1:0] Y3, output [`WIDTH**2-1:0] W); assign W[A1] = (OE2) ? A2[0] : 1'bz; assign W[A2] = (OE1) ? A2[1] : 1'bz; // have 2 different 'chips' drive the PAD to act like a bi-directional bus wire [`WIDTH-1:0] PAD; io_ring io_ring1 (.OE(OE1), .A(A1), .O(Y1), .PAD(PAD)); io_ring io_ring2 (.OE(OE2), .A(A2), .O(Y2), .PAD(PAD)); assign Y3 = PAD; pullup p1(PAD); // pulldown p1(PAD); wire [5:0] fill = { 4'b0, A1 }; endmodule module io_ring (input OE, input [`WIDTH-1:0] A, output [`WIDTH-1:0] O, inout [`WIDTH-1:0] PAD); io io[`WIDTH-1:0] (.OE(OE), .I(A), .O(O), .PAD(PAD)); endmodule module io (input OE, input I, output O, inout PAD); assign O = PAD; assign PAD = OE ? I : 1'bz; endmodule verilator-3.874/test_regress/t/t_package_enum.v0000664000177100017500000000133612473477707021655 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. package pkg; typedef enum bit [1:0] { E__NOT = 2'b00, E__VAL = 2'b11 } E_t; endpackage module t; reg [1:0] ttype; reg m; enum bit [1:0] { LOCAL } l; always @ (m or 1'b0 or LOCAL) begin // Don't complain about constants in sensitivity lists end initial begin ttype = pkg::E__NOT; m = (ttype == pkg::E__VAL); if (m != 1'b0) $stop; ttype = pkg::E__VAL; m = (ttype == pkg::E__VAL); if (m != 1'b1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_func_rand.cpp0000664000177100017500000000123712473477707021512 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. #include #include "Vt_func_rand.h" int main (int argc, char *argv[]) { Vt_func_rand *topp = new Vt_func_rand; Verilated::debug(0); printf ("\nTesting\n"); for (int i = 0; i < 10; i++) { topp->clk = 0; topp->eval(); topp->clk = 1; topp->eval(); } if (topp->Rand != 0xfeed0fad) { vl_fatal(__FILE__,__LINE__,"top", "Unexpected value for Rand output\n"); } printf ("*-* All Finished *-*\n"); } verilator-3.874/test_regress/t/t_order_wireloop.v0000664000177100017500000000046712525171734022262 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs bar ); wire foo; output bar; // Oh dear. assign foo = bar; assign bar = foo; endmodule verilator-3.874/test_regress/t/t_delay_stmtdly_bad.pl0000775000177100017500000000176412473477707023100 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_delay.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( verilator_flags2 => ['-Wall -Wno-DECLFILENAME'], fails=>1, expect=> '%Warning-ASSIGNDLY: t/t_delay.v:\d+: Unsupported: Ignoring delay on this assignment/primitive. %Warning-ASSIGNDLY: Use .* %Warning-ASSIGNDLY: t/t_delay.v:\d+: Unsupported: Ignoring delay on this assignment/primitive. %Warning-ASSIGNDLY: t/t_delay.v:\d+: Unsupported: Ignoring delay on this assignment/primitive. %Warning-STMTDLY: t/t_delay.v:\d+: Unsupported: Ignoring delay on this delayed statement. .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_func_wide_out_bad.pl0000775000177100017500000000122312473477707023042 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_func_wide_out_bad.v:\d+: Unsupported: Function output argument 'data' requires 4352 bits, but connection's VARREF 'msg' generates 4350 bits. %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_signed2.v0000664000177100017500000000300612473477707021576 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Peter Debacker. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [10:0] in; reg signed[7:0] min; reg signed[7:0] max; wire signed[7:0] filtered_data; reg signed[7:0] delay_minmax[31:0]; integer k; initial begin in = 11'b10000001000; for(k=0;k<32;k=k+1) delay_minmax[k] = 0; end assign filtered_data = $signed(in[10:3]); always @(posedge clk) begin in = in + 8; `ifdef TEST_VERBOSE $write("filtered_data: %d\n", filtered_data); `endif // delay line shift for (k=31;k>0;k=k-1) begin delay_minmax[k] = delay_minmax[k-1]; end delay_minmax[0] = filtered_data; `ifdef TEST_VERBOSE $write("delay_minmax[0] = %d\n", delay_minmax[0]); $write("delay_minmax[31] = %d\n", delay_minmax[31]); `endif // find min and max min = 127; max = -128; `ifdef TEST_VERBOSE $write("max init: %d\n", max); $write("min init: %d\n", min); `endif for(k=0;k<32;k=k+1) begin if ((delay_minmax[k]) > $signed(max)) max = delay_minmax[k]; if ((delay_minmax[k]) < $signed(min)) min = delay_minmax[k]; end `ifdef TEST_VERBOSE $write("max: %d\n", max); $write("min: %d\n", min); `endif if (min == 127) begin $stop; end else if (filtered_data >= -61) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_func_twocall.v0000664000177100017500000000275212473477707021721 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (clk); input clk; reg [7:0] crc; wire [61:59] ah = crc[5:3]; wire [61:59] bh = ~crc[4:2]; wire [41:2] al = {crc,crc,crc,crc,crc}; wire [41:2] bl = ~{crc[6:0],crc[6:0],crc[6:0],crc[6:0],crc[6:0],crc[6:2]}; reg sel; wire [61:28] q = ( sel ? func(ah, al) : func(bh, bl)); function [61:28] func; input [61:59] inh; input [41:2] inl; reg [42:28] func_mid; reg carry; begin carry = &inl[27:2]; func_mid = {1'b0,inl[41:28]} + {14'b0, carry}; func[61:59] = inh + {2'b0, func_mid[42]}; func[58:42] = {17{func_mid[41]}}; func[41:28] = func_mid[41:28]; end endfunction integer cyc; initial cyc=1; always @ (posedge clk) begin //$write("%d %x\n", cyc, q); if (cyc!=0) begin cyc <= cyc + 1; sel <= ~sel; crc <= {crc[6:0], ~^ {crc[7],crc[5],crc[4],crc[3]}}; if (cyc==1) begin sel <= 1'b1; crc <= 8'h12; end if (cyc==2) if (q!=34'h100000484) $stop; if (cyc==3) if (q!=34'h37fffeddb) $stop; if (cyc==4) if (q!=34'h080001212) $stop; if (cyc==5) if (q!=34'h1fffff7ef) $stop; if (cyc==6) if (q!=34'h200000848) $stop; if (cyc==7) if (q!=34'h380001ebd) $stop; if (cyc==8) if (q!=34'h07fffe161) $stop; if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_bind.pl0000775000177100017500000000072212473477707020321 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_order_a.v0000664000177100017500000000311112473477707020642 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_order_a (/*AUTOARG*/ // Outputs m_from_clk_lev1_r, n_from_clk_lev2, o_from_com_levs11, o_from_comandclk_levs12, // Inputs clk, a_to_clk_levm3, b_to_clk_levm1, c_com_levs10, d_to_clk_levm2, one ); input clk; input [7:0] a_to_clk_levm3; input [7:0] b_to_clk_levm1; input [7:0] c_com_levs10; input [7:0] d_to_clk_levm2; input [7:0] one; output [7:0] m_from_clk_lev1_r; output [7:0] n_from_clk_lev2; output [7:0] o_from_com_levs11; output [7:0] o_from_comandclk_levs12; /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [7:0] m_from_clk_lev1_r; // End of automatics // surefire lint_off ASWEBB // surefire lint_off ASWEMB wire [7:0] a_to_clk_levm1; wire [7:0] a_to_clk_levm2; wire [7:0] c_com_levs11; reg [7:0] o_from_comandclk_levs12; wire [7:0] n_from_clk_lev2; wire [7:0] n_from_clk_lev3; assign a_to_clk_levm1 = a_to_clk_levm2 + d_to_clk_levm2; assign a_to_clk_levm2 = a_to_clk_levm3 + 0; always @ (posedge clk) begin m_from_clk_lev1_r <= a_to_clk_levm1 + b_to_clk_levm1; end assign c_com_levs11 = c_com_levs10 + one; always @ (/*AS*/c_com_levs11 or n_from_clk_lev3) o_from_comandclk_levs12 = c_com_levs11 + n_from_clk_lev3; assign n_from_clk_lev2 = m_from_clk_lev1_r; assign n_from_clk_lev3 = n_from_clk_lev2; wire [7:0] o_from_com_levs11 = c_com_levs10 + 1; endmodule verilator-3.874/test_regress/t/t_gen_cond_bitrange_bad.pl0000775000177100017500000000163512473477707023646 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Warning-SELRANGE: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Warning-SELRANGE: Use .* %Warning-SELRANGE: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Warning-SELRANGE: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Warning-SELRANGE: t/t_gen_cond_bitrange_bad.v:\d+: Selection index out of range: 2:2 outside 1:0 %Error: Exiting due to .*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_always_comb_bad.pl0000775000177100017500000000127112473477707023541 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, fails => 1, expect=> '%Warning-ALWCOMBORDER: t/t_lint_always_comb_bad.v:\d+: Always_comb variable driven after use: mid .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_vams_wreal.pl0000775000177100017500000000071712473477707021551 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_complex.out0000664000177100017500000000612512473477707022426 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Tue Apr 15 19:42:28 2014 $end $timescale 1ns $end $scope module top $end $var wire 1 9 clk $end $scope module $unit $end $var wire 1 # global_bit $end $upscope $end $scope module v $end $var wire 1 9 clk $end $var wire 32 $ cyc [31:0] $end $var real 64 3 v_arr_real(0) $end $var real 64 5 v_arr_real(1) $end $var wire 2 * v_arrp [2:1] $end $var wire 4 + v_arrp_arrp [3:0] $end $var wire 4 , v_arrp_strp [3:0] $end $var wire 1 : v_arru(1) $end $var wire 1 ; v_arru(2) $end $var wire 2 - v_arru_arrp(3) [2:1] $end $var wire 2 . v_arru_arrp(4) [2:1] $end $var wire 1 < v_arru_arru(3)(1) $end $var wire 1 = v_arru_arru(3)(2) $end $var wire 1 > v_arru_arru(4)(1) $end $var wire 1 ? v_arru_arru(4)(2) $end $var wire 2 / v_arru_strp(3) [1:0] $end $var wire 2 0 v_arru_strp(4) [1:0] $end $var real 64 1 v_real $end $var wire 64 % v_str32x2 [63:0] $end $var wire 2 ' v_strp [1:0] $end $var wire 4 ( v_strp_strp [3:0] $end $var wire 2 ) v_unip_strp [1:0] $end $scope module p2 $end $var wire 32 @ PARAM [31:0] $end $upscope $end $scope module p3 $end $var wire 32 A PARAM [31:0] $end $upscope $end $scope module unnamedblk1 $end $var wire 32 7 b [31:0] $end $scope module unnamedblk2 $end $var wire 32 8 a [31:0] $end $upscope $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 1# b00000000000000000000000000000000 $ b0000000000000000000000000000000000000000000000000000000011111111 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0 1 r0 3 r0 5 b00000000000000000000000000000000 7 b00000000000000000000000000000000 8 09 0: 0; 0< 0= 0> 0? b00000000000000000000000000000010 @ b00000000000000000000000000000011 A #10 b00000000000000000000000000000001 $ b0000000000000000000000000000000100000000000000000000000011111110 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.1 1 r0.2 3 r0.3 5 b00000000000000000000000000000101 7 b00000000000000000000000000000101 8 19 #15 09 #20 b00000000000000000000000000000010 $ b0000000000000000000000000000001000000000000000000000000011111101 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.2 1 r0.4 3 r0.6 5 19 #25 09 #30 b00000000000000000000000000000011 $ b0000000000000000000000000000001100000000000000000000000011111100 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.3 1 r0.6000000000000001 3 r0.8999999999999999 5 19 #35 09 #40 b00000000000000000000000000000100 $ b0000000000000000000000000000010000000000000000000000000011111011 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.4 1 r0.8 3 r1.2 5 19 #45 09 #50 b00000000000000000000000000000101 $ b0000000000000000000000000000010100000000000000000000000011111010 % b11 ' b1111 ( b11 ) b11 * b1111 + b1111 , b11 - b11 . b11 / b11 0 r0.5 1 r1 3 r1.5 5 19 #55 09 #60 b00000000000000000000000000000110 $ b0000000000000000000000000000011000000000000000000000000011111001 % b00 ' b0000 ( b00 ) b00 * b0000 + b0000 , b00 - b00 . b00 / b00 0 r0.6 1 r1.2 3 r1.8 5 19 verilator-3.874/test_regress/t/t_tri_gate_bufif1.pl0000775000177100017500000000134312473477707022437 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_tri_gate.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ['+define+T_BUFIF1',], make_flags => 'CPPFLAGS_ADD=-DT_BUFIF1', verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_write2_tasks.v0000664000177100017500000025433112473477707022657 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. `include "verilated.v" module t_case_write2_tasks (); // verilator lint_off WIDTH // verilator lint_off CASEINCOMPLETE `define FD_BITS 31:0 parameter STRLEN = 78; task ozonerab; input [6:0] rab; input [`FD_BITS] fd; // verilator no_inline_task begin case (rab[6:0]) 7'h00 : $fwrite (fd, " 0"); 7'h01 : $fwrite (fd, " 1"); 7'h02 : $fwrite (fd, " 2"); 7'h03 : $fwrite (fd, " 3"); 7'h04 : $fwrite (fd, " 4"); 7'h05 : $fwrite (fd, " 5"); 7'h06 : $fwrite (fd, " 6"); 7'h07 : $fwrite (fd, " 7"); 7'h08 : $fwrite (fd, " 8"); 7'h09 : $fwrite (fd, " 9"); 7'h0a : $fwrite (fd, " 10"); 7'h0b : $fwrite (fd, " 11"); 7'h0c : $fwrite (fd, " 12"); 7'h0d : $fwrite (fd, " 13"); 7'h0e : $fwrite (fd, " 14"); 7'h0f : $fwrite (fd, " 15"); 7'h10 : $fwrite (fd, " 16"); 7'h11 : $fwrite (fd, " 17"); 7'h12 : $fwrite (fd, " 18"); 7'h13 : $fwrite (fd, " 19"); 7'h14 : $fwrite (fd, " 20"); 7'h15 : $fwrite (fd, " 21"); 7'h16 : $fwrite (fd, " 22"); 7'h17 : $fwrite (fd, " 23"); 7'h18 : $fwrite (fd, " 24"); 7'h19 : $fwrite (fd, " 25"); 7'h1a : $fwrite (fd, " 26"); 7'h1b : $fwrite (fd, " 27"); 7'h1c : $fwrite (fd, " 28"); 7'h1d : $fwrite (fd, " 29"); 7'h1e : $fwrite (fd, " 30"); 7'h1f : $fwrite (fd, " 31"); 7'h20 : $fwrite (fd, " 32"); 7'h21 : $fwrite (fd, " 33"); 7'h22 : $fwrite (fd, " 34"); 7'h23 : $fwrite (fd, " 35"); 7'h24 : $fwrite (fd, " 36"); 7'h25 : $fwrite (fd, " 37"); 7'h26 : $fwrite (fd, " 38"); 7'h27 : $fwrite (fd, " 39"); 7'h28 : $fwrite (fd, " 40"); 7'h29 : $fwrite (fd, " 41"); 7'h2a : $fwrite (fd, " 42"); 7'h2b : $fwrite (fd, " 43"); 7'h2c : $fwrite (fd, " 44"); 7'h2d : $fwrite (fd, " 45"); 7'h2e : $fwrite (fd, " 46"); 7'h2f : $fwrite (fd, " 47"); 7'h30 : $fwrite (fd, " 48"); 7'h31 : $fwrite (fd, " 49"); 7'h32 : $fwrite (fd, " 50"); 7'h33 : $fwrite (fd, " 51"); 7'h34 : $fwrite (fd, " 52"); 7'h35 : $fwrite (fd, " 53"); 7'h36 : $fwrite (fd, " 54"); 7'h37 : $fwrite (fd, " 55"); 7'h38 : $fwrite (fd, " 56"); 7'h39 : $fwrite (fd, " 57"); 7'h3a : $fwrite (fd, " 58"); 7'h3b : $fwrite (fd, " 59"); 7'h3c : $fwrite (fd, " 60"); 7'h3d : $fwrite (fd, " 61"); 7'h3e : $fwrite (fd, " 62"); 7'h3f : $fwrite (fd, " 63"); 7'h40 : $fwrite (fd, " 64"); 7'h41 : $fwrite (fd, " 65"); 7'h42 : $fwrite (fd, " 66"); 7'h43 : $fwrite (fd, " 67"); 7'h44 : $fwrite (fd, " 68"); 7'h45 : $fwrite (fd, " 69"); 7'h46 : $fwrite (fd, " 70"); 7'h47 : $fwrite (fd, " 71"); 7'h48 : $fwrite (fd, " 72"); 7'h49 : $fwrite (fd, " 73"); 7'h4a : $fwrite (fd, " 74"); 7'h4b : $fwrite (fd, " 75"); 7'h4c : $fwrite (fd, " 76"); 7'h4d : $fwrite (fd, " 77"); 7'h4e : $fwrite (fd, " 78"); 7'h4f : $fwrite (fd, " 79"); 7'h50 : $fwrite (fd, " 80"); 7'h51 : $fwrite (fd, " 81"); 7'h52 : $fwrite (fd, " 82"); 7'h53 : $fwrite (fd, " 83"); 7'h54 : $fwrite (fd, " 84"); 7'h55 : $fwrite (fd, " 85"); 7'h56 : $fwrite (fd, " 86"); 7'h57 : $fwrite (fd, " 87"); 7'h58 : $fwrite (fd, " 88"); 7'h59 : $fwrite (fd, " 89"); 7'h5a : $fwrite (fd, " 90"); 7'h5b : $fwrite (fd, " 91"); 7'h5c : $fwrite (fd, " 92"); 7'h5d : $fwrite (fd, " 93"); 7'h5e : $fwrite (fd, " 94"); 7'h5f : $fwrite (fd, " 95"); 7'h60 : $fwrite (fd, " 96"); 7'h61 : $fwrite (fd, " 97"); 7'h62 : $fwrite (fd, " 98"); 7'h63 : $fwrite (fd, " 99"); 7'h64 : $fwrite (fd, " 100"); 7'h65 : $fwrite (fd, " 101"); 7'h66 : $fwrite (fd, " 102"); 7'h67 : $fwrite (fd, " 103"); 7'h68 : $fwrite (fd, " 104"); 7'h69 : $fwrite (fd, " 105"); 7'h6a : $fwrite (fd, " 106"); 7'h6b : $fwrite (fd, " 107"); 7'h6c : $fwrite (fd, " 108"); 7'h6d : $fwrite (fd, " 109"); 7'h6e : $fwrite (fd, " 110"); 7'h6f : $fwrite (fd, " 111"); 7'h70 : $fwrite (fd, " 112"); 7'h71 : $fwrite (fd, " 113"); 7'h72 : $fwrite (fd, " 114"); 7'h73 : $fwrite (fd, " 115"); 7'h74 : $fwrite (fd, " 116"); 7'h75 : $fwrite (fd, " 117"); 7'h76 : $fwrite (fd, " 118"); 7'h77 : $fwrite (fd, " 119"); 7'h78 : $fwrite (fd, " 120"); 7'h79 : $fwrite (fd, " 121"); 7'h7a : $fwrite (fd, " 122"); 7'h7b : $fwrite (fd, " 123"); 7'h7c : $fwrite (fd, " 124"); 7'h7d : $fwrite (fd, " 125"); 7'h7e : $fwrite (fd, " 126"); 7'h7f : $fwrite (fd, " 127"); default:$fwrite (fd, " 128"); endcase end endtask task ozonerb; input [5:0] rb; input [`FD_BITS] fd; // verilator no_inline_task begin case (rb[5:0]) 6'h10, 6'h17, 6'h1e, 6'h1f: $fwrite (fd, " 129"); default: ozonerab({1'b1, rb}, fd); endcase end endtask task ozonef3f4_iext; input [1:0] foo; input [15:0] im16; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo) 2'h0 : begin skyway({4{im16[15]}}, fd); skyway({4{im16[15]}}, fd); skyway(im16[15:12], fd); skyway(im16[11: 8], fd); skyway(im16[ 7: 4], fd); skyway(im16[ 3:0], fd); $fwrite (fd, " 130"); end 2'h1 : begin $fwrite (fd, " 131"); skyway(im16[15:12], fd); skyway(im16[11: 8], fd); skyway(im16[ 7: 4], fd); skyway(im16[ 3:0], fd); end 2'h2 : begin skyway({4{im16[15]}}, fd); skyway({4{im16[15]}}, fd); skyway(im16[15:12], fd); skyway(im16[11: 8], fd); skyway(im16[ 7: 4], fd); skyway(im16[ 3:0], fd); $fwrite (fd, " 132"); end 2'h3 : begin $fwrite (fd, " 133"); skyway(im16[15:12], fd); skyway(im16[11: 8], fd); skyway(im16[ 7: 4], fd); skyway(im16[ 3:0], fd); end endcase end endtask task skyway; input [ 3:0] hex; input [`FD_BITS] fd; // verilator no_inline_task begin case (hex) 4'h0 : $fwrite (fd, " 134"); 4'h1 : $fwrite (fd, " 135"); 4'h2 : $fwrite (fd, " 136"); 4'h3 : $fwrite (fd, " 137"); 4'h4 : $fwrite (fd, " 138"); 4'h5 : $fwrite (fd, " 139"); 4'h6 : $fwrite (fd, " 140"); 4'h7 : $fwrite (fd, " 141"); 4'h8 : $fwrite (fd, " 142"); 4'h9 : $fwrite (fd, " 143"); 4'ha : $fwrite (fd, " 144"); 4'hb : $fwrite (fd, " 145"); 4'hc : $fwrite (fd, " 146"); 4'hd : $fwrite (fd, " 147"); 4'he : $fwrite (fd, " 148"); 4'hf : $fwrite (fd, " 149"); endcase end endtask task ozonesr; input [ 15:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo[11: 9]) 3'h0 : $fwrite (fd, " 158"); 3'h1 : $fwrite (fd, " 159"); 3'h2 : $fwrite (fd, " 160"); 3'h3 : $fwrite (fd, " 161"); 3'h4 : $fwrite (fd, " 162"); 3'h5 : $fwrite (fd, " 163"); 3'h6 : $fwrite (fd, " 164"); 3'h7 : $fwrite (fd, " 165"); endcase end endtask task ozonejk; input k; input [`FD_BITS] fd; // verilator no_inline_task begin if (k) $fwrite (fd, " 166"); else $fwrite (fd, " 167"); end endtask task ozoneae; input [ 2:0] ae; input [`FD_BITS] fd; // verilator no_inline_task begin case (ae) 3'b000 : $fwrite (fd, " 168"); 3'b001 : $fwrite (fd, " 169"); 3'b010 : $fwrite (fd, " 170"); 3'b011 : $fwrite (fd, " 171"); 3'b100 : $fwrite (fd, " 172"); 3'b101 : $fwrite (fd, " 173"); 3'b110 : $fwrite (fd, " 174"); 3'b111 : $fwrite (fd, " 175"); endcase end endtask task ozoneaee; input [ 2:0] aee; input [`FD_BITS] fd; // verilator no_inline_task begin case (aee) 3'b001, 3'b011, 3'b101, 3'b111 : $fwrite (fd, " 176"); 3'b000 : $fwrite (fd, " 177"); 3'b010 : $fwrite (fd, " 178"); 3'b100 : $fwrite (fd, " 179"); 3'b110 : $fwrite (fd, " 180"); endcase end endtask task ozoneape; input [ 2:0] ape; input [`FD_BITS] fd; // verilator no_inline_task begin case (ape) 3'b001, 3'b011, 3'b101, 3'b111 : $fwrite (fd, " 181"); 3'b000 : $fwrite (fd, " 182"); 3'b010 : $fwrite (fd, " 183"); 3'b100 : $fwrite (fd, " 184"); 3'b110 : $fwrite (fd, " 185"); endcase end endtask task ozonef1; input [ 31:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo[24:21]) 4'h0 : if (foo[26]) $fwrite (fd, " 186"); else $fwrite (fd, " 187"); 4'h1 : case (foo[26:25]) 2'b00 : $fwrite (fd, " 188"); 2'b01 : $fwrite (fd, " 189"); 2'b10 : $fwrite (fd, " 190"); 2'b11 : $fwrite (fd, " 191"); endcase 4'h2 : $fwrite (fd, " 192"); 4'h3 : case (foo[26:25]) 2'b00 : $fwrite (fd, " 193"); 2'b01 : $fwrite (fd, " 194"); 2'b10 : $fwrite (fd, " 195"); 2'b11 : $fwrite (fd, " 196"); endcase 4'h4 : if (foo[26]) $fwrite (fd, " 197"); else $fwrite (fd, " 198"); 4'h5 : case (foo[26:25]) 2'b00 : $fwrite (fd, " 199"); 2'b01 : $fwrite (fd, " 200"); 2'b10 : $fwrite (fd, " 201"); 2'b11 : $fwrite (fd, " 202"); endcase 4'h6 : $fwrite (fd, " 203"); 4'h7 : case (foo[26:25]) 2'b00 : $fwrite (fd, " 204"); 2'b01 : $fwrite (fd, " 205"); 2'b10 : $fwrite (fd, " 206"); 2'b11 : $fwrite (fd, " 207"); endcase 4'h8 : case (foo[26:25]) 2'b00 : $fwrite (fd, " 208"); 2'b01 : $fwrite (fd, " 209"); 2'b10 : $fwrite (fd, " 210"); 2'b11 : $fwrite (fd, " 211"); endcase 4'h9 : case (foo[26:25]) 2'b00 : $fwrite (fd, " 212"); 2'b01 : $fwrite (fd, " 213"); 2'b10 : $fwrite (fd, " 214"); 2'b11 : $fwrite (fd, " 215"); endcase 4'ha : if (foo[25]) $fwrite (fd, " 216"); else $fwrite (fd, " 217"); 4'hb : if (foo[25]) $fwrite (fd, " 218"); else $fwrite (fd, " 219"); 4'hc : if (foo[26]) $fwrite (fd, " 220"); else $fwrite (fd, " 221"); 4'hd : case (foo[26:25]) 2'b00 : $fwrite (fd, " 222"); 2'b01 : $fwrite (fd, " 223"); 2'b10 : $fwrite (fd, " 224"); 2'b11 : $fwrite (fd, " 225"); endcase 4'he : case (foo[26:25]) 2'b00 : $fwrite (fd, " 226"); 2'b01 : $fwrite (fd, " 227"); 2'b10 : $fwrite (fd, " 228"); 2'b11 : $fwrite (fd, " 229"); endcase 4'hf : case (foo[26:25]) 2'b00 : $fwrite (fd, " 230"); 2'b01 : $fwrite (fd, " 231"); 2'b10 : $fwrite (fd, " 232"); 2'b11 : $fwrite (fd, " 233"); endcase endcase end endtask task ozonef1e; input [ 31:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo[27:21]) 7'h00: begin ozoneae(foo[20:18], fd); $fwrite (fd," 234"); $fwrite (fd, " 235"); end 7'h01: begin ozoneae(foo[20:18], fd); $fwrite (fd," 236"); ozoneae(foo[17:15], fd); $fwrite (fd," 237"); $fwrite (fd, " 238"); end 7'h02: $fwrite (fd, " 239"); 7'h03: begin ozoneae(foo[20:18], fd); $fwrite (fd," 240"); ozoneae(foo[17:15], fd); $fwrite (fd," 241"); $fwrite (fd, " 242"); end 7'h04: begin ozoneae(foo[20:18], fd); $fwrite (fd," 243"); $fwrite (fd," 244"); end 7'h05: begin ozoneae(foo[20:18], fd); $fwrite (fd," 245"); ozoneae(foo[17:15], fd); $fwrite (fd," 246"); end 7'h06: $fwrite (fd, " 247"); 7'h07: begin ozoneae(foo[20:18], fd); $fwrite (fd," 248"); ozoneae(foo[17:15], fd); $fwrite (fd," 249"); end 7'h08: begin ozoneae(foo[20:18], fd); $fwrite (fd," 250"); ozoneae(foo[17:15], fd); $fwrite (fd," 251"); end 7'h09: begin ozoneae(foo[20:18], fd); $fwrite (fd," 252"); ozoneae(foo[17:15], fd); $fwrite (fd," 253"); end 7'h0a: begin ozoneae(foo[17:15], fd); $fwrite (fd," 254"); end 7'h0b: begin ozoneae(foo[17:15], fd); $fwrite (fd," 255"); end 7'h0c: begin ozoneae(foo[20:18], fd); $fwrite (fd," 256"); end 7'h0d: begin ozoneae(foo[20:18], fd); $fwrite (fd," 257"); ozoneae(foo[17:15], fd); $fwrite (fd," 258"); end 7'h0e: begin ozoneae(foo[20:18], fd); $fwrite (fd," 259"); ozoneae(foo[17:15], fd); $fwrite (fd," 260"); end 7'h0f: begin ozoneae(foo[20:18], fd); $fwrite (fd," 261"); ozoneae(foo[17:15], fd); $fwrite (fd," 262"); end 7'h10: begin ozoneae(foo[20:18], fd); $fwrite (fd," 263"); ozoneae(foo[17:15], fd); $fwrite (fd," 264"); $fwrite (fd, " 265"); $fwrite (fd, " 266"); end 7'h11: begin ozoneae(foo[20:18], fd); $fwrite (fd," 267"); ozoneae(foo[17:15], fd); $fwrite (fd," 268"); $fwrite (fd, " 269"); $fwrite (fd, " 270"); end 7'h12: begin ozoneae(foo[20:18], fd); $fwrite (fd," 271"); ozoneae(foo[17:15], fd); $fwrite (fd," 272"); $fwrite (fd, " 273"); $fwrite (fd, " 274"); end 7'h13: begin ozoneae(foo[20:18], fd); $fwrite (fd," 275"); ozoneae(foo[17:15], fd); $fwrite (fd," 276"); $fwrite (fd, " 277"); $fwrite (fd, " 278"); end 7'h14: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 279"); ozoneaee(foo[17:15], fd); $fwrite (fd," 280"); ozoneape(foo[20:18], fd); $fwrite (fd," 281"); ozoneape(foo[17:15], fd); $fwrite (fd," 282"); $fwrite (fd, " 283"); $fwrite (fd, " 284"); end 7'h15: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 285"); ozoneaee(foo[17:15], fd); $fwrite (fd," 286"); ozoneape(foo[20:18], fd); $fwrite (fd," 287"); ozoneape(foo[17:15], fd); $fwrite (fd," 288"); $fwrite (fd, " 289"); $fwrite (fd, " 290"); end 7'h16: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 291"); ozoneaee(foo[17:15], fd); $fwrite (fd," 292"); ozoneape(foo[20:18], fd); $fwrite (fd," 293"); ozoneape(foo[17:15], fd); $fwrite (fd," 294"); $fwrite (fd, " 295"); $fwrite (fd, " 296"); end 7'h17: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 297"); ozoneaee(foo[17:15], fd); $fwrite (fd," 298"); ozoneape(foo[20:18], fd); $fwrite (fd," 299"); ozoneape(foo[17:15], fd); $fwrite (fd," 300"); $fwrite (fd, " 301"); $fwrite (fd, " 302"); end 7'h18: begin ozoneae(foo[20:18], fd); $fwrite (fd," 303"); ozoneae(foo[17:15], fd); $fwrite (fd," 304"); $fwrite (fd, " 305"); $fwrite (fd, " 306"); end 7'h19: begin ozoneae(foo[20:18], fd); $fwrite (fd," 307"); ozoneae(foo[17:15], fd); $fwrite (fd," 308"); $fwrite (fd, " 309"); $fwrite (fd, " 310"); end 7'h1a: begin ozoneae(foo[20:18], fd); $fwrite (fd," 311"); ozoneae(foo[17:15], fd); $fwrite (fd," 312"); $fwrite (fd, " 313"); $fwrite (fd, " 314"); end 7'h1b: begin ozoneae(foo[20:18], fd); $fwrite (fd," 315"); ozoneae(foo[17:15], fd); $fwrite (fd," 316"); $fwrite (fd, " 317"); $fwrite (fd, " 318"); end 7'h1c: begin ozoneae(foo[20:18], fd); $fwrite (fd," 319"); ozoneae(foo[17:15], fd); $fwrite (fd," 320"); $fwrite (fd, " 321"); $fwrite (fd, " 322"); end 7'h1d: begin ozoneae(foo[20:18], fd); $fwrite (fd," 323"); ozoneae(foo[17:15], fd); $fwrite (fd," 324"); $fwrite (fd, " 325"); $fwrite (fd, " 326"); end 7'h1e: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 327"); ozoneaee(foo[17:15], fd); $fwrite (fd," 328"); ozoneape(foo[20:18], fd); $fwrite (fd," 329"); ozoneape(foo[17:15], fd); $fwrite (fd," 330"); $fwrite (fd, " 331"); $fwrite (fd, " 332"); end 7'h1f: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 333"); ozoneaee(foo[17:15], fd); $fwrite (fd," 334"); ozoneape(foo[20:18], fd); $fwrite (fd," 335"); ozoneape(foo[17:15], fd); $fwrite (fd," 336"); $fwrite (fd, " 337"); $fwrite (fd, " 338"); end 7'h20: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 339"); ozoneaee(foo[17:15], fd); $fwrite (fd," 340"); ozoneape(foo[20:18], fd); $fwrite (fd," 341"); ozoneape(foo[17:15], fd); $fwrite (fd," 342"); $fwrite (fd, " 343"); $fwrite (fd, " 344"); end 7'h21: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 345"); ozoneaee(foo[17:15], fd); $fwrite (fd," 346"); ozoneape(foo[20:18], fd); $fwrite (fd," 347"); ozoneape(foo[17:15], fd); $fwrite (fd," 348"); $fwrite (fd, " 349"); $fwrite (fd, " 350"); end 7'h22: begin ozoneae(foo[20:18], fd); $fwrite (fd," 351"); ozoneae(foo[17:15], fd); $fwrite (fd," 352"); $fwrite (fd, " 353"); $fwrite (fd, " 354"); end 7'h23: begin ozoneae(foo[20:18], fd); $fwrite (fd," 355"); ozoneae(foo[17:15], fd); $fwrite (fd," 356"); $fwrite (fd, " 357"); $fwrite (fd, " 358"); end 7'h24: begin ozoneae(foo[20:18], fd); $fwrite (fd," 359"); ozoneae(foo[17:15], fd); $fwrite (fd," 360"); $fwrite (fd, " 361"); $fwrite (fd, " 362"); end 7'h25: begin ozoneae(foo[20:18], fd); $fwrite (fd," 363"); ozoneae(foo[17:15], fd); $fwrite (fd," 364"); $fwrite (fd, " 365"); $fwrite (fd, " 366"); end 7'h26: begin ozoneae(foo[20:18], fd); $fwrite (fd," 367"); ozoneae(foo[17:15], fd); $fwrite (fd," 368"); $fwrite (fd, " 369"); $fwrite (fd, " 370"); end 7'h27: begin ozoneae(foo[20:18], fd); $fwrite (fd," 371"); ozoneae(foo[17:15], fd); $fwrite (fd," 372"); $fwrite (fd, " 373"); $fwrite (fd, " 374"); end 7'h28: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 375"); ozoneaee(foo[17:15], fd); $fwrite (fd," 376"); ozoneape(foo[20:18], fd); $fwrite (fd," 377"); ozoneape(foo[17:15], fd); $fwrite (fd," 378"); $fwrite (fd, " 379"); $fwrite (fd, " 380"); end 7'h29: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 381"); ozoneaee(foo[17:15], fd); $fwrite (fd," 382"); ozoneape(foo[20:18], fd); $fwrite (fd," 383"); ozoneape(foo[17:15], fd); $fwrite (fd," 384"); $fwrite (fd, " 385"); $fwrite (fd, " 386"); end 7'h2a: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 387"); ozoneaee(foo[17:15], fd); $fwrite (fd," 388"); ozoneape(foo[20:18], fd); $fwrite (fd," 389"); ozoneape(foo[17:15], fd); $fwrite (fd," 390"); $fwrite (fd, " 391"); $fwrite (fd, " 392"); end 7'h2b: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 393"); ozoneaee(foo[17:15], fd); $fwrite (fd," 394"); ozoneape(foo[20:18], fd); $fwrite (fd," 395"); ozoneape(foo[17:15], fd); $fwrite (fd," 396"); $fwrite (fd, " 397"); $fwrite (fd, " 398"); end 7'h2c: begin ozoneae(foo[20:18], fd); $fwrite (fd," 399"); ozoneae(foo[17:15], fd); $fwrite (fd," 400"); $fwrite (fd, " 401"); $fwrite (fd, " 402"); end 7'h2d: begin ozoneae(foo[20:18], fd); $fwrite (fd," 403"); ozoneae(foo[17:15], fd); $fwrite (fd," 404"); $fwrite (fd, " 405"); $fwrite (fd, " 406"); end 7'h2e: begin ozoneae(foo[20:18], fd); $fwrite (fd," 407"); ozoneae(foo[17:15], fd); $fwrite (fd," 408"); $fwrite (fd, " 409"); $fwrite (fd, " 410"); end 7'h2f: begin ozoneae(foo[20:18], fd); $fwrite (fd," 411"); ozoneae(foo[17:15], fd); $fwrite (fd," 412"); $fwrite (fd, " 413"); $fwrite (fd, " 414"); end 7'h30: begin ozoneae(foo[20:18], fd); $fwrite (fd," 415"); ozoneae(foo[17:15], fd); $fwrite (fd," 416"); $fwrite (fd, " 417"); $fwrite (fd, " 418"); end 7'h31: begin ozoneae(foo[20:18], fd); $fwrite (fd," 419"); ozoneae(foo[17:15], fd); $fwrite (fd," 420"); $fwrite (fd, " 421"); $fwrite (fd, " 422"); end 7'h32: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 423"); ozoneaee(foo[17:15], fd); $fwrite (fd," 424"); ozoneape(foo[20:18], fd); $fwrite (fd," 425"); ozoneape(foo[17:15], fd); $fwrite (fd," 426"); $fwrite (fd, " 427"); $fwrite (fd, " 428"); end 7'h33: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 429"); ozoneaee(foo[17:15], fd); $fwrite (fd," 430"); ozoneape(foo[20:18], fd); $fwrite (fd," 431"); ozoneape(foo[17:15], fd); $fwrite (fd," 432"); $fwrite (fd, " 433"); $fwrite (fd, " 434"); end 7'h34: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 435"); ozoneaee(foo[17:15], fd); $fwrite (fd," 436"); ozoneape(foo[20:18], fd); $fwrite (fd," 437"); ozoneape(foo[17:15], fd); $fwrite (fd," 438"); $fwrite (fd, " 439"); $fwrite (fd, " 440"); end 7'h35: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 441"); ozoneaee(foo[17:15], fd); $fwrite (fd," 442"); ozoneape(foo[20:18], fd); $fwrite (fd," 443"); ozoneape(foo[17:15], fd); $fwrite (fd," 444"); $fwrite (fd, " 445"); $fwrite (fd, " 446"); end 7'h36: begin ozoneae(foo[20:18], fd); $fwrite (fd," 447"); ozoneae(foo[17:15], fd); $fwrite (fd," 448"); $fwrite (fd, " 449"); $fwrite (fd, " 450"); end 7'h37: begin ozoneae(foo[20:18], fd); $fwrite (fd," 451"); ozoneae(foo[17:15], fd); $fwrite (fd," 452"); $fwrite (fd, " 453"); $fwrite (fd, " 454"); end 7'h38: begin ozoneae(foo[20:18], fd); $fwrite (fd," 455"); ozoneae(foo[17:15], fd); $fwrite (fd," 456"); $fwrite (fd, " 457"); end 7'h39: begin ozoneae(foo[20:18], fd); $fwrite (fd," 458"); ozoneae(foo[17:15], fd); $fwrite (fd," 459"); $fwrite (fd, " 460"); end 7'h3a: begin ozoneae(foo[20:18], fd); $fwrite (fd," 461"); ozoneae(foo[17:15], fd); $fwrite (fd," 462"); $fwrite (fd, " 463"); end 7'h3b: begin ozoneae(foo[20:18], fd); $fwrite (fd," 464"); ozoneae(foo[17:15], fd); $fwrite (fd," 465"); $fwrite (fd, " 466"); end 7'h3c: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 467"); ozoneaee(foo[17:15], fd); $fwrite (fd," 468"); ozoneape(foo[20:18], fd); $fwrite (fd," 469"); ozoneape(foo[17:15], fd); $fwrite (fd," 470"); $fwrite (fd, " 471"); end 7'h3d: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 472"); ozoneaee(foo[17:15], fd); $fwrite (fd," 473"); ozoneape(foo[20:18], fd); $fwrite (fd," 474"); ozoneape(foo[17:15], fd); $fwrite (fd," 475"); $fwrite (fd, " 476"); end 7'h3e: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 477"); ozoneaee(foo[17:15], fd); $fwrite (fd," 478"); ozoneape(foo[20:18], fd); $fwrite (fd," 479"); ozoneape(foo[17:15], fd); $fwrite (fd," 480"); $fwrite (fd, " 481"); end 7'h3f: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 482"); ozoneaee(foo[17:15], fd); $fwrite (fd," 483"); ozoneape(foo[20:18], fd); $fwrite (fd," 484"); ozoneape(foo[17:15], fd); $fwrite (fd," 485"); $fwrite (fd, " 486"); end 7'h40: begin ozoneae(foo[20:18], fd); $fwrite (fd," 487"); ozoneae(foo[17:15], fd); $fwrite (fd," 488"); $fwrite (fd, " 489"); $fwrite (fd, " 490"); end 7'h41: begin $fwrite (fd, " 491"); $fwrite (fd, " 492"); end 7'h42: begin $fwrite (fd, " 493"); $fwrite (fd, " 494"); end 7'h43: begin $fwrite (fd, " 495"); $fwrite (fd, " 496"); end 7'h44: begin $fwrite (fd, " 497"); $fwrite (fd, " 498"); end 7'h45: $fwrite (fd, " 499"); 7'h46: begin ozoneae(foo[20:18], fd); $fwrite (fd," 500"); $fwrite (fd, " 501"); $fwrite (fd, " 502"); end 7'h47: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 503"); ozoneae(foo[17:15], fd); $fwrite (fd," 504"); ozoneape(foo[20:18], fd); $fwrite (fd," 505"); ozoneape(foo[20:18], fd); $fwrite (fd," 506"); $fwrite (fd, " 507"); $fwrite (fd, " 508"); end 7'h48: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 509"); ozoneape(foo[20:18], fd); $fwrite (fd," 510"); ozoneape(foo[20:18], fd); $fwrite (fd," 511"); ozoneaee(foo[17:15], fd); $fwrite (fd," 512"); ozoneape(foo[17:15], fd); $fwrite (fd," 513"); end 7'h49: begin ozoneae(foo[20:18], fd); $fwrite (fd," 514"); ozoneaee(foo[17:15], fd); $fwrite (fd," 515"); ozoneape(foo[17:15], fd); $fwrite (fd," 516"); end 7'h4a: $fwrite (fd," 517"); 7'h4b: $fwrite (fd, " 518"); 7'h4c: begin ozoneae(foo[20:18], fd); $fwrite (fd," 519"); $fwrite (fd, " 520"); $fwrite (fd, " 521"); end 7'h4d: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 522"); ozoneae(foo[17:15], fd); $fwrite (fd," 523"); ozoneape(foo[20:18], fd); $fwrite (fd," 524"); ozoneape(foo[20:18], fd); $fwrite (fd," 525"); $fwrite (fd, " 526"); $fwrite (fd, " 527"); end 7'h4e: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 528"); ozoneae(foo[17:15], fd); $fwrite (fd," 529"); ozoneape(foo[20:18], fd); $fwrite (fd," 530"); ozoneape(foo[20:18], fd); $fwrite (fd," 531"); end 7'h4f: begin ozoneae(foo[20:18], fd); $fwrite (fd," 532"); end 7'h50: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 533"); ozoneae(foo[17:15], fd); $fwrite (fd," 534"); ozoneaee(foo[20:18], fd); $fwrite (fd," 535"); ozoneae(foo[17:15], fd); $fwrite (fd," 536"); ozoneape(foo[20:18], fd); $fwrite (fd," 537"); ozoneae(foo[17:15], fd); $fwrite (fd," 538"); ozoneape(foo[20:18], fd); $fwrite (fd," 539"); ozoneae(foo[17:15], fd); $fwrite (fd," 540"); end 7'h51: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 541"); ozoneape(foo[20:18], fd); $fwrite (fd," 542"); ozoneaee(foo[20:18], fd); $fwrite (fd," 543"); ozoneape(foo[20:18], fd); $fwrite (fd," 544"); ozoneae(foo[17:15], fd); $fwrite (fd," 545"); end 7'h52: $fwrite (fd, " 546"); 7'h53: begin ozoneae(foo[20:18], fd); $fwrite (fd, " 547"); end 7'h54: begin ozoneae(foo[20:18], fd); $fwrite (fd," 548"); ozoneae(foo[17:15], fd); $fwrite (fd," 549"); end 7'h55: begin ozoneae(foo[20:18], fd); $fwrite (fd," 550"); ozoneae(foo[17:15], fd); $fwrite (fd," 551"); end 7'h56: begin ozoneae(foo[20:18], fd); $fwrite (fd," 552"); ozoneae(foo[17:15], fd); $fwrite (fd," 553"); $fwrite (fd, " 554"); end 7'h57: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 555"); ozoneae(foo[17:15], fd); $fwrite (fd," 556"); ozoneape(foo[20:18], fd); $fwrite (fd," 557"); ozoneape(foo[20:18], fd); $fwrite (fd," 558"); end 7'h58: begin ozoneae(foo[20:18], fd); $fwrite (fd, " 559"); end 7'h59: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 560"); ozoneae(foo[17:15], fd); $fwrite (fd," 561"); ozoneape(foo[20:18], fd); $fwrite (fd," 562"); ozoneape(foo[20:18], fd); $fwrite (fd," 563"); end 7'h5a: begin ozoneae(foo[20:18], fd); $fwrite (fd," 564"); ozoneae(foo[17:15], fd); $fwrite (fd, " 565"); end 7'h5b: begin ozoneae(foo[20:18], fd); $fwrite (fd," 566"); ozoneae(foo[17:15], fd); $fwrite (fd, " 567"); end 7'h5c: begin $fwrite (fd," 568"); ozoneape(foo[17:15], fd); $fwrite (fd," 569"); $fwrite (fd," 570"); ozoneape(foo[17:15], fd); $fwrite (fd," 571"); ozoneae(foo[20:18], fd); $fwrite (fd," 572"); ozoneaee(foo[17:15], fd); $fwrite (fd, " 573"); end 7'h5d: begin $fwrite (fd," 574"); ozoneape(foo[17:15], fd); $fwrite (fd," 575"); $fwrite (fd," 576"); ozoneape(foo[17:15], fd); $fwrite (fd," 577"); ozoneae(foo[20:18], fd); $fwrite (fd," 578"); ozoneaee(foo[17:15], fd); $fwrite (fd, " 579"); end 7'h5e: begin ozoneae(foo[20:18], fd); $fwrite (fd," 580"); ozoneae(foo[17:15], fd); $fwrite (fd, " 581"); end 7'h5f: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 582"); ozoneae(foo[17:15], fd); $fwrite (fd," 583"); ozoneaee(foo[20:18], fd); $fwrite (fd," 584"); ozoneae(foo[17:15], fd); $fwrite (fd," 585"); ozoneape(foo[20:18], fd); $fwrite (fd," 586"); ozoneae(foo[17:15], fd); $fwrite (fd," 587"); ozoneape(foo[20:18], fd); $fwrite (fd," 588"); ozoneae(foo[17:15], fd); $fwrite (fd," 589"); end 7'h60: begin ozoneae(foo[20:18], fd); $fwrite (fd," 590"); ozoneae(foo[17:15], fd); $fwrite (fd," 591"); end 7'h61: begin ozoneae(foo[20:18], fd); $fwrite (fd," 592"); ozoneae(foo[17:15], fd); $fwrite (fd," 593"); end 7'h62: begin ozoneae(foo[20:18], fd); $fwrite (fd," 594"); ozoneae(foo[17:15], fd); $fwrite (fd," 595"); end 7'h63: begin ozoneae(foo[20:18], fd); $fwrite (fd," 596"); ozoneae(foo[17:15], fd); $fwrite (fd," 597"); end 7'h64: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 598"); ozoneaee(foo[17:15], fd); $fwrite (fd," 599"); ozoneape(foo[20:18], fd); $fwrite (fd," 600"); ozoneape(foo[17:15], fd); $fwrite (fd," 601"); end 7'h65: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 602"); ozoneaee(foo[17:15], fd); $fwrite (fd," 603"); ozoneape(foo[20:18], fd); $fwrite (fd," 604"); ozoneape(foo[17:15], fd); $fwrite (fd," 605"); end 7'h66: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 606"); ozoneaee(foo[17:15], fd); $fwrite (fd," 607"); ozoneape(foo[20:18], fd); $fwrite (fd," 608"); ozoneape(foo[17:15], fd); $fwrite (fd," 609"); end 7'h67: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 610"); ozoneaee(foo[17:15], fd); $fwrite (fd," 611"); ozoneape(foo[20:18], fd); $fwrite (fd," 612"); ozoneape(foo[17:15], fd); $fwrite (fd," 613"); end 7'h68: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 614"); ozoneaee(foo[17:15], fd); $fwrite (fd," 615"); ozoneaee(foo[20:18], fd); $fwrite (fd," 616"); ozoneape(foo[20:18], fd); $fwrite (fd," 617"); ozoneape(foo[20:18], fd); $fwrite (fd," 618"); ozoneape(foo[17:15], fd); end 7'h69: begin ozoneae(foo[20:18], fd); $fwrite (fd," 619"); ozoneae(foo[17:15], fd); $fwrite (fd," 620"); ozoneae(foo[20:18], fd); $fwrite (fd," 621"); end 7'h6a: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 622"); ozoneae(foo[17:15], fd); $fwrite (fd," 623"); ozoneaee(foo[20:18], fd); $fwrite (fd," 624"); ozoneape(foo[20:18], fd); $fwrite (fd," 625"); ozoneaee(foo[20:18], fd); $fwrite (fd," 626"); ozoneae(foo[17:15], fd); end 7'h6b: begin ozoneae(foo[20:18], fd); $fwrite (fd," 627"); ozoneae(foo[17:15], fd); $fwrite (fd," 628"); ozoneae(foo[20:18], fd); $fwrite (fd," 629"); end 7'h6c: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 630"); ozoneae(foo[17:15], fd); $fwrite (fd," 631"); ozoneaee(foo[20:18], fd); $fwrite (fd," 632"); ozoneape(foo[20:18], fd); $fwrite (fd," 633"); ozoneaee(foo[20:18], fd); $fwrite (fd," 634"); ozoneae(foo[17:15], fd); end 7'h6d: begin ozoneae(foo[20:18], fd); $fwrite (fd," 635"); ozoneae(foo[17:15], fd); $fwrite (fd," 636"); ozoneae(foo[20:18], fd); $fwrite (fd," 637"); end 7'h6e: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 638"); ozoneaee(foo[17:15], fd); $fwrite (fd," 639"); ozoneape(foo[20:18], fd); $fwrite (fd," 640"); ozoneape(foo[17:15], fd); $fwrite (fd," 641"); end 7'h6f: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 642"); ozoneaee(foo[17:15], fd); $fwrite (fd," 643"); ozoneape(foo[20:18], fd); $fwrite (fd," 644"); ozoneape(foo[17:15], fd); $fwrite (fd," 645"); end 7'h70: begin ozoneae(foo[20:18], fd); $fwrite (fd," 646"); ozoneae(foo[20:18], fd); $fwrite (fd," 647"); ozoneae(foo[17:15], fd); $fwrite (fd," 648"); ozoneae(foo[17:15], fd); $fwrite (fd, " 649"); end 7'h71: begin ozoneae(foo[20:18], fd); $fwrite (fd," 650"); ozoneae(foo[17:15], fd); $fwrite (fd, " 651"); end 7'h72: begin ozoneae(foo[20:18], fd); $fwrite (fd," 652"); ozoneae(foo[17:15], fd); $fwrite (fd, " 653"); end 7'h73: begin ozoneae(foo[20:18], fd); $fwrite (fd," 654"); ozoneae(foo[20:18], fd); $fwrite (fd," 655"); ozoneae(foo[17:15], fd); end 7'h74: begin ozoneae(foo[20:18], fd); $fwrite (fd," 656"); ozoneae(foo[20:18], fd); $fwrite (fd," 657"); ozoneae(foo[17:15], fd); end 7'h75: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 658"); ozoneaee(foo[17:15], fd); $fwrite (fd," 659"); ozoneape(foo[20:18], fd); $fwrite (fd," 660"); ozoneape(foo[17:15], fd); $fwrite (fd," 661"); $fwrite (fd, " 662"); $fwrite (fd, " 663"); end 7'h76: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 664"); ozoneaee(foo[17:15], fd); $fwrite (fd," 665"); ozoneaee(foo[20:18], fd); $fwrite (fd," 666"); ozoneape(foo[20:18], fd); $fwrite (fd," 667"); ozoneape(foo[17:15], fd); $fwrite (fd," 668"); ozoneape(foo[20:18], fd); $fwrite (fd," 669"); end 7'h77: begin ozoneaee(foo[20:18], fd); $fwrite (fd," 670"); ozoneaee(foo[17:15], fd); $fwrite (fd," 671"); ozoneaee(foo[17:15], fd); $fwrite (fd," 672"); ozoneape(foo[20:18], fd); $fwrite (fd," 673"); ozoneape(foo[17:15], fd); $fwrite (fd," 674"); ozoneape(foo[17:15], fd); $fwrite (fd," 675"); end 7'h78, 7'h79, 7'h7a, 7'h7b, 7'h7c, 7'h7d, 7'h7e, 7'h7f: $fwrite (fd," 676"); endcase end endtask task ozonef2; input [ 31:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo[24:21]) 4'h0 : case (foo[26:25]) 2'b00 : $fwrite (fd," 677"); 2'b01 : $fwrite (fd," 678"); 2'b10 : $fwrite (fd," 679"); 2'b11 : $fwrite (fd," 680"); endcase 4'h1 : case (foo[26:25]) 2'b00 : $fwrite (fd," 681"); 2'b01 : $fwrite (fd," 682"); 2'b10 : $fwrite (fd," 683"); 2'b11 : $fwrite (fd," 684"); endcase 4'h2 : case (foo[26:25]) 2'b00 : $fwrite (fd," 685"); 2'b01 : $fwrite (fd," 686"); 2'b10 : $fwrite (fd," 687"); 2'b11 : $fwrite (fd," 688"); endcase 4'h3 : case (foo[26:25]) 2'b00 : $fwrite (fd," 689"); 2'b01 : $fwrite (fd," 690"); 2'b10 : $fwrite (fd," 691"); 2'b11 : $fwrite (fd," 692"); endcase 4'h4 : case (foo[26:25]) 2'b00 : $fwrite (fd," 693"); 2'b01 : $fwrite (fd," 694"); 2'b10 : $fwrite (fd," 695"); 2'b11 : $fwrite (fd," 696"); endcase 4'h5 : case (foo[26:25]) 2'b00 : $fwrite (fd," 697"); 2'b01 : $fwrite (fd," 698"); 2'b10 : $fwrite (fd," 699"); 2'b11 : $fwrite (fd," 700"); endcase 4'h6 : case (foo[26:25]) 2'b00 : $fwrite (fd," 701"); 2'b01 : $fwrite (fd," 702"); 2'b10 : $fwrite (fd," 703"); 2'b11 : $fwrite (fd," 704"); endcase 4'h7 : case (foo[26:25]) 2'b00 : $fwrite (fd," 705"); 2'b01 : $fwrite (fd," 706"); 2'b10 : $fwrite (fd," 707"); 2'b11 : $fwrite (fd," 708"); endcase 4'h8 : if (foo[26]) $fwrite (fd," 709"); else $fwrite (fd," 710"); 4'h9 : case (foo[26:25]) 2'b00 : $fwrite (fd," 711"); 2'b01 : $fwrite (fd," 712"); 2'b10 : $fwrite (fd," 713"); 2'b11 : $fwrite (fd," 714"); endcase 4'ha : case (foo[26:25]) 2'b00 : $fwrite (fd," 715"); 2'b01 : $fwrite (fd," 716"); 2'b10 : $fwrite (fd," 717"); 2'b11 : $fwrite (fd," 718"); endcase 4'hb : case (foo[26:25]) 2'b00 : $fwrite (fd," 719"); 2'b01 : $fwrite (fd," 720"); 2'b10 : $fwrite (fd," 721"); 2'b11 : $fwrite (fd," 722"); endcase 4'hc : if (foo[26]) $fwrite (fd," 723"); else $fwrite (fd," 724"); 4'hd : case (foo[26:25]) 2'b00 : $fwrite (fd," 725"); 2'b01 : $fwrite (fd," 726"); 2'b10 : $fwrite (fd," 727"); 2'b11 : $fwrite (fd," 728"); endcase 4'he : case (foo[26:25]) 2'b00 : $fwrite (fd," 729"); 2'b01 : $fwrite (fd," 730"); 2'b10 : $fwrite (fd," 731"); 2'b11 : $fwrite (fd," 732"); endcase 4'hf : case (foo[26:25]) 2'b00 : $fwrite (fd," 733"); 2'b01 : $fwrite (fd," 734"); 2'b10 : $fwrite (fd," 735"); 2'b11 : $fwrite (fd," 736"); endcase endcase end endtask task ozonef2e; input [ 31:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin casez (foo[25:21]) 5'h00 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 737"); ozoneae(foo[17:15], fd); $fwrite (fd," 738"); end 5'h01 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 739"); ozoneae(foo[17:15], fd); $fwrite (fd," 740"); end 5'h02 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 741"); ozoneae(foo[17:15], fd); $fwrite (fd," 742"); end 5'h03 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 743"); ozoneae(foo[17:15], fd); $fwrite (fd," 744"); end 5'h04 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 745"); ozoneae(foo[17:15], fd); $fwrite (fd," 746"); end 5'h05 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 747"); ozoneae(foo[17:15], fd); $fwrite (fd," 748"); end 5'h06 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 749"); ozoneae(foo[17:15], fd); $fwrite (fd," 750"); end 5'h07 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 751"); ozoneae(foo[17:15], fd); $fwrite (fd," 752"); end 5'h08 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 753"); if (foo[ 6]) $fwrite (fd," 754"); else $fwrite (fd," 755"); end 5'h09 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 756"); ozoneae(foo[17:15], fd); $fwrite (fd," 757"); end 5'h0a : begin ozoneae(foo[20:18], fd); $fwrite (fd," 758"); ozoneae(foo[17:15], fd); end 5'h0b : begin ozoneae(foo[20:18], fd); $fwrite (fd," 759"); ozoneae(foo[17:15], fd); $fwrite (fd," 760"); end 5'h0c : begin ozoneae(foo[20:18], fd); $fwrite (fd," 761"); end 5'h0d : begin ozoneae(foo[20:18], fd); $fwrite (fd," 762"); ozoneae(foo[17:15], fd); $fwrite (fd," 763"); end 5'h0e : begin ozoneae(foo[20:18], fd); $fwrite (fd," 764"); ozoneae(foo[17:15], fd); end 5'h0f : begin ozoneae(foo[20:18], fd); $fwrite (fd," 765"); ozoneae(foo[17:15], fd); end 5'h10 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 766"); ozoneae(foo[17:15], fd); $fwrite (fd," 767"); end 5'h11 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 768"); ozoneae(foo[17:15], fd); $fwrite (fd," 769"); end 5'h18 : begin ozoneae(foo[20:18], fd); $fwrite (fd," 770"); if (foo[ 6]) $fwrite (fd," 771"); else $fwrite (fd," 772"); end 5'h1a : begin ozoneae(foo[20:18], fd); $fwrite (fd," 773"); ozoneae(foo[17:15], fd); $fwrite (fd," 774"); end 5'h1b : begin ozoneae(foo[20:18], fd); $fwrite (fd," 775"); ozoneae(foo[17:15], fd); $fwrite (fd," 776"); if (foo[ 6]) $fwrite (fd," 777"); else $fwrite (fd," 778"); $fwrite (fd," 779"); end 5'h1c : begin ozoneae(foo[20:18], fd); $fwrite (fd," 780"); end 5'h1d : begin ozoneae(foo[20:18], fd); $fwrite (fd," 781"); if (foo[ 6]) $fwrite (fd," 782"); else $fwrite (fd," 783"); $fwrite (fd," 784"); end 5'h1e : begin ozoneae(foo[20:18], fd); $fwrite (fd," 785"); if (foo[ 6]) $fwrite (fd," 786"); else $fwrite (fd," 787"); $fwrite (fd," 788"); end 5'h1f : begin ozoneae(foo[20:18], fd); $fwrite (fd," 789"); ozoneae(foo[17:15], fd); $fwrite (fd," 790"); if (foo[ 6]) $fwrite (fd," 791"); else $fwrite (fd," 792"); $fwrite (fd," 793"); end default : $fwrite (fd," 794"); endcase end endtask task ozonef3e; input [ 31:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo[25:21]) 5'h00, 5'h01, 5'h02: begin ozoneae(foo[20:18], fd); case (foo[22:21]) 2'h0: $fwrite (fd," 795"); 2'h1: $fwrite (fd," 796"); 2'h2: $fwrite (fd," 797"); endcase ozoneae(foo[17:15], fd); $fwrite (fd," 798"); if (foo[ 9]) ozoneae(foo[ 8: 6], fd); else ozonef3e_te(foo[ 8: 6], fd); $fwrite (fd," 799"); end 5'h08, 5'h09, 5'h0d, 5'h0e, 5'h0f: begin ozoneae(foo[20:18], fd); $fwrite (fd," 800"); ozoneae(foo[17:15], fd); case (foo[23:21]) 3'h0: $fwrite (fd," 801"); 3'h1: $fwrite (fd," 802"); 3'h5: $fwrite (fd," 803"); 3'h6: $fwrite (fd," 804"); 3'h7: $fwrite (fd," 805"); endcase if (foo[ 9]) ozoneae(foo[ 8: 6], fd); else ozonef3e_te(foo[ 8: 6], fd); end 5'h0a, 5'h0b: begin ozoneae(foo[17:15], fd); if (foo[21]) $fwrite (fd," 806"); else $fwrite (fd," 807"); if (foo[ 9]) ozoneae(foo[ 8: 6], fd); else ozonef3e_te(foo[ 8: 6], fd); end 5'h0c: begin ozoneae(foo[20:18], fd); $fwrite (fd," 808"); if (foo[ 9]) ozoneae(foo[ 8: 6], fd); else ozonef3e_te(foo[ 8: 6], fd); $fwrite (fd," 809"); ozoneae(foo[17:15], fd); end 5'h10, 5'h11, 5'h12, 5'h13: begin ozoneae(foo[20:18], fd); $fwrite (fd," 810"); ozoneae(foo[17:15], fd); case (foo[22:21]) 2'h0, 2'h2: $fwrite (fd," 811"); 2'h1, 2'h3: $fwrite (fd," 812"); endcase ozoneae(foo[ 8: 6], fd); $fwrite (fd," 813"); ozoneae((foo[20:18]+1), fd); $fwrite (fd," 814"); ozoneae((foo[17:15]+1), fd); case (foo[22:21]) 2'h0, 2'h3: $fwrite (fd," 815"); 2'h1, 2'h2: $fwrite (fd," 816"); endcase ozoneae((foo[ 8: 6]+1), fd); end 5'h18: begin ozoneae(foo[20:18], fd); $fwrite (fd," 817"); ozoneae(foo[17:15], fd); $fwrite (fd," 818"); ozoneae(foo[ 8: 6], fd); $fwrite (fd," 819"); ozoneae(foo[20:18], fd); $fwrite (fd," 820"); ozoneae(foo[17:15], fd); $fwrite (fd," 821"); ozoneae(foo[ 8: 6], fd); end default : $fwrite (fd," 822"); endcase end endtask task ozonef3e_te; input [ 2:0] te; input [`FD_BITS] fd; // verilator no_inline_task begin case (te) 3'b100 : $fwrite (fd, " 823"); 3'b101 : $fwrite (fd, " 824"); 3'b110 : $fwrite (fd, " 825"); default: $fwrite (fd, " 826"); endcase end endtask task ozonearm; input [ 2:0] ate; input [`FD_BITS] fd; // verilator no_inline_task begin case (ate) 3'b000 : $fwrite (fd, " 827"); 3'b001 : $fwrite (fd, " 828"); 3'b010 : $fwrite (fd, " 829"); 3'b011 : $fwrite (fd, " 830"); 3'b100 : $fwrite (fd, " 831"); 3'b101 : $fwrite (fd, " 832"); 3'b110 : $fwrite (fd, " 833"); 3'b111 : $fwrite (fd, " 834"); endcase end endtask task ozonebmuop; input [ 4:0] f4; input [`FD_BITS] fd; // verilator no_inline_task begin case (f4[ 4:0]) 5'h00, 5'h04 : $fwrite (fd, " 835"); 5'h01, 5'h05 : $fwrite (fd, " 836"); 5'h02, 5'h06 : $fwrite (fd, " 837"); 5'h03, 5'h07 : $fwrite (fd, " 838"); 5'h08, 5'h18 : $fwrite (fd, " 839"); 5'h09, 5'h19 : $fwrite (fd, " 840"); 5'h0a, 5'h1a : $fwrite (fd, " 841"); 5'h0b : $fwrite (fd, " 842"); 5'h1b : $fwrite (fd, " 843"); 5'h0c, 5'h1c : $fwrite (fd, " 844"); 5'h0d, 5'h1d : $fwrite (fd, " 845"); 5'h1e : $fwrite (fd, " 846"); endcase end endtask task ozonef3; input [ 31:0] foo; input [`FD_BITS] fd; reg nacho; // verilator no_inline_task begin : f3_body nacho = 1'b0; case (foo[24:21]) 4'h0: case (foo[26:25]) 2'b00 : $fwrite (fd, " 847"); 2'b01 : $fwrite (fd, " 848"); 2'b10 : $fwrite (fd, " 849"); 2'b11 : $fwrite (fd, " 850"); endcase 4'h1: case (foo[26:25]) 2'b00 : $fwrite (fd, " 851"); 2'b01 : $fwrite (fd, " 852"); 2'b10 : $fwrite (fd, " 853"); 2'b11 : $fwrite (fd, " 854"); endcase 4'h2: case (foo[26:25]) 2'b00 : $fwrite (fd, " 855"); 2'b01 : $fwrite (fd, " 856"); 2'b10 : $fwrite (fd, " 857"); 2'b11 : $fwrite (fd, " 858"); endcase 4'h8, 4'h9, 4'hd, 4'he, 4'hf : case (foo[26:25]) 2'b00 : $fwrite (fd, " 859"); 2'b01 : $fwrite (fd, " 860"); 2'b10 : $fwrite (fd, " 861"); 2'b11 : $fwrite (fd, " 862"); endcase 4'ha, 4'hb : if (foo[25]) $fwrite (fd, " 863"); else $fwrite (fd, " 864"); 4'hc : if (foo[26]) $fwrite (fd, " 865"); else $fwrite (fd, " 866"); default : begin $fwrite (fd, " 867"); nacho = 1'b1; end endcase if (~nacho) begin case (foo[24:21]) 4'h8 : $fwrite (fd, " 868"); 4'h9 : $fwrite (fd, " 869"); 4'ha, 4'he : $fwrite (fd, " 870"); 4'hb, 4'hf : $fwrite (fd, " 871"); 4'hd : $fwrite (fd, " 872"); endcase if (foo[20]) case (foo[18:16]) 3'b000 : $fwrite (fd, " 873"); 3'b100 : $fwrite (fd, " 874"); default: $fwrite (fd, " 875"); endcase else ozoneae(foo[18:16], fd); if (foo[24:21] === 4'hc) if (foo[25]) $fwrite (fd, " 876"); else $fwrite (fd, " 877"); case (foo[24:21]) 4'h0, 4'h1, 4'h2: $fwrite (fd, " 878"); endcase end end endtask task ozonerx; input [ 31:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo[19:18]) 2'h0 : $fwrite (fd, " 879"); 2'h1 : $fwrite (fd, " 880"); 2'h2 : $fwrite (fd, " 881"); 2'h3 : $fwrite (fd, " 882"); endcase case (foo[17:16]) 2'h1 : $fwrite (fd, " 883"); 2'h2 : $fwrite (fd, " 884"); 2'h3 : $fwrite (fd, " 885"); endcase end endtask task ozonerme; input [ 2:0] rme; input [`FD_BITS] fd; // verilator no_inline_task begin case (rme) 3'h0 : $fwrite (fd, " 886"); 3'h1 : $fwrite (fd, " 887"); 3'h2 : $fwrite (fd, " 888"); 3'h3 : $fwrite (fd, " 889"); 3'h4 : $fwrite (fd, " 890"); 3'h5 : $fwrite (fd, " 891"); 3'h6 : $fwrite (fd, " 892"); 3'h7 : $fwrite (fd, " 893"); endcase end endtask task ozoneye; input [5:0] ye; input l; input [`FD_BITS] fd; // verilator no_inline_task begin $fwrite (fd, " 894"); ozonerme(ye[5:3], fd); case ({ye[ 2:0], l}) 4'h2, 4'ha: $fwrite (fd, " 895"); 4'h4, 4'hb: $fwrite (fd, " 896"); 4'h6, 4'he: $fwrite (fd, " 897"); 4'h8, 4'hc: $fwrite (fd, " 898"); endcase end endtask task ozonef1e_ye; input [5:0] ye; input l; input [`FD_BITS] fd; // verilator no_inline_task begin $fwrite (fd, " 899"); ozonerme(ye[5:3], fd); ozonef1e_inc_dec(ye[5:0], l , fd); end endtask task ozonef1e_h; input [ 2:0] e; input [`FD_BITS] fd; // verilator no_inline_task begin if (e[ 2:0] <= 3'h4) $fwrite (fd, " 900"); end endtask task ozonef1e_inc_dec; input [5:0] ye; input l; input [`FD_BITS] fd; // verilator no_inline_task begin case ({ye[ 2:0], l}) 4'h2, 4'h3, 4'ha: $fwrite (fd, " 901"); 4'h4, 4'h5, 4'hb: $fwrite (fd, " 902"); 4'h6, 4'h7, 4'he: $fwrite (fd, " 903"); 4'h8, 4'h9, 4'hc: $fwrite (fd, " 904"); 4'hf: $fwrite (fd, " 905"); endcase end endtask task ozonef1e_hl; input [ 2:0] e; input l; input [`FD_BITS] fd; // verilator no_inline_task begin case ({e[ 2:0], l}) 4'h0, 4'h2, 4'h4, 4'h6, 4'h8: $fwrite (fd, " 906"); 4'h1, 4'h3, 4'h5, 4'h7, 4'h9: $fwrite (fd, " 907"); endcase end endtask task ozonexe; input [ 3:0] xe; input [`FD_BITS] fd; // verilator no_inline_task begin case (xe[3]) 1'b0 : $fwrite (fd, " 908"); 1'b1 : $fwrite (fd, " 909"); endcase case (xe[ 2:0]) 3'h1, 3'h5: $fwrite (fd, " 910"); 3'h2, 3'h6: $fwrite (fd, " 911"); 3'h3, 3'h7: $fwrite (fd, " 912"); 3'h4: $fwrite (fd, " 913"); endcase end endtask task ozonerp; input [ 2:0] rp; input [`FD_BITS] fd; // verilator no_inline_task begin case (rp) 3'h0 : $fwrite (fd, " 914"); 3'h1 : $fwrite (fd, " 915"); 3'h2 : $fwrite (fd, " 916"); 3'h3 : $fwrite (fd, " 917"); 3'h4 : $fwrite (fd, " 918"); 3'h5 : $fwrite (fd, " 919"); 3'h6 : $fwrite (fd, " 920"); 3'h7 : $fwrite (fd, " 921"); endcase end endtask task ozonery; input [ 3:0] ry; input [`FD_BITS] fd; // verilator no_inline_task begin case (ry) 4'h0 : $fwrite (fd, " 922"); 4'h1 : $fwrite (fd, " 923"); 4'h2 : $fwrite (fd, " 924"); 4'h3 : $fwrite (fd, " 925"); 4'h4 : $fwrite (fd, " 926"); 4'h5 : $fwrite (fd, " 927"); 4'h6 : $fwrite (fd, " 928"); 4'h7 : $fwrite (fd, " 929"); 4'h8 : $fwrite (fd, " 930"); 4'h9 : $fwrite (fd, " 931"); 4'ha : $fwrite (fd, " 932"); 4'hb : $fwrite (fd, " 933"); 4'hc : $fwrite (fd, " 934"); 4'hd : $fwrite (fd, " 935"); 4'he : $fwrite (fd, " 936"); 4'hf : $fwrite (fd, " 937"); endcase end endtask task ozonearx; input [ 15:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo[1:0]) 2'h0 : $fwrite (fd, " 938"); 2'h1 : $fwrite (fd, " 939"); 2'h2 : $fwrite (fd, " 940"); 2'h3 : $fwrite (fd, " 941"); endcase end endtask task ozonef3f4imop; input [ 4:0] f3f4iml; input [`FD_BITS] fd; // verilator no_inline_task begin casez (f3f4iml) 5'b000??: $fwrite (fd, " 942"); 5'b001??: $fwrite (fd, " 943"); 5'b?10??: $fwrite (fd, " 944"); 5'b0110?: $fwrite (fd, " 945"); 5'b01110: $fwrite (fd, " 946"); 5'b01111: $fwrite (fd, " 947"); 5'b10???: $fwrite (fd, " 948"); 5'b11100: $fwrite (fd, " 949"); 5'b11101: $fwrite (fd, " 950"); 5'b11110: $fwrite (fd, " 951"); 5'b11111: $fwrite (fd, " 952"); endcase end endtask task ozonecon; input [ 4:0] con; input [`FD_BITS] fd; // verilator no_inline_task begin case (con) 5'h00 : $fwrite (fd, " 953"); 5'h01 : $fwrite (fd, " 954"); 5'h02 : $fwrite (fd, " 955"); 5'h03 : $fwrite (fd, " 956"); 5'h04 : $fwrite (fd, " 957"); 5'h05 : $fwrite (fd, " 958"); 5'h06 : $fwrite (fd, " 959"); 5'h07 : $fwrite (fd, " 960"); 5'h08 : $fwrite (fd, " 961"); 5'h09 : $fwrite (fd, " 962"); 5'h0a : $fwrite (fd, " 963"); 5'h0b : $fwrite (fd, " 964"); 5'h0c : $fwrite (fd, " 965"); 5'h0d : $fwrite (fd, " 966"); 5'h0e : $fwrite (fd, " 967"); 5'h0f : $fwrite (fd, " 968"); 5'h10 : $fwrite (fd, " 969"); 5'h11 : $fwrite (fd, " 970"); 5'h12 : $fwrite (fd, " 971"); 5'h13 : $fwrite (fd, " 972"); 5'h14 : $fwrite (fd, " 973"); 5'h15 : $fwrite (fd, " 974"); 5'h16 : $fwrite (fd, " 975"); 5'h17 : $fwrite (fd, " 976"); 5'h18 : $fwrite (fd, " 977"); 5'h19 : $fwrite (fd, " 978"); 5'h1a : $fwrite (fd, " 979"); 5'h1b : $fwrite (fd, " 980"); 5'h1c : $fwrite (fd, " 981"); 5'h1d : $fwrite (fd, " 982"); 5'h1e : $fwrite (fd, " 983"); 5'h1f : $fwrite (fd, " 984"); endcase end endtask task ozonedr; input [ 15:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo[ 9: 6]) 4'h0 : $fwrite (fd, " 985"); 4'h1 : $fwrite (fd, " 986"); 4'h2 : $fwrite (fd, " 987"); 4'h3 : $fwrite (fd, " 988"); 4'h4 : $fwrite (fd, " 989"); 4'h5 : $fwrite (fd, " 990"); 4'h6 : $fwrite (fd, " 991"); 4'h7 : $fwrite (fd, " 992"); 4'h8 : $fwrite (fd, " 993"); 4'h9 : $fwrite (fd, " 994"); 4'ha : $fwrite (fd, " 995"); 4'hb : $fwrite (fd, " 996"); 4'hc : $fwrite (fd, " 997"); 4'hd : $fwrite (fd, " 998"); 4'he : $fwrite (fd, " 999"); 4'hf : $fwrite (fd, " 1000"); endcase end endtask task ozoneshift; input [ 15:0] foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo[ 4: 3]) 2'h0 : $fwrite (fd, " 1001"); 2'h1 : $fwrite (fd, " 1002"); 2'h2 : $fwrite (fd, " 1003"); 2'h3 : $fwrite (fd, " 1004"); endcase end endtask task ozoneacc; input foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo) 2'h0 : $fwrite (fd, " 1005"); 2'h1 : $fwrite (fd, " 1006"); endcase end endtask task ozonehl; input foo; input [`FD_BITS] fd; // verilator no_inline_task begin case (foo) 2'h0 : $fwrite (fd, " 1007"); 2'h1 : $fwrite (fd, " 1008"); endcase end endtask task dude; input [`FD_BITS] fd; // verilator no_inline_task $fwrite(fd," dude"); endtask task big_case; input [ `FD_BITS] fd; input [ 31:0] foo; // verilator no_inline_task begin $fwrite(fd," 1009"); if (&foo === 1'bx) $fwrite(fd, " 1010"); else casez ( {foo[31:26], foo[19:15], foo[5:0]} ) 17'b00_111?_?_????_??_???? : begin ozonef1(foo, fd); $fwrite (fd, " 1011"); ozoneacc(~foo[26], fd); ozonehl(foo[20], fd); $fwrite (fd, " 1012"); ozonerx(foo, fd); dude(fd); $fwrite (fd, " 1013"); end 17'b01_001?_?_????_??_???? : begin ozonef1(foo, fd); $fwrite (fd, " 1014"); ozonerx(foo, fd); $fwrite (fd, " 1015"); $fwrite (fd, " 1016:%x", foo[20]); ozonehl(foo[20], fd); dude(fd); $fwrite (fd, " 1017"); end 17'b10_100?_?_????_??_???? : begin ozonef1(foo, fd); $fwrite (fd, " 1018"); ozonerx(foo, fd); $fwrite (fd, " 1019"); $fwrite (fd, " 1020"); ozonehl(foo[20], fd); dude(fd); $fwrite (fd, " 1021"); end 17'b10_101?_?_????_??_???? : begin ozonef1(foo, fd); $fwrite (fd, " 1022"); if (foo[20]) begin $fwrite (fd, " 1023"); ozoneacc(foo[18], fd); $fwrite (fd, " 1024"); $fwrite (fd, " 1025"); if (foo[19]) $fwrite (fd, " 1026"); else $fwrite (fd, " 1027"); end else ozonerx(foo, fd); dude(fd); $fwrite (fd, " 1028"); end 17'b10_110?_?_????_??_???? : begin ozonef1(foo, fd); $fwrite (fd, " 1029"); $fwrite (fd, " 1030"); ozonehl(foo[20], fd); $fwrite (fd, " 1031"); ozonerx(foo, fd); dude(fd); $fwrite (fd, " 1032"); end 17'b10_111?_?_????_??_???? : begin ozonef1(foo, fd); $fwrite (fd, " 1033"); $fwrite (fd, " 1034"); ozonehl(foo[20], fd); $fwrite (fd, " 1035"); ozonerx(foo, fd); dude(fd); $fwrite (fd, " 1036"); end 17'b11_001?_?_????_??_???? : begin ozonef1(foo, fd); $fwrite (fd, " 1037"); ozonerx(foo, fd); $fwrite (fd, " 1038"); $fwrite (fd, " 1039"); ozonehl(foo[20], fd); dude(fd); $fwrite (fd, " 1040"); end 17'b11_111?_?_????_??_???? : begin ozonef1(foo, fd); $fwrite (fd, " 1041"); $fwrite (fd, " 1042"); ozonerx(foo, fd); $fwrite (fd, " 1043"); if (foo[20]) $fwrite (fd, " 1044"); else $fwrite (fd, " 1045"); dude(fd); $fwrite (fd, " 1046"); end 17'b00_10??_?_????_?1_1111 : casez (foo[11: 5]) 7'b??_0_010_0: begin $fwrite (fd, " 1047"); ozonecon(foo[14:10], fd); $fwrite (fd, " 1048"); ozonef1e(foo, fd); dude(fd); $fwrite (fd, " 1049"); end 7'b00_?_110_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1050"); case ({foo[ 9],foo[ 5]}) 2'b00: begin $fwrite (fd, " 1051"); ozoneae(foo[14:12], fd); ozonehl(foo[ 5], fd); end 2'b01: begin $fwrite (fd, " 1052"); ozoneae(foo[14:12], fd); ozonehl(foo[ 5], fd); end 2'b10: begin $fwrite (fd, " 1053"); ozoneae(foo[14:12], fd); end 2'b11: $fwrite (fd, " 1054"); endcase dude(fd); $fwrite (fd, " 1055"); end 7'b01_?_110_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1056"); case ({foo[ 9],foo[ 5]}) 2'b00: begin ozoneae(foo[14:12], fd); ozonehl(foo[ 5], fd); $fwrite (fd, " 1057"); end 2'b01: begin ozoneae(foo[14:12], fd); ozonehl(foo[ 5], fd); $fwrite (fd, " 1058"); end 2'b10: begin ozoneae(foo[14:12], fd); $fwrite (fd, " 1059"); end 2'b11: $fwrite (fd, " 1060"); endcase dude(fd); $fwrite (fd, " 1061"); end 7'b10_0_110_0: begin ozonef1e(foo, fd); $fwrite (fd, " 1062"); $fwrite (fd, " 1063"); if (foo[12]) $fwrite (fd, " 1064"); else ozonerab({4'b1001, foo[14:12]}, fd); dude(fd); $fwrite (fd, " 1065"); end 7'b10_0_110_1: begin ozonef1e(foo, fd); $fwrite (fd, " 1066"); if (foo[12]) $fwrite (fd, " 1067"); else ozonerab({4'b1001, foo[14:12]}, fd); $fwrite (fd, " 1068"); dude(fd); $fwrite (fd, " 1069"); end 7'b??_?_000_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1070"); $fwrite (fd, " 1071"); ozonef1e_hl(foo[11:9],foo[ 5], fd); $fwrite (fd, " 1072"); ozonef1e_ye(foo[14:9],foo[ 5], fd); dude(fd); $fwrite (fd, " 1073"); end 7'b??_?_100_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1074"); $fwrite (fd, " 1075"); ozonef1e_hl(foo[11:9],foo[ 5], fd); $fwrite (fd, " 1076"); ozonef1e_ye(foo[14:9],foo[ 5], fd); dude(fd); $fwrite (fd, " 1077"); end 7'b??_?_001_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1078"); ozonef1e_ye(foo[14:9],foo[ 5], fd); $fwrite (fd, " 1079"); $fwrite (fd, " 1080"); ozonef1e_hl(foo[11:9],foo[ 5], fd); dude(fd); $fwrite (fd, " 1081"); end 7'b??_?_011_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1082"); ozonef1e_ye(foo[14:9],foo[ 5], fd); $fwrite (fd, " 1083"); $fwrite (fd, " 1084"); ozonef1e_hl(foo[11:9],foo[ 5], fd); dude(fd); $fwrite (fd, " 1085"); end 7'b??_?_101_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1086"); ozonef1e_ye(foo[14:9],foo[ 5], fd); dude(fd); $fwrite (fd, " 1087"); end endcase 17'b00_10??_?_????_?0_0110 : begin ozonef1e(foo, fd); $fwrite (fd, " 1088"); ozoneae(foo[ 8: 6], fd); ozonef1e_hl(foo[11:9],foo[ 5], fd); $fwrite (fd, " 1089"); ozonef1e_ye(foo[14:9],foo[ 5], fd); dude(fd); $fwrite (fd, " 1090"); end 17'b00_10??_?_????_00_0111 : begin ozonef1e(foo, fd); $fwrite (fd, " 1091"); if (foo[ 6]) $fwrite (fd, " 1092"); else ozonerab({4'b1001, foo[ 8: 6]}, fd); $fwrite (fd, " 1093"); $fwrite (fd, " 1094"); ozonerme(foo[14:12], fd); case (foo[11: 9]) 3'h2, 3'h5, 3'h6, 3'h7: ozonef1e_inc_dec(foo[14:9],1'b0, fd); 3'h1, 3'h3, 3'h4: $fwrite (fd, " 1095"); endcase dude(fd); $fwrite (fd, " 1096"); end 17'b00_10??_?_????_?0_0100 : begin ozonef1e(foo, fd); $fwrite (fd, " 1097"); ozonef1e_ye(foo[14:9],foo[ 5], fd); $fwrite (fd, " 1098"); ozoneae(foo[ 8: 6], fd); ozonef1e_hl(foo[11:9],foo[ 5], fd); dude(fd); $fwrite (fd, " 1099"); end 17'b00_10??_?_????_10_0111 : begin ozonef1e(foo, fd); $fwrite (fd, " 1100"); $fwrite (fd, " 1101"); ozonerme(foo[14:12], fd); case (foo[11: 9]) 3'h2, 3'h5, 3'h6, 3'h7: ozonef1e_inc_dec(foo[14:9],1'b0, fd); 3'h1, 3'h3, 3'h4: $fwrite (fd, " 1102"); endcase $fwrite (fd, " 1103"); if (foo[ 6]) $fwrite (fd, " 1104"); else ozonerab({4'b1001, foo[ 8: 6]}, fd); dude(fd); $fwrite (fd, " 1105"); end 17'b00_10??_?_????_?0_1110 : begin ozonef1e(foo, fd); $fwrite (fd, " 1106"); case (foo[11:9]) 3'h2: begin $fwrite (fd, " 1107"); if (foo[14:12] == 3'h0) $fwrite (fd, " 1108"); else ozonerme(foo[14:12], fd); $fwrite (fd, " 1109"); end 3'h6: begin $fwrite (fd, " 1110"); if (foo[14:12] == 3'h0) $fwrite (fd, " 1111"); else ozonerme(foo[14:12], fd); $fwrite (fd, " 1112"); end 3'h0: begin $fwrite (fd, " 1113"); if (foo[14:12] == 3'h0) $fwrite (fd, " 1114"); else ozonerme(foo[14:12], fd); $fwrite (fd, " 1115"); if (foo[ 7: 5] >= 3'h5) $fwrite (fd, " 1116"); else ozonexe(foo[ 8: 5], fd); end 3'h1: begin $fwrite (fd, " 1117"); if (foo[14:12] == 3'h0) $fwrite (fd, " 1118"); else ozonerme(foo[14:12], fd); $fwrite (fd, " 1119"); if (foo[ 7: 5] >= 3'h5) $fwrite (fd, " 1120"); else ozonexe(foo[ 8: 5], fd); end 3'h4: begin $fwrite (fd, " 1121"); if (foo[14:12] == 3'h0) $fwrite (fd, " 1122"); else ozonerme(foo[14:12], fd); $fwrite (fd, " 1123"); if (foo[ 7: 5] >= 3'h5) $fwrite (fd, " 1124"); else ozonexe(foo[ 8: 5], fd); end 3'h5: begin $fwrite (fd, " 1125"); if (foo[14:12] == 3'h0) $fwrite (fd, " 1126"); else ozonerme(foo[14:12], fd); $fwrite (fd, " 1127"); if (foo[ 7: 5] >= 3'h5) $fwrite (fd, " 1128"); else ozonexe(foo[ 8: 5], fd); end endcase dude(fd); $fwrite (fd, " 1129"); end 17'b00_10??_?_????_?0_1111 : casez (foo[14: 9]) 6'b001_10_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1130"); $fwrite (fd, " 1131"); ozonef1e_hl(foo[ 7: 5],foo[ 9], fd); $fwrite (fd, " 1132"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1133"); end 6'b???_11_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1134"); ozoneae(foo[14:12], fd); ozonef1e_hl(foo[ 7: 5],foo[ 9], fd); $fwrite (fd, " 1135"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1136"); end 6'b000_10_1, 6'b010_10_1, 6'b100_10_1, 6'b110_10_1: begin ozonef1e(foo, fd); $fwrite (fd, " 1137"); ozonerab({4'b1001, foo[14:12]}, fd); $fwrite (fd, " 1138"); if ((foo[ 7: 5] >= 3'h1) & (foo[ 7: 5] <= 3'h3)) $fwrite (fd, " 1139"); else ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1140"); end 6'b000_10_0, 6'b010_10_0, 6'b100_10_0, 6'b110_10_0: begin ozonef1e(foo, fd); $fwrite (fd, " 1141"); $fwrite (fd, " 1142"); ozonerab({4'b1001, foo[14:12]}, fd); $fwrite (fd, " 1143"); $fwrite (fd, " 1144"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1145"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1146"); end 6'b???_00_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1147"); if (foo[ 9]) begin $fwrite (fd, " 1148"); ozoneae(foo[14:12], fd); end else begin $fwrite (fd, " 1149"); ozoneae(foo[14:12], fd); $fwrite (fd, " 1150"); end $fwrite (fd, " 1151"); $fwrite (fd, " 1152"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1153"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1154"); end 6'b???_01_?: begin ozonef1e(foo, fd); $fwrite (fd, " 1155"); ozoneae(foo[14:12], fd); if (foo[ 9]) $fwrite (fd, " 1156"); else $fwrite (fd, " 1157"); $fwrite (fd, " 1158"); $fwrite (fd, " 1159"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1160"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1161"); end 6'b011_10_0: begin ozonef1e(foo, fd); $fwrite (fd, " 1162"); case (foo[ 8: 5]) 4'h0: $fwrite (fd, " 1163"); 4'h1: $fwrite (fd, " 1164"); 4'h2: $fwrite (fd, " 1165"); 4'h3: $fwrite (fd, " 1166"); 4'h4: $fwrite (fd, " 1167"); 4'h5: $fwrite (fd, " 1168"); 4'h8: $fwrite (fd, " 1169"); 4'h9: $fwrite (fd, " 1170"); 4'ha: $fwrite (fd, " 1171"); 4'hb: $fwrite (fd, " 1172"); 4'hc: $fwrite (fd, " 1173"); 4'hd: $fwrite (fd, " 1174"); default: $fwrite (fd, " 1175"); endcase dude(fd); $fwrite (fd, " 1176"); end default: $fwrite (fd, " 1177"); endcase 17'b00_10??_?_????_?0_110? : begin ozonef1e(foo, fd); $fwrite (fd, " 1178"); $fwrite (fd, " 1179"); ozonef1e_hl(foo[11:9], foo[0], fd); $fwrite (fd, " 1180"); ozonef1e_ye(foo[14:9],1'b0, fd); $fwrite (fd, " 1181"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1182"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1183"); end 17'b00_10??_?_????_?1_110? : begin ozonef1e(foo, fd); $fwrite (fd, " 1184"); $fwrite (fd, " 1185"); ozonef1e_hl(foo[11:9],foo[0], fd); $fwrite (fd, " 1186"); ozonef1e_ye(foo[14:9],foo[ 0], fd); $fwrite (fd, " 1187"); $fwrite (fd, " 1188"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1189"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1190"); end 17'b00_10??_?_????_?0_101? : begin ozonef1e(foo, fd); $fwrite (fd, " 1191"); ozonef1e_ye(foo[14:9],foo[ 0], fd); $fwrite (fd, " 1192"); $fwrite (fd, " 1193"); ozonef1e_hl(foo[11:9],foo[0], fd); $fwrite (fd, " 1194"); $fwrite (fd, " 1195"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1196"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1197"); end 17'b00_10??_?_????_?0_1001 : begin ozonef1e(foo, fd); $fwrite (fd, " 1198"); $fwrite (fd, " 1199"); ozonef1e_h(foo[11:9], fd); $fwrite (fd, " 1200"); ozonef1e_ye(foo[14:9],1'b0, fd); $fwrite (fd, " 1201"); case (foo[ 7: 5]) 3'h1, 3'h2, 3'h3: $fwrite (fd, " 1202"); default: begin $fwrite (fd, " 1203"); $fwrite (fd, " 1204"); ozonexe(foo[ 8: 5], fd); end endcase dude(fd); $fwrite (fd, " 1205"); end 17'b00_10??_?_????_?0_0101 : begin ozonef1e(foo, fd); $fwrite (fd, " 1206"); case (foo[11: 9]) 3'h1, 3'h3, 3'h4: $fwrite (fd, " 1207"); default: begin ozonef1e_ye(foo[14:9],1'b0, fd); $fwrite (fd, " 1208"); $fwrite (fd, " 1209"); end endcase $fwrite (fd, " 1210"); $fwrite (fd, " 1211"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1212"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1213"); end 17'b00_10??_?_????_?1_1110 : begin ozonef1e(foo, fd); $fwrite (fd, " 1214"); ozonef1e_ye(foo[14:9],1'b0, fd); $fwrite (fd, " 1215"); $fwrite (fd, " 1216"); ozonef1e_h(foo[11: 9], fd); $fwrite (fd, " 1217"); $fwrite (fd, " 1218"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1219"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1220"); end 17'b00_10??_?_????_?0_1000 : begin ozonef1e(foo, fd); $fwrite (fd, " 1221"); ozonef1e_ye(foo[14:9],1'b0, fd); $fwrite (fd, " 1222"); $fwrite (fd, " 1223"); ozonef1e_h(foo[11: 9], fd); $fwrite (fd, " 1224"); $fwrite (fd, " 1225"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1226"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite (fd, " 1227"); end 17'b10_01??_?_????_??_???? : begin if (foo[27]) $fwrite (fd," 1228"); else $fwrite (fd," 1229"); ozonecon(foo[20:16], fd); $fwrite (fd, " 1230"); ozonef2(foo[31:0], fd); dude(fd); $fwrite (fd, " 1231"); end 17'b00_1000_?_????_01_0011 : if (~|foo[ 9: 8]) begin if (foo[ 7]) $fwrite (fd," 1232"); else $fwrite (fd," 1233"); ozonecon(foo[14:10], fd); $fwrite (fd, " 1234"); ozonef2e(foo[31:0], fd); dude(fd); $fwrite (fd, " 1235"); end else begin $fwrite (fd, " 1236"); ozonecon(foo[14:10], fd); $fwrite (fd, " 1237"); ozonef3e(foo[31:0], fd); dude(fd); $fwrite (fd, " 1238"); end 17'b11_110?_1_????_??_???? : begin ozonef3(foo[31:0], fd); dude(fd); $fwrite(fd, " 1239"); end 17'b11_110?_0_????_??_???? : begin : f4_body casez (foo[24:20]) 5'b0_1110, 5'b1_0???, 5'b1_1111: begin $fwrite (fd, " 1240"); end 5'b0_00??: begin ozoneacc(foo[26], fd); $fwrite (fd, " 1241"); ozoneacc(foo[25], fd); ozonebmuop(foo[24:20], fd); ozoneae(foo[18:16], fd); $fwrite (fd, " 1242"); dude(fd); $fwrite(fd, " 1243"); end 5'b0_01??: begin ozoneacc(foo[26], fd); $fwrite (fd, " 1244"); ozoneacc(foo[25], fd); ozonebmuop(foo[24:20], fd); ozonearm(foo[18:16], fd); dude(fd); $fwrite(fd, " 1245"); end 5'b0_1011: begin ozoneacc(foo[26], fd); $fwrite (fd, " 1246"); ozonebmuop(foo[24:20], fd); $fwrite (fd, " 1247"); ozoneae(foo[18:16], fd); $fwrite (fd, " 1248"); dude(fd); $fwrite(fd, " 1249"); end 5'b0_100?, 5'b0_1010, 5'b0_110? : begin ozoneacc(foo[26], fd); $fwrite (fd, " 1250"); ozonebmuop(foo[24:20], fd); $fwrite (fd, " 1251"); ozoneacc(foo[25], fd); $fwrite (fd, " 1252"); ozoneae(foo[18:16], fd); $fwrite (fd, " 1253"); dude(fd); $fwrite(fd, " 1254"); end 5'b0_1111 : begin ozoneacc(foo[26], fd); $fwrite (fd, " 1255"); ozoneacc(foo[25], fd); $fwrite (fd, " 1256"); ozoneae(foo[18:16], fd); dude(fd); $fwrite(fd, " 1257"); end 5'b1_10??, 5'b1_110?, 5'b1_1110 : begin ozoneacc(foo[26], fd); $fwrite (fd, " 1258"); ozonebmuop(foo[24:20], fd); $fwrite (fd, " 1259"); ozoneacc(foo[25], fd); $fwrite (fd, " 1260"); ozonearm(foo[18:16], fd); $fwrite (fd, " 1261"); dude(fd); $fwrite(fd, " 1262"); end endcase end 17'b11_100?_?_????_??_???? : casez (foo[23:19]) 5'b111??, 5'b0111?: begin ozoneae(foo[26:24], fd); $fwrite (fd, " 1263"); ozonef3f4imop(foo[23:19], fd); $fwrite (fd, " 1264"); ozoneae(foo[18:16], fd); $fwrite (fd, " 1265"); skyway(foo[15:12], fd); skyway(foo[11: 8], fd); skyway(foo[ 7: 4], fd); skyway(foo[ 3:0], fd); $fwrite (fd, " 1266"); dude(fd); $fwrite(fd, " 1267"); end 5'b?0???, 5'b110??: begin ozoneae(foo[26:24], fd); $fwrite (fd, " 1268"); if (foo[23:21] == 3'b100) $fwrite (fd, " 1269"); ozoneae(foo[18:16], fd); if (foo[19]) $fwrite (fd, " 1270"); else $fwrite (fd, " 1271"); ozonef3f4imop(foo[23:19], fd); $fwrite (fd, " 1272"); ozonef3f4_iext(foo[20:19], foo[15:0], fd); dude(fd); $fwrite(fd, " 1273"); end 5'b010??, 5'b0110?: begin ozoneae(foo[18:16], fd); if (foo[19]) $fwrite (fd, " 1274"); else $fwrite (fd, " 1275"); ozonef3f4imop(foo[23:19], fd); $fwrite (fd, " 1276"); ozonef3f4_iext(foo[20:19], foo[15:0], fd); dude(fd); $fwrite(fd, " 1277"); end endcase 17'b00_1000_?_????_11_0011 : begin $fwrite (fd," 1278"); ozonecon(foo[14:10], fd); $fwrite (fd, " 1279"); casez (foo[25:21]) 5'b0_1110, 5'b1_0???, 5'b1_1111: begin $fwrite(fd, " 1280"); end 5'b0_00??: begin ozoneae(foo[20:18], fd); $fwrite (fd, " 1281"); ozoneae(foo[17:15], fd); ozonebmuop(foo[25:21], fd); ozoneae(foo[ 8: 6], fd); $fwrite (fd, " 1282"); dude(fd); $fwrite(fd, " 1283"); end 5'b0_01??: begin ozoneae(foo[20:18], fd); $fwrite (fd, " 1284"); ozoneae(foo[17:15], fd); ozonebmuop(foo[25:21], fd); ozonearm(foo[ 8: 6], fd); dude(fd); $fwrite(fd, " 1285"); end 5'b0_1011: begin ozoneae(foo[20:18], fd); $fwrite (fd, " 1286"); ozonebmuop(foo[25:21], fd); $fwrite (fd, " 1287"); ozoneae(foo[ 8: 6], fd); $fwrite (fd, " 1288"); dude(fd); $fwrite(fd, " 1289"); end 5'b0_100?, 5'b0_1010, 5'b0_110? : begin ozoneae(foo[20:18], fd); $fwrite (fd, " 1290"); ozonebmuop(foo[25:21], fd); $fwrite (fd, " 1291"); ozoneae(foo[17:15], fd); $fwrite (fd, " 1292"); ozoneae(foo[ 8: 6], fd); $fwrite (fd, " 1293"); dude(fd); $fwrite(fd, " 1294"); end 5'b0_1111 : begin ozoneae(foo[20:18], fd); $fwrite (fd, " 1295"); ozoneae(foo[17:15], fd); $fwrite (fd, " 1296"); ozoneae(foo[ 8: 6], fd); dude(fd); $fwrite(fd, " 1297"); end 5'b1_10??, 5'b1_110?, 5'b1_1110 : begin ozoneae(foo[20:18], fd); $fwrite (fd, " 1298"); ozonebmuop(foo[25:21], fd); $fwrite (fd, " 1299"); ozoneae(foo[17:15], fd); $fwrite (fd, " 1300"); ozonearm(foo[ 8: 6], fd); $fwrite (fd, " 1301"); dude(fd); $fwrite(fd, " 1302"); end endcase end 17'b00_0010_?_????_??_???? : begin ozonerab({1'b0, foo[25:20]}, fd); $fwrite (fd, " 1303"); skyway(foo[19:16], fd); dude(fd); $fwrite(fd, " 1304"); end 17'b00_01??_?_????_??_???? : begin if (foo[27]) begin $fwrite (fd, " 1305"); if (foo[26]) $fwrite (fd, " 1306"); else $fwrite (fd, " 1307"); skyway(foo[19:16], fd); $fwrite (fd, " 1308"); ozonerab({1'b0, foo[25:20]}, fd); end else begin ozonerab({1'b0, foo[25:20]}, fd); $fwrite (fd, " 1309"); if (foo[26]) $fwrite (fd, " 1310"); else $fwrite (fd, " 1311"); skyway(foo[19:16], fd); $fwrite (fd, " 1312"); end dude(fd); $fwrite(fd, " 1313"); end 17'b01_000?_?_????_??_???? : begin if (foo[26]) begin ozonerb(foo[25:20], fd); $fwrite (fd, " 1314"); ozoneae(foo[18:16], fd); ozonehl(foo[19], fd); end else begin ozoneae(foo[18:16], fd); ozonehl(foo[19], fd); $fwrite (fd, " 1315"); ozonerb(foo[25:20], fd); end dude(fd); $fwrite(fd, " 1316"); end 17'b01_10??_?_????_??_???? : begin if (foo[27]) begin ozonerab({1'b0, foo[25:20]}, fd); $fwrite (fd, " 1317"); ozonerx(foo, fd); end else begin ozonerx(foo, fd); $fwrite (fd, " 1318"); ozonerab({1'b0, foo[25:20]}, fd); end dude(fd); $fwrite(fd, " 1319"); end 17'b11_101?_?_????_??_???? : begin ozonerab (foo[26:20], fd); $fwrite (fd, " 1320"); skyway(foo[19:16], fd); skyway(foo[15:12], fd); skyway(foo[11: 8], fd); skyway(foo[ 7: 4], fd); skyway(foo[ 3: 0], fd); dude(fd); $fwrite(fd, " 1321"); end 17'b11_0000_?_????_??_???? : begin casez (foo[25:23]) 3'b00?: begin ozonerab(foo[22:16], fd); $fwrite (fd, " 1322"); end 3'b01?: begin $fwrite (fd, " 1323"); if (foo[22:16]>=7'h60) $fwrite (fd, " 1324"); else ozonerab(foo[22:16], fd); end 3'b110: $fwrite (fd, " 1325"); 3'b10?: begin $fwrite (fd, " 1326"); if (foo[22:16]>=7'h60) $fwrite (fd, " 1327"); else ozonerab(foo[22:16], fd); end 3'b111: begin $fwrite (fd, " 1328"); ozonerab(foo[22:16], fd); $fwrite (fd, " 1329"); end endcase dude(fd); $fwrite(fd, " 1330"); end 17'b00_10??_?_????_?1_0000 : begin if (foo[27]) begin $fwrite (fd, " 1331"); ozonerp(foo[14:12], fd); $fwrite (fd, " 1332"); skyway(foo[19:16], fd); skyway({foo[15],foo[11: 9]}, fd); skyway(foo[ 8: 5], fd); $fwrite (fd, " 1333"); if (foo[26:20]>=7'h60) $fwrite (fd, " 1334"); else ozonerab(foo[26:20], fd); end else begin ozonerab(foo[26:20], fd); $fwrite (fd, " 1335"); $fwrite (fd, " 1336"); ozonerp(foo[14:12], fd); $fwrite (fd, " 1337"); skyway(foo[19:16], fd); skyway({foo[15],foo[11: 9]}, fd); skyway(foo[ 8: 5], fd); $fwrite (fd, " 1338"); end dude(fd); $fwrite(fd, " 1339"); end 17'b00_101?_1_0000_?1_0010 : if (~|foo[11: 7]) begin if (foo[ 6]) begin $fwrite (fd, " 1340"); ozonerp(foo[14:12], fd); $fwrite (fd, " 1341"); ozonejk(foo[ 5], fd); $fwrite (fd, " 1342"); if (foo[26:20]>=7'h60) $fwrite (fd, " 1343"); else ozonerab(foo[26:20], fd); end else begin ozonerab(foo[26:20], fd); $fwrite (fd, " 1344"); $fwrite (fd, " 1345"); ozonerp(foo[14:12], fd); $fwrite (fd, " 1346"); ozonejk(foo[ 5], fd); $fwrite (fd, " 1347"); end dude(fd); $fwrite(fd, " 1348"); end else $fwrite(fd, " 1349"); 17'b00_100?_0_0011_?1_0101 : if (~|foo[ 8: 7]) begin if (foo[6]) begin ozonerab(foo[26:20], fd); $fwrite (fd, " 1350"); ozoneye(foo[14: 9],foo[ 5], fd); end else begin ozoneye(foo[14: 9],foo[ 5], fd); $fwrite (fd, " 1351"); if (foo[26:20]>=7'h60) $fwrite (fd, " 1352"); else ozonerab(foo[26:20], fd); end dude(fd); $fwrite(fd, " 1353"); end else $fwrite(fd, " 1354"); 17'b00_1001_0_0000_?1_0010 : if (~|foo[25:20]) begin ozoneye(foo[14: 9],1'b0, fd); $fwrite (fd, " 1355"); ozonef1e_h(foo[11: 9], fd); $fwrite (fd, " 1356"); ozonef1e_h(foo[ 7: 5], fd); $fwrite (fd, " 1357"); ozonexe(foo[ 8: 5], fd); dude(fd); $fwrite(fd, " 1358"); end else $fwrite(fd, " 1359"); 17'b00_101?_0_????_?1_0010 : if (~foo[13]) begin if (foo[12]) begin $fwrite (fd, " 1360"); if (foo[26:20]>=7'h60) $fwrite (fd, " 1361"); else ozonerab(foo[26:20], fd); $fwrite (fd, " 1362"); $fwrite (fd, " 1363"); skyway({1'b0,foo[18:16]}, fd); skyway({foo[15],foo[11: 9]}, fd); skyway(foo[ 8: 5], fd); dude(fd); $fwrite(fd, " 1364"); end else begin ozonerab(foo[26:20], fd); $fwrite (fd, " 1365"); $fwrite (fd, " 1366"); skyway({1'b0,foo[18:16]}, fd); skyway({foo[15],foo[11: 9]}, fd); skyway(foo[ 8: 5], fd); dude(fd); $fwrite(fd, " 1367"); end end else $fwrite(fd, " 1368"); 17'b01_01??_?_????_??_???? : begin ozonerab({1'b0,foo[27:26],foo[19:16]}, fd); $fwrite (fd, " 1369"); ozonerab({1'b0,foo[25:20]}, fd); dude(fd); $fwrite(fd, " 1370"); end 17'b00_100?_?_???0_11_0101 : if (~foo[6]) begin $fwrite (fd," 1371"); ozonecon(foo[14:10], fd); $fwrite (fd, " 1372"); ozonerab({foo[ 9: 7],foo[19:16]}, fd); $fwrite (fd, " 1373"); ozonerab({foo[26:20]}, fd); dude(fd); $fwrite(fd, " 1374"); end else $fwrite(fd, " 1375"); 17'b00_1000_?_????_?1_0010 : if (~|foo[25:24]) begin ozonery(foo[23:20], fd); $fwrite (fd, " 1376"); ozonerp(foo[14:12], fd); $fwrite (fd, " 1377"); skyway(foo[19:16], fd); skyway({foo[15],foo[11: 9]}, fd); skyway(foo[ 8: 5], fd); dude(fd); $fwrite(fd, " 1378"); end else if ((foo[25:24] == 2'b10) & ~|foo[19:15] & ~|foo[11: 6]) begin ozonery(foo[23:20], fd); $fwrite (fd, " 1379"); ozonerp(foo[14:12], fd); $fwrite (fd, " 1380"); ozonejk(foo[ 5], fd); dude(fd); $fwrite(fd, " 1381"); end else $fwrite(fd, " 1382"); 17'b11_01??_?_????_??_????, 17'b10_00??_?_????_??_???? : if (foo[30]) $fwrite(fd, " 1383:%x", foo[27:16]); else $fwrite(fd, " 1384:%x", foo[27:16]); 17'b00_10??_?_????_01_1000 : if (~foo[6]) begin if (foo[7]) $fwrite(fd, " 1385:%x", foo[27: 8]); else $fwrite(fd, " 1386:%x", foo[27: 8]); end else $fwrite(fd, " 1387"); 17'b00_10??_?_????_11_1000 : begin $fwrite (fd," 1388"); ozonecon(foo[14:10], fd); $fwrite (fd, " 1389"); if (foo[15]) $fwrite (fd, " 1390"); else $fwrite (fd, " 1391"); skyway(foo[27:24], fd); skyway(foo[23:20], fd); skyway(foo[19:16], fd); skyway(foo[ 9: 6], fd); dude(fd); $fwrite(fd, " 1392"); end 17'b11_0001_?_????_??_???? : casez (foo[25:22]) 4'b01?? : begin $fwrite (fd," 1393"); ozonecon(foo[20:16], fd); case (foo[23:21]) 3'h0 : $fwrite (fd, " 1394"); 3'h1 : $fwrite (fd, " 1395"); 3'h2 : $fwrite (fd, " 1396"); 3'h3 : $fwrite (fd, " 1397"); 3'h4 : $fwrite (fd, " 1398"); 3'h5 : $fwrite (fd, " 1399"); 3'h6 : $fwrite (fd, " 1400"); 3'h7 : $fwrite (fd, " 1401"); endcase dude(fd); $fwrite(fd, " 1402"); end 4'b0000 : $fwrite(fd, " 1403:%x", foo[21:16]); 4'b0010 : if (~|foo[21:16]) $fwrite(fd, " 1404"); 4'b1010 : if (~|foo[21:17]) begin if (foo[16]) $fwrite(fd, " 1405"); else $fwrite(fd, " 1406"); end default : $fwrite(fd, " 1407"); endcase 17'b01_11??_?_????_??_???? : if (foo[27:23] === 5'h00) $fwrite(fd, " 1408:%x", foo[22:16]); else $fwrite(fd, " 1409:%x", foo[22:16]); default: $fwrite(fd, " 1410"); endcase end endtask //(query-replace-regexp "\\([a-z0-9_]+\\) *( *\\([][a-z0-9_~': ]+\\) *, *\\([][a-z0-9'~: ]+\\) *, *\\([][a-z0-9'~: ]+\\) *);" "$c(\"\\1(\",\\2,\",\",\\3,\",\",\\4,\");\");" nil nil nil) //(query-replace-regexp "\\([a-z0-9_]+\\) *( *\\([][a-z0-9_~': ]+\\) *, *\\([][a-z0-9'~: ]+\\) *);" "$c(\"\\1(\",\\2,\",\",\\3,\");\");" nil nil nil) endmodule verilator-3.874/test_regress/t/t_dedupe_seq_logic.v0000664000177100017500000000525212473477707022532 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Dedupe optimization test. // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // Contributed 2012 by Varun Koyyalagunta, Centaur Technology. // // Test consists of the follow logic tree, which has many obvious // places for dedupe: /* output + --------------/ \-------------- / \ + + ----/ \----- ----/ \---- / + / + + / \ + / \ -/ \- a b -/ \- a b / \ / \ + + + + / \ / \ / \ / \ a b c d a b c d */ module t(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; wire left,right; add add(sum,left,right,clk); l l(left,a,b,c,d,clk); r r(right,a,b,c,d,clk); endmodule module l(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; wire left, right; add add(sum,left,right,clk); ll ll(left,a,b,c,d,clk); lr lr(right,a,b,c,d,clk); endmodule module ll(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; wire left, right; add add(sum,left,right,clk); lll lll(left,a,b,c,d,clk); llr llr(right,a,b,c,d,clk); endmodule module lll(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; add add(sum,a,b,clk); endmodule module llr(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; add add(sum,c,d,clk); endmodule module lr(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; add add(sum,a,b,clk); endmodule module r(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; wire left, right; add add(sum,left,right,clk); rl rl(left,a,b,c,d,clk); rr rr(right,a,b,c,d,clk); endmodule module rr(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; add add(sum,a,b,clk); endmodule module rl(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; wire left, right; add add(sum,left,right,clk); rll rll(left,a,b,c,d,clk); rlr rlr(right,a,b,c,d,clk); endmodule module rll(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; add2 add(sum,a,b,clk); endmodule module rlr(sum,a,b,c,d,clk); output sum; input a,b,c,d,clk; add2 add(sum,c,d,clk); endmodule module add(sum,x,y,clk); output sum; input x,y,clk; reg t1,t2; always @(posedge clk) begin sum <= x + y; end endmodule module add2(sum,x,y,clk); output sum; input x,y,clk; reg t1,t2; always @(posedge clk) begin sum <= x + y; end endmodule verilator-3.874/test_regress/t/t_tri_select_unsized.pl0000775000177100017500000000074512473477707023310 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # Compile only test compile ( verilator_flags2 => ["-Wno-WIDTH"], ); ok(1); 1; verilator-3.874/test_regress/t/t_var_pins_sc_biguint.pl0000775000177100017500000000467012473477707023442 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.874/test_regress/t/t_tri_select.pl0000775000177100017500000000116512473477707021544 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_wideconst.v0000664000177100017500000000220412473477707022265 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [41:0] aaa; wire [41:0] bbb; // verilator public_module wire [41:0] z_0; wire [41:0] z_1; wide w_0( .xxx( { {40{1'b0}},2'b11 } ), .yyy( aaa[1:0] ), .zzz( z_0 ) ); wide w_1( .xxx( aaa ), .yyy( 2'b10 ), .zzz( z_1 ) ); assign bbb= z_0 + z_1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin aaa <= 42'b01; end if (cyc==2) begin aaa <= 42'b10; if (z_0 != 42'h4) $stop; if (z_1 != 42'h3) $stop; end if (cyc==3) begin if (z_0 != 42'h5) $stop; if (z_1 != 42'h4) $stop; end if (cyc==4) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module wide ( input [41:0] xxx, input [1:0] yyy, output [41:0] zzz ); // verilator public_module assign zzz = xxx+ { {40{1'b0}},yyy }; endmodule verilator-3.874/test_regress/t/t_gen_inc.v0000664000177100017500000001272412473477707020643 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; genvar g; integer i; reg [31:0] v; reg [31:0] gen_pre_PLUSPLUS = 32'h0; reg [31:0] gen_pre_MINUSMINUS = 32'h0; reg [31:0] gen_post_PLUSPLUS = 32'h0; reg [31:0] gen_post_MINUSMINUS = 32'h0; reg [31:0] gen_PLUSEQ = 32'h0; reg [31:0] gen_MINUSEQ = 32'h0; reg [31:0] gen_TIMESEQ = 32'h0; reg [31:0] gen_DIVEQ = 32'h0; reg [31:0] gen_MODEQ = 32'h0; reg [31:0] gen_ANDEQ = 32'h0; reg [31:0] gen_OREQ = 32'h0; reg [31:0] gen_XOREQ = 32'h0; reg [31:0] gen_SLEFTEQ = 32'h0; reg [31:0] gen_SRIGHTEQ = 32'h0; reg [31:0] gen_SSRIGHTEQ = 32'h0; generate for (g=8; g<=16; ++g) always @(posedge clk) gen_pre_PLUSPLUS[g] = 1'b1; for (g=16; g>=8; --g) always @(posedge clk) gen_pre_MINUSMINUS[g] = 1'b1; for (g=8; g<=16; g++) always @(posedge clk) gen_post_PLUSPLUS[g] = 1'b1; for (g=16; g>=8; g--) always @(posedge clk) gen_post_MINUSMINUS[g] = 1'b1; for (g=8; g<=16; g+=2) always @(posedge clk) gen_PLUSEQ[g] = 1'b1; for (g=16; g>=8; g-=2) always @(posedge clk) gen_MINUSEQ[g] = 1'b1; `ifndef verilator //UNSUPPORTED for (g=8; g<=16; g*=2) always @(posedge clk) gen_TIMESEQ[g] = 1'b1; for (g=16; g>=8; g/=2) always @(posedge clk) gen_DIVEQ[g] = 1'b1; for (g=15; g>8; g%=8) always @(posedge clk) gen_MODEQ[g] = 1'b1; for (g=7; g>4; g&=4) always @(posedge clk) gen_ANDEQ[g] = 1'b1; for (g=1; g<=1; g|=2) always @(posedge clk) gen_OREQ[g] = 1'b1; for (g=7; g==7; g^=2) always @(posedge clk) gen_XOREQ[g] = 1'b1; for (g=8; g<=16; g<<=2) always @(posedge clk) gen_SLEFTEQ[g] = 1'b1; for (g=16; g>=8; g>>=2) always @(posedge clk) gen_SRIGHTEQ[g] = 1'b1; for (g=16; g>=8; g>>>=2) always @(posedge clk) gen_SSRIGHTEQ[g] = 1'b1; `endif endgenerate always @ (posedge clk) begin cyc <= cyc + 1; if (cyc == 3) begin `ifdef TEST_VERBOSE $write("gen_pre_PLUSPLUS %b\n", gen_pre_PLUSPLUS); $write("gen_pre_MINUSMINUS %b\n", gen_pre_MINUSMINUS); $write("gen_post_PLUSPLUS %b\n", gen_post_PLUSPLUS); $write("gen_post_MINUSMINUS %b\n", gen_post_MINUSMINUS); $write("gen_PLUSEQ %b\n", gen_PLUSEQ); $write("gen_MINUSEQ %b\n", gen_MINUSEQ); $write("gen_TIMESEQ %b\n", gen_TIMESEQ); $write("gen_DIVEQ %b\n", gen_DIVEQ); $write("gen_MODEQ %b\n", gen_MODEQ); $write("gen_ANDEQ %b\n", gen_ANDEQ); $write("gen_OREQ %b\n", gen_OREQ); $write("gen_XOREQ %b\n", gen_XOREQ); $write("gen_SLEFTEQ %b\n", gen_SLEFTEQ); $write("gen_SRIGHTEQ %b\n", gen_SRIGHTEQ); $write("gen_SSRIGHTEQ %b\n", gen_SSRIGHTEQ); `endif if (gen_pre_PLUSPLUS !== 32'b00000000000000011111111100000000) $stop; if (gen_pre_MINUSMINUS !== 32'b00000000000000011111111100000000) $stop; if (gen_post_PLUSPLUS !== 32'b00000000000000011111111100000000) $stop; if (gen_post_MINUSMINUS!== 32'b00000000000000011111111100000000) $stop; if (gen_PLUSEQ !== 32'b00000000000000010101010100000000) $stop; if (gen_MINUSEQ !== 32'b00000000000000010101010100000000) $stop; `ifndef verilator //UNSUPPORTED if (gen_TIMESEQ !== 32'b00000000000000010000000100000000) $stop; if (gen_DIVEQ !== 32'b00000000000000010000000100000000) $stop; if (gen_MODEQ !== 32'b00000000000000001000000000000000) $stop; if (gen_ANDEQ !== 32'b00000000000000000000000010000000) $stop; if (gen_OREQ !== 32'b00000000000000000000000000000010) $stop; if (gen_XOREQ !== 32'b00000000000000000000000010000000) $stop; if (gen_SLEFTEQ !== 32'b00000000000000000000000100000000) $stop; if (gen_SRIGHTEQ !== 32'b00000000000000010000000000000000) $stop; if (gen_SSRIGHTEQ !== 32'b00000000000000010000000000000000) $stop; `endif v=0; for (i=8; i<=16; ++i) v[i] = 1'b1; if (v !== 32'b00000000000000011111111100000000) $stop; v=0; for (i=16; i>=8; --i) v[i] = 1'b1; if (v !== 32'b00000000000000011111111100000000) $stop; v=0; for (i=8; i<=16; i++) v[i] = 1'b1; if (v !== 32'b00000000000000011111111100000000) $stop; v=0; for (i=16; i>=8; i--) v[i] = 1'b1; if (v !== 32'b00000000000000011111111100000000) $stop; v=0; for (i=8; i<=16; i+=2) v[i] = 1'b1; if (v !== 32'b00000000000000010101010100000000) $stop; v=0; for (i=16; i>=8; i-=2) v[i] = 1'b1; if (v !== 32'b00000000000000010101010100000000) $stop; `ifndef verilator //UNSUPPORTED v=0; for (i=8; i<=16; i*=2) v[i] = 1'b1; if (v !== 32'b00000000000000010000000100000000) $stop; v=0; for (i=16; i>=8; i/=2) v[i] = 1'b1; if (v !== 32'b00000000000000010000000100000000) $stop; v=0; for (i=15; i>8; i%=8) v[i] = 1'b1; if (v !== 32'b00000000000000001000000000000000) $stop; v=0; for (i=7; i>4; i&=4) v[i] = 1'b1; if (v !== 32'b00000000000000000000000010000000) $stop; v=0; for (i=1; i<=1; i|=2) v[i] = 1'b1; if (v !== 32'b00000000000000000000000000000010) $stop; v=0; for (i=7; i==7; i^=2) v[i] = 1'b1; if (v !== 32'b00000000000000000000000010000000) $stop; v=0; for (i=8; i<=16; i<<=2) v[i] =1'b1; if (v !== 32'b00000000000000000000000100000000) $stop; v=0; for (i=16; i>=8; i>>=2) v[i] =1'b1; if (v !== 32'b00000000000000010000000000000000) $stop; v=0; for (i=16; i>=8; i>>>=2) v[i]=1'b1; if (v !== 32'b00000000000000010000000000000000) $stop; `endif $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_var_pins_sc2.pl0000775000177100017500000000407112473477707021776 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -pins-bv 2 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.874/test_regress/t/t_lint_defparam_bad.pl0000775000177100017500000000154512473477707023024 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. top_filename("t/t_lint_defparam.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only -Wwarn-style -Wno-DECLFILENAME"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning-DEFPARAM: t/t_lint_defparam.v:\d+: Suggest replace defparam with Verilog 2001 #\(.P\(...etc...\)\) %Warning-DEFPARAM: Use .* to disable this message. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_inout2.pl0000775000177100017500000000066012473477707021504 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 by Wilson Snyder. This program is free software; you can # redistribute it and/or modify it under the terms of either the GNU # General Public License or the Perl Artistic License. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_define.vc0000664000177100017500000000023212473477707021616 0ustar wsnyderwsnyder+define+D1A +define+D2A=VALA +define+D3A+D3B +define+D4A=VALA+D4B +define+D5A=VALA+D5B=VALB // Quotes do NOT escape the plus //+define+D5A="VALA+D5B"+D5C verilator-3.874/test_regress/t/t_pp_display.pl0000775000177100017500000000160212473477707021547 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, expect=>quotemeta( qq{pre thrupre thrumid thrupost post: "right side" left side: "right side" left side: "right side" left_side: "right_side" na: "right_side" prep ( midp1 left_side midp2 ( outp ) ): "right_side" na: "nana" left_side right_side: "left_side right_side" left side: "right side" : "" left side: "right side" left side: "right side" standalone twoline: "first second" Line 49 File "t/t_pp_display.v" *-* All Finished *-* })); ok(1); 1; verilator-3.874/test_regress/t/t_trace_complex_structs.out0000664000177100017500000000765112473477707024222 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Tue Apr 15 12:58:17 2014 $end $timescale 1ns $end $scope module top $end $var wire 1 D clk $end $scope module $unit $end $var wire 1 # global_bit $end $upscope $end $scope module v $end $var wire 1 D clk $end $var wire 32 $ cyc [31:0] $end $var real 64 > v_arr_real(0) $end $var real 64 @ v_arr_real(1) $end $var wire 2 / v_arrp [2:1] $end $var wire 2 0 v_arrp_arrp(3) [1:0] $end $var wire 2 1 v_arrp_arrp(4) [1:0] $end $var wire 1 E v_arru(1) $end $var wire 1 F v_arru(2) $end $var wire 2 6 v_arru_arrp(3) [2:1] $end $var wire 2 7 v_arru_arrp(4) [2:1] $end $var wire 1 G v_arru_arru(3)(1) $end $var wire 1 H v_arru_arru(3)(2) $end $var wire 1 I v_arru_arru(4)(1) $end $var wire 1 J v_arru_arru(4)(2) $end $var real 64 < v_real $end $scope module unnamedblk1 $end $var wire 32 B b [31:0] $end $scope module unnamedblk2 $end $var wire 32 C a [31:0] $end $upscope $end $upscope $end $scope module v_arrp_strp(3) $end $var wire 1 3 b0 $end $var wire 1 2 b1 $end $upscope $end $scope module v_arrp_strp(4) $end $var wire 1 5 b0 $end $var wire 1 4 b1 $end $upscope $end $scope module v_arru_strp(3) $end $var wire 1 9 b0 $end $var wire 1 8 b1 $end $upscope $end $scope module v_arru_strp(4) $end $var wire 1 ; b0 $end $var wire 1 : b1 $end $upscope $end $scope module v_str32x2(0) $end $var wire 32 % data [31:0] $end $upscope $end $scope module v_str32x2(1) $end $var wire 32 & data [31:0] $end $upscope $end $scope module v_strp $end $var wire 1 ( b0 $end $var wire 1 ' b1 $end $upscope $end $scope module v_strp_strp $end $scope module x0 $end $var wire 1 , b0 $end $var wire 1 + b1 $end $upscope $end $scope module x1 $end $var wire 1 * b0 $end $var wire 1 ) b1 $end $upscope $end $upscope $end $scope module v_unip_strp $end $scope module x0 $end $var wire 1 . b0 $end $var wire 1 - b1 $end $upscope $end $scope module x1 $end $var wire 1 . b0 $end $var wire 1 - b1 $end $upscope $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 1# b00000000000000000000000000000000 $ b00000000000000000000000011111111 % b00000000000000000000000000000000 & 0' 0( 0) 0* 0+ 0, 0- 0. b00 / b00 0 b00 1 02 03 04 05 b00 6 b00 7 08 09 0: 0; r0 < r0 > r0 @ b00000000000000000000000000000000 B b00000000000000000000000000000000 C 0D 0E 0F 0G 0H 0I 0J #10 b00000000000000000000000000000001 $ b00000000000000000000000011111110 % b00000000000000000000000000000001 & 1' 1( 1) 1* 1+ 1, 1- 1. b11 / b11 0 b11 1 12 13 14 15 b11 6 b11 7 18 19 1: 1; r0.1 < r0.2 > r0.3 @ b00000000000000000000000000000101 B b00000000000000000000000000000101 C 1D #15 0D #20 b00000000000000000000000000000010 $ b00000000000000000000000011111101 % b00000000000000000000000000000010 & 0' 0( 0) 0* 0+ 0, 0- 0. b00 / b00 0 b00 1 02 03 04 05 b00 6 b00 7 08 09 0: 0; r0.2 < r0.4 > r0.6 @ 1D #25 0D #30 b00000000000000000000000000000011 $ b00000000000000000000000011111100 % b00000000000000000000000000000011 & 1' 1( 1) 1* 1+ 1, 1- 1. b11 / b11 0 b11 1 12 13 14 15 b11 6 b11 7 18 19 1: 1; r0.3 < r0.6000000000000001 > r0.8999999999999999 @ 1D #35 0D #40 b00000000000000000000000000000100 $ b00000000000000000000000011111011 % b00000000000000000000000000000100 & 0' 0( 0) 0* 0+ 0, 0- 0. b00 / b00 0 b00 1 02 03 04 05 b00 6 b00 7 08 09 0: 0; r0.4 < r0.8 > r1.2 @ 1D #45 0D #50 b00000000000000000000000000000101 $ b00000000000000000000000011111010 % b00000000000000000000000000000101 & 1' 1( 1) 1* 1+ 1, 1- 1. b11 / b11 0 b11 1 12 13 14 15 b11 6 b11 7 18 19 1: 1; r0.5 < r1 > r1.5 @ 1D #55 0D #60 b00000000000000000000000000000110 $ b00000000000000000000000011111001 % b00000000000000000000000000000110 & 0' 0( 0) 0* 0+ 0, 0- 0. b00 / b00 0 b00 1 02 03 04 05 b00 6 b00 7 08 09 0: 0; r0.6 < r1.2 > r1.8 @ 1D verilator-3.874/test_regress/t/t_display_wide.pl0000775000177100017500000001053712473477707022067 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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->{vl_time_multiplier} = 1000; compile ( ); execute ( check_finished=>1, expect=> quotemeta( '[1000.000] cyc==99 crc=2961926edde3e5c6018be970cdbf327b72b5f3c5eab42995891005eec8767e5fdf03051edbe9d222ee756ee34d8d6c83ee877aad65c487140ac87d26c636a66214b4a69acad924c568cc8e8c79f97d07a6eedf91011919d0e3cdda5215ee58c942f6c4dea48b3f38abc77bf47e4f6d6a859fcc5b5d46ec9d2f6a5bf7b978b1ba7ca15d0713a2eb06ade1570c4e3a12db687625eef8dfebcb4095ab4bdffe79c1298f609307a5ef773a6432b855e3e54deb88ca342bf5a7fecc5f2f3e165a59cdb9179718a2d11c9d55f14d69f40b01e41fcb7335a8872a6ba7876ec684d6a3af0b82aa31cca6e26340a2589cf7bf886faa8d23844596dc71233c7025c5250a968b770ab72db90b03d8c045fb8848159df544a3a3bf063269be0aa11d5507f5c8b328b760a6df9e3fbe276faad8eadee126443ad3f99d595b12d0ae514b20693298a58642a07718f9ab7ea8c66575f7f8d0e3ba77d992235b3d5a4e015a7ff9b97a8c4f48ebdbfc2365e6bca4dd3ba6bfc7e850f7c8e2842c717a1d85a977a033f564fc [1000.000] cyc==99 crc=001010010110000110010010011011101101110111100011111001011100011000000001100010111110100101110000110011011011111100110010011110110111001010110101111100111100010111101010101101000010100110010101100010010001000000000101111011101100100001110110011111100101111111011111000000110000010100011110110110111110100111010010001000101110111001110101011011101110001101001101100011010110110010000011111011101000011101111010101011010110010111000100100001110001010000001010110010000111110100100110110001100011011010100110011000100001010010110100101001101001101011001010110110010010010011000101011010001100110010001110100011000111100111111001011111010000011110100110111011101101111110010001000000010001100100011001110100001110001111001101110110100101001000010101111011100101100011001001010000101111011011000100110111101010010010001011001111110011100010101011110001110111101111110100011111100100111101101101011010101000010110011111110011000101101101011101010001101110110010011101001011110110101001011011111101111011100101111000101100011011101001111100101000010101110100000111000100111010001011101011000001101010110111100001010101110000110001001110001110100001001011011011011010000111011000100101111011101111100011011111111010111100101101000000100101011010101101001011110111111111111001111001110000010010100110001111011000001001001100000111101001011110111101110111001110100110010000110010101110000101010111100011111001010100110111101011100010001100101000110100001010111111010110100111111111101100110001011111001011110011111000010110010110100101100111001101101110010001011110010111000110001010001011010001000111001001110101010101111100010100110101101001111101000000101100000001111001000001111111001011011100110011010110101000100001110010101001101011101001111000011101101110110001101000010011010110101000111010111100001011100000101010101000110001110011001010011011100010011000110100000010100010010110001001110011110111101111111000100001101111101010101000110100100011100001000100010110010110110111000111000100100011001111000111000000100101110001010010010100001010100101101000101101110111000010101011011100101101101110010000101100000011110110001100000001000101111110111000100001001000000101011001110111110101010001001010001110100011101111110000011000110010011010011011111000001010101000010001110101010101000001111111010111001000101100110010100010110111011000001010011011011111100111100011111110111110001001110110111110101010110110001110101011011110111000010010011001000100001110101101001111111001100111010101100101011011000100101101000010101110010100010100101100100000011010010011001010011000101001011000011001000010101000000111011100011000111110011010101101111110101010001100011001100101011101011111011111111000110100001110001110111010011101111101100110010010001000110101101100111101010110100100111000000001010110100111111111111001101110010111101010001100010011110100100011101011110110111111110000100011011001011110011010111100101001001101110100111011101001101011111111000111111010000101000011110111110010001110001010000100001011000111000101111010000111011000010110101001011101111010000000110011111101010110010011111100' ), ); ok(1); 1; verilator-3.874/test_regress/t/t_pp_misdef_bad.pl0000775000177100017500000000117312473477707022162 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_pp_misdef_bad.v:\d+: Define or directive not defined: `NOTDEF %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_param_named_2.v0000664000177100017500000000206312473477707021721 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); parameter PAR = 3; input clk; m3 m3_inst (.clk(clk)); defparam m3_inst.FROMDEFP = 19; defparam m3_inst.P2 = 2; //defparam m3_inst.P3 = PAR; defparam m3_inst.P3 = 3; integer cyc=1; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==1) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module m3 (/*AUTOARG*/ // Inputs clk ); input clk; localparam LOC = 13; parameter UNCH = 99; parameter P1 = 10; parameter P2 = 20; parameter P3 = 30; parameter FROMDEFP = 11; initial begin $display("%x %x %x",P1,P2,P3); end always @ (posedge clk) begin if (UNCH !== 99) $stop; if (P1 !== 10) $stop; if (P2 !== 2) $stop; if (P3 !== 3) $stop; if (FROMDEFP !== 19) $stop; end endmodule verilator-3.874/test_regress/t/t_func_v.pl0000775000177100017500000000072212473477707020665 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface2.v0000664000177100017500000000470312473477707021261 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; counter_io c1_data(); counter_io c2_data(); //counter_io c3_data; // IEEE illegal, and VCS doesn't allow non-() as it does with cells counter_io c3_data(); counter_ansi c1 (.clkm(clk), .c_data(c1_data), .i_value(4'h1)); counter_ansi c2 (.clkm(clk), .c_data(c2_data), .i_value(4'h2)); `ifdef VERILATOR counter_ansi `else counter_nansi `endif /**/ c3 (.clkm(clk), .c_data(c3_data), .i_value(4'h3)); initial begin c1_data.value = 4'h4; c2_data.value = 4'h5; c3_data.value = 4'h6; end always @ (posedge clk) begin cyc <= cyc + 1; if (cyc<2) begin c1_data.reset <= 1; c2_data.reset <= 1; c3_data.reset <= 1; end if (cyc==2) begin c1_data.reset <= 0; c2_data.reset <= 0; c3_data.reset <= 0; end if (cyc==3) begin if (c1_data.get_lcl() != 12345) $stop; end if (cyc==20) begin $write("[%0t] c1 cyc%0d: c1 %0x %0x c2 %0x %0x c3 %0x %0x\n", $time, cyc, c1_data.value, c1_data.reset, c2_data.value, c2_data.reset, c3_data.value, c3_data.reset); if (c1_data.value != 2) $stop; if (c2_data.value != 3) $stop; if (c3_data.value != 4) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule interface counter_io; logic [3:0] value; logic reset; integer lcl; task set_lcl (input integer a); lcl=a; endtask function integer get_lcl (); return lcl; endfunction endinterface interface ifunused; logic unused; endinterface module counter_ansi ( input clkm, counter_io c_data, input logic [3:0] i_value ); initial begin c_data.set_lcl(12345); end always @ (posedge clkm) begin c_data.value <= c_data.reset ? i_value : c_data.value + 1; end endmodule : counter_ansi `ifndef VERILATOR // non-ansi modports not seen in the wild yet. Verilog-Perl needs parser improvement too. module counter_nansi(clkm, c_data, i_value); input clkm; counter_io c_data; input logic [3:0] i_value; always @ (posedge clkm) begin c_data.value <= c_data.reset ? i_value : c_data.value + 1; end endmodule : counter_nansi `endif module modunused (ifunused ifinunused); ifunused ifunused(); endmodule verilator-3.874/test_regress/t/t_package_twodeep.pl0000775000177100017500000000071712473477707022533 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_inout.v0000664000177100017500000000105312473477707021246 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks module top (input A, input B, input SEL, output Y1, output Y2, output Z); io io1(.A(A), .OE( SEL), .Z(Z), .Y(Y1)); pass io2(.A(B), .OE(!SEL), .Z(Z), .Y(Y2)); assign Z = 1'bz; endmodule module pass (input A, input OE, inout Z, output Y); io io(.A(A), .OE(OE), .Z(Z), .Y(Y)); assign Z = 1'bz; endmodule module io (input A, input OE, inout Z, output Y); assign Z = (OE) ? A : 1'bz; assign Y = Z; assign Z = 1'bz; endmodule verilator-3.874/test_regress/t/t_lint_width.pl0000775000177100017500000000110612473477707021547 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( v_flags2 => ["--lint-only"], make_top_shell => 0, make_main => 0, verilator_make_gcc => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_order_loop_bad.pl0000775000177100017500000000143212473477707022356 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Error: Circular logic when ordering code .* %Error: Example path: t/t_order_loop_bad.v:\d+: ALWAYS %Error: Example path: t/t_order_loop_bad.v:\d+: v.ready %Error: Example path: t/t_order_loop_bad.v:\d+: ACTIVE .*', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_signed.pl0000775000177100017500000000071412473477707021670 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_scstruct.v0000664000177100017500000000071312525171734022251 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. // verilator lint_off UNUSED // verilator lint_off UNDRIVEN //bug858 typedef struct packed { logic m_1; logic m_2; } struct_t; typedef struct packed { logic [94:0] m_1; logic m_2; } struct96_t; module t ( input struct_t test_input, input struct96_t t96 ); endmodule verilator-3.874/test_regress/t/t_tri_various.pl0000775000177100017500000000025212473477707021751 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_unused.pl0000775000177100017500000000121012473477707021727 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only --bbox-sys --bbox-unsup -Wall -Wno-DECLFILENAME"], fails=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_concat64.pl0000775000177100017500000000071712473477707022043 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_pins_cc.pl0000775000177100017500000000303312473477707021671 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ['-cc'], verilator_make_gcc => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_IN8 \(i1,0,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_IN8 \(i8,7,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_IN16 \(i16,15,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_IN \(i32,31,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_IN64 \(i64,63,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_INW \(i65,64,0,3\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_OUT8 \(o1,0,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_OUT8 \(o8,7,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_OUT16\(o16,15,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_OUT \(o32,31,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_OUT64\(o64,63,0\);/x); file_grep ("$Self->{obj_dir}/Vt_var_pins_cc.h", qr/VL_OUTW \(o65,64,0,3\);/x); } ok(1); 1; verilator-3.874/test_regress/t/t_gen_intdot.pl0000775000177100017500000000071712473477707021543 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_pick.pl0000775000177100017500000000072212473477707021344 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_2in.pl0000775000177100017500000000114512473477707020726 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe","$Self->{t_dir}/$Self->{name}.cpp"], vcs_flags2 => ['-assert'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_bad_sv.pl0000775000177100017500000000151712473477707021516 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Error: t/t_var_bad_sv.v:\d+: Unexpected "do": "do" is a SystemVerilog keyword misused as an identifier. %Error: t/t_var_bad_sv.v:\d+: Modify the Verilog-2001 code to avoid SV keywords, or use `begin_keywords or --language. %Error: t/t_var_bad_sv.v:\d+: Unexpected "do": "do" is a SystemVerilog keyword misused as an identifier. .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_dedupe_clk_gate.pl0000775000177100017500000000106712473477707022507 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--stats"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 4); } ok(1); 1; verilator-3.874/test_regress/t/t_mem_multidim_Ox.pl0000775000177100017500000000102612473477707022533 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_mem_multidim.v"); compile ( verilator_flags2 => ['--Ox'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_rand.pl0000775000177100017500000000071712473477707021233 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vpi_memory.cpp0000664000177100017500000001640612525171734021732 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifdef IS_VPI #include "vpi_user.h" #include #else #include "Vt_vpi_memory.h" #include "verilated.h" #include "svdpi.h" #include "Vt_vpi_memory__Dpi.h" #include "verilated_vpi.h" #include "verilated_vpi.cpp" #include "verilated_vcd_c.h" #endif #include #include #include using namespace std; #include "TestSimulator.h" #include "TestVpi.h" // __FILE__ is too long #define FILENM "t_vpi_memory.cpp" #define DEBUG if (0) printf unsigned int main_time = false; //====================================================================== #define CHECK_RESULT_VH(got, exp) \ if ((got) != (exp)) { \ printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \ FILENM,__LINE__, (got), (exp)); \ return __LINE__; \ } #define CHECK_RESULT_NZ(got) \ if (!(got)) { \ printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \ return __LINE__; \ } // Use cout to avoid issues with %d/%lx etc #define CHECK_RESULT(got, exp) \ if ((got != exp)) { \ cout<", (exp)?(exp):""); \ return __LINE__; \ } #define CHECK_RESULT_CSTR_STRIP(got, exp) \ CHECK_RESULT_CSTR(got+strspn(got, " "), exp) int _mon_check_range(TestVpiHandle& handle, int size, int left, int right) { TestVpiHandle iter_h, left_h, right_h; s_vpi_value value = { vpiIntVal }; // check size of object int vpisize = vpi_get(vpiSize, handle); CHECK_RESULT(vpisize, size); // check size of range vpisize = vpi_get(vpiSize, handle); CHECK_RESULT(vpisize, size); // check left hand side of range left_h = vpi_handle(vpiLeftRange, handle); CHECK_RESULT_NZ(left_h); vpi_get_value(left_h, &value); CHECK_RESULT(value.value.integer, left); int coherency = value.value.integer; // check right hand side of range right_h = vpi_handle(vpiRightRange, handle); CHECK_RESULT_NZ(right_h); vpi_get_value(right_h, &value); CHECK_RESULT(value.value.integer, right); coherency -= value.value.integer; // calculate size & check coherency = abs(coherency) + 1; CHECK_RESULT(coherency, size); return 0; // Ok } int _mon_check_memory() { int cnt; TestVpiHandle mem_h, lcl_h; vpiHandle iter_h; // icarus does not like auto free of iterator handles s_vpi_value value = { vpiIntVal }; vpi_printf((PLI_BYTE8*)"Check memory vpi ...\n"); mem_h = vpi_handle_by_name((PLI_BYTE8*)TestSimulator::rooted("mem0"), NULL); CHECK_RESULT_NZ(mem_h); // check type int vpitype = vpi_get(vpiType, mem_h); CHECK_RESULT(vpitype, vpiMemory); if (int status = _mon_check_range(mem_h, 16, 16, 1)) return status; // iterate and store iter_h = vpi_iterate(vpiMemoryWord, mem_h); cnt = 0; while ((lcl_h = vpi_scan(iter_h))) { value.value.integer = ++cnt; vpi_put_value(lcl_h, &value, NULL, vpiNoDelay); // check size and range if (int status = _mon_check_range(lcl_h, 32, 31, 0)) return status; } CHECK_RESULT(cnt, 16); // should be 16 addresses // iterate and accumulate iter_h = vpi_iterate(vpiMemoryWord, mem_h); cnt = 0; while ((lcl_h = vpi_scan(iter_h))) { ++cnt; vpi_get_value(lcl_h, &value); CHECK_RESULT(value.value.integer, cnt); } CHECK_RESULT(cnt, 16); // should be 16 addresses // don't care for non verilator // (crashes on Icarus) if (TestSimulator::is_icarus()) { vpi_printf((PLI_BYTE8*)"Skipping property checks for simulator %s\n", TestSimulator::get_info().product); return 0; // Ok } // make sure trying to get properties that don't exist // doesn't crash int should_be_0 = vpi_get(vpiSize, iter_h); CHECK_RESULT(should_be_0, 0); should_be_0 = vpi_get(vpiIndex, iter_h); CHECK_RESULT(should_be_0, 0); vpiHandle should_be_NULL = vpi_handle(vpiLeftRange, iter_h); CHECK_RESULT(should_be_NULL, 0); should_be_NULL = vpi_handle(vpiRightRange, iter_h); CHECK_RESULT(should_be_NULL, 0); should_be_NULL = vpi_handle(vpiScope, iter_h); CHECK_RESULT(should_be_NULL, 0); return 0; // Ok } int mon_check() { // Callback from initial block in monitor if (int status = _mon_check_memory()) return status; return 0; // Ok } //====================================================================== #ifdef IS_VPI static int mon_check_vpi() { vpiHandle href = vpi_handle(vpiSysTfCall, 0); s_vpi_value vpi_value; vpi_value.format = vpiIntVal; vpi_value.value.integer = mon_check(); vpi_put_value(href, &vpi_value, NULL, vpiNoDelay); return 0; } static s_vpi_systf_data vpi_systf_data[] = { {vpiSysFunc, vpiIntFunc, (PLI_BYTE8*)"$mon_check", (PLI_INT32(*)(PLI_BYTE8*))mon_check_vpi, 0, 0, 0}, 0 }; // cver entry void vpi_compat_bootstrap(void) { p_vpi_systf_data systf_data_p; systf_data_p = &(vpi_systf_data[0]); while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++); } // icarus entry void (*vlog_startup_routines[])() = { vpi_compat_bootstrap, 0 }; #else double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { double sim_time = 1100; Verilated::commandArgs(argc, argv); Verilated::debug(0); Verilated::fatalOnVpiError(0); // we're going to be checking for these errors do don't crash out VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out #ifdef VERILATOR # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif #endif #if VM_TRACE Verilated::traceEverOn(true); VL_PRINTF("Enabling waves...\n"); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_vpi_var/simx.vcd"); #endif topp->eval(); topp->clk = 0; main_time += 10; while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += 1; topp->eval(); VerilatedVpi::callValueCbs(); topp->clk = !topp->clk; //mon_do(); #if VM_TRACE if (tfp) tfp->dump (main_time); #endif } if (!Verilated::gotFinish()) { vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish"); } topp->final(); #if VM_TRACE if (tfp) tfp->close(); #endif delete topp; topp=NULL; exit(0L); } #endif verilator-3.874/test_regress/t/t_inst_prepost.pl0000775000177100017500000000065112473477707022137 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_gen2.pl0000775000177100017500000000072712473477707022265 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_uniqueif_fail4.pl0000775000177100017500000000144012473477707022307 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_uniqueif.v"); compile ( v_flags2 => ['+define+FAILING_ASSERTION4'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], fails => $Self->{nc}, ); execute ( fails => $Self->{vlt}, expect=> '.*%Error: t_uniqueif.v:\d+: Assertion failed in top.v: \'unique if\' statement violated %Error: t/t_uniqueif.v:\d+: Verilog \$stop .*', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_signed3.pl0000775000177100017500000000072212473477707021752 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inside_wild.v0000664000177100017500000000334112473477707021526 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; wire [4:0] in = crc[4:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) logic out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out), // Inputs .clk (clk), .in (in[4:0])); // Aggregate outputs into a single result vector wire [63:0] result = {63'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h7a7bd4ee927e7cc3 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); //bug718 input clk; input logic [4:0] in; output logic out; always @(posedge clk) begin out <= in inside {5'b1_1?1?}; end endmodule // tverilator-3.874/test_regress/t/t_inst_v2k__sub.vi0000664000177100017500000000101312473477707022146 0ustar wsnyderwsnyder// -*- Verilog -*- // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. // This file is named .vi to test +libext+ flags. module t_inst_v2k__sub ( output reg [7:0] osizedreg, output wire oonewire /*verilator public*/, input [7:0] isizedwire, input wire ionewire, output reg [1:0] tied = 2'b10 ); assign oonewire = ionewire; always @* begin osizedreg = isizedwire; end endmodule verilator-3.874/test_regress/t/t_inst_recurse_bad.v0000664000177100017500000000057512473477707022555 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; looped looped (); endmodule module looped (/*AUTOARG*/); looped2 looped2 (); endmodule module looped2 (/*AUTOARG*/); looped looped (); endmodule verilator-3.874/test_regress/t/t_mem_multi_io3.v0000664000177100017500000000305512473477707022000 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013. module t ( input logic clk, input logic daten, input logic [8:0] datval, output logic signed [3:0][3:0][35:0] datao ); logic signed [3:0][3:0][3:0][8:0] datat; genvar i; generate for (i=0; i<4; i++)begin testio dut(.clk(clk), .arr3d_in(datat[i]), .arr2d_out(datao[i])); end endgenerate genvar j; generate for (i=0; i<4; i++) begin for (j=0; j<4; j++) begin always_comb datat[i][j][0] = daten ? 9'h0 : datval; always_comb datat[i][j][1] = daten ? 9'h1 : datval; always_comb datat[i][j][2] = daten ? 9'h2 : datval; always_comb datat[i][j][3] = daten ? 9'h3 : datval; end end endgenerate endmodule module testio ( input clk, input logic signed [3:0] [3:0] [8:0] arr3d_in, output logic signed [3:0] [35:0] arr2d_out ); logic signed [3:0] [35:0] ar2d_out_pre; always_comb ar2d_out_pre[0][35:0] = {arr3d_in[0][0][8:0], arr3d_in[0][1][8:0], arr3d_in[0][2][8:0], arr3d_in[0][3][8:0]}; always_comb ar2d_out_pre[0][35:0] = {arr3d_in[0][0][8:0], arr3d_in[0][1][8:0], arr3d_in[0][2][8:0], arr3d_in[0][3][8:0]}; always_comb ar2d_out_pre[0][35:0] = {arr3d_in[0][0][8:0], arr3d_in[0][1][8:0], arr3d_in[0][2][8:0], arr3d_in[0][3][8:0]}; always_comb ar2d_out_pre[0][35:0] = {arr3d_in[0][0][8:0], arr3d_in[0][1][8:0], arr3d_in[0][2][8:0], arr3d_in[0][3][8:0]}; always_ff @(posedge clk) begin if (clk) arr2d_out <= ar2d_out_pre; end endmodule verilator-3.874/test_regress/t/t_for_count.v0000664000177100017500000000457412473477707021243 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; integer j; reg [63:0] cam_lookup_hit_vector; integer hit_count; always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin hit_count = 0; for (j=0; j < 64; j=j+1) begin hit_count = hit_count + {31'h0, cam_lookup_hit_vector[j]}; end end integer hit_count2; always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin hit_count2 = 0; for (j=63; j >= 0; j=j-1) begin hit_count2 = hit_count2 + {31'h0, cam_lookup_hit_vector[j]}; end end integer hit_count3; always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin hit_count3 = 0; for (j=63; j > 0; j=j-1) begin if (cam_lookup_hit_vector[j]) hit_count3 = hit_count3 + 32'd1; end end reg [127:0] wide_for_index; reg [31:0] wide_for_count; always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin wide_for_count = 0; for (wide_for_index = 128'hff_00000000_00000000; wide_for_index < 128'hff_00000000_00000100; wide_for_index = wide_for_index + 2) begin wide_for_count = wide_for_count+32'h1; end end // While loop integer w; initial begin while (w<10) w=w+1; if (w!=10) $stop; while (w<20) begin w=w+2; end while (w<20) begin w=w+99999; end // NEVER if (w!=20) $stop; end // Do-While loop integer dw; initial begin do dw=dw+1; while (dw<10); if (dw!=10) $stop; do dw=dw+2; while (dw<20); if (dw!=20) $stop; do dw=dw+5; while (dw<20); // Once if (dw!=25) $stop; end always @ (posedge clk) begin cam_lookup_hit_vector <= 0; if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin cam_lookup_hit_vector <= 64'h00010000_00010000; end if (cyc==2) begin if (hit_count != 32'd2) $stop; if (hit_count2 != 32'd2) $stop; if (hit_count3 != 32'd2) $stop; cam_lookup_hit_vector <= 64'h01010010_00010001; end if (cyc==3) begin if (hit_count != 32'd5) $stop; if (hit_count2 != 32'd5) $stop; if (hit_count3 != 32'd4) $stop; if (wide_for_count != 32'h80) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_dpi_context_c.cpp0000664000177100017500000000633312473477707022377 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2009 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include "svdpi.h" //====================================================================== #if defined(VERILATOR) # ifdef T_DPI_CONTEXT_NOOPT # include "Vt_dpi_context_noopt__Dpi.h" # else # include "Vt_dpi_context__Dpi.h" # endif #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef VERILATOR # include "verilated.h" #endif #ifdef NEED_EXTERNS extern "C" { extern int dpic_line(); extern int dpic_save(int value); extern int dpic_restore(); extern unsigned dpic_getcontext(); } #endif //====================================================================== int dpic_line() { svScope scope = svGetScope(); if (!scope) { printf("%%Warning: svGetScope failed\n"); return 0; } #ifdef VERILATOR static int didDump = 0; if (didDump++ == 0) { Verilated::scopesDump(); } #endif const char* scopenamep = svGetNameFromScope(scope); if (!scopenamep) { printf("%%Warning: svGetNameFromScope failed\n"); return 0; } if (scope != svGetScopeFromName(scopenamep)) { printf("%%Warning: svGetScopeFromName repeat failed\n"); return 0; } const char* filenamep = ""; int lineno = 0; if (svGetCallerInfo(&filenamep, &lineno)) { printf("Call from %s:%d:%s\n", filenamep, lineno, scopenamep); } else { printf("%%Warning: svGetCallerInfo failed\n"); return 0; } return lineno; } extern int Dpic_Unique; int Dpic_Unique = 0; // Address used for uniqueness int dpic_save(int value) { svScope scope = svGetScope(); if (!scope) { printf("%%Warning: svGetScope failed\n"); return 0; } // Use union to avoid cast to different size pointer warnings union valpack { void* ptr; int i; } vp; vp.i = value; if (svPutUserData(scope, &Dpic_Unique, vp.ptr)) { printf("%%Warning: svPutUserData failed\n"); return 0; } return 1; } int dpic_restore() { svScope scope = svGetScope(); if (!scope) { printf("%%Warning: svGetScope failed\n"); return 0; } if (void* userp = svGetUserData(scope, (void*)&Dpic_Unique)) { // Use union to avoid cast to different size pointer warnings union valpack { void* ptr; int i; } vp; vp.ptr = userp; return vp.i; } else { printf("%%Warning: svGetUserData failed\n"); return 0; } } unsigned dpic_getcontext() { svScope scope = svGetScope(); printf("%%Info: svGetScope returned scope (%p) with name %s\n", scope, svGetNameFromScope(scope)); return (unsigned) (uintptr_t) scope; } verilator-3.874/test_regress/t/t_math_shift_rep.pl0000775000177100017500000000101612473477707022376 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb -O0'"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_ldflags_so.cpp0000664000177100017500000000134012473477707022654 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* extern "C" { void dpii_so_library() {} }; verilator-3.874/test_regress/t/t_interface2.pl0000775000177100017500000000100312473477707021420 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ["--top-module t"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_order_loop_bad.v0000664000177100017500000000153612473477707022212 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Non-cutable edge in loop // // This code (stripped down from a much larger application) has a loop between // the use of ready in the first two always blocks. However it should // trivially trigger the $write on the first clk posedge. // // This is a regression test against issue 513. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg ready; initial begin ready = 1'b0; end always @(posedge ready) begin if ((ready === 1'b1)) begin $write("*-* All Finished *-*\n"); $finish; end end always @(posedge ready) begin if ((ready === 1'b0)) begin ready = 1'b1 ; end end always @(posedge clk) begin ready = 1'b1; end endmodule verilator-3.874/test_regress/t/t_dpi_shortcircuit.v0000664000177100017500000002052712473477707022617 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. `ifdef VCS `define NO_SHORTREAL `endif `ifdef NC `define NO_SHORTREAL `endif `ifdef VERILATOR // Unsupported `define NO_SHORTREAL `endif module t (/*AUTOARG*/); // Note these are NOT pure. import "DPI-C" function int dpii_clear (); import "DPI-C" function int dpii_count (input int i); import "DPI-C" function bit dpii_inc0 (input int i); import "DPI-C" function bit dpii_inc1 (input int i); import "DPI-C" function bit dpii_incx (input int i, input bit value); // verilator lint_off UNUSED integer i; bit b; // verilator lint_on UNUSED integer errors; task check1(integer line, bit got, bit ex); if (got != ex) begin $display("%%Error: Line %0d: Bad result, got=%0d expect=%0d",line,got,ex); errors++; end endtask task check(integer line, int got, int ex); if (got != ex) begin $display("%%Error: Line %0d: Bad result, got=%0d expect=%0d",line,got,ex); errors++; end endtask // Test loop initial begin // Spec says && || -> and ?: short circuit, no others do. // Check both constant & non constants. dpii_clear(); check1(`__LINE__, (1'b0 && dpii_inc0(0)), 1'b0); check1(`__LINE__, (1'b1 && dpii_inc0(1)), 1'b0); check1(`__LINE__, (dpii_inc0(2) && dpii_inc0(3)), 1'b0); check1(`__LINE__, (dpii_inc1(4) && dpii_inc0(5)), 1'b0); check1(`__LINE__, (dpii_inc0(6) && dpii_inc1(7)), 1'b0); check1(`__LINE__, (!(dpii_inc1(8) && dpii_inc1(9))), 1'b0); check (`__LINE__, dpii_count(0), 0); check (`__LINE__, dpii_count(1), 1); check (`__LINE__, dpii_count(2), 1); check (`__LINE__, dpii_count(3), 0); check (`__LINE__, dpii_count(4), 1); check (`__LINE__, dpii_count(5), 1); check (`__LINE__, dpii_count(6), 1); check (`__LINE__, dpii_count(7), 0); check (`__LINE__, dpii_count(8), 1); check (`__LINE__, dpii_count(9), 1); // dpii_clear(); check1(`__LINE__, (1'b0 & dpii_inc0(0)), 1'b0); check1(`__LINE__, (1'b1 & dpii_inc0(1)), 1'b0); check1(`__LINE__, (dpii_inc0(2) & dpii_inc0(3)), 1'b0); check1(`__LINE__, (dpii_inc1(4) & dpii_inc0(5)), 1'b0); check1(`__LINE__, (dpii_inc0(6) & dpii_inc1(7)), 1'b0); check1(`__LINE__, (!(dpii_inc1(8) & dpii_inc1(9))), 1'b0); check (`__LINE__, dpii_count(0), 1); check (`__LINE__, dpii_count(1), 1); check (`__LINE__, dpii_count(2), 1); check (`__LINE__, dpii_count(3), 1); check (`__LINE__, dpii_count(4), 1); check (`__LINE__, dpii_count(5), 1); check (`__LINE__, dpii_count(6), 1); check (`__LINE__, dpii_count(7), 1); check (`__LINE__, dpii_count(8), 1); check (`__LINE__, dpii_count(9), 1); // dpii_clear(); check1(`__LINE__, (1'b0 || dpii_inc0(0)), 1'b0); check1(`__LINE__, (1'b1 || dpii_inc0(1)), 1'b1); check1(`__LINE__, (dpii_inc0(2) || dpii_inc0(3)), 1'b0); check1(`__LINE__, (dpii_inc1(4) || dpii_inc0(5)), 1'b1); check1(`__LINE__, (dpii_inc0(6) || dpii_inc1(7)), 1'b1); check1(`__LINE__, (!(dpii_inc1(8) || dpii_inc1(9))), 1'b0); check (`__LINE__, dpii_count(0), 1); check (`__LINE__, dpii_count(1), 0); check (`__LINE__, dpii_count(2), 1); check (`__LINE__, dpii_count(3), 1); check (`__LINE__, dpii_count(4), 1); check (`__LINE__, dpii_count(5), 0); check (`__LINE__, dpii_count(6), 1); check (`__LINE__, dpii_count(7), 1); check (`__LINE__, dpii_count(8), 1); check (`__LINE__, dpii_count(9), 0); // dpii_clear(); check1(`__LINE__, (1'b0 | dpii_inc0(0)), 1'b0); check1(`__LINE__, (1'b1 | dpii_inc0(1)), 1'b1); check1(`__LINE__, (dpii_inc0(2) | dpii_inc0(3)), 1'b0); check1(`__LINE__, (dpii_inc1(4) | dpii_inc0(5)), 1'b1); check1(`__LINE__, (dpii_inc0(6) | dpii_inc1(7)), 1'b1); check1(`__LINE__, (!(dpii_inc1(8) | dpii_inc1(9))), 1'b0); check (`__LINE__, dpii_count(0), 1); check (`__LINE__, dpii_count(1), 1); check (`__LINE__, dpii_count(2), 1); check (`__LINE__, dpii_count(3), 1); check (`__LINE__, dpii_count(4), 1); check (`__LINE__, dpii_count(5), 1); check (`__LINE__, dpii_count(6), 1); check (`__LINE__, dpii_count(7), 1); check (`__LINE__, dpii_count(8), 1); check (`__LINE__, dpii_count(9), 1); // dpii_clear(); check1(`__LINE__, (1'b0 -> dpii_inc0(0)), 1'b1); check1(`__LINE__, (1'b1 -> dpii_inc0(1)), 1'b0); check1(`__LINE__, (dpii_inc0(2) -> dpii_inc0(3)), 1'b1); check1(`__LINE__, (dpii_inc1(4) -> dpii_inc0(5)), 1'b0); check1(`__LINE__, (dpii_inc0(6) -> dpii_inc1(7)), 1'b1); check1(`__LINE__, (!(dpii_inc1(8) -> dpii_inc1(9))), 1'b0); check (`__LINE__, dpii_count(0), 0); check (`__LINE__, dpii_count(1), 1); check (`__LINE__, dpii_count(2), 1); check (`__LINE__, dpii_count(3), 0); check (`__LINE__, dpii_count(4), 1); check (`__LINE__, dpii_count(5), 1); check (`__LINE__, dpii_count(6), 1); check (`__LINE__, dpii_count(7), 0); check (`__LINE__, dpii_count(8), 1); check (`__LINE__, dpii_count(9), 1); // dpii_clear(); check1(`__LINE__, (1'b0 ? dpii_inc0(0) : dpii_inc0(1)), 1'b0); check1(`__LINE__, (1'b1 ? dpii_inc0(2) : dpii_inc0(3)), 1'b0); check1(`__LINE__, (dpii_inc0(4) ? dpii_inc0(5) : dpii_inc0(6)), 1'b0); check1(`__LINE__, (dpii_inc1(7) ? dpii_inc0(8) : dpii_inc0(9)), 1'b0); check (`__LINE__, dpii_count(0), 0); check (`__LINE__, dpii_count(1), 1); check (`__LINE__, dpii_count(2), 1); check (`__LINE__, dpii_count(3), 0); check (`__LINE__, dpii_count(4), 1); check (`__LINE__, dpii_count(5), 0); check (`__LINE__, dpii_count(6), 1); check (`__LINE__, dpii_count(7), 1); check (`__LINE__, dpii_count(8), 1); check (`__LINE__, dpii_count(9), 0); // dpii_clear(); check1(`__LINE__, (1'b0 * dpii_inc0(0)), 1'b0); check1(`__LINE__, (1'b1 * dpii_inc0(1)), 1'b0); check1(`__LINE__, (dpii_inc0(2) * dpii_inc0(3)), 1'b0); check1(`__LINE__, (dpii_inc1(4) * dpii_inc0(5)), 1'b0); check1(`__LINE__, (dpii_inc0(6) * dpii_inc1(7)), 1'b0); check1(`__LINE__, (!(dpii_inc1(8) * dpii_inc1(9))), 1'b0); check (`__LINE__, dpii_count(0), 1); check (`__LINE__, dpii_count(1), 1); check (`__LINE__, dpii_count(2), 1); check (`__LINE__, dpii_count(3), 1); check (`__LINE__, dpii_count(4), 1); check (`__LINE__, dpii_count(5), 1); check (`__LINE__, dpii_count(6), 1); check (`__LINE__, dpii_count(7), 1); check (`__LINE__, dpii_count(8), 1); check (`__LINE__, dpii_count(9), 1); // dpii_clear(); check1(`__LINE__, (1'b0 + dpii_inc0(0)), 1'b0); check1(`__LINE__, (1'b1 + dpii_inc0(1)), 1'b1); check1(`__LINE__, (dpii_inc0(2) + dpii_inc0(3)), 1'b0); check1(`__LINE__, (dpii_inc1(4) + dpii_inc0(5)), 1'b1); check1(`__LINE__, (dpii_inc0(6) + dpii_inc1(7)), 1'b1); check1(`__LINE__, (dpii_inc1(8) + dpii_inc1(9)), 1'b0); check (`__LINE__, dpii_count(0), 1); check (`__LINE__, dpii_count(1), 1); check (`__LINE__, dpii_count(2), 1); check (`__LINE__, dpii_count(3), 1); check (`__LINE__, dpii_count(4), 1); check (`__LINE__, dpii_count(5), 1); check (`__LINE__, dpii_count(6), 1); check (`__LINE__, dpii_count(7), 1); check (`__LINE__, dpii_count(8), 1); check (`__LINE__, dpii_count(9), 1); // // Something a lot more complicated dpii_clear(); for (i=0; i<64; i++) begin b = ( ((dpii_incx(0,i[0]) && (dpii_incx(1,i[1]) || dpii_incx(2,i[2]) | dpii_incx(3,i[3]))) // | not || || dpii_incx(4,i[4])) -> dpii_incx(5,i[5])); end check (`__LINE__, dpii_count(0), 64); check (`__LINE__, dpii_count(1), 32); check (`__LINE__, dpii_count(2), 16); check (`__LINE__, dpii_count(3), 16); check (`__LINE__, dpii_count(4), 36); check (`__LINE__, dpii_count(5), 46); if (|errors) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_attr_parenstar.v0000664000177100017500000000133412473477707022265 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; always @(*) begin if (clk) begin end end always @(* ) begin if (clk) begin end end // Not legal in some simulators, legal in others // always @(* /*cmt*/ ) begin // if (clk) begin end // end // Not legal in some simulators, legal in others // always @(* // cmt // ) begin // if (clk) begin end // end always @ (* ) begin if (clk) begin end end initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_tri_pullup.v0000664000177100017500000000106512473477707021434 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks module top (input A, input OE, output X, output Y, output Z); pullup p1(Z); assign Z = OE ? A : 1'bz; pulldown p2(Y); assign Y = OE ? A : 1'bz; pass pass(.A(A), .OE(OE), .X(X)); pullup_module p(X); endmodule module pass (input A, input OE, inout X); io io(.A(A), .OE(OE), .X(X)); endmodule module io (input A, input OE, inout X); assign X = (OE) ? A : 1'bz; endmodule module pullup_module (output X); pullup p1(X); endmodule verilator-3.874/test_regress/t/t_vpi_unimpl.pl0000775000177100017500000000113712473477707021570 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --no-l2name $Self->{t_dir}/t_vpi_unimpl.cpp"], ); execute ( check_finished=>1 ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_multi_ref_bad.v0000664000177100017500000000140412473477707022664 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/); reg dimn; reg [1:0] dim0; reg [1:0] dim1 [1:0]; reg [1:0] dim2 [1:0][1:0]; reg dim0nv[1:0]; initial begin dimn[1:0] = 0; // Bad: Not ranged dim0[1][1] = 0; // Bad: Not arrayed dim1[1][1][1] = 0; // Bad: Not arrayed to right depth dim2[1][1][1] = 0; // OK dim2[0 +: 1][1] = 0; // Bad: Range on non-bits dim2[1 : 0][1] = 0; // Bad: Range on non-bits dim2[1][1:0] = 0; // Bad: Bitsel too soon dim0nv[1:0] = 0; // Bad: Not vectored dim0nv[1][1] = 0; // Bad: Not arrayed to right depth end endmodule verilator-3.874/test_regress/t/t_typedef.pl0000775000177100017500000000071712473477707021051 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_assert_synth_off.pl0000775000177100017500000000121012473477707022756 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_assert_synth.v"); compile ( v_flags2 => ['+define+FAILING_FULL', '+define+FAILING_PARALLEL', '+define+FAILING_OH', '+define+FAILING_OC', ], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_tie_bad.v0000664000177100017500000000054012473477707021634 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/); initial begin func(0, 1'b1); end function automatic int func ( input int a, output bit b ); return 0; endfunction endmodule verilator-3.874/test_regress/t/t_gen_index.pl0000775000177100017500000000101112473477707021335 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug517"); # Compile time only test compile ( ); ok(1); 1; verilator-3.874/test_regress/t/t_emit_constw.v0000664000177100017500000000335112473477707021570 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; reg [2*32-1:0] w2; initial w2 = {2 {32'h12345678}}; reg [9*32-1:0] w9; initial w9 = {9 {32'h12345678}}; reg [10*32-1:0] w10; initial w10 = {10{32'h12345678}}; reg [11*32-1:0] w11; initial w11 = {11{32'h12345678}}; reg [15*32-1:0] w15; initial w15 = {15{32'h12345678}}; reg [31*32-1:0] w31; initial w31 = {31{32'h12345678}}; reg [47*32-1:0] w47; initial w47 = {47{32'h12345678}}; reg [63*32-1:0] w63; initial w63 = {63{32'h12345678}}; // Aggregate outputs into a single result vector wire [63:0] result = (w2[63:0] ^ w9[64:1] ^ w10[65:2] ^ w11[66:3] ^ w15[67:4] ^ w31[68:5] ^ w47[69:6] ^ w63[70:7]); // What checksum will we end up with `define EXPECTED_SUM 64'h184cb39122d8c6e3 // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin w2 <= w2 >> 1; w9 <= w9 >> 1; w10 <= w10 >> 1; w11 <= w11 >> 1; w15 <= w15 >> 1; w31 <= w31 >> 1; w47 <= w47 >> 1; w63 <= w63 >> 1; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_clocker.pl0000775000177100017500000000077612525171734021025 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( # verilator_flags2 => ["-Wno-UNOPTFLAT"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sv_conditional.pl0000775000177100017500000000072212473477707022420 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_public.v0000664000177100017500000000137712473477707021701 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. //bug505 module t (/*AUTOARG*/ // Inputs clk ); input clk; a #(1) a1 (); b #(2) b2 (); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule module a; parameter ONE /*verilator public*/ = 22; initial if (ONE != 1) $stop; `ifdef VERILATOR initial if ($c32("ONE") != 1) $stop; `endif endmodule module b #( parameter TWO /*verilator public*/ = 22 ); initial if (TWO != 2) $stop; `ifdef VERILATOR initial if ($c32("TWO") != 2) $stop; `endif endmodule //bug804 package p; localparam INPACK /*verilator public*/ = 6; endpackage verilator-3.874/test_regress/t/t_preproc_def09.out0000664000177100017500000000255212473477707022242 0ustar wsnyderwsnyder`line 1 "t/t_preproc_def09.v" 1 `line 3 "t/t_preproc_def09.v" 0 `line 8 "t/t_preproc_def09.v" 0 'initial $display("start", "msg1" , "msg2", "end");' 'initial $display("start", "msg1" , "msg2" , "end");' 'initial $display("start", " msg1" , , "end");' 'initial $display("start", " msg1" , , "end");' 'initial $display("start", , "msg2 ", "end");' 'initial $display("start", , "msg2 ", "end");' 'initial $display("start", , , "end");' 'initial $display("start", , , "end");' 'initial $display("start", , , "end");' 'initial $display("start", , , "end");' `line 25 "t/t_preproc_def09.v" 0 '$display(5,,2,,3);' '$display(5,,2,,3);' '$display(1,,"B",,3);' '$display(1 ,,"B",,3 );' '$display(5,,2,,);' '$display(5,,2,,);' `line 35 "t/t_preproc_def09.v" 0 '$display(1,,,,3);' '$display(5,,,,"C");' '$display(5,,2,,"C");' '$display(5,,2,,"C");' '$display(5,,2,,"C");' '$display(5,,2,,"C");' `line 43 "t/t_preproc_def09.v" 0 '$display(1,,0,,"C");' '$display(1 ,,0,,"C");' '$display(5,,0,,"C");' '$display(5,,0,,"C");' `line 50 "t/t_preproc_def09.v" 0 'b + 1 + 42 + a' 'b + 1 + 42 + a' `line 54 "t/t_preproc_def09.v" 0 '"==)" "((((" () '; '"==)" "((((" () '; `line 59 "t/t_preproc_def09.v" 0 `line 70 "t/t_preproc_def09.v" 0 '(6) (eq=al) ZOT' HERE-71 - Line71 `line 73 "t/t_preproc_def09.v" 0 `line 75 "t/t_preproc_def09.v" 2 verilator-3.874/test_regress/t/t_package_dimport.pl0000775000177100017500000000066712473477707022546 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); # Compile only ok(1); 1; verilator-3.874/test_regress/t/t_var_static.pl0000775000177100017500000000103112525171734021523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug546"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_tree_inl1_pub1.pl0000775000177100017500000000112512473477707023251 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_tree.v"); compile ( v_flags2 => ['+define+USE_INLINE', '+define+USE_PUBLIC'], ); execute ( check_finished=>1, expect=> '\] (%m|.*v\.ps): Clocked ', ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_skipidentical.pl0000775000177100017500000000170712473477707023225 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); { compile (); my $outfile = "$Self->{obj_dir}/V".$Self->{name}.".cpp"; my @oldstats = stat($outfile); print "Old mtime=",$oldstats[9],"\n"; $oldstats[9] or $Self->error("No output file found: $outfile\n"); sleep (1); # Or else it might take < 1 second to compile and see no diff. compile (); my @newstats = stat($outfile); print "New mtime=",$newstats[9],"\n"; ($oldstats[9] == $newstats[9]) or $Self->error("--skip-identical was ignored -- recompiled\n"); } ok(1); 1; verilator-3.874/test_regress/t/t_alw_combdly.v0000664000177100017500000000244112473477707021530 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [31:0] a, b, c, d, e, f, g, h; always @ (*) begin // Test Verilog 2001 (*) // verilator lint_off COMBDLY c <= a | b; // verilator lint_on COMBDLY end always @ (posedge (clk)) begin // always bug 2008/4/18 d <= a | b; end always @ ((d)) begin // always bug 2008/4/18 e = d; end parameter CONSTANT = 1; always @ (e, 1'b0, CONSTANT) begin // not technically legal, see bug412 f = e; end always @ (1'b0, CONSTANT, f) begin // not technically legal, see bug412 g = f; end always @ ({CONSTANT, g}) begin // bug745 h = g; end //always @ ((posedge b) or (a or b)) begin // note both illegal always @ (posedge clk) begin if (cyc!=0) begin cyc<=cyc+1; if (cyc==1) begin a <= 32'hfeed0000; b <= 32'h0000face; end if (cyc==2) begin if (c != 32'hfeedface) $stop; end if (cyc==3) begin if (h != 32'hfeedface) $stop; end if (cyc==7) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_func_gen.pl0000775000177100017500000000071712473477707021175 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_x_bad.v0000664000177100017500000000064712473477707021312 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005-2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs value ); input [3:0] value; always @ (/*AS*/value) begin casex (value) default: $stop; endcase case (value) 4'b0000: $stop; 4'b1xxx: $stop; default: $stop; endcase end endmodule verilator-3.874/test_regress/t/t_lint_incabspath_bad.pl0000775000177100017500000000157112473477707023360 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. top_filename("t/t_lint_incabspath.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning-INCABSPATH: t/t_lint_incabspath.v:\d+: Suggest `include with absolute path be made relative, and use \+include: /dev/null %Warning-INCABSPATH: Use .* to disable this message. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_svl2.v0000664000177100017500000000155112473477707021134 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin // New number format if ('0 !== {66{1'b0}}) $stop; if ('1 !== {66{1'b1}}) $stop; if ('x !== {66{1'bx}}) $stop; if ('z !== {66{1'bz}}) $stop; `ifndef NC // NC-Verilog 5.50-s09 chokes on this test if ("\v" != 8'd11) $stop; if ("\f" != 8'd12) $stop; if ("\a" != 8'd7) $stop; if ("\x9a" != 8'h9a) $stop; if ("\xf1" != 8'hf1) $stop; `endif end if (cyc==8) begin end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_var_in_assign.v0000664000177100017500000000252712473477707022063 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; integer v; reg i; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire oa; // From a of a.v wire oz; // From z of z.v // End of automatics a a (.*); z z (.*); always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d i=%x oa=%x oz=%x\n",$time, cyc, i, oa, oz); `endif cyc <= cyc + 1; i <= cyc[0]; if (cyc==0) begin v = 3; if (v !== 3) $stop; if (assignin(v) !== 2) $stop; if (v !== 3) $stop; // Make sure V didn't get changed end else if (cyc<10) begin if (cyc==11 && oz!==1'b0) $stop; if (cyc==12 && oz!==1'b1) $stop; if (cyc==12 && oa!==1'b1) $stop; end else if (cyc<90) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end function integer assignin(input integer i); i = 2; assignin = i; endfunction endmodule module a (input i, output oa); // verilator lint_off ASSIGNIN assign i = 1'b1; assign oa = i; endmodule module z (input i, output oz); assign oz = i; endmodule verilator-3.874/test_regress/t/t_lint_once_bad.pl0000775000177100017500000000153612473477707022171 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--lint-only -Wwarn-UNUSED"], verilator_make_gcc => 0, fails=>1, expect=> '%Warning-UNUSED: t/t_lint_once_bad.v:\d+: Signal is not driven, nor used: unus1 %Warning-UNUSED: Use .* to disable this message. %Warning-UNUSED: t/t_lint_once_bad.v:\d+: Signal is not driven, nor used: unus2 %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_select_little.pl0000775000177100017500000000071712473477707022245 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_order_quad.v0000664000177100017500000000070712473477707021364 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. //bug 762 module t(a0, y); input [3:0] a0; output [44:0] y; assign y[40] = 0; assign y[30] = 0; // verilator lint_off UNOPTFLAT assign { y[44:41], y[39:31], y[29:0] } = { 6'b000000, a0, 7'b0000000, y[40], y[30], y[30], y[30], y[30], 21'b000000000000000000000 }; endmodule verilator-3.874/test_regress/t/t_pp_dupdef_bad.pl0000775000177100017500000000200512473477707022155 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. top_filename("t/t_pp_dupdef.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Warning-REDEFMACRO: t/t_pp_dupdef.v:\d+: Redefining existing define: DUP, with different value: barney %Warning-REDEFMACRO: Use .* to disable this message. %Warning-REDEFMACRO: t/t_pp_dupdef.v:\d+: Previous definition is here, with value: fred %Warning-REDEFMACRO: t/t_pp_dupdef.v:\d+: Redefining existing define: DUPP, with different value: .* %Warning-REDEFMACRO: t/t_pp_dupdef.v:\d+: Previous definition is here, with value: .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_cellarray.v0000664000177100017500000000423412473477707021214 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jie Xu. // // change these two parameters to see the speed differences `define DATA_WIDTH 8 `define REP_COUNT4 `DATA_WIDTH/4 `define REP_COUNT2 `DATA_WIDTH/2 module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [3:0] count4 = 0; reg [1:0] count2 = 0; reg [`DATA_WIDTH-1:0] a = {`REP_COUNT4{4'b0000}}; reg [`DATA_WIDTH-1:0] b = {`REP_COUNT4{4'b1111}}; reg [`DATA_WIDTH-1:0] c = {`REP_COUNT4{4'b1111}}; reg [`DATA_WIDTH-1:0] d = {`REP_COUNT4{4'b1111}}; reg [`DATA_WIDTH-1:0] res1; reg [`DATA_WIDTH-1:0] res2; reg [`DATA_WIDTH-1:0] res3; reg [`DATA_WIDTH-1:0] res4; drv1 t_drv1 [`DATA_WIDTH-1:0] (.colSelA(a), .datao(res1)); drv2 t_drv2 [`DATA_WIDTH-1:0] (.colSelA(a), .colSelB(b), .datao(res2)); drv3 t_drv3 [`DATA_WIDTH-1:0] (.colSelA(a), .colSelB(b), .colSelC(c), .datao(res3)); drv4 t_drv4 [`DATA_WIDTH-1:0] (.colSelA(a), .colSelB(b), .colSelC(c), .colSelD(d), .datao(res4)); always@(posedge clk) begin count2 <= count2 + 1; count4 <= count4 + 1; a <= {`REP_COUNT4{count4}}; b <= {`REP_COUNT4{count4}}; c <= {`REP_COUNT2{count2}}; d <= {`REP_COUNT2{count2}}; if (res1 != (a)) begin $stop; end if (res2 != (a&b)) begin $stop; end if (res3 != (a&b&c)) begin $stop; end if (res4 != (a&b&c&d)) begin $stop; end if (count4 > 10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module drv1 (input colSelA, output datao ); assign datao = colSelA; endmodule module drv2 (input colSelA, input colSelB, output datao ); assign datao = colSelB & colSelA; endmodule module drv3 (input colSelA, input colSelB, input colSelC, output datao ); assign datao = colSelB & colSelA & colSelC; endmodule module drv4 (input colSelA, input colSelB, input colSelC, input colSelD, output datao ); assign datao = colSelB & colSelA & colSelC & colSelD; endmodule verilator-3.874/test_regress/t/t_tri_pull2_bad.pl0000775000177100017500000000116312473477707022127 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( fails=>$Self->{v3}, expect=> '%Error: t/t_tri_pull2_bad.v:\d+: Unsupported: Conflicting pull directions. %Error: t/t_tri_pull2_bad.v:\d+: ... Location of conflicting pull. %Error: Exiting due to', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_vliw.pl0000775000177100017500000000071712473477707021403 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_hierarchy_unnamed.v0000664000177100017500000000062312473477707022721 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Chandan Egbert. module sub(); endmodule module t(input logic a, input logic b, output logic x, output logic y); always_comb begin integer i; x = a; end sub u0(); always_comb begin integer j; y = b; end endmodule verilator-3.874/test_regress/t/t_math_div0.pl0000775000177100017500000000074512473477707021265 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ['--x-assign 0'], ); execute ( ); ok(1); 1; verilator-3.874/test_regress/t/t_param_bit_sel.pl0000775000177100017500000000072212473477707022206 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_realcvt_bad.v0000664000177100017500000000035412473477707022531 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module sub; integer i; initial begin i = 23.2; end endmodule verilator-3.874/test_regress/t/t_func_numones.v0000664000177100017500000000202012473477707021724 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (clk); input clk; reg [31:0] r32; wire [3:0] w4; wire [4:0] w5; assign w4 = NUMONES_8 ( r32[7:0] ); assign w5 = NUMONES_16( r32[15:0] ); function [3:0] NUMONES_8; input [7:0] i8; reg [7:0] i8; begin NUMONES_8 = 4'b1; end endfunction // NUMONES_8 function [4:0] NUMONES_16; input [15:0] i16; reg [15:0] i16; begin NUMONES_16 = ( NUMONES_8( i16[7:0] ) + NUMONES_8( i16[15:8] )); end endfunction integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin r32 <= 32'h12345678; end if (cyc==2) begin if (w4 !== 1) $stop; if (w5 !== 2) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_inst_dtree_inlc.pl0000775000177100017500000000107712473477707022556 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_dtree.v"); compile ( v_flags2 => ['+define+INLINE_C'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_dtree_inlac.pl0000775000177100017500000000112012473477707022704 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_dtree.v"); compile ( v_flags2 => ['+define+INLINE_A +define+INLINE_C'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_preproc_undefineall.pl0000775000177100017500000000111512473477707023422 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ['+define+PREDEF_COMMAND_LINE'], verilator_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface1_modport.v0000664000177100017500000000176612525171734023017 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // Very simple test for interface pathclearing interface ifc; integer hidden_from_isub; integer value; modport out_modport (output value); endinterface module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc itop(); sub c1 (.isub(itop), .i_value(4)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==20) begin if (itop.value != 4) $stop; itop.hidden_from_isub = 20; if (itop.hidden_from_isub != 20) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub `ifdef NANSI // bug868 ( isub, i_value ); ifc.out_modport isub; // Note parenthesis are not legal here input integer i_value; `else ( ifc.out_modport isub, input integer i_value ); `endif always @* begin isub.value = i_value; end endmodule verilator-3.874/test_regress/t/t_param_public.cpp0000664000177100017500000000103212473477707022202 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. #include #include "Vt_param_public.h" #include "Vt_param_public_p.h" int main (int argc, char *argv[]) { Vt_param_public *topp = new Vt_param_public; Verilated::debug(0); // Make sure public tag worked if (Vt_param_public_p::INPACK) {} for (int i = 0; i < 10; i++) { topp->eval(); } } verilator-3.874/test_regress/t/t_mem_fifo.pl0000775000177100017500000000071712473477707021172 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_precedence.v0000664000177100017500000001060412473477707022342 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; wire [1:0] a = crc[1 +: 2]; wire [1:0] b = crc[3 +: 2]; wire [1:0] c = crc[5 +: 2]; wire [1:0] d = crc[7 +: 2]; wire [1:0] e = crc[9 +: 2]; wire [1:0] f = crc[11+: 2]; wire [1:0] g = crc[13+: 2]; // left () [] :: . // unary + - ! ~ & ~& | ~| ^ ~^ ^~ ++ -- (unary) // left ** // left * / % // left + - (binary) // left << >> <<< >>> // left < <= > >= inside dist // left == != === !== ==? !=? // left & (binary) // left ^ ~^ ^~ (binary) // left | (binary) // left && // left || // left ? : // right -> // none = += -= *= /= %= &= ^= |= <<= >>= <<<= >>>= := :/ <= // {} {{}} concatenation wire [1:0] bnz = (b==2'b0) ? 2'b11 : b; wire [1:0] cnz = (c==2'b0) ? 2'b11 : c; wire [1:0] dnz = (d==2'b0) ? 2'b11 : d; wire [1:0] enz = (e==2'b0) ? 2'b11 : e; // verilator lint_off WIDTH // Do a few in each group wire [1:0] o1 = ~ a; // Can't get more than one reduction to parse wire [1:0] o2 = ^ b; // Can't get more than one reduction to parse wire [1:0] o3 = a ** b ** c; // Some simulators botch this wire [1:0] o4 = a * b / cnz % dnz * enz; wire [1:0] o5 = a + b - c + d; wire [1:0] o6 = a << b >> c <<< d >>> e <<< f; wire [1:0] o7 = a < b <= c; wire [1:0] o8 = a == b != c === d == e; wire [1:0] o9 = a & b & c; wire [1:0] o10 = a ^ b ~^ c ^~ d ^ a; wire [1:0] o11 = a | b | c; wire [1:0] o12 = a && b && c; wire [1:0] o13 = a || b || c; wire [1:0] o14 = a ? b ? c : d : e; wire [1:0] o15 = a ? b : c ? d : e; // Now cross each pair of groups wire [1:0] x1 = ~ a ** ~ b ** ~c; // Some simulators botch this wire [1:0] x2 = a ** b * c ** d; // Some simulators botch this wire [1:0] x3 = a + b * c + d; wire [1:0] x4 = a + b << c + d; wire [1:0] x5 = a == b << c == d; wire [1:0] x6 = a & b << c & d; wire [1:0] x7 = a ^ b & c ^ d; wire [1:0] x8 = a | b ^ c | d; wire [1:0] x9 = a && b | c && d; wire [1:0] x10 = a || b && c || d; wire [1:0] x11 = a ? b || c : d ? e : f; // verilator lint_on WIDTH function [1:0] pow (input [1:0] x, input [1:0] y); casez ({x,y}) 4'b00_??: pow = 2'b00; 4'b01_00: pow = 2'b01; 4'b01_01: pow = 2'b01; 4'b01_10: pow = 2'b01; 4'b01_11: pow = 2'b01; 4'b10_00: pow = 2'b01; 4'b10_01: pow = 2'b10; 4'b10_10: pow = 2'b00; 4'b10_11: pow = 2'b00; 4'b11_00: pow = 2'b01; 4'b11_01: pow = 2'b11; 4'b11_10: pow = 2'b01; 4'b11_11: pow = 2'b11; endcase endfunction // Aggregate outputs into a single result vector wire [63:0] result = {12'h0, x11,x10,x9,x8,x7,x6,x5,x4,x3,x2,x1, o15,o14,o13,o12,o11,o10,o9,o8,o7,o6,o5,o4,o3,o2,o1}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x ",$time, cyc, crc, result); $write(" %b",o1); $write(" %b",o2); $write(" %b",o3); $write(" %b",o4); $write(" %b",o5); $write(" %b",o6); $write(" %b",o7); $write(" %b",o8); $write(" %b",o9); $write(" %b",o10); $write(" %b",o11); $write(" %b",o12); $write(" %b",o13); $write(" %b",o14); $write(" %b",o15); // Now cross each pair of groups $write(" %b",x1); $write(" %b",x2); $write(" %b",x3); $write(" %b",x4); $write(" %b",x5); $write(" %b",x6); $write(" %b",x7); $write(" %b",x8); $write(" %b",x9); $write(" %b",x10); $write(" %b",x11); $write("\n"); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h2756ea365ec7520e if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_bitsel_struct3.pl0000775000177100017500000000072212473477707022356 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_array_packed_write_read.v0000664000177100017500000002350712473477707024074 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; // parameters for array sizes localparam WA = 8; // address dimension size localparam WB = 8; // bit dimension size localparam NO = 10; // number of access events // 2D packed arrays logic [WA-1:0] [WB-1:0] array_bg; // big endian array /* verilator lint_off LITENDIAN */ logic [0:WA-1] [0:WB-1] array_lt; // little endian array /* verilator lint_on LITENDIAN */ integer cnt = 0; // msg926 logic [3:0][31:0] packedArray; initial packedArray <= '0; // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if ((cnt[30:2]==NO) && (cnt[1:0]==2'd0)) begin $write("*-* All Finished *-*\n"); $finish; end // big endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaaults (all bits to 0) if (cnt[30:2]==0) array_bg <= '0; else if (cnt[30:2]==1) array_bg <= '0; else if (cnt[30:2]==2) array_bg <= '0; else if (cnt[30:2]==3) array_bg <= '0; else if (cnt[30:2]==4) array_bg <= '0; else if (cnt[30:2]==5) array_bg <= '0; else if (cnt[30:2]==6) array_bg <= '0; else if (cnt[30:2]==7) array_bg <= '0; else if (cnt[30:2]==8) array_bg <= '0; else if (cnt[30:2]==9) array_bg <= '0; end else if (cnt[1:0]==2'd1) begin // write value to array if (cnt[30:2]==0) begin end else if (cnt[30:2]==1) array_bg <= {WA *WB +0{1'b1}}; else if (cnt[30:2]==2) array_bg [WA/2-1:0 ] <= {WA/2*WB +0{1'b1}}; else if (cnt[30:2]==3) array_bg [WA -1:WA/2] <= {WA/2*WB +0{1'b1}}; else if (cnt[30:2]==4) array_bg [ 0 ] <= {1 *WB +0{1'b1}}; else if (cnt[30:2]==5) array_bg [WA -1 ] <= {1 *WB +0{1'b1}}; else if (cnt[30:2]==6) array_bg [ 0 ][WB/2-1:0 ] <= {1 *WB/2+0{1'b1}}; else if (cnt[30:2]==7) array_bg [WA -1 ][WB -1:WB/2] <= {1 *WB/2+0{1'b1}}; else if (cnt[30:2]==8) array_bg [ 0 ][ 0 ] <= {1 *1 +0{1'b1}}; else if (cnt[30:2]==9) array_bg [WA -1 ][WB -1 ] <= {1 *1 +0{1'b1}}; end else if (cnt[1:0]==2'd2) begin // check array value if (cnt[30:2]==0) begin if (array_bg !== 64'b0000000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==1) begin if (array_bg !== 64'b1111111111111111111111111111111111111111111111111111111111111111) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==2) begin if (array_bg !== 64'b0000000000000000000000000000000011111111111111111111111111111111) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==3) begin if (array_bg !== 64'b1111111111111111111111111111111100000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==4) begin if (array_bg !== 64'b0000000000000000000000000000000000000000000000000000000011111111) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==5) begin if (array_bg !== 64'b1111111100000000000000000000000000000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==6) begin if (array_bg !== 64'b0000000000000000000000000000000000000000000000000000000000001111) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==7) begin if (array_bg !== 64'b1111000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==8) begin if (array_bg !== 64'b0000000000000000000000000000000000000000000000000000000000000001) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]==9) begin if (array_bg !== 64'b1000000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_bg); $stop(); end end end else if (cnt[1:0]==2'd3) begin // read value from array (not a very good test for now) if (cnt[30:2]==0) begin if (array_bg !== {WA *WB {1'b0}}) $stop(); end else if (cnt[30:2]==1) begin if (array_bg !== {WA *WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==2) begin if (array_bg [WA/2-1:0 ] !== {WA/2*WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==3) begin if (array_bg [WA -1:WA/2] !== {WA/2*WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==4) begin if (array_bg [ 0 ] !== {1 *WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==5) begin if (array_bg [WA -1 ] !== {1 *WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==6) begin if (array_bg [ 0 ][WB/2-1:0 ] !== {1 *WB/2+0{1'b1}}) $stop(); end else if (cnt[30:2]==7) begin if (array_bg [WA -1 ][WB -1:WB/2] !== {1 *WB/2+0{1'b1}}) $stop(); end else if (cnt[30:2]==8) begin if (array_bg [ 0 ][ 0 ] !== {1 *1 +0{1'b1}}) $stop(); end else if (cnt[30:2]==9) begin if (array_bg [WA -1 ][WB -1 ] !== {1 *1 +0{1'b1}}) $stop(); end end // little endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaaults (all bits to 0) if (cnt[30:2]==0) array_lt <= '0; else if (cnt[30:2]==1) array_lt <= '0; else if (cnt[30:2]==2) array_lt <= '0; else if (cnt[30:2]==3) array_lt <= '0; else if (cnt[30:2]==4) array_lt <= '0; else if (cnt[30:2]==5) array_lt <= '0; else if (cnt[30:2]==6) array_lt <= '0; else if (cnt[30:2]==7) array_lt <= '0; else if (cnt[30:2]==8) array_lt <= '0; else if (cnt[30:2]==9) array_lt <= '0; end else if (cnt[1:0]==2'd1) begin // write value to array if (cnt[30:2]==0) begin end else if (cnt[30:2]==1) array_lt <= {WA *WB +0{1'b1}}; else if (cnt[30:2]==2) array_lt [0 :WA/2-1] <= {WA/2*WB +0{1'b1}}; else if (cnt[30:2]==3) array_lt [WA/2:WA -1] <= {WA/2*WB +0{1'b1}}; else if (cnt[30:2]==4) array_lt [0 ] <= {1 *WB +0{1'b1}}; else if (cnt[30:2]==5) array_lt [ WA -1] <= {1 *WB +0{1'b1}}; else if (cnt[30:2]==6) array_lt [0 ][0 :WB/2-1] <= {1 *WB/2+0{1'b1}}; else if (cnt[30:2]==7) array_lt [ WA -1][WB/2:WB -1] <= {1 *WB/2+0{1'b1}}; else if (cnt[30:2]==8) array_lt [0 ][0 ] <= {1 *1 +0{1'b1}}; else if (cnt[30:2]==9) array_lt [ WA -1][ WB -1] <= {1 *1 +0{1'b1}}; end else if (cnt[1:0]==2'd2) begin // check array value if (cnt[30:2]==0) begin if (array_lt !== 64'b0000000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==1) begin if (array_lt !== 64'b1111111111111111111111111111111111111111111111111111111111111111) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==2) begin if (array_lt !== 64'b1111111111111111111111111111111100000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==3) begin if (array_lt !== 64'b0000000000000000000000000000000011111111111111111111111111111111) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==4) begin if (array_lt !== 64'b1111111100000000000000000000000000000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==5) begin if (array_lt !== 64'b0000000000000000000000000000000000000000000000000000000011111111) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==6) begin if (array_lt !== 64'b1111000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==7) begin if (array_lt !== 64'b0000000000000000000000000000000000000000000000000000000000001111) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==8) begin if (array_lt !== 64'b1000000000000000000000000000000000000000000000000000000000000000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==9) begin if (array_lt !== 64'b0000000000000000000000000000000000000000000000000000000000000001) begin $display("%b", array_lt); $stop(); end end end else if (cnt[1:0]==2'd3) begin // read value from array (not a very good test for now) if (cnt[30:2]==0) begin if (array_lt !== {WA *WB {1'b0}}) $stop(); end else if (cnt[30:2]==1) begin if (array_lt !== {WA *WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==2) begin if (array_lt [0 :WA/2-1] !== {WA/2*WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==3) begin if (array_lt [WA/2:WA -1] !== {WA/2*WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==4) begin if (array_lt [0 ] !== {1 *WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==5) begin if (array_lt [ WA -1] !== {1 *WB +0{1'b1}}) $stop(); end else if (cnt[30:2]==6) begin if (array_lt [0 ][0 :WB/2-1] !== {1 *WB/2+0{1'b1}}) $stop(); end else if (cnt[30:2]==7) begin if (array_lt [ WA -1][WB/2:WB -1] !== {1 *WB/2+0{1'b1}}) $stop(); end else if (cnt[30:2]==8) begin if (array_lt [0 ][0 ] !== {1 *1 +0{1'b1}}) $stop(); end else if (cnt[30:2]==9) begin if (array_lt [ WA -1][ WB -1] !== {1 *1 +0{1'b1}}) $stop(); end end endmodule verilator-3.874/test_regress/t/t_dpi_display.v0000664000177100017500000000215312473477707021535 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2010 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. module t (); `ifndef VERILATOR `error "Only Verilator supports PLI-ish DPI calls and sformat conversion." `endif import "DPI-C" context dpii_display_call = function void \$dpii_display (input string formatted /*verilator sformat*/ ); integer a; initial begin // Check variable width constant string conversions $dpii_display(""); $dpii_display("c"); $dpii_display("co"); $dpii_display("cons"); $dpii_display("constant"); $dpii_display("constant_value"); a = $c("10"); // Don't optimize away "a" $display ("one10=%x ",a); // Check single arg $dpii_display("one10=%x ",a); $display ("Mod=%m 16=%d 10=%x ",a,a); // Check multiarg $dpii_display("Mod=%m 16=%d 10=%x ",a,a); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_cover_toggle.v0000664000177100017500000000603312473477707021714 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; typedef struct packed { union packed { logic ua; logic ub; } u; logic b; } str_t; reg toggle; initial toggle='0; str_t stoggle; initial stoggle='0; const reg aconst = '0; reg [1:0][1:0] ptoggle; initial ptoggle=0; integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; wire toggle_up; alpha a1 (/*AUTOINST*/ // Outputs .toggle_up (toggle_up), // Inputs .clk (clk), .toggle (toggle), .cyc_copy (cyc_copy[7:0])); alpha a2 (/*AUTOINST*/ // Outputs .toggle_up (toggle_up), // Inputs .clk (clk), .toggle (toggle), .cyc_copy (cyc_copy[7:0])); beta b1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle_up (toggle_up)); off o1 (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle)); reg [1:0] memory[121:110]; reg [1023:0] largeish; // CHECK_COVER_MISSING(-1) always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; memory[cyc + 'd100] <= memory[cyc + 'd100] + 2'b1; toggle <= '0; stoggle.u <= toggle; stoggle.b <= toggle; ptoggle[0][0] <= toggle; if (cyc==3) begin toggle <= '1; end if (cyc==4) begin toggle <= '0; end else if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module alpha (/*AUTOARG*/ // Outputs toggle_up, // Inputs clk, toggle, cyc_copy ); // t.a1 and t.a2 collapse to a count of 2 input clk; input toggle; // CHECK_COVER(-1,"top.v.a*",4) // 2 edges * (t.a1 and t.a2) input [7:0] cyc_copy; // CHECK_COVER(-1,"top.v.a*","cyc_copy[0]",22) // CHECK_COVER(-2,"top.v.a*","cyc_copy[1]",10) // CHECK_COVER(-3,"top.v.a*","cyc_copy[2]",4) // CHECK_COVER(-4,"top.v.a*","cyc_copy[3]",2) // CHECK_COVER(-5,"top.v.a*","cyc_copy[4]",0) // CHECK_COVER(-6,"top.v.a*","cyc_copy[5]",0) // CHECK_COVER(-7,"top.v.a*","cyc_copy[6]",0) // CHECK_COVER(-8,"top.v.a*","cyc_copy[7]",0) reg toggle_internal; // CHECK_COVER(-1,"top.v.a*",4) // 2 edges * (t.a1 and t.a2) output reg toggle_up; // CHECK_COVER(-1,"top.v.a*",4) // 2 edges * (t.a1 and t.a2) always @ (posedge clk) begin toggle_internal <= toggle; toggle_up <= toggle; end endmodule module beta (/*AUTOARG*/ // Inputs clk, toggle_up ); input clk; input toggle_up; // CHECK_COVER(-1,"top.v.b1","toggle_up",2) /* verilator public_module */ always @ (posedge clk) begin if (0 && toggle_up) begin end end endmodule module off (/*AUTOARG*/ // Inputs clk, toggle ); // verilator coverage_off input clk; // CHECK_COVER_MISSING(-1) // verilator coverage_on input toggle; // CHECK_COVER(-1,"top.v.o1","toggle",2) endmodule verilator-3.874/test_regress/t/t_clk_gen.pl0000775000177100017500000000071712473477707021013 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_pindup_bad.pl0000775000177100017500000000174712473477707022550 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Error: t/t_lint_pindup_bad.v:\d+: Duplicate pin connection: i %Error: t/t_lint_pindup_bad.v:\d+: ... Location of original pin connection %Error: t/t_lint_pindup_bad.v:\d+: Pin not found: __pinNumber4 %Error: t/t_lint_pindup_bad.v:\d+: Duplicate parameter pin connection: P %Error: t/t_lint_pindup_bad.v:\d+: ... Location of original parameter pin connection %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_select_bad_range3.v0000664000177100017500000000071512525171734022547 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs outwires, // Inputs inwires ); input [7:0] inwires [12:10]; output wire [7:0] outwires [12:10]; assign outwires[10] = inwires[11]; assign outwires[11] = inwires[12]; assign outwires[12] = inwires[13]; // must be an error here endmodule verilator-3.874/test_regress/t/t_var_init.v0000664000177100017500000000124112473477707021044 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter [31:0] p2=2, p3=3; integer i2=2, i3=3; reg [31:0] r2=2, r3=3; wire [31:0] w2=2, w3=3; always @ (posedge clk) begin if (p2 !== 2) $stop; if (p3 !== 3) $stop; if (i2 !== 2) $stop; if (i3 !== 3) $stop; if (r2 !== 2) $stop; if (r3 !== 3) $stop; if (w2 !== 2) $stop; if (w3 !== 3) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_preproc_noline.out0000664000177100017500000000010712473477707022611 0ustar wsnyderwsnyderHello in t_preproc_psl.v yes Multi text multiline line Line: 20 verilator-3.874/test_regress/t/t_gate_array.v0000664000177100017500000000414612473477707021356 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [7:0] a = crc[7:0]; wire [7:0] b = crc[15:8]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [63:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[63:0]), // Inputs .clk (clk), .a (a[7:0]), .b (b[7:0])); // Aggregate outputs into a single result vector wire [63:0] result = {out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h0908a1f2194d24ee if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, a, b ); input clk; input [7:0] a; input [7:0] b; output reg [63:0] out; and u0[7:0] (out[7:0], a[7:0], b[7:0]); and u1[7:0] (out[15:8], a[0], b[7:0]); and u2[7:0] (out[23:16], a[0], b[0]); nand u3[7:0] (out[31:24], a[0], b[7:0]); or u4[7:0] (out[39:32], a[0], b[7:0]); nor u5[7:0] (out[47:40], a[0], b[7:0]); xor u6[7:0] (out[55:48], a[0], b[7:0]); xnor u7[7:0] (out[63:56], a[0], b[7:0]); endmodule verilator-3.874/test_regress/t/t_param_type.pl0000775000177100017500000000102612473477707021544 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug376"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_default_bad.v0000664000177100017500000000055512473477707022465 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs value ); input [3:0] value; always @ (/*AS*/value) begin case (value) default: $stop; 4'd0000: $stop; default: $stop; endcase end endmodule verilator-3.874/test_regress/t/t_case_zx_bad.v0000664000177100017500000000056512473477707021503 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005-2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs value ); input [3:0] value; always @ (/*AS*/value) begin casez (value) 4'b0000: $stop; 4'b1xxx: $stop; default: $stop; endcase end endmodule verilator-3.874/test_regress/t/t_order_multidriven.cpp0000664000177100017500000000214312473477707023305 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Ted Campbell. #include "Vt_order_multidriven.h" #include "verilated.h" #include "verilated_vcd_c.h" Vt_order_multidriven * vcore; VerilatedVcdC * vcd; vluint64_t vtime; #define PHASE_90 static void half_cycle( int clk ) { if ( clk & 1 ) vcore->i_clk_wr = !vcore->i_clk_wr; if ( clk & 2 ) vcore->i_clk_rd = !vcore->i_clk_rd; vtime += 10 / 2; vcore->eval(); vcore->eval(); vcd->dump( vtime ); } static void cycle() { #ifdef PHASE_90 half_cycle( 1 ); half_cycle( 2 ); half_cycle( 1 ); half_cycle( 2 ); #else half_cycle( 3 ); half_cycle( 3 ); #endif } int main() { Verilated::traceEverOn( true ); vcore = new Vt_order_multidriven; vcd = new VerilatedVcdC; vcore->trace( vcd, 99 ); vcd->open( "obj_dir/t_order_multidriven/sim.vcd" ); vcore->i_clk_wr = 0; vcore->i_clk_rd = 0; for ( int i = 0; i < 256; ++i ) cycle( ); vcd->close( ); printf("*-* All Finished *-*\n"); } verilator-3.874/test_regress/t/t_flag_f__3.v0000664000177100017500000000002312473477707021025 0ustar wsnyderwsnyder`define GOT_DEF3 1 verilator-3.874/test_regress/t/t_math_clog2.v0000664000177100017500000000513712473477707021260 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. `ifdef verilator `define CLOG2 $clog2 `else `define CLOG2 clog2_emulate `endif module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Need temp wires as function has different width rules than $clog2 wire [127:0] pows = 128'h1<> 1); end endfunction endmodule verilator-3.874/test_regress/t/t_langext_4_bad.pl0000775000177100017500000000103612473477707022077 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_langext_2.v"); # This is a compile only test. compile ( v_flags2 => ["+1800-2005ext+v"], fails => 1 ); ok(1); 1; verilator-3.874/test_regress/t/t_EXAMPLE.pl0000775000177100017500000000072212473477707020500 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_initial.v0000664000177100017500000000154712473477707020673 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg _ranit; `include "t_initial_inc.vh" // surefire lint_off STMINI initial assign user_loaded_value = 1; initial _ranit = 0; always @ (posedge clk) begin if (!_ranit) begin _ranit <= 1; // Test $time // surefire lint_off CWECBB if ($time<20) $write("time<20\n"); // surefire lint_on CWECBB // Test $write $write ("[%0t] %m: User loaded ", $time); $display ("%b", user_loaded_value); if (user_loaded_value!=1) $stop; // Test $c `ifdef VERILATOR $c ("VL_PRINTF(\"Hi From C++\\n\");"); `endif user_loaded_value <= 2; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_func_real_param.pl0000775000177100017500000000071712473477707022527 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vams_basic.pl0000775000177100017500000000071712473477707021520 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_system.v0000664000177100017500000000114012473477707021451 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t; integer i; initial begin `ifndef VERILATOR `ifndef VCS `ifndef NC $system(); // Legal per spec, but not supported everywhere and nonsensical `endif `endif `endif $system("exit 0"); $system("echo hello"); `ifndef VCS i = $system("exit 0"); if (i!==0) $stop; i = $system("exit 10"); if (i!==10) $stop; `endif $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_interface_modport_export.pl0000775000177100017500000000103112473477707024504 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug696"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_display.pl0000775000177100017500000000151712473477707021711 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["t/t_dpi_display_c.cpp"], ); execute ( check_finished=>1, expect=>quotemeta( q{dpii_display_call: dpii_display_call: c dpii_display_call: co dpii_display_call: cons dpii_display_call: constant dpii_display_call: constant_value one10=0000000a dpii_display_call: one10=0000000a Mod=top.v 16= 10 10=0000000a dpii_display_call: Mod=top.v 16= 10 10=0000000a *-* All Finished *-* }), ); ok(1); 1; verilator-3.874/test_regress/t/t_func_bad2.v0000664000177100017500000000052712473477707021062 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; function recurse; input i; recurse = recurse2(i); endfunction function recurse2; input i; recurse2 = recurse(i); endfunction endmodule verilator-3.874/test_regress/t/t_initial.pl0000775000177100017500000000071712473477707021042 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_embed1.v0000664000177100017500000000621412473477707020373 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire bit_in = crc[0]; wire [30:0] vec_in = crc[31:1]; wire [123:0] wide_in = {crc[59:0],~crc[63:0]}; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire exp_bit_out; // From reference of t_embed1_child.v wire exp_did_init_out; // From reference of t_embed1_child.v wire [30:0] exp_vec_out; // From reference of t_embed1_child.v wire [123:0] exp_wide_out; // From reference of t_embed1_child.v wire got_bit_out; // From test of t_embed1_wrap.v wire got_did_init_out; // From test of t_embed1_wrap.v wire [30:0] got_vec_out; // From test of t_embed1_wrap.v wire [123:0] got_wide_out; // From test of t_embed1_wrap.v // End of automatics // A non-embedded master /* t_embed1_child AUTO_TEMPLATE( .\(.*_out\) (exp_\1[]), .is_ref (1'b1)); */ t_embed1_child reference (/*AUTOINST*/ // Outputs .bit_out (exp_bit_out), // Templated .vec_out (exp_vec_out[30:0]), // Templated .wide_out (exp_wide_out[123:0]), // Templated .did_init_out (exp_did_init_out), // Templated // Inputs .clk (clk), .bit_in (bit_in), .vec_in (vec_in[30:0]), .wide_in (wide_in[123:0]), .is_ref (1'b1)); // Templated // The embeded comparison /* t_embed1_wrap AUTO_TEMPLATE( .\(.*_out\) (got_\1[]), .is_ref (1'b0)); */ t_embed1_wrap test (/*AUTOINST*/ // Outputs .bit_out (got_bit_out), // Templated .vec_out (got_vec_out[30:0]), // Templated .wide_out (got_wide_out[123:0]), // Templated .did_init_out (got_did_init_out), // Templated // Inputs .clk (clk), .bit_in (bit_in), .vec_in (vec_in[30:0]), .wide_in (wide_in[123:0]), .is_ref (1'b0)); // Templated // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, got_wide_out !== exp_wide_out, got_vec_out !== exp_vec_out, got_bit_out !== exp_bit_out, got_did_init_out !== exp_did_init_out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x gv=%x ev=%x\n",$time, cyc, crc, result, got_vec_out, exp_vec_out); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin end else if (cyc<90) begin if (result != 64'h0) begin $display("Bit mismatch, result=%x\n", result); $stop; end end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; //Child prints this: $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_dpi_vams.cpp0000664000177100017500000000223012473477707021347 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. #include #include "Vt_dpi_vams.h" //====================================================================== #if defined(VERILATOR) # include "Vt_dpi_vams__Dpi.h" #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef NEED_EXTERNS extern "C" { extern void dpii_call (double in, double* outp); } #endif void dpii_call (double in, double* outp) { *outp = in + 0.1; } //====================================================================== unsigned int main_time = 0; double sc_time_stamp () { return main_time; } VM_PREFIX* topp = NULL; int main (int argc, char *argv[]) { topp = new VM_PREFIX; Verilated::debug(0); topp->in = 1.1; topp->eval(); if (topp->out != 1.2) { VL_PRINTF("*-* All Finished *-*\n"); topp->final(); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results\n"); } return 0; } verilator-3.874/test_regress/t/t_param_while.pl0000775000177100017500000000072212473477707021675 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_unoptflat_simple_3.v0000664000177100017500000000230512473477707023042 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Simple test of unoptflat // // Demonstration of an UNOPTFLAT combinatorial loop using 3 bits and looping // through 2 sub-modules. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [2:0] x; initial begin x = 3'b000; end test1 test1i ( .clk (clk), .xvecin (x[1:0]), .xvecout (x[2:1])); test2 test2i ( .clk (clk), .xvecin (x[2:1]), .xvecout (x[1:0])); always @(posedge clk or negedge clk) begin `ifdef TEST_VERBOSE $write("x = %x\n", x); `endif if (x[1] != 0) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule // t module test1 (/*AUTOARG*/ // Inputs clk, xvecin, // Outputs xvecout ); input clk; input wire [1:0] xvecin; output wire [1:0] xvecout; assign xvecout = {xvecin[0], clk}; endmodule // test module test2 (/*AUTOARG*/ // Inputs clk, xvecin, // Outputs xvecout ); input clk; input wire [1:0] xvecin; output wire [1:0] xvecout; assign xvecout = {clk, xvecin[1]}; endmodule // test verilator-3.874/test_regress/t/t_param_module.v0000664000177100017500000000231212473477707021676 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This test case is used for testing a modeule parameterized with a typed // localparam. // // We find Verilator appears to mis-evaluate the parameter WIDTH as -16 when // used in the test module to set the value of MSB. A number of warnings and // errors follow, starting with: // // %Warning-LITENDIAN: t/t_param_module.v:42: Little bit endian vector: MSB // < LSB of bit range: -17:0 // // This file ONLY is placed into the Public Domain, for any use, without // warranty, 2013 by Jie Xu. // bug606 module t (/*AUTOARG*/ // Inputs clk ); input clk; localparam logic[4:0] WID = 16; //localparam WID = 16; // No problem if defined like this wire [15:0] b33; test #(WID) i_test_33(.clk (clk), .b (b33)); endmodule module test (/*AUTOARG*/ //Inputs clk, // Outputs b ); parameter WIDTH = 10; localparam MSB = WIDTH - 1; input clk; output wire [MSB:0] b; wire [MSB:0] a; assign b = {~a[MSB-1:0], clk}; initial begin if ($bits(WIDTH)!=5) $stop; // Comes from the parent! if ($bits(MSB)!=32) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_wire_types.pl0000775000177100017500000000106312473477707021576 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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->{verilated_randReset} = 1; # allow checking if we initialize vars to zero only when needed compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_array_inl1.pl0000775000177100017500000000103612473477707022502 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_inst_array.v"); compile ( v_flags2 => ['+define+USE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_context.pl0000775000177100017500000000077012473477707021730 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["t/t_dpi_context_c.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_v_noinl.pl0000775000177100017500000000103612473477707022063 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_func_v.v"); compile ( v_flags2 => ['+define+T_FUNC_V_NOINL',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_inout2.v0000664000177100017500000000267312473477707021341 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [2:0] in; wire a,y,y_fixed; wire b = in[0]; wire en = in[1]; pullup(a); ChildA childa ( .A(a), .B(b), .en(en), .Y(y),.Yfix(y_fixed) ); initial in=0; initial en=0; // Test loop always @ (posedge clk) begin in <= in + 1; $display ( "a %d b %d en %d y %d yfix: %d)" , a, b, en, y, y_fixed); if (en) begin // driving b // a should be b // y and yfix should also be b if (a!=b || y != b || y_fixed != b) begin $display ( "Expected a %d y %b yfix %b" , a, y, y_fixed); $stop; end end else begin // not driving b // a should be 1 (pullup) // y and yfix shold be 1 if (a!=1 || y != 1 || y_fixed != 1) begin $display( "Expected a,y,yfix == 1"); $stop; end end if (in==3) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module ChildA(inout A, input B, input en, output Y, output Yfix); // workaround wire a_in = A; ChildB childB(.A(A), .Y(Y)); assign A = en ? B : 1'bz; ChildB childBfix(.A(a_in),.Y(Yfix)); endmodule module ChildB(input A, output Y); assign Y = A; endmodule verilator-3.874/test_regress/t/t_math_shiftrs.pl0000775000177100017500000000071712473477707022104 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_stream.pl0000775000177100017500000000072212473477707020700 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_uniqueif_fail3.pl0000775000177100017500000000144012473477707022306 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_uniqueif.v"); compile ( v_flags2 => ['+define+FAILING_ASSERTION3'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], fails => $Self->{nc}, ); execute ( fails => $Self->{vlt}, expect=> '.*%Error: t_uniqueif.v:\d+: Assertion failed in top.v: \'unique if\' statement violated %Error: t/t_uniqueif.v:\d+: Verilog \$stop .*', ); ok(1); 1; verilator-3.874/test_regress/t/t_package_verb.v0000664000177100017500000000070712473477707021650 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // bug474 package verb_pkg; typedef enum int {VERB_I, VERB_W} Verb_t; Verb_t verb = VERB_I; string message = " "; endpackage module t; import verb_pkg::*; string message = "*x*"; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_slice_struct_array_modport.v0000664000177100017500000000060512525171734024666 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Varun Koyyalagunta. typedef struct packed { logic p; } s_data; module m1 (output s_data data[1:0]); assign data[0].p = 0; assign data[1].p = 0; endmodule module top (output s_data data[2:0]); m1 m1_inst (.data(data[1:0])); endmodule verilator-3.874/test_regress/t/t_delay.pl0000775000177100017500000000100612473477707020477 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ['-Wno-STMTDLY -Wno-ASSIGNDLY'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_string.v0000664000177100017500000000116212473477707021375 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. module t (); import "DPI-C" function int dpii_string(input string DSM_NAME); generate begin : DSM string SOME_STRING; end endgenerate initial begin $sformat(DSM.SOME_STRING, "%m"); if (dpii_string(DSM.SOME_STRING) != 5) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_vlt_warn.vlt0000664000177100017500000000110312473477707021422 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. `verilator_config lint_off -msg CASEINCOMPLETE -file "t/t_vlt_warn.v" lint_off -msg WIDTH -file "t/t_vlt_warn.v" -lines 18 // Test wildcard filenames lint_off -msg WIDTH -file "*/t_vlt_warn.v" -lines 19-19 // Test global disables lint_off -file "*/t_vlt_warn.v" -lines 20-20 coverage_off -file "t/t_vlt_warn.v" // Test --flag is also accepted tracing_off --file "t/t_vlt_warn.v" verilator-3.874/test_regress/t/t_pipe_exit_bad.pf0000664000177100017500000000060312473477707022166 0ustar wsnyderwsnyder#!/usr/bin/perl -w # DESCRIPTION: Verilator: Verilog Test example --pipe-filter script # # Copyright 2010 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. die "%Error: t_pipe_exit_bad.pf: Intentional bad exit status...\n"; verilator-3.874/test_regress/t/t_slice_struct_array_modport.pl0000775000177100017500000000104212525171734025033 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_func.v0000664000177100017500000000523712473477707021033 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [2:0] q; // From test of Test.v // End of automatics Test test ( // Outputs .q (q[2:0]), // Inputs .clk (clk), .reset_l (crc[0]), .enable (crc[2]), .q_var0 (crc[19:10]), .q_var2 (crc[29:20]), .q_var4 (crc[39:30]), .q_var6 (crc[49:40]) /*AUTOINST*/); // Aggregate outputs into a single result vector wire [63:0] result = {61'h0,q}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; `define EXPECTED_SUM 64'h58b162c58d6e35ba if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( input clk, input reset_l, input enable, input [ 9:0] q_var0, input [ 9:0] q_var2, input [ 9:0] q_var4, input [ 9:0] q_var6, output reg [2:0] q ); reg [7:0] p1_r [6:0]; always @(posedge clk) begin if (!reset_l) begin p1_r[0] <= 'b0; p1_r[1] <= 'b0; p1_r[2] <= 'b0; p1_r[3] <= 'b0; p1_r[4] <= 'b0; p1_r[5] <= 'b0; p1_r[6] <= 'b0; end else if (enable) begin : pass1 match(q_var0, q_var2, q_var4, q_var6); end end // verilator lint_off WIDTH always @(posedge clk) begin : l reg [10:0] bd; reg [3:0] idx; q = 0; bd = 0; for (idx=0; idx<7; idx=idx+1) begin q = idx+1; bd = bd + p1_r[idx]; end end task match; input [9:0] p0, p1, p2, p3; reg [9:0] p[3:0]; begin p[0] = p0; p[1] = p1; p[2] = p2; p[3] = p3; p1_r[0] = p[0]; p1_r[1] = p[1]; end endtask endmodule verilator-3.874/test_regress/t/t_pp_display.v0000664000177100017500000000430612473477707021402 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t; wire d1 = 1'b1; wire d2 = 1'b1; wire d3 = 1'b1; wire o1,o2,o3; add1 add1 (d1,o1); add2 add2 (d2,o2); `define ls left_side `define rs right_side `define noarg na//note extra space `define thru(x) x `define thruthru `ls `rs // Doesn't expand `define msg(x,y) `"x: `\`"y`\`"`" `define left(m,left) m // The 'left' as the variable name shouldn't match the "left" in the `" string initial begin //$display(`msg( \`, \`)); // Illegal $display(`msg(pre `thru(thrupre `thru(thrumid) thrupost) post,right side)); $display(`msg(left side,right side)); $display(`msg( left side , right side )); $display(`msg( `ls , `rs )); $display(`msg( `noarg , `rs )); $display(`msg( prep ( midp1 `ls midp2 ( outp ) ) , `rs )); $display(`msg(`noarg,`noarg`noarg)); $display(`msg( `thruthru , `thruthru )); // Results vary between simulators $display(`left(`msg( left side , right side ), left_replaced)); //$display(`msg( `"tickquoted_left`", `"tickquoted_right`" )); // Syntax error `ifndef VCS // Sim bug - wrong number of arguments, but we're right $display(`msg(`thru(),)); // Empty `endif $display(`msg(`thru(left side),`thru(right side))); $display(`msg( `thru( left side ) , `thru( right side ) )); `ifndef NC $display(`"standalone`"); `endif `ifdef VERILATOR // Illegal on some simulators, as the "..." crosses two lines `define twoline first \ second $display(`msg(twoline, `twoline)); `endif $display("Line %0d File \"%s\"",`__LINE__,`__FILE__); //$display(`msg(left side, \ right side \ )); // Not sure \{space} is legal. $write("*-* All Finished *-*\n"); $finish; end endmodule `define ADD_UP(a,c) \ wire tmp_``a = a; \ wire tmp_``c = tmp_``a + 1; \ assign c = tmp_``c ; module add1 ( input wire d1, output wire o1); `ADD_UP(d1,o1) // expansion is OK endmodule module add2 ( input wire d2, output wire o2); `ADD_UP( d2 , o2 ) // expansion is bad endmodule // `ADD_UP( \d3 , \o3 ) // This really is illegal verilator-3.874/test_regress/t/t_math_msvc_64.pl0000775000177100017500000000101712473477707021675 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--compiler msvc"], # Bug requires msvc ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_value.pl0000775000177100017500000000071712473477707021705 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mod_recurse.pl0000775000177100017500000000103112473477707021706 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug659"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_uniqueif_fail1.pl0000775000177100017500000000144012473477707022304 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_uniqueif.v"); compile ( v_flags2 => ['+define+FAILING_ASSERTION1'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], fails => $Self->{nc}, ); execute ( fails => $Self->{vlt}, expect=> '.*%Error: t_uniqueif.v:\d+: Assertion failed in top.v: \'unique if\' statement violated %Error: t/t_uniqueif.v:\d+: Verilog \$stop .*', ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_readmem_bad_notfound.v0000664000177100017500000000053212473477707024265 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; reg [175:0] hex [15:0]; initial begin $readmemh("t/t_sys_readmem_bad_NOTFOUND.mem", hex); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_tri_gate.cpp0000664000177100017500000000313012473477707021343 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks #ifdef T_COND # include "Vt_tri_gate_cond.h" #elif defined(T_BUFIF0) # include "Vt_tri_gate_bufif0.h" #elif defined(T_BUFIF1) # include "Vt_tri_gate_bufif1.h" #elif defined(T_NOTIF0) # include "Vt_tri_gate_notif0.h" #elif defined(T_NOTIF1) # include "Vt_tri_gate_notif1.h" #elif defined(T_PMOS) # include "Vt_tri_gate_pmos.h" #elif defined(T_NMOS) # include "Vt_tri_gate_nmos.h" #else # error "Unknown test" #endif VM_PREFIX* tb = NULL; double sc_time_stamp() { return 0; } bool check() { bool pass; int c = (tb->A >> tb->SEL) & 0x1; #ifdef TEST_VERBOSE bool verbose = true; #else bool verbose = false; #endif if(tb->W == c && tb->X == c && tb->Y == c && tb->Z == c) { pass = true; if (verbose) printf("- pass: "); } else { pass = false; verbose = true; printf("%%E-FAIL: "); } if (verbose) { printf("SEL=%d A=%d got: W=%d X=%d Y=%d Z=%d exp: WXYZ=%d\n", tb->SEL, tb->A, tb->W, tb->X, tb->Y, tb->Z, c); } return pass; } int main() { bool pass = true; Verilated::debug(0); tb = new VM_PREFIX ("tb"); // loop through every possibility and check the result for (tb->SEL=0; tb->SEL<2; tb->SEL++) { for (tb->A=0; tb->A<4; tb->A++) { tb->eval(); if(!check()) { pass =false; } } } if(pass) { VL_PRINTF("*-* All Finished *-*\n"); tb->final(); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from tristate test\n"); } return 0; } verilator-3.874/test_regress/t/t_case_reducer.pl0000775000177100017500000000072212473477707022031 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_package_export.v0000664000177100017500000000115512473477707022231 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett // see bug 591 package pkg2; parameter PARAM2 = 16; endpackage // pkg2 package pkg1; import pkg2::*; `ifdef T_PACKAGE_EXPORT export pkg2::*; // Not supported on all simulators `endif parameter PARAM1 = 8; endpackage // pkg1 module t (/*AUTOARG*/ // Inputs clk ); input clk; import pkg1::*; reg [PARAM1:0] bus1; reg [PARAM2:0] bus2; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_math_div0.v0000664000177100017500000000031112473477707021101 0ustar wsnyderwsnydermodule t(y); output [3:0] y; // bug775 // verilator lint_off WIDTH assign y = ((0/0) ? 1 : 2) % 0; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_trace_ena.v0000664000177100017500000000144112473477707021154 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // verilator tracing_off integer b_trace_off; // verilator tracing_on integer c_trace_on; real r; // verilator tracing_off sub sub (); // verilator tracing_on always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; b_trace_off <= cyc; c_trace_on <= b_trace_off; r <= r + 0.1; if (cyc==4) begin if (c_trace_on != 2) $stop; end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module sub; integer inside_sub = 0; endmodule verilator-3.874/test_regress/t/t_math_imm.pl0000775000177100017500000000104612473477707021200 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--compiler msvc"], # We have deep expressions we want to test ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_mismodport_bad.v0000664000177100017500000000114712473477707024261 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. interface ifc; integer ok; integer bad; modport out_modport (output ok); endinterface module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc itop(); counter_ansi c1 (.isub(itop), .i_value(4'h4)); endmodule module counter_ansi ( ifc.out_modport isub, input logic [3:0] i_value ); always @* begin isub.ok = i_value; isub.bad = i_value; // Illegal access end endmodule verilator-3.874/test_regress/t/t_tri_unconn.pl0000775000177100017500000000072212473477707021563 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gate_unsup.v0000664000177100017500000000126712473477707021413 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/); wire d, en, nc, pc; // verilator lint_off IMPLICIT cmos (cm0, d, nc, pc); rcmos (rc0, d, nc, pc); nmos (nm0, d, en); pmos (pm0, d, en); rnmos (rn0, d, en); rpmos (rp0, d, en); rtran (rt0, d); tran (tr0, d); rtranif0 (r00, d, en); rtranif1 (r10, d, en); tranif0 (t00, d, en); tranif1 (t10, d, en); // verilator lint_on IMPLICIT initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_const_overflow_bad.v0000664000177100017500000000110112473477707023103 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005-2007 by Wilson Snyder. module t (/*AUTOARG*/); parameter [200:0] TOO_SMALL = 94'd123456789012345678901234567890; // One to many digits parameter [200:0] SMALLH = 8'habc; // One to many digits parameter [200:0] SMALLO = 6'o1234; // One to many digits parameter [200:0] SMALLB = 3'b1111; // One to many digits // We'll allow this though; no reason to be cruel parameter [200:0] OKH = 8'h000000001; endmodule verilator-3.874/test_regress/t/t_gate_elim.pl0000775000177100017500000000071712473477707021337 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_real_param.v0000664000177100017500000000104312473477707022347 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. // bug475 module t(); function real get_real_one; input ignored; get_real_one = 1.1; endfunction localparam R_PARAM = get_real_one(1'b0); localparam R_PARAM_2 = (R_PARAM > 0); generate initial begin if (R_PARAM != 1.1) $stop; if (R_PARAM_2 != 1'b1) $stop; $write("*-* All Finished *-*\n"); $finish; end endgenerate endmodule verilator-3.874/test_regress/t/t_stream.v0000664000177100017500000002617112473477707020535 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Glen Gibb. //module t; module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // The 'initial' code block below tests compilation-time // evaluation/optimization of the stream operator. All occurences of the stream // operator within this block are replaced prior to generation of C code. logic [3:0] dout; logic [31:0] dout32; logic [10:0] dout11; initial begin // Stream operator: << // Location: rhs of assignment // // Test slice sizes from 1 - 5 dout = { << {4'b0001}}; if (dout != 4'b1000) $stop; dout = { << 2 {4'b0001}}; if (dout != 4'b0100) $stop; dout = { << 3 {4'b0001}}; if (dout != 4'b0010) $stop; dout = { << 4 {4'b0001}}; if (dout != 4'b0001) $stop; dout = { << 5 {4'b0001}}; if (dout != 4'b0001) $stop; // Stream operator: >> // Location: rhs of assignment // // Right-streaming operator on RHS does not reorder bits dout = { >> {4'b0001}}; if (dout != 4'b0001) $stop; dout = { >> 2 {4'b0001}}; if (dout != 4'b0001) $stop; dout = { >> 3 {4'b0001}}; if (dout != 4'b0001) $stop; dout = { >> 4 {4'b0001}}; if (dout != 4'b0001) $stop; dout = { >> 5 {4'b0001}}; if (dout != 4'b0001) $stop; // Stream operator: << // Location: lhs of assignment { << {dout}} = 4'b0001; if (dout != 4'b1000) $stop; { << 2 {dout}} = 4'b0001; if (dout != 4'b0100) $stop; { << 3 {dout}} = 4'b0001; if (dout != 4'b0010) $stop; { << 4 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { << 5 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; // Stream operator: >> // Location: lhs of assignment { >> {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { >> 2 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { >> 3 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { >> 4 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; { >> 5 {dout}} = 4'b0001; if (dout != 4'b0001) $stop; // Stream operator: << // Location: lhs of assignment // RHS is *wider* than LHS /* verilator lint_off WIDTH */ { << {dout}} = 5'b00001; if (dout != 4'b1000) $stop; { << 2 {dout}} = 5'b00001; if (dout != 4'b0100) $stop; { << 3 {dout}} = 5'b00001; if (dout != 4'b0010) $stop; { << 4 {dout}} = 5'b00001; if (dout != 4'b0001) $stop; { << 5 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; /* verilator lint_on WIDTH */ // Stream operator: >> // Location: lhs of assignment // RHS is *wider* than LHS /* verilator lint_off WIDTH */ { >> {dout}} = 5'b01101; if (dout != 4'b0110) $stop; { >> 2 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; { >> 3 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; { >> 4 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; { >> 5 {dout}} = 5'b01101; if (dout != 4'b0110) $stop; /* verilator lint_on WIDTH */ // Stream operator: << // Location: both sides of assignment { << {dout}} = { << {4'b0001}}; if (dout != 4'b0001) $stop; { << 2 {dout}} = { << 2 {4'b0001}}; if (dout != 4'b0001) $stop; { << 3 {dout}} = { << 3 {4'b0001}}; if (dout != 4'b0100) $stop; { << 4 {dout}} = { << 4 {4'b0001}}; if (dout != 4'b0001) $stop; { << 5 {dout}} = { << 5 {4'b0001}}; if (dout != 4'b0001) $stop; // Stream operator: << // Location: as an operand within a statement // // Test slice sizes from 1 - 5 if (4'({ << {4'b0001}}) != 4'b1000) $stop; if (4'({ << 2 {4'b0001}}) != 4'b0100) $stop; if (4'({ << 3 {4'b0001}}) != 4'b0010) $stop; if (4'({ << 4 {4'b0001}}) != 4'b0001) $stop; if (4'({ << 5 {4'b0001}}) != 4'b0001) $stop; // case dout32 = { << 3 { 32'b11010111000010100100010010010111 }}; if (dout32 != 32'he92910eb) $stop; dout11 = { << 4 { 11'b10010010111 }}; if (dout11 != 11'h3cc) $stop; end // The two always blocks below test run-time evaluation of the stream // operator in generated C code. // // Various stream operators are optimized away. Here's a brief summary: // // Stream op on RHS of assign // -------------------------- // X = { << a { Y } } --- C function evaluates stream operator // -- if log2(a) == int --> "fast" eval func // -- if log2(a) != int --> "slow" eval func // X = { >> a { Y } } --- stream operator is optimized away // // Stream op on LHS of assign // -------------------------- // Note: if Y.width() > X.width, then the MSBs of Y are used, not the LSBs! // { << a { X } } = Y --- stream operator is moved to RHS, eval as above // { >> a { X } } = Y --- stream operator is optimized away logic [31:0] din_i; logic [63:0] din_q; logic [95:0] din_w; // Stream op on RHS, left-stream operator logic [31:0] dout_rhs_ls_i; logic [63:0] dout_rhs_ls_q; logic [95:0] dout_rhs_ls_w; // Stream op on RHS, right-stream operator logic [31:0] dout_rhs_rs_i; logic [63:0] dout_rhs_rs_q; logic [95:0] dout_rhs_rs_w; // Stream op on both sides, left-stream operator logic [31:0] dout_bhs_ls_i; logic [63:0] dout_bhs_ls_q; logic [95:0] dout_bhs_ls_w; // Stream op on both sides, right-stream operator logic [31:0] dout_bhs_rs_i; logic [63:0] dout_bhs_rs_q; logic [95:0] dout_bhs_rs_w; // Stream operator on LHS (with concatenation on LHS) logic [3:0] din_lhs; logic [1:0] dout_lhs_ls_a, dout_lhs_ls_b; logic [1:0] dout_lhs_rs_a, dout_lhs_rs_b; // Addition operator on LHS, right-shift tests: // Testing various shift sizes to exercise fast + slow funcs logic [22:0] dout_rhs_ls_i_23_3; logic [22:0] dout_rhs_ls_i_23_4; logic [36:0] dout_rhs_ls_q_37_3; logic [36:0] dout_rhs_ls_q_37_4; always @* begin // Stream operator: << // Location: rhs of assignment // // Test each data type (I, Q, W) dout_rhs_ls_i = { << {din_i}}; dout_rhs_ls_q = { << {din_q}}; dout_rhs_ls_w = { << {din_w}}; // Stream operator: >> // Location: rhs of assignment dout_rhs_rs_i = { >> {din_i}}; dout_rhs_rs_q = { >> {din_q}}; dout_rhs_rs_w = { >> {din_w}}; // Stream operator: << // Location: lhs of assignment { << 2 {dout_lhs_ls_a, dout_lhs_ls_b}} = din_lhs; // Stream operator: >> // Location: lhs of assignment { >> 2 {dout_lhs_rs_a, dout_lhs_rs_b}} = din_lhs; // Stream operator: << // Location: both sides of assignment { << 5 {dout_bhs_ls_i}} = { << 5 {din_i}}; { << 5 {dout_bhs_ls_q}} = { << 5 {din_q}}; { << 5 {dout_bhs_ls_w}} = { << 5 {din_w}}; // Stream operator: >> // Location: both sides of assignment { >> 5 {dout_bhs_rs_i}} = { >> 5 {din_i}}; { >> 5 {dout_bhs_rs_q}} = { >> 5 {din_q}}; { >> 5 {dout_bhs_rs_w}} = { >> 5 {din_w}}; // Stream operator: << // Location: both sides of assignment { << 5 {dout_bhs_ls_i}} = { << 5 {din_i}}; { << 5 {dout_bhs_ls_q}} = { << 5 {din_q}}; { << 5 {dout_bhs_ls_w}} = { << 5 {din_w}}; // Stream operator: << // Location: rhs of assignment // // Verify both fast and slow paths (fast: sliceSize = power of 2) dout_rhs_ls_i_23_3 = { << 3 {din_i[22:0]}}; // SLOW dout_rhs_ls_i_23_4 = { << 4 {din_i[22:0]}}; // FAST dout_rhs_ls_q_37_3 = { << 3 {din_q[36:0]}}; // SLOW dout_rhs_ls_q_37_4 = { << 4 {din_q[36:0]}}; // FAST end always @(posedge clk) begin if (cyc != 0) begin cyc <= cyc + 1; if (cyc == 1) begin din_i <= 32'h_00_00_00_01; din_q <= 64'h_00_00_00_00_00_00_00_01; din_w <= 96'h_00_00_00_00_00_00_00_00_00_00_00_01; din_lhs <= 4'b_00_01; end if (cyc == 2) begin din_i <= 32'h_04_03_02_01; din_q <= 64'h_08_07_06_05_04_03_02_01; din_w <= 96'h_0c_0b_0a_09_08_07_06_05_04_03_02_01; din_lhs <= 4'b_01_11; if (dout_rhs_ls_i != 32'h_80_00_00_00) $stop; if (dout_rhs_ls_q != 64'h_80_00_00_00_00_00_00_00) $stop; if (dout_rhs_ls_w != 96'h_80_00_00_00_00_00_00_00_00_00_00_00) $stop; if (dout_rhs_rs_i != 32'h_00_00_00_01) $stop; if (dout_rhs_rs_q != 64'h_00_00_00_00_00_00_00_01) $stop; if (dout_rhs_rs_w != 96'h_00_00_00_00_00_00_00_00_00_00_00_01) $stop; if (dout_lhs_ls_a != 2'b_01) $stop; if (dout_lhs_ls_b != 2'b_00) $stop; if (dout_lhs_rs_a != 2'b_00) $stop; if (dout_lhs_rs_b != 2'b_01) $stop; if (dout_bhs_rs_i != 32'h_00_00_00_01) $stop; if (dout_bhs_rs_q != 64'h_00_00_00_00_00_00_00_01) $stop; if (dout_bhs_rs_w != 96'h_00_00_00_00_00_00_00_00_00_00_00_01) $stop; if (dout_bhs_ls_i != 32'h_00_00_00_10) $stop; if (dout_bhs_ls_q != 64'h_00_00_00_00_00_00_01_00) $stop; if (dout_bhs_ls_w != 96'h_00_00_00_00_00_00_00_00_00_00_00_04) $stop; if (dout_rhs_ls_i_23_3 != 23'h_10_00_00) $stop; if (dout_rhs_ls_i_23_4 != 23'h_08_00_00) $stop; if (dout_rhs_ls_q_37_3 != 37'h_04_00_00_00_00) $stop; if (dout_rhs_ls_q_37_4 != 37'h_02_00_00_00_00) $stop; end if (cyc == 3) begin // The values below test the strange shift-merge done at the end of // the fast stream operators. // All-1s in the bits being streamed should end up as all-1s. din_i <= 32'h_00_7f_ff_ff; din_q <= 64'h_00_00_00_1f_ff_ff_ff_ff; if (dout_rhs_ls_i != 32'h_80_40_c0_20) $stop; if (dout_rhs_ls_q != 64'h_80_40_c0_20_a0_60_e0_10) $stop; if (dout_rhs_ls_w != 96'h_80_40_c0_20_a0_60_e0_10_90_50_d0_30) $stop; if (dout_rhs_rs_i != 32'h_04_03_02_01) $stop; if (dout_rhs_rs_q != 64'h_08_07_06_05_04_03_02_01) $stop; if (dout_rhs_rs_w != 96'h_0c_0b_0a_09_08_07_06_05_04_03_02_01) $stop; if (dout_bhs_ls_i != 32'h_40_30_00_18) $stop; if (dout_bhs_ls_q != 64'h_06_00_c1_81_41_00_c1_80) $stop; if (dout_bhs_ls_w != 96'h_30_2c_28_20_01_1c_1a_04_14_0c_00_06) $stop; if (dout_bhs_rs_i != 32'h_04_03_02_01) $stop; if (dout_bhs_rs_q != 64'h_08_07_06_05_04_03_02_01) $stop; if (dout_bhs_rs_w != 96'h_0c_0b_0a_09_08_07_06_05_04_03_02_01) $stop; if (dout_lhs_ls_a != 2'b_11) $stop; if (dout_lhs_ls_b != 2'b_01) $stop; if (dout_lhs_rs_a != 2'b_01) $stop; if (dout_lhs_rs_b != 2'b_11) $stop; if (dout_rhs_ls_i_23_3 != 23'h_10_08_c0) $stop; if (dout_rhs_ls_i_23_4 != 23'h_08_10_18) $stop; if (dout_rhs_ls_q_37_3 != 37'h_04_02_30_10_44) $stop; if (dout_rhs_ls_q_37_4 != 37'h_02_04_06_08_0a) $stop; end if (cyc == 4) begin if (dout_rhs_ls_i_23_3 != 23'h_7f_ff_ff) $stop; if (dout_rhs_ls_i_23_4 != 23'h_7f_ff_ff) $stop; if (dout_rhs_ls_q_37_3 != 37'h_1f_ff_ff_ff_ff) $stop; if (dout_rhs_ls_q_37_4 != 37'h_1f_ff_ff_ff_ff) $stop; end if (cyc == 9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_func_lib_sub.v0000664000177100017500000000415612473477707021673 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. `define zednkw 200 module BreadAddrDP (zfghtn, cjtmau, vipmpg, knquim, kqxkkr); input zfghtn; input [4:0] cjtmau; input vipmpg; input [7:0] knquim; input [7:0] kqxkkr; reg covfok; reg [15:0] xwieqw; reg [2:0] ofnjjt; reg [37:0] hdsejo[1:0]; reg wxxzgd, tceppr, ratebp, fjizkr, iwwrnq; reg vrqrih, ryyjxy; reg fgzsox; wire xdjikl = ~wxxzgd & ~tceppr & ~ratebp & fjizkr; wire iytyol = ~wxxzgd & ~tceppr & ratebp & ~fjizkr & ~xwieqw[10]; wire dywooz = ~wxxzgd & ~tceppr & ratebp & ~fjizkr & xwieqw[10]; wire qnpfus = ~wxxzgd & ~tceppr & ratebp & fjizkr; wire fqlkrg = ~wxxzgd & tceppr & ~ratebp & ~fjizkr; wire ktsveg = hdsejo[0][6] | (hdsejo[0][37:34] == 4'h1); wire smxixw = vrqrih | (ryyjxy & ktsveg); wire [7:0] grvsrs, kyxrft, uxhkka; wire [7:0] eianuv = 8'h01 << ofnjjt; wire [7:0] jvpnxn = {8{qnpfus}} & eianuv; wire [7:0] zlnzlj = {8{fqlkrg}} & eianuv; wire [7:0] nahzat = {8{iytyol}} & eianuv; genvar i; generate for (i=0;i<8;i=i+1) begin : dnlpyw DecCountReg4 bzpytc (zfghtn, fgzsox, zlnzlj[i], knquim[3:0], covfok, grvsrs[i]); DecCountReg4 oghukp (zfghtn, fgzsox, zlnzlj[i], knquim[7:4], covfok, kyxrft[i]); DecCountReg4 ttvjoo (zfghtn, fgzsox, nahzat[i], kqxkkr[3:0], covfok, uxhkka[i]); end endgenerate endmodule module DecCountReg4 (clk, fgzsox, fckiyr, uezcjy, covfok, juvlsh); input clk, fgzsox, fckiyr, covfok; input [3:0] uezcjy; output juvlsh; task Xinit; begin `ifdef TEST_HARNESS khgawe = 1'b0; `endif end endtask function X; input vrdejo; begin `ifdef TEST_HARNESS if ((vrdejo & ~vrdejo) !== 1'h0) khgawe = 1'b1; `endif X = vrdejo; end endfunction task Xcheck; input vzpwwy; begin end endtask reg [3:0] udbvtl; assign juvlsh = |udbvtl; wire [3:0] mppedc = {4{fgzsox}} & (fckiyr ? uezcjy : (udbvtl - 4'h1)); wire qqibou = ((juvlsh | fckiyr) & covfok) | ~fgzsox; always @(posedge clk) begin Xinit; if (X(qqibou)) udbvtl <= #`zednkw mppedc; Xcheck(fgzsox); end endmodule verilator-3.874/test_regress/t/t_var_pins_sc64.pl0000775000177100017500000000404412473477707022066 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.874/test_regress/t/t_alw_splitord.v0000664000177100017500000000757412473477707021753 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [15:0] m_din; // OK reg [15:0] c_split_1, c_split_2, c_split_3, c_split_4, c_split_5; always @ (posedge clk) begin if (cyc==0) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops c_split_1 <= 16'h0; c_split_2 <= 16'h0; c_split_3 <= 16'h0; c_split_4 <= 0; c_split_5 <= 0; // End of automatics end else begin c_split_1 <= m_din; c_split_2 <= c_split_1; c_split_3 <= c_split_2 & {16{(cyc!=0)}}; if (cyc==1) begin c_split_4 <= 16'h4; c_split_5 <= 16'h5; end else begin c_split_4 <= c_split_3; c_split_5 <= c_split_4; end end end // OK reg [15:0] d_split_1, d_split_2; always @ (posedge clk) begin if (cyc==0) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops d_split_1 <= 16'h0; d_split_2 <= 16'h0; // End of automatics end else begin d_split_1 <= m_din; d_split_2 <= d_split_1; d_split_1 <= ~m_din; end end // Not OK always @ (posedge clk) begin if (cyc==0) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops // End of automatics end else begin $write(" foo %x", m_din); $write(" bar %x\n", m_din); end end // Not OK reg [15:0] e_split_1, e_split_2; always @ (posedge clk) begin if (cyc==0) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops e_split_1 = 16'h0; e_split_2 = 16'h0; // End of automatics end else begin e_split_1 = m_din; e_split_2 = e_split_1; end end // Not OK reg [15:0] f_split_1, f_split_2; always @ (posedge clk) begin if (cyc==0) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops f_split_1 = 16'h0; f_split_2 = 16'h0; // End of automatics end else begin f_split_2 = f_split_1; f_split_1 = m_din; end end always @ (posedge clk) begin if (cyc!=0) begin //$write(" C %d %x %x\n", cyc, c_split_1, c_split_2); cyc<=cyc+1; if (cyc==1) begin m_din <= 16'hfeed; end if (cyc==3) begin end if (cyc==4) begin m_din <= 16'he11e; if (!(d_split_1==16'h0112 && d_split_2==16'h0112)) $stop; if (!(e_split_1==16'hfeed && e_split_2==16'hfeed)) $stop; if (!(f_split_1==16'hfeed && f_split_2==16'hfeed)) $stop; end if (cyc==5) begin m_din <= 16'he22e; if (!(d_split_1==16'h0112 && d_split_2==16'h0112)) $stop; // Two valid orderings, as we don't know which posedge clk gets evaled first if (!(e_split_1==16'hfeed && e_split_2==16'hfeed) && !(e_split_1==16'he11e && e_split_2==16'he11e)) $stop; if (!(f_split_1==16'hfeed && f_split_2==16'hfeed) && !(f_split_1==16'he11e && f_split_2==16'hfeed)) $stop; end if (cyc==6) begin m_din <= 16'he33e; if (!(c_split_1==16'he11e && c_split_2==16'hfeed && c_split_3==16'hfeed)) $stop; if (!(d_split_1==16'h1ee1 && d_split_2==16'h0112)) $stop; // Two valid orderings, as we don't know which posedge clk gets evaled first if (!(e_split_1==16'he11e && e_split_2==16'he11e) && !(e_split_1==16'he22e && e_split_2==16'he22e)) $stop; if (!(f_split_1==16'he11e && f_split_2==16'hfeed) && !(f_split_1==16'he22e && f_split_2==16'he11e)) $stop; end if (cyc==7) begin m_din <= 16'he44e; if (!(c_split_1==16'he22e && c_split_2==16'he11e && c_split_3==16'hfeed)) $stop; end if (cyc==8) begin m_din <= 16'he55e; if (!(c_split_1==16'he33e && c_split_2==16'he22e && c_split_3==16'he11e && c_split_4==16'hfeed && c_split_5==16'hfeed)) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_bitsel_slice.pl0000775000177100017500000000072212473477707022046 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_repeat_bad.v0000664000177100017500000000054612473477707022354 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test of select from constant // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (); sub #(.Z(0)) sub1 (); sub #(.Z(1)) sub2 (); sub #(.Z(2)) sub3 (); endmodule module sub; parameter Z = 0; wire [1:0] a = 2'b11; wire [0:0] b = a; endmodule verilator-3.874/test_regress/t/t_math_synmul_mul.v0000664000177100017500000121176612473477707022466 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Mahesh Kumashikar module t_math_synmul_mul ( /*AUTOARG*/ // Outputs product_d4, // Inputs clk, enable, negate, datA, datB ); input clk; input enable; input negate; input [31:0] datA; input [31:0] datB; // verilator lint_off UNOPTFLAT output reg [64:0] product_d4; reg [33:0] datA_d1r; reg [33:0] datB_d1r; always @ (posedge clk) begin if (enable) begin datA_d1r <= {2'b0,datA}; datB_d1r <= {2'b0,datB}; // The extra multiplier bits were for signed, for this // test we've ripped that out if (negate) $stop; end end reg en_d1; reg en_d2; reg en_d3; always @ (posedge clk) begin en_d1 <= enable; en_d2 <= en_d1; en_d3 <= en_d2; end wire [63:0] prod_d3; smmultiplier_34_34 mul (.OPA(datA_d1r), .OPB(datB_d1r), .RESULT(prod_d3), /*AUTOINST*/ // Inputs .clk (clk), .en_d1 (en_d1), .en_d2 (en_d2)); always @ (posedge clk) begin if (en_d3) begin product_d4 <= {1'b0,prod_d3}; end end endmodule // The below was originally generated by the "Synthesizable Arithmetic Module Generator" // at http://modgen.fysel.ntnu.no/~pihl/iwlas98/ then cleaned up by hand. // Unfortunately the generator no longer appears available. Please contact // us if you know otherwise. module smmultiplier_34_34 ( input clk, input en_d1, input en_d2, input [33:0] OPA, input [33:0] OPB, output [63:0] RESULT ); wire [628:0] PPBIT; wire [66:0] INT_CARRY; wire [66:0] INT_SUM; smboothcoder_34_34 db (.OPA(OPA[33:0]), .OPB(OPB[33:0]), .SUMMAND(PPBIT[628:0]) ); smwallace_34_34 dw (.SUMMAND(PPBIT[628:0]), .CARRY(INT_CARRY[66:1]), .SUM(INT_SUM[66:0]), /*AUTOINST*/ // Inputs .clk (clk), .en_d1 (en_d1), .en_d2 (en_d2)); assign INT_CARRY[0] = 1'b0; smdblcadder_128_128 dd (.OPA(INT_SUM[63:0]), .OPB(INT_CARRY[63:0]), .CIN (1'b0), .SUM(RESULT)); endmodule module smdblcadder_128_128 ( OPA, OPB, CIN, SUM ); input [63:0] OPA; input [63:0] OPB; input CIN; output [63:0] SUM; wire [63:0] INTPROP; wire [63:0] INTGEN; wire [0:0] PBIT; wire [63:0] CARRY; smprestage_128 dp (OPA[63:0], OPB[63:0], CIN, INTPROP, INTGEN ); smdblctree_128 dd (INTPROP[63:0], INTGEN[63:0], CARRY[63:0], PBIT ); smxorstage_128 dx (OPA[63:0], OPB[63:0], PBIT[0], CARRY[63:0], SUM ); endmodule module smdblctree_128 ( PIN, GIN, GOUT, POUT ); input [63:0] PIN; input [63:0] GIN; output [63:0] GOUT; output [0:0] POUT; wire [63:0] INTPROP_0; wire [63:0] INTGEN_0; wire [63:0] INTPROP_1; wire [63:0] INTGEN_1; wire [63:0] INTPROP_2; wire [63:0] INTGEN_2; wire [63:0] INTPROP_3; wire [63:0] INTGEN_3; wire [63:0] INTPROP_4; wire [63:0] INTGEN_4; wire [63:0] INTPROP_5; wire [63:0] INTGEN_5; smdblc_0_128 ddb0 (.PIN(PIN), .GIN(GIN), .POUT(INTPROP_0), .GOUT(INTGEN_0) ); smdblc_1_128 ddb1 (.PIN(INTPROP_0), .GIN(INTGEN_0), .POUT(INTPROP_1), .GOUT(INTGEN_1) ); smdblc_2_128 ddb2 (.PIN(INTPROP_1), .GIN(INTGEN_1), .POUT(INTPROP_2), .GOUT(INTGEN_2) ); smdblc_3_128 ddb3 (.PIN(INTPROP_2), .GIN(INTGEN_2), .POUT(INTPROP_3), .GOUT(INTGEN_3) ); smdblc_4_128 ddb4 (.PIN(INTPROP_3), .GIN(INTGEN_3), .POUT(INTPROP_4), .GOUT(INTGEN_4) ); smdblc_5_128 ddb5 (.PIN(INTPROP_4), .GIN(INTGEN_4), .POUT(INTPROP_5), .GOUT(INTGEN_5) ); smdblc_6_128 ddb6 (.PIN(INTPROP_5), .GIN(INTGEN_5), .POUT(POUT), .GOUT(GOUT) ); endmodule module smwallace_34_34 ( input clk, input en_d1, input en_d2, input [628:0] SUMMAND, output [65:0] CARRY, output [66:0] SUM ); wire [628:0] LATCHED_PP; wire [551:0] INT_CARRY; wire [687:0] INT_SUM; smffa dla0 (.D(SUMMAND[0]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[0]) ); smffa dla1 (.D(SUMMAND[1]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[1]) ); smhalfadder dha0 (.DATA_A (LATCHED_PP[0]), .DATA_B (LATCHED_PP[1]), .SAVE (INT_SUM[0]), .CARRY (INT_CARRY[0]) ); smffb dla2 (.D(INT_SUM[0]), .clk(clk), .en_d2(en_d2), .Q(SUM[0]) ); smffb dla3 (.D(INT_CARRY[0]), .clk(clk), .en_d2(en_d2), .Q(CARRY[0]) ); smffa dla4 (.D(SUMMAND[2]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[2]) ); assign INT_SUM[1] = LATCHED_PP[2]; assign CARRY[1] = 1'b0; smffb dla5 (.D(INT_SUM[1]), .clk(clk), .en_d2(en_d2), .Q(SUM[1]) ); smffa dla6 (.D(SUMMAND[3]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[3]) ); smffa dla7 (.D(SUMMAND[4]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[4]) ); smffa dla8 (.D(SUMMAND[5]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[5]) ); smfulladder dfa0 (.DATA_A (LATCHED_PP[3]), .DATA_B (LATCHED_PP[4]), .DATA_C (LATCHED_PP[5]), .SAVE (INT_SUM[2]), .CARRY (INT_CARRY[1]) ); smffb dla9 (.D(INT_SUM[2]), .clk(clk), .en_d2(en_d2), .Q(SUM[2]) ); smffb dla10 (.D(INT_CARRY[1]), .clk(clk), .en_d2(en_d2), .Q(CARRY[2]) ); smffa dla11 (.D(SUMMAND[6]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[6]) ); smffa dla12 (.D(SUMMAND[7]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[7]) ); smhalfadder dha1 (.DATA_A (LATCHED_PP[6]), .DATA_B (LATCHED_PP[7]), .SAVE (INT_SUM[3]), .CARRY (INT_CARRY[2]) ); smffb dla13 (.D(INT_SUM[3]), .clk(clk), .en_d2(en_d2), .Q(SUM[3]) ); smffb dla14 (.D(INT_CARRY[2]), .clk(clk), .en_d2(en_d2), .Q(CARRY[3]) ); smffa dla15 (.D(SUMMAND[8]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[8]) ); smffa dla16 (.D(SUMMAND[9]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[9]) ); smffa dla17 (.D(SUMMAND[10]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[10]) ); smfulladder dfa1 (.DATA_A (LATCHED_PP[8]), .DATA_B (LATCHED_PP[9]), .DATA_C (LATCHED_PP[10]), .SAVE (INT_SUM[4]), .CARRY (INT_CARRY[4]) ); smffa dla18 (.D(SUMMAND[11]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[11]) ); assign INT_SUM[5] = LATCHED_PP[11]; smhalfadder dha2 (.DATA_A (INT_SUM[4]), .DATA_B (INT_SUM[5]), .SAVE (INT_SUM[6]), .CARRY (INT_CARRY[3]) ); smffb dla19 (.D(INT_SUM[6]), .clk(clk), .en_d2(en_d2), .Q(SUM[4]) ); smffb dla20 (.D(INT_CARRY[3]), .clk(clk), .en_d2(en_d2), .Q(CARRY[4]) ); smffa dla21 (.D(SUMMAND[12]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[12]) ); smffa dla22 (.D(SUMMAND[13]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[13]) ); smffa dla23 (.D(SUMMAND[14]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[14]) ); smfulladder dfa2 (.DATA_A (LATCHED_PP[12]), .DATA_B (LATCHED_PP[13]), .DATA_C (LATCHED_PP[14]), .SAVE (INT_SUM[7]), .CARRY (INT_CARRY[6]) ); smhalfadder dha3 (.DATA_A (INT_SUM[7]), .DATA_B (INT_CARRY[4]), .SAVE (INT_SUM[8]), .CARRY (INT_CARRY[5]) ); smffb dla24 (.D(INT_SUM[8]), .clk(clk), .en_d2(en_d2), .Q(SUM[5]) ); smffb dla25 (.D(INT_CARRY[5]), .clk(clk), .en_d2(en_d2), .Q(CARRY[5]) ); smffa dla26 (.D(SUMMAND[15]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[15]) ); smffa dla27 (.D(SUMMAND[16]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[16]) ); smffa dla28 (.D(SUMMAND[17]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[17]) ); smfulladder dfa3 (.DATA_A (LATCHED_PP[15]), .DATA_B (LATCHED_PP[16]), .DATA_C (LATCHED_PP[17]), .SAVE (INT_SUM[9]), .CARRY (INT_CARRY[8]) ); smffa dla29 (.D(SUMMAND[18]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[18]) ); smffa dla30 (.D(SUMMAND[19]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[19]) ); smhalfadder dha4 (.DATA_A (LATCHED_PP[18]), .DATA_B (LATCHED_PP[19]), .SAVE (INT_SUM[10]), .CARRY (INT_CARRY[9]) ); smfulladder dfa4 (.DATA_A (INT_SUM[9]), .DATA_B (INT_SUM[10]), .DATA_C (INT_CARRY[6]), .SAVE (INT_SUM[11]), .CARRY (INT_CARRY[7]) ); smffb dla31 (.D(INT_SUM[11]), .clk(clk), .en_d2(en_d2), .Q(SUM[6]) ); smffb dla32 (.D(INT_CARRY[7]), .clk(clk), .en_d2(en_d2), .Q(CARRY[6]) ); smffa dla33 (.D(SUMMAND[20]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[20]) ); smffa dla34 (.D(SUMMAND[21]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[21]) ); smffa dla35 (.D(SUMMAND[22]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[22]) ); smfulladder dfa5 (.DATA_A (LATCHED_PP[20]), .DATA_B (LATCHED_PP[21]), .DATA_C (LATCHED_PP[22]), .SAVE (INT_SUM[12]), .CARRY (INT_CARRY[11]) ); smffa dla36 (.D(SUMMAND[23]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[23]) ); assign INT_SUM[13] = LATCHED_PP[23]; smfulladder dfa6 (.DATA_A (INT_SUM[12]), .DATA_B (INT_SUM[13]), .DATA_C (INT_CARRY[8]), .SAVE (INT_SUM[14]), .CARRY (INT_CARRY[12]) ); assign INT_SUM[15] = INT_CARRY[9]; smhalfadder dha5 (.DATA_A (INT_SUM[14]), .DATA_B (INT_SUM[15]), .SAVE (INT_SUM[16]), .CARRY (INT_CARRY[10]) ); smffb dla37 (.D(INT_SUM[16]), .clk(clk), .en_d2(en_d2), .Q(SUM[7]) ); smffb dla38 (.D(INT_CARRY[10]), .clk(clk), .en_d2(en_d2), .Q(CARRY[7]) ); smffa dla39 (.D(SUMMAND[24]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[24]) ); smffa dla40 (.D(SUMMAND[25]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[25]) ); smffa dla41 (.D(SUMMAND[26]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[26]) ); smfulladder dfa7 (.DATA_A (LATCHED_PP[24]), .DATA_B (LATCHED_PP[25]), .DATA_C (LATCHED_PP[26]), .SAVE (INT_SUM[17]), .CARRY (INT_CARRY[14]) ); smffa dla42 (.D(SUMMAND[27]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[27]) ); smffa dla43 (.D(SUMMAND[28]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[28]) ); smffa dla44 (.D(SUMMAND[29]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[29]) ); smfulladder dfa8 (.DATA_A (LATCHED_PP[27]), .DATA_B (LATCHED_PP[28]), .DATA_C (LATCHED_PP[29]), .SAVE (INT_SUM[18]), .CARRY (INT_CARRY[15]) ); smfulladder dfa9 (.DATA_A (INT_SUM[17]), .DATA_B (INT_SUM[18]), .DATA_C (INT_CARRY[11]), .SAVE (INT_SUM[19]), .CARRY (INT_CARRY[16]) ); smhalfadder dha6 (.DATA_A (INT_SUM[19]), .DATA_B (INT_CARRY[12]), .SAVE (INT_SUM[20]), .CARRY (INT_CARRY[13]) ); smffb dla45 (.D(INT_SUM[20]), .clk(clk), .en_d2(en_d2), .Q(SUM[8]) ); smffb dla46 (.D(INT_CARRY[13]), .clk(clk), .en_d2(en_d2), .Q(CARRY[8]) ); smffa dla47 (.D(SUMMAND[30]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[30]) ); smffa dla48 (.D(SUMMAND[31]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[31]) ); smffa dla49 (.D(SUMMAND[32]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[32]) ); smfulladder dfa10 (.DATA_A (LATCHED_PP[30]), .DATA_B (LATCHED_PP[31]), .DATA_C (LATCHED_PP[32]), .SAVE (INT_SUM[21]), .CARRY (INT_CARRY[18]) ); smffa dla50 (.D(SUMMAND[33]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[33]) ); smffa dla51 (.D(SUMMAND[34]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[34]) ); smhalfadder dha7 (.DATA_A (LATCHED_PP[33]), .DATA_B (LATCHED_PP[34]), .SAVE (INT_SUM[22]), .CARRY (INT_CARRY[19]) ); smfulladder dfa11 (.DATA_A (INT_SUM[21]), .DATA_B (INT_SUM[22]), .DATA_C (INT_CARRY[14]), .SAVE (INT_SUM[23]), .CARRY (INT_CARRY[20]) ); assign INT_SUM[24] = INT_CARRY[15]; smfulladder dfa12 (.DATA_A (INT_SUM[23]), .DATA_B (INT_SUM[24]), .DATA_C (INT_CARRY[16]), .SAVE (INT_SUM[25]), .CARRY (INT_CARRY[17]) ); smffb dla52 (.D(INT_SUM[25]), .clk(clk), .en_d2(en_d2), .Q(SUM[9]) ); smffb dla53 (.D(INT_CARRY[17]), .clk(clk), .en_d2(en_d2), .Q(CARRY[9]) ); smffa dla54 (.D(SUMMAND[35]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[35]) ); smffa dla55 (.D(SUMMAND[36]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[36]) ); smffa dla56 (.D(SUMMAND[37]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[37]) ); smfulladder dfa13 (.DATA_A (LATCHED_PP[35]), .DATA_B (LATCHED_PP[36]), .DATA_C (LATCHED_PP[37]), .SAVE (INT_SUM[26]), .CARRY (INT_CARRY[22]) ); smffa dla57 (.D(SUMMAND[38]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[38]) ); smffa dla58 (.D(SUMMAND[39]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[39]) ); smffa dla59 (.D(SUMMAND[40]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[40]) ); smfulladder dfa14 (.DATA_A (LATCHED_PP[38]), .DATA_B (LATCHED_PP[39]), .DATA_C (LATCHED_PP[40]), .SAVE (INT_SUM[27]), .CARRY (INT_CARRY[23]) ); smffa dla60 (.D(SUMMAND[41]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[41]) ); assign INT_SUM[28] = LATCHED_PP[41]; smfulladder dfa15 (.DATA_A (INT_SUM[26]), .DATA_B (INT_SUM[27]), .DATA_C (INT_SUM[28]), .SAVE (INT_SUM[29]), .CARRY (INT_CARRY[24]) ); smhalfadder dha8 (.DATA_A (INT_CARRY[18]), .DATA_B (INT_CARRY[19]), .SAVE (INT_SUM[30]), .CARRY (INT_CARRY[25]) ); smfulladder dfa16 (.DATA_A (INT_SUM[29]), .DATA_B (INT_SUM[30]), .DATA_C (INT_CARRY[20]), .SAVE (INT_SUM[31]), .CARRY (INT_CARRY[21]) ); smffb dla61 (.D(INT_SUM[31]), .clk(clk), .en_d2(en_d2), .Q(SUM[10]) ); smffb dla62 (.D(INT_CARRY[21]), .clk(clk), .en_d2(en_d2), .Q(CARRY[10]) ); smffa dla63 (.D(SUMMAND[42]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[42]) ); smffa dla64 (.D(SUMMAND[43]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[43]) ); smffa dla65 (.D(SUMMAND[44]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[44]) ); smfulladder dfa17 (.DATA_A (LATCHED_PP[42]), .DATA_B (LATCHED_PP[43]), .DATA_C (LATCHED_PP[44]), .SAVE (INT_SUM[32]), .CARRY (INT_CARRY[27]) ); smffa dla66 (.D(SUMMAND[45]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[45]) ); smffa dla67 (.D(SUMMAND[46]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[46]) ); smffa dla68 (.D(SUMMAND[47]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[47]) ); smfulladder dfa18 (.DATA_A (LATCHED_PP[45]), .DATA_B (LATCHED_PP[46]), .DATA_C (LATCHED_PP[47]), .SAVE (INT_SUM[33]), .CARRY (INT_CARRY[28]) ); smfulladder dfa19 (.DATA_A (INT_SUM[32]), .DATA_B (INT_SUM[33]), .DATA_C (INT_CARRY[22]), .SAVE (INT_SUM[34]), .CARRY (INT_CARRY[29]) ); assign INT_SUM[35] = INT_CARRY[23]; smfulladder dfa20 (.DATA_A (INT_SUM[34]), .DATA_B (INT_SUM[35]), .DATA_C (INT_CARRY[24]), .SAVE (INT_SUM[36]), .CARRY (INT_CARRY[30]) ); assign INT_SUM[37] = INT_CARRY[25]; smhalfadder dha9 (.DATA_A (INT_SUM[36]), .DATA_B (INT_SUM[37]), .SAVE (INT_SUM[38]), .CARRY (INT_CARRY[26]) ); smffb dla69 (.D(INT_SUM[38]), .clk(clk), .en_d2(en_d2), .Q(SUM[11]) ); smffb dla70 (.D(INT_CARRY[26]), .clk(clk), .en_d2(en_d2), .Q(CARRY[11]) ); smffa dla71 (.D(SUMMAND[48]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[48]) ); smffa dla72 (.D(SUMMAND[49]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[49]) ); smffa dla73 (.D(SUMMAND[50]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[50]) ); smfulladder dfa21 (.DATA_A (LATCHED_PP[48]), .DATA_B (LATCHED_PP[49]), .DATA_C (LATCHED_PP[50]), .SAVE (INT_SUM[39]), .CARRY (INT_CARRY[32]) ); smffa dla74 (.D(SUMMAND[51]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[51]) ); smffa dla75 (.D(SUMMAND[52]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[52]) ); smffa dla76 (.D(SUMMAND[53]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[53]) ); smfulladder dfa22 (.DATA_A (LATCHED_PP[51]), .DATA_B (LATCHED_PP[52]), .DATA_C (LATCHED_PP[53]), .SAVE (INT_SUM[40]), .CARRY (INT_CARRY[33]) ); smffa dla77 (.D(SUMMAND[54]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[54]) ); assign INT_SUM[41] = LATCHED_PP[54]; smffa dla78 (.D(SUMMAND[55]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[55]) ); assign INT_SUM[42] = LATCHED_PP[55]; smfulladder dfa23 (.DATA_A (INT_SUM[39]), .DATA_B (INT_SUM[40]), .DATA_C (INT_SUM[41]), .SAVE (INT_SUM[43]), .CARRY (INT_CARRY[34]) ); smfulladder dfa24 (.DATA_A (INT_SUM[42]), .DATA_B (INT_CARRY[27]), .DATA_C (INT_CARRY[28]), .SAVE (INT_SUM[44]), .CARRY (INT_CARRY[35]) ); smfulladder dfa25 (.DATA_A (INT_SUM[43]), .DATA_B (INT_SUM[44]), .DATA_C (INT_CARRY[29]), .SAVE (INT_SUM[45]), .CARRY (INT_CARRY[36]) ); smhalfadder dha10 (.DATA_A (INT_SUM[45]), .DATA_B (INT_CARRY[30]), .SAVE (INT_SUM[46]), .CARRY (INT_CARRY[31]) ); smffb dla79 (.D(INT_SUM[46]), .clk(clk), .en_d2(en_d2), .Q(SUM[12]) ); smffb dla80 (.D(INT_CARRY[31]), .clk(clk), .en_d2(en_d2), .Q(CARRY[12]) ); smffa dla81 (.D(SUMMAND[56]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[56]) ); smffa dla82 (.D(SUMMAND[57]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[57]) ); smffa dla83 (.D(SUMMAND[58]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[58]) ); smfulladder dfa26 (.DATA_A (LATCHED_PP[56]), .DATA_B (LATCHED_PP[57]), .DATA_C (LATCHED_PP[58]), .SAVE (INT_SUM[47]), .CARRY (INT_CARRY[38]) ); smffa dla84 (.D(SUMMAND[59]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[59]) ); smffa dla85 (.D(SUMMAND[60]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[60]) ); smffa dla86 (.D(SUMMAND[61]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[61]) ); smfulladder dfa27 (.DATA_A (LATCHED_PP[59]), .DATA_B (LATCHED_PP[60]), .DATA_C (LATCHED_PP[61]), .SAVE (INT_SUM[48]), .CARRY (INT_CARRY[39]) ); smffa dla87 (.D(SUMMAND[62]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[62]) ); assign INT_SUM[49] = LATCHED_PP[62]; smfulladder dfa28 (.DATA_A (INT_SUM[47]), .DATA_B (INT_SUM[48]), .DATA_C (INT_SUM[49]), .SAVE (INT_SUM[50]), .CARRY (INT_CARRY[40]) ); smhalfadder dha11 (.DATA_A (INT_CARRY[32]), .DATA_B (INT_CARRY[33]), .SAVE (INT_SUM[51]), .CARRY (INT_CARRY[41]) ); smfulladder dfa29 (.DATA_A (INT_SUM[50]), .DATA_B (INT_SUM[51]), .DATA_C (INT_CARRY[34]), .SAVE (INT_SUM[52]), .CARRY (INT_CARRY[42]) ); assign INT_SUM[53] = INT_CARRY[35]; smfulladder dfa30 (.DATA_A (INT_SUM[52]), .DATA_B (INT_SUM[53]), .DATA_C (INT_CARRY[36]), .SAVE (INT_SUM[54]), .CARRY (INT_CARRY[37]) ); smffb dla88 (.D(INT_SUM[54]), .clk(clk), .en_d2(en_d2), .Q(SUM[13]) ); smffb dla89 (.D(INT_CARRY[37]), .clk(clk), .en_d2(en_d2), .Q(CARRY[13]) ); smffa dla90 (.D(SUMMAND[63]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[63]) ); smffa dla91 (.D(SUMMAND[64]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[64]) ); smffa dla92 (.D(SUMMAND[65]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[65]) ); smfulladder dfa31 (.DATA_A (LATCHED_PP[63]), .DATA_B (LATCHED_PP[64]), .DATA_C (LATCHED_PP[65]), .SAVE (INT_SUM[55]), .CARRY (INT_CARRY[44]) ); smffa dla93 (.D(SUMMAND[66]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[66]) ); smffa dla94 (.D(SUMMAND[67]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[67]) ); smffa dla95 (.D(SUMMAND[68]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[68]) ); smfulladder dfa32 (.DATA_A (LATCHED_PP[66]), .DATA_B (LATCHED_PP[67]), .DATA_C (LATCHED_PP[68]), .SAVE (INT_SUM[56]), .CARRY (INT_CARRY[45]) ); smffa dla96 (.D(SUMMAND[69]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[69]) ); smffa dla97 (.D(SUMMAND[70]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[70]) ); smffa dla98 (.D(SUMMAND[71]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[71]) ); smfulladder dfa33 (.DATA_A (LATCHED_PP[69]), .DATA_B (LATCHED_PP[70]), .DATA_C (LATCHED_PP[71]), .SAVE (INT_SUM[57]), .CARRY (INT_CARRY[46]) ); smfulladder dfa34 (.DATA_A (INT_SUM[55]), .DATA_B (INT_SUM[56]), .DATA_C (INT_SUM[57]), .SAVE (INT_SUM[58]), .CARRY (INT_CARRY[47]) ); smhalfadder dha12 (.DATA_A (INT_CARRY[38]), .DATA_B (INT_CARRY[39]), .SAVE (INT_SUM[59]), .CARRY (INT_CARRY[48]) ); smfulladder dfa35 (.DATA_A (INT_SUM[58]), .DATA_B (INT_SUM[59]), .DATA_C (INT_CARRY[40]), .SAVE (INT_SUM[60]), .CARRY (INT_CARRY[49]) ); assign INT_SUM[61] = INT_CARRY[41]; smfulladder dfa36 (.DATA_A (INT_SUM[60]), .DATA_B (INT_SUM[61]), .DATA_C (INT_CARRY[42]), .SAVE (INT_SUM[62]), .CARRY (INT_CARRY[43]) ); smffb dla99 (.D(INT_SUM[62]), .clk(clk), .en_d2(en_d2), .Q(SUM[14]) ); smffb dla100 (.D(INT_CARRY[43]), .clk(clk), .en_d2(en_d2), .Q(CARRY[14]) ); smffa dla101 (.D(SUMMAND[72]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[72]) ); smffa dla102 (.D(SUMMAND[73]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[73]) ); smffa dla103 (.D(SUMMAND[74]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[74]) ); smfulladder dfa37 (.DATA_A (LATCHED_PP[72]), .DATA_B (LATCHED_PP[73]), .DATA_C (LATCHED_PP[74]), .SAVE (INT_SUM[63]), .CARRY (INT_CARRY[51]) ); smffa dla104 (.D(SUMMAND[75]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[75]) ); smffa dla105 (.D(SUMMAND[76]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[76]) ); smffa dla106 (.D(SUMMAND[77]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[77]) ); smfulladder dfa38 (.DATA_A (LATCHED_PP[75]), .DATA_B (LATCHED_PP[76]), .DATA_C (LATCHED_PP[77]), .SAVE (INT_SUM[64]), .CARRY (INT_CARRY[52]) ); smffa dla107 (.D(SUMMAND[78]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[78]) ); smffa dla108 (.D(SUMMAND[79]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[79]) ); smhalfadder dha13 (.DATA_A (LATCHED_PP[78]), .DATA_B (LATCHED_PP[79]), .SAVE (INT_SUM[65]), .CARRY (INT_CARRY[53]) ); smfulladder dfa39 (.DATA_A (INT_SUM[63]), .DATA_B (INT_SUM[64]), .DATA_C (INT_SUM[65]), .SAVE (INT_SUM[66]), .CARRY (INT_CARRY[54]) ); smfulladder dfa40 (.DATA_A (INT_CARRY[44]), .DATA_B (INT_CARRY[45]), .DATA_C (INT_CARRY[46]), .SAVE (INT_SUM[67]), .CARRY (INT_CARRY[55]) ); smfulladder dfa41 (.DATA_A (INT_SUM[66]), .DATA_B (INT_SUM[67]), .DATA_C (INT_CARRY[47]), .SAVE (INT_SUM[68]), .CARRY (INT_CARRY[56]) ); assign INT_SUM[69] = INT_CARRY[48]; smfulladder dfa42 (.DATA_A (INT_SUM[68]), .DATA_B (INT_SUM[69]), .DATA_C (INT_CARRY[49]), .SAVE (INT_SUM[70]), .CARRY (INT_CARRY[50]) ); smffb dla109 (.D(INT_SUM[70]), .clk(clk), .en_d2(en_d2), .Q(SUM[15]) ); smffb dla110 (.D(INT_CARRY[50]), .clk(clk), .en_d2(en_d2), .Q(CARRY[15]) ); smffa dla111 (.D(SUMMAND[80]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[80]) ); smffa dla112 (.D(SUMMAND[81]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[81]) ); smffa dla113 (.D(SUMMAND[82]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[82]) ); smfulladder dfa43 (.DATA_A (LATCHED_PP[80]), .DATA_B (LATCHED_PP[81]), .DATA_C (LATCHED_PP[82]), .SAVE (INT_SUM[71]), .CARRY (INT_CARRY[58]) ); smffa dla114 (.D(SUMMAND[83]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[83]) ); smffa dla115 (.D(SUMMAND[84]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[84]) ); smffa dla116 (.D(SUMMAND[85]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[85]) ); smfulladder dfa44 (.DATA_A (LATCHED_PP[83]), .DATA_B (LATCHED_PP[84]), .DATA_C (LATCHED_PP[85]), .SAVE (INT_SUM[72]), .CARRY (INT_CARRY[59]) ); smffa dla117 (.D(SUMMAND[86]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[86]) ); smffa dla118 (.D(SUMMAND[87]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[87]) ); smffa dla119 (.D(SUMMAND[88]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[88]) ); smfulladder dfa45 (.DATA_A (LATCHED_PP[86]), .DATA_B (LATCHED_PP[87]), .DATA_C (LATCHED_PP[88]), .SAVE (INT_SUM[73]), .CARRY (INT_CARRY[60]) ); smffa dla120 (.D(SUMMAND[89]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[89]) ); assign INT_SUM[74] = LATCHED_PP[89]; smfulladder dfa46 (.DATA_A (INT_SUM[71]), .DATA_B (INT_SUM[72]), .DATA_C (INT_SUM[73]), .SAVE (INT_SUM[75]), .CARRY (INT_CARRY[61]) ); smfulladder dfa47 (.DATA_A (INT_SUM[74]), .DATA_B (INT_CARRY[51]), .DATA_C (INT_CARRY[52]), .SAVE (INT_SUM[76]), .CARRY (INT_CARRY[62]) ); assign INT_SUM[77] = INT_CARRY[53]; smfulladder dfa48 (.DATA_A (INT_SUM[75]), .DATA_B (INT_SUM[76]), .DATA_C (INT_SUM[77]), .SAVE (INT_SUM[78]), .CARRY (INT_CARRY[63]) ); smhalfadder dha14 (.DATA_A (INT_CARRY[54]), .DATA_B (INT_CARRY[55]), .SAVE (INT_SUM[79]), .CARRY (INT_CARRY[64]) ); smfulladder dfa49 (.DATA_A (INT_SUM[78]), .DATA_B (INT_SUM[79]), .DATA_C (INT_CARRY[56]), .SAVE (INT_SUM[80]), .CARRY (INT_CARRY[57]) ); smffb dla121 (.D(INT_SUM[80]), .clk(clk), .en_d2(en_d2), .Q(SUM[16]) ); smffb dla122 (.D(INT_CARRY[57]), .clk(clk), .en_d2(en_d2), .Q(CARRY[16]) ); smffa dla123 (.D(SUMMAND[90]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[90]) ); smffa dla124 (.D(SUMMAND[91]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[91]) ); smffa dla125 (.D(SUMMAND[92]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[92]) ); smfulladder dfa50 (.DATA_A (LATCHED_PP[90]), .DATA_B (LATCHED_PP[91]), .DATA_C (LATCHED_PP[92]), .SAVE (INT_SUM[81]), .CARRY (INT_CARRY[66]) ); smffa dla126 (.D(SUMMAND[93]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[93]) ); smffa dla127 (.D(SUMMAND[94]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[94]) ); smffa dla128 (.D(SUMMAND[95]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[95]) ); smfulladder dfa51 (.DATA_A (LATCHED_PP[93]), .DATA_B (LATCHED_PP[94]), .DATA_C (LATCHED_PP[95]), .SAVE (INT_SUM[82]), .CARRY (INT_CARRY[67]) ); smffa dla129 (.D(SUMMAND[96]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[96]) ); smffa dla130 (.D(SUMMAND[97]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[97]) ); smffa dla131 (.D(SUMMAND[98]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[98]) ); smfulladder dfa52 (.DATA_A (LATCHED_PP[96]), .DATA_B (LATCHED_PP[97]), .DATA_C (LATCHED_PP[98]), .SAVE (INT_SUM[83]), .CARRY (INT_CARRY[68]) ); smfulladder dfa53 (.DATA_A (INT_SUM[81]), .DATA_B (INT_SUM[82]), .DATA_C (INT_SUM[83]), .SAVE (INT_SUM[84]), .CARRY (INT_CARRY[69]) ); smfulladder dfa54 (.DATA_A (INT_CARRY[58]), .DATA_B (INT_CARRY[59]), .DATA_C (INT_CARRY[60]), .SAVE (INT_SUM[85]), .CARRY (INT_CARRY[70]) ); smfulladder dfa55 (.DATA_A (INT_SUM[84]), .DATA_B (INT_SUM[85]), .DATA_C (INT_CARRY[61]), .SAVE (INT_SUM[86]), .CARRY (INT_CARRY[71]) ); assign INT_SUM[87] = INT_CARRY[62]; smfulladder dfa56 (.DATA_A (INT_SUM[86]), .DATA_B (INT_SUM[87]), .DATA_C (INT_CARRY[63]), .SAVE (INT_SUM[88]), .CARRY (INT_CARRY[72]) ); assign INT_SUM[89] = INT_CARRY[64]; smhalfadder dha15 (.DATA_A (INT_SUM[88]), .DATA_B (INT_SUM[89]), .SAVE (INT_SUM[90]), .CARRY (INT_CARRY[65]) ); smffb dla132 (.D(INT_SUM[90]), .clk(clk), .en_d2(en_d2), .Q(SUM[17]) ); smffb dla133 (.D(INT_CARRY[65]), .clk(clk), .en_d2(en_d2), .Q(CARRY[17]) ); smffa dla134 (.D(SUMMAND[99]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[99]) ); smffa dla135 (.D(SUMMAND[100]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[100]) ); smffa dla136 (.D(SUMMAND[101]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[101]) ); smfulladder dfa57 (.DATA_A (LATCHED_PP[99]), .DATA_B (LATCHED_PP[100]), .DATA_C (LATCHED_PP[101]), .SAVE (INT_SUM[91]), .CARRY (INT_CARRY[74]) ); smffa dla137 (.D(SUMMAND[102]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[102]) ); smffa dla138 (.D(SUMMAND[103]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[103]) ); smffa dla139 (.D(SUMMAND[104]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[104]) ); smfulladder dfa58 (.DATA_A (LATCHED_PP[102]), .DATA_B (LATCHED_PP[103]), .DATA_C (LATCHED_PP[104]), .SAVE (INT_SUM[92]), .CARRY (INT_CARRY[75]) ); smffa dla140 (.D(SUMMAND[105]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[105]) ); smffa dla141 (.D(SUMMAND[106]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[106]) ); smffa dla142 (.D(SUMMAND[107]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[107]) ); smfulladder dfa59 (.DATA_A (LATCHED_PP[105]), .DATA_B (LATCHED_PP[106]), .DATA_C (LATCHED_PP[107]), .SAVE (INT_SUM[93]), .CARRY (INT_CARRY[76]) ); smffa dla143 (.D(SUMMAND[108]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[108]) ); assign INT_SUM[94] = LATCHED_PP[108]; smffa dla144 (.D(SUMMAND[109]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[109]) ); assign INT_SUM[95] = LATCHED_PP[109]; smfulladder dfa60 (.DATA_A (INT_SUM[91]), .DATA_B (INT_SUM[92]), .DATA_C (INT_SUM[93]), .SAVE (INT_SUM[96]), .CARRY (INT_CARRY[77]) ); smfulladder dfa61 (.DATA_A (INT_SUM[94]), .DATA_B (INT_SUM[95]), .DATA_C (INT_CARRY[66]), .SAVE (INT_SUM[97]), .CARRY (INT_CARRY[78]) ); assign INT_SUM[98] = INT_CARRY[67]; assign INT_SUM[99] = INT_CARRY[68]; smfulladder dfa62 (.DATA_A (INT_SUM[96]), .DATA_B (INT_SUM[97]), .DATA_C (INT_SUM[98]), .SAVE (INT_SUM[100]), .CARRY (INT_CARRY[79]) ); smfulladder dfa63 (.DATA_A (INT_SUM[99]), .DATA_B (INT_CARRY[69]), .DATA_C (INT_CARRY[70]), .SAVE (INT_SUM[101]), .CARRY (INT_CARRY[80]) ); smfulladder dfa64 (.DATA_A (INT_SUM[100]), .DATA_B (INT_SUM[101]), .DATA_C (INT_CARRY[71]), .SAVE (INT_SUM[102]), .CARRY (INT_CARRY[81]) ); smhalfadder dha16 (.DATA_A (INT_SUM[102]), .DATA_B (INT_CARRY[72]), .SAVE (INT_SUM[103]), .CARRY (INT_CARRY[73]) ); smffb dla145 (.D(INT_SUM[103]), .clk(clk), .en_d2(en_d2), .Q(SUM[18]) ); smffb dla146 (.D(INT_CARRY[73]), .clk(clk), .en_d2(en_d2), .Q(CARRY[18]) ); smffa dla147 (.D(SUMMAND[110]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[110]) ); smffa dla148 (.D(SUMMAND[111]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[111]) ); smffa dla149 (.D(SUMMAND[112]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[112]) ); smfulladder dfa65 (.DATA_A (LATCHED_PP[110]), .DATA_B (LATCHED_PP[111]), .DATA_C (LATCHED_PP[112]), .SAVE (INT_SUM[104]), .CARRY (INT_CARRY[83]) ); smffa dla150 (.D(SUMMAND[113]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[113]) ); smffa dla151 (.D(SUMMAND[114]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[114]) ); smffa dla152 (.D(SUMMAND[115]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[115]) ); smfulladder dfa66 (.DATA_A (LATCHED_PP[113]), .DATA_B (LATCHED_PP[114]), .DATA_C (LATCHED_PP[115]), .SAVE (INT_SUM[105]), .CARRY (INT_CARRY[84]) ); smffa dla153 (.D(SUMMAND[116]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[116]) ); smffa dla154 (.D(SUMMAND[117]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[117]) ); smffa dla155 (.D(SUMMAND[118]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[118]) ); smfulladder dfa67 (.DATA_A (LATCHED_PP[116]), .DATA_B (LATCHED_PP[117]), .DATA_C (LATCHED_PP[118]), .SAVE (INT_SUM[106]), .CARRY (INT_CARRY[85]) ); smffa dla156 (.D(SUMMAND[119]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[119]) ); assign INT_SUM[107] = LATCHED_PP[119]; smfulladder dfa68 (.DATA_A (INT_SUM[104]), .DATA_B (INT_SUM[105]), .DATA_C (INT_SUM[106]), .SAVE (INT_SUM[108]), .CARRY (INT_CARRY[86]) ); smfulladder dfa69 (.DATA_A (INT_SUM[107]), .DATA_B (INT_CARRY[74]), .DATA_C (INT_CARRY[75]), .SAVE (INT_SUM[109]), .CARRY (INT_CARRY[87]) ); assign INT_SUM[110] = INT_CARRY[76]; smfulladder dfa70 (.DATA_A (INT_SUM[108]), .DATA_B (INT_SUM[109]), .DATA_C (INT_SUM[110]), .SAVE (INT_SUM[111]), .CARRY (INT_CARRY[88]) ); smhalfadder dha17 (.DATA_A (INT_CARRY[77]), .DATA_B (INT_CARRY[78]), .SAVE (INT_SUM[112]), .CARRY (INT_CARRY[89]) ); smfulladder dfa71 (.DATA_A (INT_SUM[111]), .DATA_B (INT_SUM[112]), .DATA_C (INT_CARRY[79]), .SAVE (INT_SUM[113]), .CARRY (INT_CARRY[90]) ); assign INT_SUM[114] = INT_CARRY[80]; smfulladder dfa72 (.DATA_A (INT_SUM[113]), .DATA_B (INT_SUM[114]), .DATA_C (INT_CARRY[81]), .SAVE (INT_SUM[115]), .CARRY (INT_CARRY[82]) ); smffb dla157 (.D(INT_SUM[115]), .clk(clk), .en_d2(en_d2), .Q(SUM[19]) ); smffb dla158 (.D(INT_CARRY[82]), .clk(clk), .en_d2(en_d2), .Q(CARRY[19]) ); smffa dla159 (.D(SUMMAND[120]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[120]) ); smffa dla160 (.D(SUMMAND[121]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[121]) ); smffa dla161 (.D(SUMMAND[122]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[122]) ); smfulladder dfa73 (.DATA_A (LATCHED_PP[120]), .DATA_B (LATCHED_PP[121]), .DATA_C (LATCHED_PP[122]), .SAVE (INT_SUM[116]), .CARRY (INT_CARRY[92]) ); smffa dla162 (.D(SUMMAND[123]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[123]) ); smffa dla163 (.D(SUMMAND[124]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[124]) ); smffa dla164 (.D(SUMMAND[125]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[125]) ); smfulladder dfa74 (.DATA_A (LATCHED_PP[123]), .DATA_B (LATCHED_PP[124]), .DATA_C (LATCHED_PP[125]), .SAVE (INT_SUM[117]), .CARRY (INT_CARRY[93]) ); smffa dla165 (.D(SUMMAND[126]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[126]) ); smffa dla166 (.D(SUMMAND[127]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[127]) ); smffa dla167 (.D(SUMMAND[128]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[128]) ); smfulladder dfa75 (.DATA_A (LATCHED_PP[126]), .DATA_B (LATCHED_PP[127]), .DATA_C (LATCHED_PP[128]), .SAVE (INT_SUM[118]), .CARRY (INT_CARRY[94]) ); smffa dla168 (.D(SUMMAND[129]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[129]) ); smffa dla169 (.D(SUMMAND[130]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[130]) ); smffa dla170 (.D(SUMMAND[131]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[131]) ); smfulladder dfa76 (.DATA_A (LATCHED_PP[129]), .DATA_B (LATCHED_PP[130]), .DATA_C (LATCHED_PP[131]), .SAVE (INT_SUM[119]), .CARRY (INT_CARRY[95]) ); smfulladder dfa77 (.DATA_A (INT_SUM[116]), .DATA_B (INT_SUM[117]), .DATA_C (INT_SUM[118]), .SAVE (INT_SUM[120]), .CARRY (INT_CARRY[96]) ); smfulladder dfa78 (.DATA_A (INT_SUM[119]), .DATA_B (INT_CARRY[83]), .DATA_C (INT_CARRY[84]), .SAVE (INT_SUM[121]), .CARRY (INT_CARRY[97]) ); assign INT_SUM[122] = INT_CARRY[85]; smfulladder dfa79 (.DATA_A (INT_SUM[120]), .DATA_B (INT_SUM[121]), .DATA_C (INT_SUM[122]), .SAVE (INT_SUM[123]), .CARRY (INT_CARRY[98]) ); smhalfadder dha18 (.DATA_A (INT_CARRY[86]), .DATA_B (INT_CARRY[87]), .SAVE (INT_SUM[124]), .CARRY (INT_CARRY[99]) ); smfulladder dfa80 (.DATA_A (INT_SUM[123]), .DATA_B (INT_SUM[124]), .DATA_C (INT_CARRY[88]), .SAVE (INT_SUM[125]), .CARRY (INT_CARRY[100]) ); assign INT_SUM[126] = INT_CARRY[89]; smfulladder dfa81 (.DATA_A (INT_SUM[125]), .DATA_B (INT_SUM[126]), .DATA_C (INT_CARRY[90]), .SAVE (INT_SUM[127]), .CARRY (INT_CARRY[91]) ); smffb dla171 (.D(INT_SUM[127]), .clk(clk), .en_d2(en_d2), .Q(SUM[20]) ); smffb dla172 (.D(INT_CARRY[91]), .clk(clk), .en_d2(en_d2), .Q(CARRY[20]) ); smffa dla173 (.D(SUMMAND[132]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[132]) ); smffa dla174 (.D(SUMMAND[133]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[133]) ); smffa dla175 (.D(SUMMAND[134]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[134]) ); smfulladder dfa82 (.DATA_A (LATCHED_PP[132]), .DATA_B (LATCHED_PP[133]), .DATA_C (LATCHED_PP[134]), .SAVE (INT_SUM[128]), .CARRY (INT_CARRY[102]) ); smffa dla176 (.D(SUMMAND[135]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[135]) ); smffa dla177 (.D(SUMMAND[136]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[136]) ); smffa dla178 (.D(SUMMAND[137]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[137]) ); smfulladder dfa83 (.DATA_A (LATCHED_PP[135]), .DATA_B (LATCHED_PP[136]), .DATA_C (LATCHED_PP[137]), .SAVE (INT_SUM[129]), .CARRY (INT_CARRY[103]) ); smffa dla179 (.D(SUMMAND[138]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[138]) ); smffa dla180 (.D(SUMMAND[139]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[139]) ); smffa dla181 (.D(SUMMAND[140]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[140]) ); smfulladder dfa84 (.DATA_A (LATCHED_PP[138]), .DATA_B (LATCHED_PP[139]), .DATA_C (LATCHED_PP[140]), .SAVE (INT_SUM[130]), .CARRY (INT_CARRY[104]) ); smffa dla182 (.D(SUMMAND[141]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[141]) ); assign INT_SUM[131] = LATCHED_PP[141]; smffa dla183 (.D(SUMMAND[142]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[142]) ); assign INT_SUM[132] = LATCHED_PP[142]; smfulladder dfa85 (.DATA_A (INT_SUM[128]), .DATA_B (INT_SUM[129]), .DATA_C (INT_SUM[130]), .SAVE (INT_SUM[133]), .CARRY (INT_CARRY[105]) ); smfulladder dfa86 (.DATA_A (INT_SUM[131]), .DATA_B (INT_SUM[132]), .DATA_C (INT_CARRY[92]), .SAVE (INT_SUM[134]), .CARRY (INT_CARRY[106]) ); smfulladder dfa87 (.DATA_A (INT_CARRY[93]), .DATA_B (INT_CARRY[94]), .DATA_C (INT_CARRY[95]), .SAVE (INT_SUM[135]), .CARRY (INT_CARRY[107]) ); smfulladder dfa88 (.DATA_A (INT_SUM[133]), .DATA_B (INT_SUM[134]), .DATA_C (INT_SUM[135]), .SAVE (INT_SUM[136]), .CARRY (INT_CARRY[108]) ); smhalfadder dha19 (.DATA_A (INT_CARRY[96]), .DATA_B (INT_CARRY[97]), .SAVE (INT_SUM[137]), .CARRY (INT_CARRY[109]) ); smfulladder dfa89 (.DATA_A (INT_SUM[136]), .DATA_B (INT_SUM[137]), .DATA_C (INT_CARRY[98]), .SAVE (INT_SUM[138]), .CARRY (INT_CARRY[110]) ); assign INT_SUM[139] = INT_CARRY[99]; smfulladder dfa90 (.DATA_A (INT_SUM[138]), .DATA_B (INT_SUM[139]), .DATA_C (INT_CARRY[100]), .SAVE (INT_SUM[140]), .CARRY (INT_CARRY[101]) ); smffb dla184 (.D(INT_SUM[140]), .clk(clk), .en_d2(en_d2), .Q(SUM[21]) ); smffb dla185 (.D(INT_CARRY[101]), .clk(clk), .en_d2(en_d2), .Q(CARRY[21]) ); smffa dla186 (.D(SUMMAND[143]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[143]) ); smffa dla187 (.D(SUMMAND[144]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[144]) ); smffa dla188 (.D(SUMMAND[145]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[145]) ); smfulladder dfa91 (.DATA_A (LATCHED_PP[143]), .DATA_B (LATCHED_PP[144]), .DATA_C (LATCHED_PP[145]), .SAVE (INT_SUM[141]), .CARRY (INT_CARRY[112]) ); smffa dla189 (.D(SUMMAND[146]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[146]) ); smffa dla190 (.D(SUMMAND[147]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[147]) ); smffa dla191 (.D(SUMMAND[148]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[148]) ); smfulladder dfa92 (.DATA_A (LATCHED_PP[146]), .DATA_B (LATCHED_PP[147]), .DATA_C (LATCHED_PP[148]), .SAVE (INT_SUM[142]), .CARRY (INT_CARRY[113]) ); smffa dla192 (.D(SUMMAND[149]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[149]) ); smffa dla193 (.D(SUMMAND[150]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[150]) ); smffa dla194 (.D(SUMMAND[151]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[151]) ); smfulladder dfa93 (.DATA_A (LATCHED_PP[149]), .DATA_B (LATCHED_PP[150]), .DATA_C (LATCHED_PP[151]), .SAVE (INT_SUM[143]), .CARRY (INT_CARRY[114]) ); smffa dla195 (.D(SUMMAND[152]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[152]) ); smffa dla196 (.D(SUMMAND[153]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[153]) ); smffa dla197 (.D(SUMMAND[154]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[154]) ); smfulladder dfa94 (.DATA_A (LATCHED_PP[152]), .DATA_B (LATCHED_PP[153]), .DATA_C (LATCHED_PP[154]), .SAVE (INT_SUM[144]), .CARRY (INT_CARRY[115]) ); smffa dla198 (.D(SUMMAND[155]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[155]) ); assign INT_SUM[145] = LATCHED_PP[155]; smfulladder dfa95 (.DATA_A (INT_SUM[141]), .DATA_B (INT_SUM[142]), .DATA_C (INT_SUM[143]), .SAVE (INT_SUM[146]), .CARRY (INT_CARRY[116]) ); smfulladder dfa96 (.DATA_A (INT_SUM[144]), .DATA_B (INT_SUM[145]), .DATA_C (INT_CARRY[102]), .SAVE (INT_SUM[147]), .CARRY (INT_CARRY[117]) ); smhalfadder dha20 (.DATA_A (INT_CARRY[103]), .DATA_B (INT_CARRY[104]), .SAVE (INT_SUM[148]), .CARRY (INT_CARRY[118]) ); smfulladder dfa97 (.DATA_A (INT_SUM[146]), .DATA_B (INT_SUM[147]), .DATA_C (INT_SUM[148]), .SAVE (INT_SUM[149]), .CARRY (INT_CARRY[119]) ); smfulladder dfa98 (.DATA_A (INT_CARRY[105]), .DATA_B (INT_CARRY[106]), .DATA_C (INT_CARRY[107]), .SAVE (INT_SUM[150]), .CARRY (INT_CARRY[120]) ); smfulladder dfa99 (.DATA_A (INT_SUM[149]), .DATA_B (INT_SUM[150]), .DATA_C (INT_CARRY[108]), .SAVE (INT_SUM[151]), .CARRY (INT_CARRY[121]) ); assign INT_SUM[152] = INT_CARRY[109]; smfulladder dfa100 (.DATA_A (INT_SUM[151]), .DATA_B (INT_SUM[152]), .DATA_C (INT_CARRY[110]), .SAVE (INT_SUM[153]), .CARRY (INT_CARRY[111]) ); smffb dla199 (.D(INT_SUM[153]), .clk(clk), .en_d2(en_d2), .Q(SUM[22]) ); smffb dla200 (.D(INT_CARRY[111]), .clk(clk), .en_d2(en_d2), .Q(CARRY[22]) ); smffa dla201 (.D(SUMMAND[156]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[156]) ); smffa dla202 (.D(SUMMAND[157]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[157]) ); smffa dla203 (.D(SUMMAND[158]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[158]) ); smfulladder dfa101 (.DATA_A (LATCHED_PP[156]), .DATA_B (LATCHED_PP[157]), .DATA_C (LATCHED_PP[158]), .SAVE (INT_SUM[154]), .CARRY (INT_CARRY[123]) ); smffa dla204 (.D(SUMMAND[159]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[159]) ); smffa dla205 (.D(SUMMAND[160]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[160]) ); smffa dla206 (.D(SUMMAND[161]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[161]) ); smfulladder dfa102 (.DATA_A (LATCHED_PP[159]), .DATA_B (LATCHED_PP[160]), .DATA_C (LATCHED_PP[161]), .SAVE (INT_SUM[155]), .CARRY (INT_CARRY[124]) ); smffa dla207 (.D(SUMMAND[162]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[162]) ); smffa dla208 (.D(SUMMAND[163]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[163]) ); smffa dla209 (.D(SUMMAND[164]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[164]) ); smfulladder dfa103 (.DATA_A (LATCHED_PP[162]), .DATA_B (LATCHED_PP[163]), .DATA_C (LATCHED_PP[164]), .SAVE (INT_SUM[156]), .CARRY (INT_CARRY[125]) ); smffa dla210 (.D(SUMMAND[165]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[165]) ); smffa dla211 (.D(SUMMAND[166]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[166]) ); smffa dla212 (.D(SUMMAND[167]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[167]) ); smfulladder dfa104 (.DATA_A (LATCHED_PP[165]), .DATA_B (LATCHED_PP[166]), .DATA_C (LATCHED_PP[167]), .SAVE (INT_SUM[157]), .CARRY (INT_CARRY[126]) ); smfulladder dfa105 (.DATA_A (INT_SUM[154]), .DATA_B (INT_SUM[155]), .DATA_C (INT_SUM[156]), .SAVE (INT_SUM[158]), .CARRY (INT_CARRY[127]) ); smfulladder dfa106 (.DATA_A (INT_SUM[157]), .DATA_B (INT_CARRY[112]), .DATA_C (INT_CARRY[113]), .SAVE (INT_SUM[159]), .CARRY (INT_CARRY[128]) ); smhalfadder dha21 (.DATA_A (INT_CARRY[114]), .DATA_B (INT_CARRY[115]), .SAVE (INT_SUM[160]), .CARRY (INT_CARRY[129]) ); smfulladder dfa107 (.DATA_A (INT_SUM[158]), .DATA_B (INT_SUM[159]), .DATA_C (INT_SUM[160]), .SAVE (INT_SUM[161]), .CARRY (INT_CARRY[130]) ); smfulladder dfa108 (.DATA_A (INT_CARRY[116]), .DATA_B (INT_CARRY[117]), .DATA_C (INT_CARRY[118]), .SAVE (INT_SUM[162]), .CARRY (INT_CARRY[131]) ); smfulladder dfa109 (.DATA_A (INT_SUM[161]), .DATA_B (INT_SUM[162]), .DATA_C (INT_CARRY[119]), .SAVE (INT_SUM[163]), .CARRY (INT_CARRY[132]) ); assign INT_SUM[164] = INT_CARRY[120]; smfulladder dfa110 (.DATA_A (INT_SUM[163]), .DATA_B (INT_SUM[164]), .DATA_C (INT_CARRY[121]), .SAVE (INT_SUM[165]), .CARRY (INT_CARRY[122]) ); smffb dla213 (.D(INT_SUM[165]), .clk(clk), .en_d2(en_d2), .Q(SUM[23]) ); smffb dla214 (.D(INT_CARRY[122]), .clk(clk), .en_d2(en_d2), .Q(CARRY[23]) ); smffa dla215 (.D(SUMMAND[168]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[168]) ); smffa dla216 (.D(SUMMAND[169]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[169]) ); smffa dla217 (.D(SUMMAND[170]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[170]) ); smfulladder dfa111 (.DATA_A (LATCHED_PP[168]), .DATA_B (LATCHED_PP[169]), .DATA_C (LATCHED_PP[170]), .SAVE (INT_SUM[166]), .CARRY (INT_CARRY[134]) ); smffa dla218 (.D(SUMMAND[171]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[171]) ); smffa dla219 (.D(SUMMAND[172]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[172]) ); smffa dla220 (.D(SUMMAND[173]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[173]) ); smfulladder dfa112 (.DATA_A (LATCHED_PP[171]), .DATA_B (LATCHED_PP[172]), .DATA_C (LATCHED_PP[173]), .SAVE (INT_SUM[167]), .CARRY (INT_CARRY[135]) ); smffa dla221 (.D(SUMMAND[174]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[174]) ); smffa dla222 (.D(SUMMAND[175]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[175]) ); smffa dla223 (.D(SUMMAND[176]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[176]) ); smfulladder dfa113 (.DATA_A (LATCHED_PP[174]), .DATA_B (LATCHED_PP[175]), .DATA_C (LATCHED_PP[176]), .SAVE (INT_SUM[168]), .CARRY (INT_CARRY[136]) ); smffa dla224 (.D(SUMMAND[177]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[177]) ); smffa dla225 (.D(SUMMAND[178]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[178]) ); smffa dla226 (.D(SUMMAND[179]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[179]) ); smfulladder dfa114 (.DATA_A (LATCHED_PP[177]), .DATA_B (LATCHED_PP[178]), .DATA_C (LATCHED_PP[179]), .SAVE (INT_SUM[169]), .CARRY (INT_CARRY[137]) ); smffa dla227 (.D(SUMMAND[180]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[180]) ); smffa dla228 (.D(SUMMAND[181]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[181]) ); smhalfadder dha22 (.DATA_A (LATCHED_PP[180]), .DATA_B (LATCHED_PP[181]), .SAVE (INT_SUM[170]), .CARRY (INT_CARRY[138]) ); smfulladder dfa115 (.DATA_A (INT_SUM[166]), .DATA_B (INT_SUM[167]), .DATA_C (INT_SUM[168]), .SAVE (INT_SUM[171]), .CARRY (INT_CARRY[139]) ); smfulladder dfa116 (.DATA_A (INT_SUM[169]), .DATA_B (INT_SUM[170]), .DATA_C (INT_CARRY[123]), .SAVE (INT_SUM[172]), .CARRY (INT_CARRY[140]) ); smfulladder dfa117 (.DATA_A (INT_CARRY[124]), .DATA_B (INT_CARRY[125]), .DATA_C (INT_CARRY[126]), .SAVE (INT_SUM[173]), .CARRY (INT_CARRY[141]) ); smfulladder dfa118 (.DATA_A (INT_SUM[171]), .DATA_B (INT_SUM[172]), .DATA_C (INT_SUM[173]), .SAVE (INT_SUM[174]), .CARRY (INT_CARRY[142]) ); smfulladder dfa119 (.DATA_A (INT_CARRY[127]), .DATA_B (INT_CARRY[128]), .DATA_C (INT_CARRY[129]), .SAVE (INT_SUM[175]), .CARRY (INT_CARRY[143]) ); smfulladder dfa120 (.DATA_A (INT_SUM[174]), .DATA_B (INT_SUM[175]), .DATA_C (INT_CARRY[130]), .SAVE (INT_SUM[176]), .CARRY (INT_CARRY[144]) ); assign INT_SUM[177] = INT_CARRY[131]; smfulladder dfa121 (.DATA_A (INT_SUM[176]), .DATA_B (INT_SUM[177]), .DATA_C (INT_CARRY[132]), .SAVE (INT_SUM[178]), .CARRY (INT_CARRY[133]) ); smffb dla229 (.D(INT_SUM[178]), .clk(clk), .en_d2(en_d2), .Q(SUM[24]) ); smffb dla230 (.D(INT_CARRY[133]), .clk(clk), .en_d2(en_d2), .Q(CARRY[24]) ); smffa dla231 (.D(SUMMAND[182]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[182]) ); smffa dla232 (.D(SUMMAND[183]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[183]) ); smffa dla233 (.D(SUMMAND[184]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[184]) ); smfulladder dfa122 (.DATA_A (LATCHED_PP[182]), .DATA_B (LATCHED_PP[183]), .DATA_C (LATCHED_PP[184]), .SAVE (INT_SUM[179]), .CARRY (INT_CARRY[146]) ); smffa dla234 (.D(SUMMAND[185]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[185]) ); smffa dla235 (.D(SUMMAND[186]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[186]) ); smffa dla236 (.D(SUMMAND[187]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[187]) ); smfulladder dfa123 (.DATA_A (LATCHED_PP[185]), .DATA_B (LATCHED_PP[186]), .DATA_C (LATCHED_PP[187]), .SAVE (INT_SUM[180]), .CARRY (INT_CARRY[147]) ); smffa dla237 (.D(SUMMAND[188]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[188]) ); smffa dla238 (.D(SUMMAND[189]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[189]) ); smffa dla239 (.D(SUMMAND[190]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[190]) ); smfulladder dfa124 (.DATA_A (LATCHED_PP[188]), .DATA_B (LATCHED_PP[189]), .DATA_C (LATCHED_PP[190]), .SAVE (INT_SUM[181]), .CARRY (INT_CARRY[148]) ); smffa dla240 (.D(SUMMAND[191]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[191]) ); smffa dla241 (.D(SUMMAND[192]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[192]) ); smffa dla242 (.D(SUMMAND[193]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[193]) ); smfulladder dfa125 (.DATA_A (LATCHED_PP[191]), .DATA_B (LATCHED_PP[192]), .DATA_C (LATCHED_PP[193]), .SAVE (INT_SUM[182]), .CARRY (INT_CARRY[149]) ); smffa dla243 (.D(SUMMAND[194]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[194]) ); assign INT_SUM[183] = LATCHED_PP[194]; smfulladder dfa126 (.DATA_A (INT_SUM[179]), .DATA_B (INT_SUM[180]), .DATA_C (INT_SUM[181]), .SAVE (INT_SUM[184]), .CARRY (INT_CARRY[150]) ); smfulladder dfa127 (.DATA_A (INT_SUM[182]), .DATA_B (INT_SUM[183]), .DATA_C (INT_CARRY[134]), .SAVE (INT_SUM[185]), .CARRY (INT_CARRY[151]) ); smfulladder dfa128 (.DATA_A (INT_CARRY[135]), .DATA_B (INT_CARRY[136]), .DATA_C (INT_CARRY[137]), .SAVE (INT_SUM[186]), .CARRY (INT_CARRY[152]) ); assign INT_SUM[187] = INT_CARRY[138]; smfulladder dfa129 (.DATA_A (INT_SUM[184]), .DATA_B (INT_SUM[185]), .DATA_C (INT_SUM[186]), .SAVE (INT_SUM[188]), .CARRY (INT_CARRY[153]) ); smfulladder dfa130 (.DATA_A (INT_SUM[187]), .DATA_B (INT_CARRY[139]), .DATA_C (INT_CARRY[140]), .SAVE (INT_SUM[189]), .CARRY (INT_CARRY[154]) ); assign INT_SUM[190] = INT_CARRY[141]; smfulladder dfa131 (.DATA_A (INT_SUM[188]), .DATA_B (INT_SUM[189]), .DATA_C (INT_SUM[190]), .SAVE (INT_SUM[191]), .CARRY (INT_CARRY[155]) ); smhalfadder dha23 (.DATA_A (INT_CARRY[142]), .DATA_B (INT_CARRY[143]), .SAVE (INT_SUM[192]), .CARRY (INT_CARRY[156]) ); smfulladder dfa132 (.DATA_A (INT_SUM[191]), .DATA_B (INT_SUM[192]), .DATA_C (INT_CARRY[144]), .SAVE (INT_SUM[193]), .CARRY (INT_CARRY[145]) ); smffb dla244 (.D(INT_SUM[193]), .clk(clk), .en_d2(en_d2), .Q(SUM[25]) ); smffb dla245 (.D(INT_CARRY[145]), .clk(clk), .en_d2(en_d2), .Q(CARRY[25]) ); smffa dla246 (.D(SUMMAND[195]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[195]) ); smffa dla247 (.D(SUMMAND[196]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[196]) ); smffa dla248 (.D(SUMMAND[197]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[197]) ); smfulladder dfa133 (.DATA_A (LATCHED_PP[195]), .DATA_B (LATCHED_PP[196]), .DATA_C (LATCHED_PP[197]), .SAVE (INT_SUM[194]), .CARRY (INT_CARRY[158]) ); smffa dla249 (.D(SUMMAND[198]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[198]) ); smffa dla250 (.D(SUMMAND[199]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[199]) ); smffa dla251 (.D(SUMMAND[200]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[200]) ); smfulladder dfa134 (.DATA_A (LATCHED_PP[198]), .DATA_B (LATCHED_PP[199]), .DATA_C (LATCHED_PP[200]), .SAVE (INT_SUM[195]), .CARRY (INT_CARRY[159]) ); smffa dla252 (.D(SUMMAND[201]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[201]) ); smffa dla253 (.D(SUMMAND[202]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[202]) ); smffa dla254 (.D(SUMMAND[203]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[203]) ); smfulladder dfa135 (.DATA_A (LATCHED_PP[201]), .DATA_B (LATCHED_PP[202]), .DATA_C (LATCHED_PP[203]), .SAVE (INT_SUM[196]), .CARRY (INT_CARRY[160]) ); smffa dla255 (.D(SUMMAND[204]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[204]) ); smffa dla256 (.D(SUMMAND[205]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[205]) ); smffa dla257 (.D(SUMMAND[206]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[206]) ); smfulladder dfa136 (.DATA_A (LATCHED_PP[204]), .DATA_B (LATCHED_PP[205]), .DATA_C (LATCHED_PP[206]), .SAVE (INT_SUM[197]), .CARRY (INT_CARRY[161]) ); smffa dla258 (.D(SUMMAND[207]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[207]) ); smffa dla259 (.D(SUMMAND[208]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[208]) ); smffa dla260 (.D(SUMMAND[209]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[209]) ); smfulladder dfa137 (.DATA_A (LATCHED_PP[207]), .DATA_B (LATCHED_PP[208]), .DATA_C (LATCHED_PP[209]), .SAVE (INT_SUM[198]), .CARRY (INT_CARRY[162]) ); smfulladder dfa138 (.DATA_A (INT_SUM[194]), .DATA_B (INT_SUM[195]), .DATA_C (INT_SUM[196]), .SAVE (INT_SUM[199]), .CARRY (INT_CARRY[163]) ); smfulladder dfa139 (.DATA_A (INT_SUM[197]), .DATA_B (INT_SUM[198]), .DATA_C (INT_CARRY[146]), .SAVE (INT_SUM[200]), .CARRY (INT_CARRY[164]) ); smfulladder dfa140 (.DATA_A (INT_CARRY[147]), .DATA_B (INT_CARRY[148]), .DATA_C (INT_CARRY[149]), .SAVE (INT_SUM[201]), .CARRY (INT_CARRY[165]) ); smfulladder dfa141 (.DATA_A (INT_SUM[199]), .DATA_B (INT_SUM[200]), .DATA_C (INT_SUM[201]), .SAVE (INT_SUM[202]), .CARRY (INT_CARRY[166]) ); smfulladder dfa142 (.DATA_A (INT_CARRY[150]), .DATA_B (INT_CARRY[151]), .DATA_C (INT_CARRY[152]), .SAVE (INT_SUM[203]), .CARRY (INT_CARRY[167]) ); smfulladder dfa143 (.DATA_A (INT_SUM[202]), .DATA_B (INT_SUM[203]), .DATA_C (INT_CARRY[153]), .SAVE (INT_SUM[204]), .CARRY (INT_CARRY[168]) ); assign INT_SUM[205] = INT_CARRY[154]; smfulladder dfa144 (.DATA_A (INT_SUM[204]), .DATA_B (INT_SUM[205]), .DATA_C (INT_CARRY[155]), .SAVE (INT_SUM[206]), .CARRY (INT_CARRY[169]) ); assign INT_SUM[207] = INT_CARRY[156]; smhalfadder dha24 (.DATA_A (INT_SUM[206]), .DATA_B (INT_SUM[207]), .SAVE (INT_SUM[208]), .CARRY (INT_CARRY[157]) ); smffb dla261 (.D(INT_SUM[208]), .clk(clk), .en_d2(en_d2), .Q(SUM[26]) ); smffb dla262 (.D(INT_CARRY[157]), .clk(clk), .en_d2(en_d2), .Q(CARRY[26]) ); smffa dla263 (.D(SUMMAND[210]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[210]) ); smffa dla264 (.D(SUMMAND[211]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[211]) ); smffa dla265 (.D(SUMMAND[212]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[212]) ); smfulladder dfa145 (.DATA_A (LATCHED_PP[210]), .DATA_B (LATCHED_PP[211]), .DATA_C (LATCHED_PP[212]), .SAVE (INT_SUM[209]), .CARRY (INT_CARRY[171]) ); smffa dla266 (.D(SUMMAND[213]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[213]) ); smffa dla267 (.D(SUMMAND[214]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[214]) ); smffa dla268 (.D(SUMMAND[215]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[215]) ); smfulladder dfa146 (.DATA_A (LATCHED_PP[213]), .DATA_B (LATCHED_PP[214]), .DATA_C (LATCHED_PP[215]), .SAVE (INT_SUM[210]), .CARRY (INT_CARRY[172]) ); smffa dla269 (.D(SUMMAND[216]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[216]) ); smffa dla270 (.D(SUMMAND[217]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[217]) ); smffa dla271 (.D(SUMMAND[218]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[218]) ); smfulladder dfa147 (.DATA_A (LATCHED_PP[216]), .DATA_B (LATCHED_PP[217]), .DATA_C (LATCHED_PP[218]), .SAVE (INT_SUM[211]), .CARRY (INT_CARRY[173]) ); smffa dla272 (.D(SUMMAND[219]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[219]) ); smffa dla273 (.D(SUMMAND[220]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[220]) ); smffa dla274 (.D(SUMMAND[221]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[221]) ); smfulladder dfa148 (.DATA_A (LATCHED_PP[219]), .DATA_B (LATCHED_PP[220]), .DATA_C (LATCHED_PP[221]), .SAVE (INT_SUM[212]), .CARRY (INT_CARRY[174]) ); smffa dla275 (.D(SUMMAND[222]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[222]) ); smffa dla276 (.D(SUMMAND[223]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[223]) ); smhalfadder dha25 (.DATA_A (LATCHED_PP[222]), .DATA_B (LATCHED_PP[223]), .SAVE (INT_SUM[213]), .CARRY (INT_CARRY[175]) ); smfulladder dfa149 (.DATA_A (INT_SUM[209]), .DATA_B (INT_SUM[210]), .DATA_C (INT_SUM[211]), .SAVE (INT_SUM[214]), .CARRY (INT_CARRY[176]) ); smfulladder dfa150 (.DATA_A (INT_SUM[212]), .DATA_B (INT_SUM[213]), .DATA_C (INT_CARRY[158]), .SAVE (INT_SUM[215]), .CARRY (INT_CARRY[177]) ); smfulladder dfa151 (.DATA_A (INT_CARRY[159]), .DATA_B (INT_CARRY[160]), .DATA_C (INT_CARRY[161]), .SAVE (INT_SUM[216]), .CARRY (INT_CARRY[178]) ); assign INT_SUM[217] = INT_CARRY[162]; smfulladder dfa152 (.DATA_A (INT_SUM[214]), .DATA_B (INT_SUM[215]), .DATA_C (INT_SUM[216]), .SAVE (INT_SUM[218]), .CARRY (INT_CARRY[179]) ); smfulladder dfa153 (.DATA_A (INT_SUM[217]), .DATA_B (INT_CARRY[163]), .DATA_C (INT_CARRY[164]), .SAVE (INT_SUM[219]), .CARRY (INT_CARRY[180]) ); assign INT_SUM[220] = INT_CARRY[165]; smfulladder dfa154 (.DATA_A (INT_SUM[218]), .DATA_B (INT_SUM[219]), .DATA_C (INT_SUM[220]), .SAVE (INT_SUM[221]), .CARRY (INT_CARRY[181]) ); assign INT_SUM[222] = INT_CARRY[166]; assign INT_SUM[223] = INT_CARRY[167]; smfulladder dfa155 (.DATA_A (INT_SUM[221]), .DATA_B (INT_SUM[222]), .DATA_C (INT_SUM[223]), .SAVE (INT_SUM[224]), .CARRY (INT_CARRY[182]) ); assign INT_SUM[225] = INT_CARRY[168]; smfulladder dfa156 (.DATA_A (INT_SUM[224]), .DATA_B (INT_SUM[225]), .DATA_C (INT_CARRY[169]), .SAVE (INT_SUM[226]), .CARRY (INT_CARRY[170]) ); smffb dla277 (.D(INT_SUM[226]), .clk(clk), .en_d2(en_d2), .Q(SUM[27]) ); smffb dla278 (.D(INT_CARRY[170]), .clk(clk), .en_d2(en_d2), .Q(CARRY[27]) ); smffa dla279 (.D(SUMMAND[224]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[224]) ); smffa dla280 (.D(SUMMAND[225]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[225]) ); smffa dla281 (.D(SUMMAND[226]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[226]) ); smfulladder dfa157 (.DATA_A (LATCHED_PP[224]), .DATA_B (LATCHED_PP[225]), .DATA_C (LATCHED_PP[226]), .SAVE (INT_SUM[227]), .CARRY (INT_CARRY[184]) ); smffa dla282 (.D(SUMMAND[227]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[227]) ); smffa dla283 (.D(SUMMAND[228]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[228]) ); smffa dla284 (.D(SUMMAND[229]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[229]) ); smfulladder dfa158 (.DATA_A (LATCHED_PP[227]), .DATA_B (LATCHED_PP[228]), .DATA_C (LATCHED_PP[229]), .SAVE (INT_SUM[228]), .CARRY (INT_CARRY[185]) ); smffa dla285 (.D(SUMMAND[230]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[230]) ); smffa dla286 (.D(SUMMAND[231]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[231]) ); smffa dla287 (.D(SUMMAND[232]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[232]) ); smfulladder dfa159 (.DATA_A (LATCHED_PP[230]), .DATA_B (LATCHED_PP[231]), .DATA_C (LATCHED_PP[232]), .SAVE (INT_SUM[229]), .CARRY (INT_CARRY[186]) ); smffa dla288 (.D(SUMMAND[233]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[233]) ); smffa dla289 (.D(SUMMAND[234]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[234]) ); smffa dla290 (.D(SUMMAND[235]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[235]) ); smfulladder dfa160 (.DATA_A (LATCHED_PP[233]), .DATA_B (LATCHED_PP[234]), .DATA_C (LATCHED_PP[235]), .SAVE (INT_SUM[230]), .CARRY (INT_CARRY[187]) ); smffa dla291 (.D(SUMMAND[236]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[236]) ); smffa dla292 (.D(SUMMAND[237]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[237]) ); smffa dla293 (.D(SUMMAND[238]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[238]) ); smfulladder dfa161 (.DATA_A (LATCHED_PP[236]), .DATA_B (LATCHED_PP[237]), .DATA_C (LATCHED_PP[238]), .SAVE (INT_SUM[231]), .CARRY (INT_CARRY[188]) ); smffa dla294 (.D(SUMMAND[239]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[239]) ); assign INT_SUM[232] = LATCHED_PP[239]; smfulladder dfa162 (.DATA_A (INT_SUM[227]), .DATA_B (INT_SUM[228]), .DATA_C (INT_SUM[229]), .SAVE (INT_SUM[233]), .CARRY (INT_CARRY[189]) ); smfulladder dfa163 (.DATA_A (INT_SUM[230]), .DATA_B (INT_SUM[231]), .DATA_C (INT_SUM[232]), .SAVE (INT_SUM[234]), .CARRY (INT_CARRY[190]) ); smfulladder dfa164 (.DATA_A (INT_CARRY[171]), .DATA_B (INT_CARRY[172]), .DATA_C (INT_CARRY[173]), .SAVE (INT_SUM[235]), .CARRY (INT_CARRY[191]) ); assign INT_SUM[236] = INT_CARRY[174]; assign INT_SUM[237] = INT_CARRY[175]; smfulladder dfa165 (.DATA_A (INT_SUM[233]), .DATA_B (INT_SUM[234]), .DATA_C (INT_SUM[235]), .SAVE (INT_SUM[238]), .CARRY (INT_CARRY[192]) ); smfulladder dfa166 (.DATA_A (INT_SUM[236]), .DATA_B (INT_SUM[237]), .DATA_C (INT_CARRY[176]), .SAVE (INT_SUM[239]), .CARRY (INT_CARRY[193]) ); assign INT_SUM[240] = INT_CARRY[177]; assign INT_SUM[241] = INT_CARRY[178]; smfulladder dfa167 (.DATA_A (INT_SUM[238]), .DATA_B (INT_SUM[239]), .DATA_C (INT_SUM[240]), .SAVE (INT_SUM[242]), .CARRY (INT_CARRY[194]) ); smfulladder dfa168 (.DATA_A (INT_SUM[241]), .DATA_B (INT_CARRY[179]), .DATA_C (INT_CARRY[180]), .SAVE (INT_SUM[243]), .CARRY (INT_CARRY[195]) ); smfulladder dfa169 (.DATA_A (INT_SUM[242]), .DATA_B (INT_SUM[243]), .DATA_C (INT_CARRY[181]), .SAVE (INT_SUM[244]), .CARRY (INT_CARRY[196]) ); smhalfadder dha26 (.DATA_A (INT_SUM[244]), .DATA_B (INT_CARRY[182]), .SAVE (INT_SUM[245]), .CARRY (INT_CARRY[183]) ); smffb dla295 (.D(INT_SUM[245]), .clk(clk), .en_d2(en_d2), .Q(SUM[28]) ); smffb dla296 (.D(INT_CARRY[183]), .clk(clk), .en_d2(en_d2), .Q(CARRY[28]) ); smffa dla297 (.D(SUMMAND[240]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[240]) ); smffa dla298 (.D(SUMMAND[241]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[241]) ); smffa dla299 (.D(SUMMAND[242]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[242]) ); smfulladder dfa170 (.DATA_A (LATCHED_PP[240]), .DATA_B (LATCHED_PP[241]), .DATA_C (LATCHED_PP[242]), .SAVE (INT_SUM[246]), .CARRY (INT_CARRY[198]) ); smffa dla300 (.D(SUMMAND[243]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[243]) ); smffa dla301 (.D(SUMMAND[244]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[244]) ); smffa dla302 (.D(SUMMAND[245]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[245]) ); smfulladder dfa171 (.DATA_A (LATCHED_PP[243]), .DATA_B (LATCHED_PP[244]), .DATA_C (LATCHED_PP[245]), .SAVE (INT_SUM[247]), .CARRY (INT_CARRY[199]) ); smffa dla303 (.D(SUMMAND[246]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[246]) ); smffa dla304 (.D(SUMMAND[247]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[247]) ); smffa dla305 (.D(SUMMAND[248]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[248]) ); smfulladder dfa172 (.DATA_A (LATCHED_PP[246]), .DATA_B (LATCHED_PP[247]), .DATA_C (LATCHED_PP[248]), .SAVE (INT_SUM[248]), .CARRY (INT_CARRY[200]) ); smffa dla306 (.D(SUMMAND[249]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[249]) ); smffa dla307 (.D(SUMMAND[250]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[250]) ); smffa dla308 (.D(SUMMAND[251]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[251]) ); smfulladder dfa173 (.DATA_A (LATCHED_PP[249]), .DATA_B (LATCHED_PP[250]), .DATA_C (LATCHED_PP[251]), .SAVE (INT_SUM[249]), .CARRY (INT_CARRY[201]) ); smffa dla309 (.D(SUMMAND[252]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[252]) ); smffa dla310 (.D(SUMMAND[253]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[253]) ); smffa dla311 (.D(SUMMAND[254]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[254]) ); smfulladder dfa174 (.DATA_A (LATCHED_PP[252]), .DATA_B (LATCHED_PP[253]), .DATA_C (LATCHED_PP[254]), .SAVE (INT_SUM[250]), .CARRY (INT_CARRY[202]) ); smfulladder dfa175 (.DATA_A (INT_SUM[246]), .DATA_B (INT_SUM[247]), .DATA_C (INT_SUM[248]), .SAVE (INT_SUM[251]), .CARRY (INT_CARRY[203]) ); smfulladder dfa176 (.DATA_A (INT_SUM[249]), .DATA_B (INT_SUM[250]), .DATA_C (INT_CARRY[184]), .SAVE (INT_SUM[252]), .CARRY (INT_CARRY[204]) ); smfulladder dfa177 (.DATA_A (INT_CARRY[185]), .DATA_B (INT_CARRY[186]), .DATA_C (INT_CARRY[187]), .SAVE (INT_SUM[253]), .CARRY (INT_CARRY[205]) ); assign INT_SUM[254] = INT_CARRY[188]; smfulladder dfa178 (.DATA_A (INT_SUM[251]), .DATA_B (INT_SUM[252]), .DATA_C (INT_SUM[253]), .SAVE (INT_SUM[255]), .CARRY (INT_CARRY[206]) ); smfulladder dfa179 (.DATA_A (INT_SUM[254]), .DATA_B (INT_CARRY[189]), .DATA_C (INT_CARRY[190]), .SAVE (INT_SUM[256]), .CARRY (INT_CARRY[207]) ); assign INT_SUM[257] = INT_CARRY[191]; smfulladder dfa180 (.DATA_A (INT_SUM[255]), .DATA_B (INT_SUM[256]), .DATA_C (INT_SUM[257]), .SAVE (INT_SUM[258]), .CARRY (INT_CARRY[208]) ); smhalfadder dha27 (.DATA_A (INT_CARRY[192]), .DATA_B (INT_CARRY[193]), .SAVE (INT_SUM[259]), .CARRY (INT_CARRY[209]) ); smfulladder dfa181 (.DATA_A (INT_SUM[258]), .DATA_B (INT_SUM[259]), .DATA_C (INT_CARRY[194]), .SAVE (INT_SUM[260]), .CARRY (INT_CARRY[210]) ); assign INT_SUM[261] = INT_CARRY[195]; smfulladder dfa182 (.DATA_A (INT_SUM[260]), .DATA_B (INT_SUM[261]), .DATA_C (INT_CARRY[196]), .SAVE (INT_SUM[262]), .CARRY (INT_CARRY[197]) ); smffb dla312 (.D(INT_SUM[262]), .clk(clk), .en_d2(en_d2), .Q(SUM[29]) ); smffb dla313 (.D(INT_CARRY[197]), .clk(clk), .en_d2(en_d2), .Q(CARRY[29]) ); smffa dla314 (.D(SUMMAND[255]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[255]) ); smffa dla315 (.D(SUMMAND[256]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[256]) ); smffa dla316 (.D(SUMMAND[257]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[257]) ); smfulladder dfa183 (.DATA_A (LATCHED_PP[255]), .DATA_B (LATCHED_PP[256]), .DATA_C (LATCHED_PP[257]), .SAVE (INT_SUM[263]), .CARRY (INT_CARRY[212]) ); smffa dla317 (.D(SUMMAND[258]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[258]) ); smffa dla318 (.D(SUMMAND[259]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[259]) ); smffa dla319 (.D(SUMMAND[260]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[260]) ); smfulladder dfa184 (.DATA_A (LATCHED_PP[258]), .DATA_B (LATCHED_PP[259]), .DATA_C (LATCHED_PP[260]), .SAVE (INT_SUM[264]), .CARRY (INT_CARRY[213]) ); smffa dla320 (.D(SUMMAND[261]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[261]) ); smffa dla321 (.D(SUMMAND[262]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[262]) ); smffa dla322 (.D(SUMMAND[263]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[263]) ); smfulladder dfa185 (.DATA_A (LATCHED_PP[261]), .DATA_B (LATCHED_PP[262]), .DATA_C (LATCHED_PP[263]), .SAVE (INT_SUM[265]), .CARRY (INT_CARRY[214]) ); smffa dla323 (.D(SUMMAND[264]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[264]) ); smffa dla324 (.D(SUMMAND[265]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[265]) ); smffa dla325 (.D(SUMMAND[266]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[266]) ); smfulladder dfa186 (.DATA_A (LATCHED_PP[264]), .DATA_B (LATCHED_PP[265]), .DATA_C (LATCHED_PP[266]), .SAVE (INT_SUM[266]), .CARRY (INT_CARRY[215]) ); smffa dla326 (.D(SUMMAND[267]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[267]) ); smffa dla327 (.D(SUMMAND[268]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[268]) ); smffa dla328 (.D(SUMMAND[269]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[269]) ); smfulladder dfa187 (.DATA_A (LATCHED_PP[267]), .DATA_B (LATCHED_PP[268]), .DATA_C (LATCHED_PP[269]), .SAVE (INT_SUM[267]), .CARRY (INT_CARRY[216]) ); smffa dla329 (.D(SUMMAND[270]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[270]) ); assign INT_SUM[268] = LATCHED_PP[270]; smffa dla330 (.D(SUMMAND[271]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[271]) ); assign INT_SUM[269] = LATCHED_PP[271]; smfulladder dfa188 (.DATA_A (INT_SUM[263]), .DATA_B (INT_SUM[264]), .DATA_C (INT_SUM[265]), .SAVE (INT_SUM[270]), .CARRY (INT_CARRY[217]) ); smfulladder dfa189 (.DATA_A (INT_SUM[266]), .DATA_B (INT_SUM[267]), .DATA_C (INT_SUM[268]), .SAVE (INT_SUM[271]), .CARRY (INT_CARRY[218]) ); smfulladder dfa190 (.DATA_A (INT_SUM[269]), .DATA_B (INT_CARRY[198]), .DATA_C (INT_CARRY[199]), .SAVE (INT_SUM[272]), .CARRY (INT_CARRY[219]) ); smfulladder dfa191 (.DATA_A (INT_CARRY[200]), .DATA_B (INT_CARRY[201]), .DATA_C (INT_CARRY[202]), .SAVE (INT_SUM[273]), .CARRY (INT_CARRY[220]) ); smfulladder dfa192 (.DATA_A (INT_SUM[270]), .DATA_B (INT_SUM[271]), .DATA_C (INT_SUM[272]), .SAVE (INT_SUM[274]), .CARRY (INT_CARRY[221]) ); smfulladder dfa193 (.DATA_A (INT_SUM[273]), .DATA_B (INT_CARRY[203]), .DATA_C (INT_CARRY[204]), .SAVE (INT_SUM[275]), .CARRY (INT_CARRY[222]) ); assign INT_SUM[276] = INT_CARRY[205]; smfulladder dfa194 (.DATA_A (INT_SUM[274]), .DATA_B (INT_SUM[275]), .DATA_C (INT_SUM[276]), .SAVE (INT_SUM[277]), .CARRY (INT_CARRY[223]) ); smhalfadder dha28 (.DATA_A (INT_CARRY[206]), .DATA_B (INT_CARRY[207]), .SAVE (INT_SUM[278]), .CARRY (INT_CARRY[224]) ); smfulladder dfa195 (.DATA_A (INT_SUM[277]), .DATA_B (INT_SUM[278]), .DATA_C (INT_CARRY[208]), .SAVE (INT_SUM[279]), .CARRY (INT_CARRY[225]) ); assign INT_SUM[280] = INT_CARRY[209]; smfulladder dfa196 (.DATA_A (INT_SUM[279]), .DATA_B (INT_SUM[280]), .DATA_C (INT_CARRY[210]), .SAVE (INT_SUM[281]), .CARRY (INT_CARRY[211]) ); smffb dla331 (.D(INT_SUM[281]), .clk(clk), .en_d2(en_d2), .Q(SUM[30]) ); smffb dla332 (.D(INT_CARRY[211]), .clk(clk), .en_d2(en_d2), .Q(CARRY[30]) ); smffa dla333 (.D(SUMMAND[272]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[272]) ); smffa dla334 (.D(SUMMAND[273]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[273]) ); smffa dla335 (.D(SUMMAND[274]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[274]) ); smfulladder dfa197 (.DATA_A (LATCHED_PP[272]), .DATA_B (LATCHED_PP[273]), .DATA_C (LATCHED_PP[274]), .SAVE (INT_SUM[282]), .CARRY (INT_CARRY[227]) ); smffa dla336 (.D(SUMMAND[275]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[275]) ); smffa dla337 (.D(SUMMAND[276]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[276]) ); smffa dla338 (.D(SUMMAND[277]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[277]) ); smfulladder dfa198 (.DATA_A (LATCHED_PP[275]), .DATA_B (LATCHED_PP[276]), .DATA_C (LATCHED_PP[277]), .SAVE (INT_SUM[283]), .CARRY (INT_CARRY[228]) ); smffa dla339 (.D(SUMMAND[278]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[278]) ); smffa dla340 (.D(SUMMAND[279]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[279]) ); smffa dla341 (.D(SUMMAND[280]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[280]) ); smfulladder dfa199 (.DATA_A (LATCHED_PP[278]), .DATA_B (LATCHED_PP[279]), .DATA_C (LATCHED_PP[280]), .SAVE (INT_SUM[284]), .CARRY (INT_CARRY[229]) ); smffa dla342 (.D(SUMMAND[281]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[281]) ); smffa dla343 (.D(SUMMAND[282]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[282]) ); smffa dla344 (.D(SUMMAND[283]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[283]) ); smfulladder dfa200 (.DATA_A (LATCHED_PP[281]), .DATA_B (LATCHED_PP[282]), .DATA_C (LATCHED_PP[283]), .SAVE (INT_SUM[285]), .CARRY (INT_CARRY[230]) ); smffa dla345 (.D(SUMMAND[284]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[284]) ); smffa dla346 (.D(SUMMAND[285]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[285]) ); smffa dla347 (.D(SUMMAND[286]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[286]) ); smfulladder dfa201 (.DATA_A (LATCHED_PP[284]), .DATA_B (LATCHED_PP[285]), .DATA_C (LATCHED_PP[286]), .SAVE (INT_SUM[286]), .CARRY (INT_CARRY[231]) ); smffa dla348 (.D(SUMMAND[287]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[287]) ); assign INT_SUM[287] = LATCHED_PP[287]; smfulladder dfa202 (.DATA_A (INT_SUM[282]), .DATA_B (INT_SUM[283]), .DATA_C (INT_SUM[284]), .SAVE (INT_SUM[288]), .CARRY (INT_CARRY[232]) ); smfulladder dfa203 (.DATA_A (INT_SUM[285]), .DATA_B (INT_SUM[286]), .DATA_C (INT_SUM[287]), .SAVE (INT_SUM[289]), .CARRY (INT_CARRY[233]) ); smfulladder dfa204 (.DATA_A (INT_CARRY[212]), .DATA_B (INT_CARRY[213]), .DATA_C (INT_CARRY[214]), .SAVE (INT_SUM[290]), .CARRY (INT_CARRY[234]) ); assign INT_SUM[291] = INT_CARRY[215]; assign INT_SUM[292] = INT_CARRY[216]; smfulladder dfa205 (.DATA_A (INT_SUM[288]), .DATA_B (INT_SUM[289]), .DATA_C (INT_SUM[290]), .SAVE (INT_SUM[293]), .CARRY (INT_CARRY[235]) ); smfulladder dfa206 (.DATA_A (INT_SUM[291]), .DATA_B (INT_SUM[292]), .DATA_C (INT_CARRY[217]), .SAVE (INT_SUM[294]), .CARRY (INT_CARRY[236]) ); smfulladder dfa207 (.DATA_A (INT_CARRY[218]), .DATA_B (INT_CARRY[219]), .DATA_C (INT_CARRY[220]), .SAVE (INT_SUM[295]), .CARRY (INT_CARRY[237]) ); smfulladder dfa208 (.DATA_A (INT_SUM[293]), .DATA_B (INT_SUM[294]), .DATA_C (INT_SUM[295]), .SAVE (INT_SUM[296]), .CARRY (INT_CARRY[238]) ); smhalfadder dha29 (.DATA_A (INT_CARRY[221]), .DATA_B (INT_CARRY[222]), .SAVE (INT_SUM[297]), .CARRY (INT_CARRY[239]) ); smfulladder dfa209 (.DATA_A (INT_SUM[296]), .DATA_B (INT_SUM[297]), .DATA_C (INT_CARRY[223]), .SAVE (INT_SUM[298]), .CARRY (INT_CARRY[240]) ); assign INT_SUM[299] = INT_CARRY[224]; smfulladder dfa210 (.DATA_A (INT_SUM[298]), .DATA_B (INT_SUM[299]), .DATA_C (INT_CARRY[225]), .SAVE (INT_SUM[300]), .CARRY (INT_CARRY[226]) ); smffb dla349 (.D(INT_SUM[300]), .clk(clk), .en_d2(en_d2), .Q(SUM[31]) ); smffb dla350 (.D(INT_CARRY[226]), .clk(clk), .en_d2(en_d2), .Q(CARRY[31]) ); smffa dla351 (.D(SUMMAND[288]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[288]) ); smffa dla352 (.D(SUMMAND[289]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[289]) ); smffa dla353 (.D(SUMMAND[290]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[290]) ); smfulladder dfa211 (.DATA_A (LATCHED_PP[288]), .DATA_B (LATCHED_PP[289]), .DATA_C (LATCHED_PP[290]), .SAVE (INT_SUM[301]), .CARRY (INT_CARRY[242]) ); smffa dla354 (.D(SUMMAND[291]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[291]) ); smffa dla355 (.D(SUMMAND[292]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[292]) ); smffa dla356 (.D(SUMMAND[293]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[293]) ); smfulladder dfa212 (.DATA_A (LATCHED_PP[291]), .DATA_B (LATCHED_PP[292]), .DATA_C (LATCHED_PP[293]), .SAVE (INT_SUM[302]), .CARRY (INT_CARRY[243]) ); smffa dla357 (.D(SUMMAND[294]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[294]) ); smffa dla358 (.D(SUMMAND[295]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[295]) ); smffa dla359 (.D(SUMMAND[296]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[296]) ); smfulladder dfa213 (.DATA_A (LATCHED_PP[294]), .DATA_B (LATCHED_PP[295]), .DATA_C (LATCHED_PP[296]), .SAVE (INT_SUM[303]), .CARRY (INT_CARRY[244]) ); smffa dla360 (.D(SUMMAND[297]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[297]) ); smffa dla361 (.D(SUMMAND[298]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[298]) ); smffa dla362 (.D(SUMMAND[299]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[299]) ); smfulladder dfa214 (.DATA_A (LATCHED_PP[297]), .DATA_B (LATCHED_PP[298]), .DATA_C (LATCHED_PP[299]), .SAVE (INT_SUM[304]), .CARRY (INT_CARRY[245]) ); smffa dla363 (.D(SUMMAND[300]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[300]) ); smffa dla364 (.D(SUMMAND[301]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[301]) ); smffa dla365 (.D(SUMMAND[302]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[302]) ); smfulladder dfa215 (.DATA_A (LATCHED_PP[300]), .DATA_B (LATCHED_PP[301]), .DATA_C (LATCHED_PP[302]), .SAVE (INT_SUM[305]), .CARRY (INT_CARRY[246]) ); smffa dla366 (.D(SUMMAND[303]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[303]) ); smffa dla367 (.D(SUMMAND[304]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[304]) ); smffa dla368 (.D(SUMMAND[305]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[305]) ); smfulladder dfa216 (.DATA_A (LATCHED_PP[303]), .DATA_B (LATCHED_PP[304]), .DATA_C (LATCHED_PP[305]), .SAVE (INT_SUM[306]), .CARRY (INT_CARRY[247]) ); smfulladder dfa217 (.DATA_A (INT_SUM[301]), .DATA_B (INT_SUM[302]), .DATA_C (INT_SUM[303]), .SAVE (INT_SUM[307]), .CARRY (INT_CARRY[248]) ); smfulladder dfa218 (.DATA_A (INT_SUM[304]), .DATA_B (INT_SUM[305]), .DATA_C (INT_SUM[306]), .SAVE (INT_SUM[308]), .CARRY (INT_CARRY[249]) ); smfulladder dfa219 (.DATA_A (INT_CARRY[227]), .DATA_B (INT_CARRY[228]), .DATA_C (INT_CARRY[229]), .SAVE (INT_SUM[309]), .CARRY (INT_CARRY[250]) ); smhalfadder dha30 (.DATA_A (INT_CARRY[230]), .DATA_B (INT_CARRY[231]), .SAVE (INT_SUM[310]), .CARRY (INT_CARRY[251]) ); smfulladder dfa220 (.DATA_A (INT_SUM[307]), .DATA_B (INT_SUM[308]), .DATA_C (INT_SUM[309]), .SAVE (INT_SUM[311]), .CARRY (INT_CARRY[252]) ); smfulladder dfa221 (.DATA_A (INT_SUM[310]), .DATA_B (INT_CARRY[232]), .DATA_C (INT_CARRY[233]), .SAVE (INT_SUM[312]), .CARRY (INT_CARRY[253]) ); assign INT_SUM[313] = INT_CARRY[234]; smfulladder dfa222 (.DATA_A (INT_SUM[311]), .DATA_B (INT_SUM[312]), .DATA_C (INT_SUM[313]), .SAVE (INT_SUM[314]), .CARRY (INT_CARRY[254]) ); smfulladder dfa223 (.DATA_A (INT_CARRY[235]), .DATA_B (INT_CARRY[236]), .DATA_C (INT_CARRY[237]), .SAVE (INT_SUM[315]), .CARRY (INT_CARRY[255]) ); smfulladder dfa224 (.DATA_A (INT_SUM[314]), .DATA_B (INT_SUM[315]), .DATA_C (INT_CARRY[238]), .SAVE (INT_SUM[316]), .CARRY (INT_CARRY[256]) ); assign INT_SUM[317] = INT_CARRY[239]; smfulladder dfa225 (.DATA_A (INT_SUM[316]), .DATA_B (INT_SUM[317]), .DATA_C (INT_CARRY[240]), .SAVE (INT_SUM[318]), .CARRY (INT_CARRY[241]) ); smffb dla369 (.D(INT_SUM[318]), .clk(clk), .en_d2(en_d2), .Q(SUM[32]) ); smffb dla370 (.D(INT_CARRY[241]), .clk(clk), .en_d2(en_d2), .Q(CARRY[32]) ); smffa dla371 (.D(SUMMAND[306]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[306]) ); smffa dla372 (.D(SUMMAND[307]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[307]) ); smffa dla373 (.D(SUMMAND[308]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[308]) ); smfulladder dfa226 (.DATA_A (LATCHED_PP[306]), .DATA_B (LATCHED_PP[307]), .DATA_C (LATCHED_PP[308]), .SAVE (INT_SUM[319]), .CARRY (INT_CARRY[258]) ); smffa dla374 (.D(SUMMAND[309]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[309]) ); smffa dla375 (.D(SUMMAND[310]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[310]) ); smffa dla376 (.D(SUMMAND[311]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[311]) ); smfulladder dfa227 (.DATA_A (LATCHED_PP[309]), .DATA_B (LATCHED_PP[310]), .DATA_C (LATCHED_PP[311]), .SAVE (INT_SUM[320]), .CARRY (INT_CARRY[259]) ); smffa dla377 (.D(SUMMAND[312]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[312]) ); smffa dla378 (.D(SUMMAND[313]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[313]) ); smffa dla379 (.D(SUMMAND[314]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[314]) ); smfulladder dfa228 (.DATA_A (LATCHED_PP[312]), .DATA_B (LATCHED_PP[313]), .DATA_C (LATCHED_PP[314]), .SAVE (INT_SUM[321]), .CARRY (INT_CARRY[260]) ); smffa dla380 (.D(SUMMAND[315]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[315]) ); smffa dla381 (.D(SUMMAND[316]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[316]) ); smffa dla382 (.D(SUMMAND[317]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[317]) ); smfulladder dfa229 (.DATA_A (LATCHED_PP[315]), .DATA_B (LATCHED_PP[316]), .DATA_C (LATCHED_PP[317]), .SAVE (INT_SUM[322]), .CARRY (INT_CARRY[261]) ); smffa dla383 (.D(SUMMAND[318]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[318]) ); smffa dla384 (.D(SUMMAND[319]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[319]) ); smffa dla385 (.D(SUMMAND[320]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[320]) ); smfulladder dfa230 (.DATA_A (LATCHED_PP[318]), .DATA_B (LATCHED_PP[319]), .DATA_C (LATCHED_PP[320]), .SAVE (INT_SUM[323]), .CARRY (INT_CARRY[262]) ); smffa dla386 (.D(SUMMAND[321]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[321]) ); assign INT_SUM[324] = LATCHED_PP[321]; smffa dla387 (.D(SUMMAND[322]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[322]) ); assign INT_SUM[325] = LATCHED_PP[322]; smfulladder dfa231 (.DATA_A (INT_SUM[319]), .DATA_B (INT_SUM[320]), .DATA_C (INT_SUM[321]), .SAVE (INT_SUM[326]), .CARRY (INT_CARRY[263]) ); smfulladder dfa232 (.DATA_A (INT_SUM[322]), .DATA_B (INT_SUM[323]), .DATA_C (INT_SUM[324]), .SAVE (INT_SUM[327]), .CARRY (INT_CARRY[264]) ); smfulladder dfa233 (.DATA_A (INT_SUM[325]), .DATA_B (INT_CARRY[242]), .DATA_C (INT_CARRY[243]), .SAVE (INT_SUM[328]), .CARRY (INT_CARRY[265]) ); smfulladder dfa234 (.DATA_A (INT_CARRY[244]), .DATA_B (INT_CARRY[245]), .DATA_C (INT_CARRY[246]), .SAVE (INT_SUM[329]), .CARRY (INT_CARRY[266]) ); assign INT_SUM[330] = INT_CARRY[247]; smfulladder dfa235 (.DATA_A (INT_SUM[326]), .DATA_B (INT_SUM[327]), .DATA_C (INT_SUM[328]), .SAVE (INT_SUM[331]), .CARRY (INT_CARRY[267]) ); smfulladder dfa236 (.DATA_A (INT_SUM[329]), .DATA_B (INT_SUM[330]), .DATA_C (INT_CARRY[248]), .SAVE (INT_SUM[332]), .CARRY (INT_CARRY[268]) ); smfulladder dfa237 (.DATA_A (INT_CARRY[249]), .DATA_B (INT_CARRY[250]), .DATA_C (INT_CARRY[251]), .SAVE (INT_SUM[333]), .CARRY (INT_CARRY[269]) ); smfulladder dfa238 (.DATA_A (INT_SUM[331]), .DATA_B (INT_SUM[332]), .DATA_C (INT_SUM[333]), .SAVE (INT_SUM[334]), .CARRY (INT_CARRY[270]) ); smhalfadder dha31 (.DATA_A (INT_CARRY[252]), .DATA_B (INT_CARRY[253]), .SAVE (INT_SUM[335]), .CARRY (INT_CARRY[271]) ); smfulladder dfa239 (.DATA_A (INT_SUM[334]), .DATA_B (INT_SUM[335]), .DATA_C (INT_CARRY[254]), .SAVE (INT_SUM[336]), .CARRY (INT_CARRY[272]) ); assign INT_SUM[337] = INT_CARRY[255]; smfulladder dfa240 (.DATA_A (INT_SUM[336]), .DATA_B (INT_SUM[337]), .DATA_C (INT_CARRY[256]), .SAVE (INT_SUM[338]), .CARRY (INT_CARRY[257]) ); smffb dla388 (.D(INT_SUM[338]), .clk(clk), .en_d2(en_d2), .Q(SUM[33]) ); smffb dla389 (.D(INT_CARRY[257]), .clk(clk), .en_d2(en_d2), .Q(CARRY[33]) ); smffa dla390 (.D(SUMMAND[323]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[323]) ); smffa dla391 (.D(SUMMAND[324]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[324]) ); smffa dla392 (.D(SUMMAND[325]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[325]) ); smfulladder dfa241 (.DATA_A (LATCHED_PP[323]), .DATA_B (LATCHED_PP[324]), .DATA_C (LATCHED_PP[325]), .SAVE (INT_SUM[339]), .CARRY (INT_CARRY[274]) ); smffa dla393 (.D(SUMMAND[326]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[326]) ); smffa dla394 (.D(SUMMAND[327]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[327]) ); smffa dla395 (.D(SUMMAND[328]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[328]) ); smfulladder dfa242 (.DATA_A (LATCHED_PP[326]), .DATA_B (LATCHED_PP[327]), .DATA_C (LATCHED_PP[328]), .SAVE (INT_SUM[340]), .CARRY (INT_CARRY[275]) ); smffa dla396 (.D(SUMMAND[329]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[329]) ); smffa dla397 (.D(SUMMAND[330]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[330]) ); smffa dla398 (.D(SUMMAND[331]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[331]) ); smfulladder dfa243 (.DATA_A (LATCHED_PP[329]), .DATA_B (LATCHED_PP[330]), .DATA_C (LATCHED_PP[331]), .SAVE (INT_SUM[341]), .CARRY (INT_CARRY[276]) ); smffa dla399 (.D(SUMMAND[332]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[332]) ); smffa dla400 (.D(SUMMAND[333]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[333]) ); smffa dla401 (.D(SUMMAND[334]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[334]) ); smfulladder dfa244 (.DATA_A (LATCHED_PP[332]), .DATA_B (LATCHED_PP[333]), .DATA_C (LATCHED_PP[334]), .SAVE (INT_SUM[342]), .CARRY (INT_CARRY[277]) ); smffa dla402 (.D(SUMMAND[335]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[335]) ); smffa dla403 (.D(SUMMAND[336]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[336]) ); smffa dla404 (.D(SUMMAND[337]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[337]) ); smfulladder dfa245 (.DATA_A (LATCHED_PP[335]), .DATA_B (LATCHED_PP[336]), .DATA_C (LATCHED_PP[337]), .SAVE (INT_SUM[343]), .CARRY (INT_CARRY[278]) ); smffa dla405 (.D(SUMMAND[338]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[338]) ); smffa dla406 (.D(SUMMAND[339]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[339]) ); smffa dla407 (.D(SUMMAND[340]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[340]) ); smfulladder dfa246 (.DATA_A (LATCHED_PP[338]), .DATA_B (LATCHED_PP[339]), .DATA_C (LATCHED_PP[340]), .SAVE (INT_SUM[344]), .CARRY (INT_CARRY[279]) ); smfulladder dfa247 (.DATA_A (INT_SUM[339]), .DATA_B (INT_SUM[340]), .DATA_C (INT_SUM[341]), .SAVE (INT_SUM[345]), .CARRY (INT_CARRY[280]) ); smfulladder dfa248 (.DATA_A (INT_SUM[342]), .DATA_B (INT_SUM[343]), .DATA_C (INT_SUM[344]), .SAVE (INT_SUM[346]), .CARRY (INT_CARRY[281]) ); smfulladder dfa249 (.DATA_A (INT_CARRY[258]), .DATA_B (INT_CARRY[259]), .DATA_C (INT_CARRY[260]), .SAVE (INT_SUM[347]), .CARRY (INT_CARRY[282]) ); assign INT_SUM[348] = INT_CARRY[261]; assign INT_SUM[349] = INT_CARRY[262]; smfulladder dfa250 (.DATA_A (INT_SUM[345]), .DATA_B (INT_SUM[346]), .DATA_C (INT_SUM[347]), .SAVE (INT_SUM[350]), .CARRY (INT_CARRY[283]) ); smfulladder dfa251 (.DATA_A (INT_SUM[348]), .DATA_B (INT_SUM[349]), .DATA_C (INT_CARRY[263]), .SAVE (INT_SUM[351]), .CARRY (INT_CARRY[284]) ); smfulladder dfa252 (.DATA_A (INT_CARRY[264]), .DATA_B (INT_CARRY[265]), .DATA_C (INT_CARRY[266]), .SAVE (INT_SUM[352]), .CARRY (INT_CARRY[285]) ); smfulladder dfa253 (.DATA_A (INT_SUM[350]), .DATA_B (INT_SUM[351]), .DATA_C (INT_SUM[352]), .SAVE (INT_SUM[353]), .CARRY (INT_CARRY[286]) ); smfulladder dfa254 (.DATA_A (INT_CARRY[267]), .DATA_B (INT_CARRY[268]), .DATA_C (INT_CARRY[269]), .SAVE (INT_SUM[354]), .CARRY (INT_CARRY[287]) ); smfulladder dfa255 (.DATA_A (INT_SUM[353]), .DATA_B (INT_SUM[354]), .DATA_C (INT_CARRY[270]), .SAVE (INT_SUM[355]), .CARRY (INT_CARRY[288]) ); assign INT_SUM[356] = INT_CARRY[271]; smfulladder dfa256 (.DATA_A (INT_SUM[355]), .DATA_B (INT_SUM[356]), .DATA_C (INT_CARRY[272]), .SAVE (INT_SUM[357]), .CARRY (INT_CARRY[273]) ); smffb dla408 (.D(INT_SUM[357]), .clk(clk), .en_d2(en_d2), .Q(SUM[34]) ); smffb dla409 (.D(INT_CARRY[273]), .clk(clk), .en_d2(en_d2), .Q(CARRY[34]) ); smffa dla410 (.D(SUMMAND[341]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[341]) ); smffa dla411 (.D(SUMMAND[342]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[342]) ); smffa dla412 (.D(SUMMAND[343]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[343]) ); smfulladder dfa257 (.DATA_A (LATCHED_PP[341]), .DATA_B (LATCHED_PP[342]), .DATA_C (LATCHED_PP[343]), .SAVE (INT_SUM[358]), .CARRY (INT_CARRY[290]) ); smffa dla413 (.D(SUMMAND[344]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[344]) ); smffa dla414 (.D(SUMMAND[345]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[345]) ); smffa dla415 (.D(SUMMAND[346]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[346]) ); smfulladder dfa258 (.DATA_A (LATCHED_PP[344]), .DATA_B (LATCHED_PP[345]), .DATA_C (LATCHED_PP[346]), .SAVE (INT_SUM[359]), .CARRY (INT_CARRY[291]) ); smffa dla416 (.D(SUMMAND[347]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[347]) ); smffa dla417 (.D(SUMMAND[348]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[348]) ); smffa dla418 (.D(SUMMAND[349]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[349]) ); smfulladder dfa259 (.DATA_A (LATCHED_PP[347]), .DATA_B (LATCHED_PP[348]), .DATA_C (LATCHED_PP[349]), .SAVE (INT_SUM[360]), .CARRY (INT_CARRY[292]) ); smffa dla419 (.D(SUMMAND[350]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[350]) ); smffa dla420 (.D(SUMMAND[351]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[351]) ); smffa dla421 (.D(SUMMAND[352]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[352]) ); smfulladder dfa260 (.DATA_A (LATCHED_PP[350]), .DATA_B (LATCHED_PP[351]), .DATA_C (LATCHED_PP[352]), .SAVE (INT_SUM[361]), .CARRY (INT_CARRY[293]) ); smffa dla422 (.D(SUMMAND[353]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[353]) ); smffa dla423 (.D(SUMMAND[354]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[354]) ); smffa dla424 (.D(SUMMAND[355]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[355]) ); smfulladder dfa261 (.DATA_A (LATCHED_PP[353]), .DATA_B (LATCHED_PP[354]), .DATA_C (LATCHED_PP[355]), .SAVE (INT_SUM[362]), .CARRY (INT_CARRY[294]) ); smffa dla425 (.D(SUMMAND[356]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[356]) ); smffa dla426 (.D(SUMMAND[357]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[357]) ); smhalfadder dha32 (.DATA_A (LATCHED_PP[356]), .DATA_B (LATCHED_PP[357]), .SAVE (INT_SUM[363]), .CARRY (INT_CARRY[295]) ); smfulladder dfa262 (.DATA_A (INT_SUM[358]), .DATA_B (INT_SUM[359]), .DATA_C (INT_SUM[360]), .SAVE (INT_SUM[364]), .CARRY (INT_CARRY[296]) ); smfulladder dfa263 (.DATA_A (INT_SUM[361]), .DATA_B (INT_SUM[362]), .DATA_C (INT_SUM[363]), .SAVE (INT_SUM[365]), .CARRY (INT_CARRY[297]) ); smfulladder dfa264 (.DATA_A (INT_CARRY[274]), .DATA_B (INT_CARRY[275]), .DATA_C (INT_CARRY[276]), .SAVE (INT_SUM[366]), .CARRY (INT_CARRY[298]) ); smfulladder dfa265 (.DATA_A (INT_CARRY[277]), .DATA_B (INT_CARRY[278]), .DATA_C (INT_CARRY[279]), .SAVE (INT_SUM[367]), .CARRY (INT_CARRY[299]) ); smfulladder dfa266 (.DATA_A (INT_SUM[364]), .DATA_B (INT_SUM[365]), .DATA_C (INT_SUM[366]), .SAVE (INT_SUM[368]), .CARRY (INT_CARRY[300]) ); smfulladder dfa267 (.DATA_A (INT_SUM[367]), .DATA_B (INT_CARRY[280]), .DATA_C (INT_CARRY[281]), .SAVE (INT_SUM[369]), .CARRY (INT_CARRY[301]) ); assign INT_SUM[370] = INT_CARRY[282]; smfulladder dfa268 (.DATA_A (INT_SUM[368]), .DATA_B (INT_SUM[369]), .DATA_C (INT_SUM[370]), .SAVE (INT_SUM[371]), .CARRY (INT_CARRY[302]) ); smfulladder dfa269 (.DATA_A (INT_CARRY[283]), .DATA_B (INT_CARRY[284]), .DATA_C (INT_CARRY[285]), .SAVE (INT_SUM[372]), .CARRY (INT_CARRY[303]) ); smfulladder dfa270 (.DATA_A (INT_SUM[371]), .DATA_B (INT_SUM[372]), .DATA_C (INT_CARRY[286]), .SAVE (INT_SUM[373]), .CARRY (INT_CARRY[304]) ); assign INT_SUM[374] = INT_CARRY[287]; smfulladder dfa271 (.DATA_A (INT_SUM[373]), .DATA_B (INT_SUM[374]), .DATA_C (INT_CARRY[288]), .SAVE (INT_SUM[375]), .CARRY (INT_CARRY[289]) ); smffb dla427 (.D(INT_SUM[375]), .clk(clk), .en_d2(en_d2), .Q(SUM[35]) ); smffb dla428 (.D(INT_CARRY[289]), .clk(clk), .en_d2(en_d2), .Q(CARRY[35]) ); smffa dla429 (.D(SUMMAND[358]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[358]) ); smffa dla430 (.D(SUMMAND[359]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[359]) ); smffa dla431 (.D(SUMMAND[360]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[360]) ); smfulladder dfa272 (.DATA_A (LATCHED_PP[358]), .DATA_B (LATCHED_PP[359]), .DATA_C (LATCHED_PP[360]), .SAVE (INT_SUM[376]), .CARRY (INT_CARRY[306]) ); smffa dla432 (.D(SUMMAND[361]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[361]) ); smffa dla433 (.D(SUMMAND[362]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[362]) ); smffa dla434 (.D(SUMMAND[363]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[363]) ); smfulladder dfa273 (.DATA_A (LATCHED_PP[361]), .DATA_B (LATCHED_PP[362]), .DATA_C (LATCHED_PP[363]), .SAVE (INT_SUM[377]), .CARRY (INT_CARRY[307]) ); smffa dla435 (.D(SUMMAND[364]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[364]) ); smffa dla436 (.D(SUMMAND[365]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[365]) ); smffa dla437 (.D(SUMMAND[366]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[366]) ); smfulladder dfa274 (.DATA_A (LATCHED_PP[364]), .DATA_B (LATCHED_PP[365]), .DATA_C (LATCHED_PP[366]), .SAVE (INT_SUM[378]), .CARRY (INT_CARRY[308]) ); smffa dla438 (.D(SUMMAND[367]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[367]) ); smffa dla439 (.D(SUMMAND[368]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[368]) ); smffa dla440 (.D(SUMMAND[369]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[369]) ); smfulladder dfa275 (.DATA_A (LATCHED_PP[367]), .DATA_B (LATCHED_PP[368]), .DATA_C (LATCHED_PP[369]), .SAVE (INT_SUM[379]), .CARRY (INT_CARRY[309]) ); smffa dla441 (.D(SUMMAND[370]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[370]) ); smffa dla442 (.D(SUMMAND[371]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[371]) ); smffa dla443 (.D(SUMMAND[372]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[372]) ); smfulladder dfa276 (.DATA_A (LATCHED_PP[370]), .DATA_B (LATCHED_PP[371]), .DATA_C (LATCHED_PP[372]), .SAVE (INT_SUM[380]), .CARRY (INT_CARRY[310]) ); smffa dla444 (.D(SUMMAND[373]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[373]) ); assign INT_SUM[381] = LATCHED_PP[373]; smfulladder dfa277 (.DATA_A (INT_SUM[376]), .DATA_B (INT_SUM[377]), .DATA_C (INT_SUM[378]), .SAVE (INT_SUM[382]), .CARRY (INT_CARRY[311]) ); smfulladder dfa278 (.DATA_A (INT_SUM[379]), .DATA_B (INT_SUM[380]), .DATA_C (INT_SUM[381]), .SAVE (INT_SUM[383]), .CARRY (INT_CARRY[312]) ); smfulladder dfa279 (.DATA_A (INT_CARRY[290]), .DATA_B (INT_CARRY[291]), .DATA_C (INT_CARRY[292]), .SAVE (INT_SUM[384]), .CARRY (INT_CARRY[313]) ); smfulladder dfa280 (.DATA_A (INT_CARRY[293]), .DATA_B (INT_CARRY[294]), .DATA_C (INT_CARRY[295]), .SAVE (INT_SUM[385]), .CARRY (INT_CARRY[314]) ); smfulladder dfa281 (.DATA_A (INT_SUM[382]), .DATA_B (INT_SUM[383]), .DATA_C (INT_SUM[384]), .SAVE (INT_SUM[386]), .CARRY (INT_CARRY[315]) ); smfulladder dfa282 (.DATA_A (INT_SUM[385]), .DATA_B (INT_CARRY[296]), .DATA_C (INT_CARRY[297]), .SAVE (INT_SUM[387]), .CARRY (INT_CARRY[316]) ); assign INT_SUM[388] = INT_CARRY[298]; assign INT_SUM[389] = INT_CARRY[299]; smfulladder dfa283 (.DATA_A (INT_SUM[386]), .DATA_B (INT_SUM[387]), .DATA_C (INT_SUM[388]), .SAVE (INT_SUM[390]), .CARRY (INT_CARRY[317]) ); smfulladder dfa284 (.DATA_A (INT_SUM[389]), .DATA_B (INT_CARRY[300]), .DATA_C (INT_CARRY[301]), .SAVE (INT_SUM[391]), .CARRY (INT_CARRY[318]) ); smfulladder dfa285 (.DATA_A (INT_SUM[390]), .DATA_B (INT_SUM[391]), .DATA_C (INT_CARRY[302]), .SAVE (INT_SUM[392]), .CARRY (INT_CARRY[319]) ); assign INT_SUM[393] = INT_CARRY[303]; smfulladder dfa286 (.DATA_A (INT_SUM[392]), .DATA_B (INT_SUM[393]), .DATA_C (INT_CARRY[304]), .SAVE (INT_SUM[394]), .CARRY (INT_CARRY[305]) ); smffb dla445 (.D(INT_SUM[394]), .clk(clk), .en_d2(en_d2), .Q(SUM[36]) ); smffb dla446 (.D(INT_CARRY[305]), .clk(clk), .en_d2(en_d2), .Q(CARRY[36]) ); smffa dla447 (.D(SUMMAND[374]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[374]) ); smffa dla448 (.D(SUMMAND[375]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[375]) ); smffa dla449 (.D(SUMMAND[376]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[376]) ); smfulladder dfa287 (.DATA_A (LATCHED_PP[374]), .DATA_B (LATCHED_PP[375]), .DATA_C (LATCHED_PP[376]), .SAVE (INT_SUM[395]), .CARRY (INT_CARRY[321]) ); smffa dla450 (.D(SUMMAND[377]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[377]) ); smffa dla451 (.D(SUMMAND[378]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[378]) ); smffa dla452 (.D(SUMMAND[379]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[379]) ); smfulladder dfa288 (.DATA_A (LATCHED_PP[377]), .DATA_B (LATCHED_PP[378]), .DATA_C (LATCHED_PP[379]), .SAVE (INT_SUM[396]), .CARRY (INT_CARRY[322]) ); smffa dla453 (.D(SUMMAND[380]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[380]) ); smffa dla454 (.D(SUMMAND[381]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[381]) ); smffa dla455 (.D(SUMMAND[382]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[382]) ); smfulladder dfa289 (.DATA_A (LATCHED_PP[380]), .DATA_B (LATCHED_PP[381]), .DATA_C (LATCHED_PP[382]), .SAVE (INT_SUM[397]), .CARRY (INT_CARRY[323]) ); smffa dla456 (.D(SUMMAND[383]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[383]) ); smffa dla457 (.D(SUMMAND[384]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[384]) ); smffa dla458 (.D(SUMMAND[385]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[385]) ); smfulladder dfa290 (.DATA_A (LATCHED_PP[383]), .DATA_B (LATCHED_PP[384]), .DATA_C (LATCHED_PP[385]), .SAVE (INT_SUM[398]), .CARRY (INT_CARRY[324]) ); smffa dla459 (.D(SUMMAND[386]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[386]) ); smffa dla460 (.D(SUMMAND[387]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[387]) ); smffa dla461 (.D(SUMMAND[388]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[388]) ); smfulladder dfa291 (.DATA_A (LATCHED_PP[386]), .DATA_B (LATCHED_PP[387]), .DATA_C (LATCHED_PP[388]), .SAVE (INT_SUM[399]), .CARRY (INT_CARRY[325]) ); smffa dla462 (.D(SUMMAND[389]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[389]) ); assign INT_SUM[400] = LATCHED_PP[389]; smfulladder dfa292 (.DATA_A (INT_SUM[395]), .DATA_B (INT_SUM[396]), .DATA_C (INT_SUM[397]), .SAVE (INT_SUM[401]), .CARRY (INT_CARRY[326]) ); smfulladder dfa293 (.DATA_A (INT_SUM[398]), .DATA_B (INT_SUM[399]), .DATA_C (INT_SUM[400]), .SAVE (INT_SUM[402]), .CARRY (INT_CARRY[327]) ); smfulladder dfa294 (.DATA_A (INT_CARRY[306]), .DATA_B (INT_CARRY[307]), .DATA_C (INT_CARRY[308]), .SAVE (INT_SUM[403]), .CARRY (INT_CARRY[328]) ); assign INT_SUM[404] = INT_CARRY[309]; assign INT_SUM[405] = INT_CARRY[310]; smfulladder dfa295 (.DATA_A (INT_SUM[401]), .DATA_B (INT_SUM[402]), .DATA_C (INT_SUM[403]), .SAVE (INT_SUM[406]), .CARRY (INT_CARRY[329]) ); smfulladder dfa296 (.DATA_A (INT_SUM[404]), .DATA_B (INT_SUM[405]), .DATA_C (INT_CARRY[311]), .SAVE (INT_SUM[407]), .CARRY (INT_CARRY[330]) ); smfulladder dfa297 (.DATA_A (INT_CARRY[312]), .DATA_B (INT_CARRY[313]), .DATA_C (INT_CARRY[314]), .SAVE (INT_SUM[408]), .CARRY (INT_CARRY[331]) ); smfulladder dfa298 (.DATA_A (INT_SUM[406]), .DATA_B (INT_SUM[407]), .DATA_C (INT_SUM[408]), .SAVE (INT_SUM[409]), .CARRY (INT_CARRY[332]) ); smhalfadder dha33 (.DATA_A (INT_CARRY[315]), .DATA_B (INT_CARRY[316]), .SAVE (INT_SUM[410]), .CARRY (INT_CARRY[333]) ); smfulladder dfa299 (.DATA_A (INT_SUM[409]), .DATA_B (INT_SUM[410]), .DATA_C (INT_CARRY[317]), .SAVE (INT_SUM[411]), .CARRY (INT_CARRY[334]) ); assign INT_SUM[412] = INT_CARRY[318]; smfulladder dfa300 (.DATA_A (INT_SUM[411]), .DATA_B (INT_SUM[412]), .DATA_C (INT_CARRY[319]), .SAVE (INT_SUM[413]), .CARRY (INT_CARRY[320]) ); smffb dla463 (.D(INT_SUM[413]), .clk(clk), .en_d2(en_d2), .Q(SUM[37]) ); smffb dla464 (.D(INT_CARRY[320]), .clk(clk), .en_d2(en_d2), .Q(CARRY[37]) ); smffa dla465 (.D(SUMMAND[390]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[390]) ); smffa dla466 (.D(SUMMAND[391]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[391]) ); smffa dla467 (.D(SUMMAND[392]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[392]) ); smfulladder dfa301 (.DATA_A (LATCHED_PP[390]), .DATA_B (LATCHED_PP[391]), .DATA_C (LATCHED_PP[392]), .SAVE (INT_SUM[414]), .CARRY (INT_CARRY[336]) ); smffa dla468 (.D(SUMMAND[393]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[393]) ); smffa dla469 (.D(SUMMAND[394]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[394]) ); smffa dla470 (.D(SUMMAND[395]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[395]) ); smfulladder dfa302 (.DATA_A (LATCHED_PP[393]), .DATA_B (LATCHED_PP[394]), .DATA_C (LATCHED_PP[395]), .SAVE (INT_SUM[415]), .CARRY (INT_CARRY[337]) ); smffa dla471 (.D(SUMMAND[396]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[396]) ); smffa dla472 (.D(SUMMAND[397]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[397]) ); smffa dla473 (.D(SUMMAND[398]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[398]) ); smfulladder dfa303 (.DATA_A (LATCHED_PP[396]), .DATA_B (LATCHED_PP[397]), .DATA_C (LATCHED_PP[398]), .SAVE (INT_SUM[416]), .CARRY (INT_CARRY[338]) ); smffa dla474 (.D(SUMMAND[399]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[399]) ); smffa dla475 (.D(SUMMAND[400]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[400]) ); smffa dla476 (.D(SUMMAND[401]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[401]) ); smfulladder dfa304 (.DATA_A (LATCHED_PP[399]), .DATA_B (LATCHED_PP[400]), .DATA_C (LATCHED_PP[401]), .SAVE (INT_SUM[417]), .CARRY (INT_CARRY[339]) ); smffa dla477 (.D(SUMMAND[402]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[402]) ); smffa dla478 (.D(SUMMAND[403]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[403]) ); smffa dla479 (.D(SUMMAND[404]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[404]) ); smfulladder dfa305 (.DATA_A (LATCHED_PP[402]), .DATA_B (LATCHED_PP[403]), .DATA_C (LATCHED_PP[404]), .SAVE (INT_SUM[418]), .CARRY (INT_CARRY[340]) ); smfulladder dfa306 (.DATA_A (INT_SUM[414]), .DATA_B (INT_SUM[415]), .DATA_C (INT_SUM[416]), .SAVE (INT_SUM[419]), .CARRY (INT_CARRY[341]) ); smfulladder dfa307 (.DATA_A (INT_SUM[417]), .DATA_B (INT_SUM[418]), .DATA_C (INT_CARRY[321]), .SAVE (INT_SUM[420]), .CARRY (INT_CARRY[342]) ); smfulladder dfa308 (.DATA_A (INT_CARRY[322]), .DATA_B (INT_CARRY[323]), .DATA_C (INT_CARRY[324]), .SAVE (INT_SUM[421]), .CARRY (INT_CARRY[343]) ); assign INT_SUM[422] = INT_CARRY[325]; smfulladder dfa309 (.DATA_A (INT_SUM[419]), .DATA_B (INT_SUM[420]), .DATA_C (INT_SUM[421]), .SAVE (INT_SUM[423]), .CARRY (INT_CARRY[344]) ); smfulladder dfa310 (.DATA_A (INT_SUM[422]), .DATA_B (INT_CARRY[326]), .DATA_C (INT_CARRY[327]), .SAVE (INT_SUM[424]), .CARRY (INT_CARRY[345]) ); assign INT_SUM[425] = INT_CARRY[328]; smfulladder dfa311 (.DATA_A (INT_SUM[423]), .DATA_B (INT_SUM[424]), .DATA_C (INT_SUM[425]), .SAVE (INT_SUM[426]), .CARRY (INT_CARRY[346]) ); smfulladder dfa312 (.DATA_A (INT_CARRY[329]), .DATA_B (INT_CARRY[330]), .DATA_C (INT_CARRY[331]), .SAVE (INT_SUM[427]), .CARRY (INT_CARRY[347]) ); smfulladder dfa313 (.DATA_A (INT_SUM[426]), .DATA_B (INT_SUM[427]), .DATA_C (INT_CARRY[332]), .SAVE (INT_SUM[428]), .CARRY (INT_CARRY[348]) ); assign INT_SUM[429] = INT_CARRY[333]; smfulladder dfa314 (.DATA_A (INT_SUM[428]), .DATA_B (INT_SUM[429]), .DATA_C (INT_CARRY[334]), .SAVE (INT_SUM[430]), .CARRY (INT_CARRY[335]) ); smffb dla480 (.D(INT_SUM[430]), .clk(clk), .en_d2(en_d2), .Q(SUM[38]) ); smffb dla481 (.D(INT_CARRY[335]), .clk(clk), .en_d2(en_d2), .Q(CARRY[38]) ); smffa dla482 (.D(SUMMAND[405]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[405]) ); smffa dla483 (.D(SUMMAND[406]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[406]) ); smffa dla484 (.D(SUMMAND[407]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[407]) ); smfulladder dfa315 (.DATA_A (LATCHED_PP[405]), .DATA_B (LATCHED_PP[406]), .DATA_C (LATCHED_PP[407]), .SAVE (INT_SUM[431]), .CARRY (INT_CARRY[350]) ); smffa dla485 (.D(SUMMAND[408]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[408]) ); smffa dla486 (.D(SUMMAND[409]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[409]) ); smffa dla487 (.D(SUMMAND[410]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[410]) ); smfulladder dfa316 (.DATA_A (LATCHED_PP[408]), .DATA_B (LATCHED_PP[409]), .DATA_C (LATCHED_PP[410]), .SAVE (INT_SUM[432]), .CARRY (INT_CARRY[351]) ); smffa dla488 (.D(SUMMAND[411]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[411]) ); smffa dla489 (.D(SUMMAND[412]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[412]) ); smffa dla490 (.D(SUMMAND[413]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[413]) ); smfulladder dfa317 (.DATA_A (LATCHED_PP[411]), .DATA_B (LATCHED_PP[412]), .DATA_C (LATCHED_PP[413]), .SAVE (INT_SUM[433]), .CARRY (INT_CARRY[352]) ); smffa dla491 (.D(SUMMAND[414]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[414]) ); smffa dla492 (.D(SUMMAND[415]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[415]) ); smffa dla493 (.D(SUMMAND[416]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[416]) ); smfulladder dfa318 (.DATA_A (LATCHED_PP[414]), .DATA_B (LATCHED_PP[415]), .DATA_C (LATCHED_PP[416]), .SAVE (INT_SUM[434]), .CARRY (INT_CARRY[353]) ); smffa dla494 (.D(SUMMAND[417]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[417]) ); smffa dla495 (.D(SUMMAND[418]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[418]) ); smffa dla496 (.D(SUMMAND[419]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[419]) ); smfulladder dfa319 (.DATA_A (LATCHED_PP[417]), .DATA_B (LATCHED_PP[418]), .DATA_C (LATCHED_PP[419]), .SAVE (INT_SUM[435]), .CARRY (INT_CARRY[354]) ); smfulladder dfa320 (.DATA_A (INT_SUM[431]), .DATA_B (INT_SUM[432]), .DATA_C (INT_SUM[433]), .SAVE (INT_SUM[436]), .CARRY (INT_CARRY[355]) ); smfulladder dfa321 (.DATA_A (INT_SUM[434]), .DATA_B (INT_SUM[435]), .DATA_C (INT_CARRY[336]), .SAVE (INT_SUM[437]), .CARRY (INT_CARRY[356]) ); smfulladder dfa322 (.DATA_A (INT_CARRY[337]), .DATA_B (INT_CARRY[338]), .DATA_C (INT_CARRY[339]), .SAVE (INT_SUM[438]), .CARRY (INT_CARRY[357]) ); assign INT_SUM[439] = INT_CARRY[340]; smfulladder dfa323 (.DATA_A (INT_SUM[436]), .DATA_B (INT_SUM[437]), .DATA_C (INT_SUM[438]), .SAVE (INT_SUM[440]), .CARRY (INT_CARRY[358]) ); smfulladder dfa324 (.DATA_A (INT_SUM[439]), .DATA_B (INT_CARRY[341]), .DATA_C (INT_CARRY[342]), .SAVE (INT_SUM[441]), .CARRY (INT_CARRY[359]) ); assign INT_SUM[442] = INT_CARRY[343]; smfulladder dfa325 (.DATA_A (INT_SUM[440]), .DATA_B (INT_SUM[441]), .DATA_C (INT_SUM[442]), .SAVE (INT_SUM[443]), .CARRY (INT_CARRY[360]) ); smhalfadder dha34 (.DATA_A (INT_CARRY[344]), .DATA_B (INT_CARRY[345]), .SAVE (INT_SUM[444]), .CARRY (INT_CARRY[361]) ); smfulladder dfa326 (.DATA_A (INT_SUM[443]), .DATA_B (INT_SUM[444]), .DATA_C (INT_CARRY[346]), .SAVE (INT_SUM[445]), .CARRY (INT_CARRY[362]) ); assign INT_SUM[446] = INT_CARRY[347]; smfulladder dfa327 (.DATA_A (INT_SUM[445]), .DATA_B (INT_SUM[446]), .DATA_C (INT_CARRY[348]), .SAVE (INT_SUM[447]), .CARRY (INT_CARRY[349]) ); smffb dla497 (.D(INT_SUM[447]), .clk(clk), .en_d2(en_d2), .Q(SUM[39]) ); smffb dla498 (.D(INT_CARRY[349]), .clk(clk), .en_d2(en_d2), .Q(CARRY[39]) ); smffa dla499 (.D(SUMMAND[420]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[420]) ); smffa dla500 (.D(SUMMAND[421]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[421]) ); smffa dla501 (.D(SUMMAND[422]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[422]) ); smfulladder dfa328 (.DATA_A (LATCHED_PP[420]), .DATA_B (LATCHED_PP[421]), .DATA_C (LATCHED_PP[422]), .SAVE (INT_SUM[448]), .CARRY (INT_CARRY[364]) ); smffa dla502 (.D(SUMMAND[423]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[423]) ); smffa dla503 (.D(SUMMAND[424]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[424]) ); smffa dla504 (.D(SUMMAND[425]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[425]) ); smfulladder dfa329 (.DATA_A (LATCHED_PP[423]), .DATA_B (LATCHED_PP[424]), .DATA_C (LATCHED_PP[425]), .SAVE (INT_SUM[449]), .CARRY (INT_CARRY[365]) ); smffa dla505 (.D(SUMMAND[426]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[426]) ); smffa dla506 (.D(SUMMAND[427]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[427]) ); smffa dla507 (.D(SUMMAND[428]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[428]) ); smfulladder dfa330 (.DATA_A (LATCHED_PP[426]), .DATA_B (LATCHED_PP[427]), .DATA_C (LATCHED_PP[428]), .SAVE (INT_SUM[450]), .CARRY (INT_CARRY[366]) ); smffa dla508 (.D(SUMMAND[429]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[429]) ); smffa dla509 (.D(SUMMAND[430]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[430]) ); smffa dla510 (.D(SUMMAND[431]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[431]) ); smfulladder dfa331 (.DATA_A (LATCHED_PP[429]), .DATA_B (LATCHED_PP[430]), .DATA_C (LATCHED_PP[431]), .SAVE (INT_SUM[451]), .CARRY (INT_CARRY[367]) ); smffa dla511 (.D(SUMMAND[432]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[432]) ); smffa dla512 (.D(SUMMAND[433]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[433]) ); smhalfadder dha35 (.DATA_A (LATCHED_PP[432]), .DATA_B (LATCHED_PP[433]), .SAVE (INT_SUM[452]), .CARRY (INT_CARRY[368]) ); smfulladder dfa332 (.DATA_A (INT_SUM[448]), .DATA_B (INT_SUM[449]), .DATA_C (INT_SUM[450]), .SAVE (INT_SUM[453]), .CARRY (INT_CARRY[369]) ); smfulladder dfa333 (.DATA_A (INT_SUM[451]), .DATA_B (INT_SUM[452]), .DATA_C (INT_CARRY[350]), .SAVE (INT_SUM[454]), .CARRY (INT_CARRY[370]) ); smfulladder dfa334 (.DATA_A (INT_CARRY[351]), .DATA_B (INT_CARRY[352]), .DATA_C (INT_CARRY[353]), .SAVE (INT_SUM[455]), .CARRY (INT_CARRY[371]) ); assign INT_SUM[456] = INT_CARRY[354]; smfulladder dfa335 (.DATA_A (INT_SUM[453]), .DATA_B (INT_SUM[454]), .DATA_C (INT_SUM[455]), .SAVE (INT_SUM[457]), .CARRY (INT_CARRY[372]) ); smfulladder dfa336 (.DATA_A (INT_SUM[456]), .DATA_B (INT_CARRY[355]), .DATA_C (INT_CARRY[356]), .SAVE (INT_SUM[458]), .CARRY (INT_CARRY[373]) ); assign INT_SUM[459] = INT_CARRY[357]; smfulladder dfa337 (.DATA_A (INT_SUM[457]), .DATA_B (INT_SUM[458]), .DATA_C (INT_SUM[459]), .SAVE (INT_SUM[460]), .CARRY (INT_CARRY[374]) ); smhalfadder dha36 (.DATA_A (INT_CARRY[358]), .DATA_B (INT_CARRY[359]), .SAVE (INT_SUM[461]), .CARRY (INT_CARRY[375]) ); smfulladder dfa338 (.DATA_A (INT_SUM[460]), .DATA_B (INT_SUM[461]), .DATA_C (INT_CARRY[360]), .SAVE (INT_SUM[462]), .CARRY (INT_CARRY[376]) ); assign INT_SUM[463] = INT_CARRY[361]; smfulladder dfa339 (.DATA_A (INT_SUM[462]), .DATA_B (INT_SUM[463]), .DATA_C (INT_CARRY[362]), .SAVE (INT_SUM[464]), .CARRY (INT_CARRY[363]) ); smffb dla513 (.D(INT_SUM[464]), .clk(clk), .en_d2(en_d2), .Q(SUM[40]) ); smffb dla514 (.D(INT_CARRY[363]), .clk(clk), .en_d2(en_d2), .Q(CARRY[40]) ); smffa dla515 (.D(SUMMAND[434]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[434]) ); smffa dla516 (.D(SUMMAND[435]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[435]) ); smffa dla517 (.D(SUMMAND[436]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[436]) ); smfulladder dfa340 (.DATA_A (LATCHED_PP[434]), .DATA_B (LATCHED_PP[435]), .DATA_C (LATCHED_PP[436]), .SAVE (INT_SUM[465]), .CARRY (INT_CARRY[378]) ); smffa dla518 (.D(SUMMAND[437]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[437]) ); smffa dla519 (.D(SUMMAND[438]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[438]) ); smffa dla520 (.D(SUMMAND[439]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[439]) ); smfulladder dfa341 (.DATA_A (LATCHED_PP[437]), .DATA_B (LATCHED_PP[438]), .DATA_C (LATCHED_PP[439]), .SAVE (INT_SUM[466]), .CARRY (INT_CARRY[379]) ); smffa dla521 (.D(SUMMAND[440]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[440]) ); smffa dla522 (.D(SUMMAND[441]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[441]) ); smffa dla523 (.D(SUMMAND[442]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[442]) ); smfulladder dfa342 (.DATA_A (LATCHED_PP[440]), .DATA_B (LATCHED_PP[441]), .DATA_C (LATCHED_PP[442]), .SAVE (INT_SUM[467]), .CARRY (INT_CARRY[380]) ); smffa dla524 (.D(SUMMAND[443]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[443]) ); smffa dla525 (.D(SUMMAND[444]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[444]) ); smffa dla526 (.D(SUMMAND[445]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[445]) ); smfulladder dfa343 (.DATA_A (LATCHED_PP[443]), .DATA_B (LATCHED_PP[444]), .DATA_C (LATCHED_PP[445]), .SAVE (INT_SUM[468]), .CARRY (INT_CARRY[381]) ); smffa dla527 (.D(SUMMAND[446]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[446]) ); smffa dla528 (.D(SUMMAND[447]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[447]) ); smhalfadder dha37 (.DATA_A (LATCHED_PP[446]), .DATA_B (LATCHED_PP[447]), .SAVE (INT_SUM[469]), .CARRY (INT_CARRY[382]) ); smfulladder dfa344 (.DATA_A (INT_SUM[465]), .DATA_B (INT_SUM[466]), .DATA_C (INT_SUM[467]), .SAVE (INT_SUM[470]), .CARRY (INT_CARRY[383]) ); smfulladder dfa345 (.DATA_A (INT_SUM[468]), .DATA_B (INT_SUM[469]), .DATA_C (INT_CARRY[364]), .SAVE (INT_SUM[471]), .CARRY (INT_CARRY[384]) ); smfulladder dfa346 (.DATA_A (INT_CARRY[365]), .DATA_B (INT_CARRY[366]), .DATA_C (INT_CARRY[367]), .SAVE (INT_SUM[472]), .CARRY (INT_CARRY[385]) ); assign INT_SUM[473] = INT_CARRY[368]; smfulladder dfa347 (.DATA_A (INT_SUM[470]), .DATA_B (INT_SUM[471]), .DATA_C (INT_SUM[472]), .SAVE (INT_SUM[474]), .CARRY (INT_CARRY[386]) ); smfulladder dfa348 (.DATA_A (INT_SUM[473]), .DATA_B (INT_CARRY[369]), .DATA_C (INT_CARRY[370]), .SAVE (INT_SUM[475]), .CARRY (INT_CARRY[387]) ); assign INT_SUM[476] = INT_CARRY[371]; smfulladder dfa349 (.DATA_A (INT_SUM[474]), .DATA_B (INT_SUM[475]), .DATA_C (INT_SUM[476]), .SAVE (INT_SUM[477]), .CARRY (INT_CARRY[388]) ); smhalfadder dha38 (.DATA_A (INT_CARRY[372]), .DATA_B (INT_CARRY[373]), .SAVE (INT_SUM[478]), .CARRY (INT_CARRY[389]) ); smfulladder dfa350 (.DATA_A (INT_SUM[477]), .DATA_B (INT_SUM[478]), .DATA_C (INT_CARRY[374]), .SAVE (INT_SUM[479]), .CARRY (INT_CARRY[390]) ); assign INT_SUM[480] = INT_CARRY[375]; smfulladder dfa351 (.DATA_A (INT_SUM[479]), .DATA_B (INT_SUM[480]), .DATA_C (INT_CARRY[376]), .SAVE (INT_SUM[481]), .CARRY (INT_CARRY[377]) ); smffb dla529 (.D(INT_SUM[481]), .clk(clk), .en_d2(en_d2), .Q(SUM[41]) ); smffb dla530 (.D(INT_CARRY[377]), .clk(clk), .en_d2(en_d2), .Q(CARRY[41]) ); smffa dla531 (.D(SUMMAND[448]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[448]) ); smffa dla532 (.D(SUMMAND[449]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[449]) ); smffa dla533 (.D(SUMMAND[450]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[450]) ); smfulladder dfa352 (.DATA_A (LATCHED_PP[448]), .DATA_B (LATCHED_PP[449]), .DATA_C (LATCHED_PP[450]), .SAVE (INT_SUM[482]), .CARRY (INT_CARRY[392]) ); smffa dla534 (.D(SUMMAND[451]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[451]) ); smffa dla535 (.D(SUMMAND[452]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[452]) ); smffa dla536 (.D(SUMMAND[453]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[453]) ); smfulladder dfa353 (.DATA_A (LATCHED_PP[451]), .DATA_B (LATCHED_PP[452]), .DATA_C (LATCHED_PP[453]), .SAVE (INT_SUM[483]), .CARRY (INT_CARRY[393]) ); smffa dla537 (.D(SUMMAND[454]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[454]) ); smffa dla538 (.D(SUMMAND[455]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[455]) ); smffa dla539 (.D(SUMMAND[456]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[456]) ); smfulladder dfa354 (.DATA_A (LATCHED_PP[454]), .DATA_B (LATCHED_PP[455]), .DATA_C (LATCHED_PP[456]), .SAVE (INT_SUM[484]), .CARRY (INT_CARRY[394]) ); smffa dla540 (.D(SUMMAND[457]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[457]) ); smffa dla541 (.D(SUMMAND[458]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[458]) ); smffa dla542 (.D(SUMMAND[459]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[459]) ); smfulladder dfa355 (.DATA_A (LATCHED_PP[457]), .DATA_B (LATCHED_PP[458]), .DATA_C (LATCHED_PP[459]), .SAVE (INT_SUM[485]), .CARRY (INT_CARRY[395]) ); smffa dla543 (.D(SUMMAND[460]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[460]) ); assign INT_SUM[486] = LATCHED_PP[460]; smfulladder dfa356 (.DATA_A (INT_SUM[482]), .DATA_B (INT_SUM[483]), .DATA_C (INT_SUM[484]), .SAVE (INT_SUM[487]), .CARRY (INT_CARRY[396]) ); smfulladder dfa357 (.DATA_A (INT_SUM[485]), .DATA_B (INT_SUM[486]), .DATA_C (INT_CARRY[378]), .SAVE (INT_SUM[488]), .CARRY (INT_CARRY[397]) ); smfulladder dfa358 (.DATA_A (INT_CARRY[379]), .DATA_B (INT_CARRY[380]), .DATA_C (INT_CARRY[381]), .SAVE (INT_SUM[489]), .CARRY (INT_CARRY[398]) ); assign INT_SUM[490] = INT_CARRY[382]; smfulladder dfa359 (.DATA_A (INT_SUM[487]), .DATA_B (INT_SUM[488]), .DATA_C (INT_SUM[489]), .SAVE (INT_SUM[491]), .CARRY (INT_CARRY[399]) ); smfulladder dfa360 (.DATA_A (INT_SUM[490]), .DATA_B (INT_CARRY[383]), .DATA_C (INT_CARRY[384]), .SAVE (INT_SUM[492]), .CARRY (INT_CARRY[400]) ); assign INT_SUM[493] = INT_CARRY[385]; smfulladder dfa361 (.DATA_A (INT_SUM[491]), .DATA_B (INT_SUM[492]), .DATA_C (INT_SUM[493]), .SAVE (INT_SUM[494]), .CARRY (INT_CARRY[401]) ); smhalfadder dha39 (.DATA_A (INT_CARRY[386]), .DATA_B (INT_CARRY[387]), .SAVE (INT_SUM[495]), .CARRY (INT_CARRY[402]) ); smfulladder dfa362 (.DATA_A (INT_SUM[494]), .DATA_B (INT_SUM[495]), .DATA_C (INT_CARRY[388]), .SAVE (INT_SUM[496]), .CARRY (INT_CARRY[403]) ); assign INT_SUM[497] = INT_CARRY[389]; smfulladder dfa363 (.DATA_A (INT_SUM[496]), .DATA_B (INT_SUM[497]), .DATA_C (INT_CARRY[390]), .SAVE (INT_SUM[498]), .CARRY (INT_CARRY[391]) ); smffb dla544 (.D(INT_SUM[498]), .clk(clk), .en_d2(en_d2), .Q(SUM[42]) ); smffb dla545 (.D(INT_CARRY[391]), .clk(clk), .en_d2(en_d2), .Q(CARRY[42]) ); smffa dla546 (.D(SUMMAND[461]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[461]) ); smffa dla547 (.D(SUMMAND[462]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[462]) ); smffa dla548 (.D(SUMMAND[463]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[463]) ); smfulladder dfa364 (.DATA_A (LATCHED_PP[461]), .DATA_B (LATCHED_PP[462]), .DATA_C (LATCHED_PP[463]), .SAVE (INT_SUM[499]), .CARRY (INT_CARRY[405]) ); smffa dla549 (.D(SUMMAND[464]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[464]) ); smffa dla550 (.D(SUMMAND[465]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[465]) ); smffa dla551 (.D(SUMMAND[466]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[466]) ); smfulladder dfa365 (.DATA_A (LATCHED_PP[464]), .DATA_B (LATCHED_PP[465]), .DATA_C (LATCHED_PP[466]), .SAVE (INT_SUM[500]), .CARRY (INT_CARRY[406]) ); smffa dla552 (.D(SUMMAND[467]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[467]) ); smffa dla553 (.D(SUMMAND[468]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[468]) ); smffa dla554 (.D(SUMMAND[469]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[469]) ); smfulladder dfa366 (.DATA_A (LATCHED_PP[467]), .DATA_B (LATCHED_PP[468]), .DATA_C (LATCHED_PP[469]), .SAVE (INT_SUM[501]), .CARRY (INT_CARRY[407]) ); smffa dla555 (.D(SUMMAND[470]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[470]) ); smffa dla556 (.D(SUMMAND[471]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[471]) ); smffa dla557 (.D(SUMMAND[472]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[472]) ); smfulladder dfa367 (.DATA_A (LATCHED_PP[470]), .DATA_B (LATCHED_PP[471]), .DATA_C (LATCHED_PP[472]), .SAVE (INT_SUM[502]), .CARRY (INT_CARRY[408]) ); smffa dla558 (.D(SUMMAND[473]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[473]) ); smfulladder dfa368 (.DATA_A (LATCHED_PP[473]), .DATA_B (INT_CARRY[392]), .DATA_C (INT_CARRY[393]), .SAVE (INT_SUM[503]), .CARRY (INT_CARRY[409]) ); assign INT_SUM[504] = INT_CARRY[394]; assign INT_SUM[505] = INT_CARRY[395]; smfulladder dfa369 (.DATA_A (INT_SUM[499]), .DATA_B (INT_SUM[500]), .DATA_C (INT_SUM[501]), .SAVE (INT_SUM[506]), .CARRY (INT_CARRY[410]) ); smfulladder dfa370 (.DATA_A (INT_SUM[502]), .DATA_B (INT_SUM[503]), .DATA_C (INT_SUM[504]), .SAVE (INT_SUM[507]), .CARRY (INT_CARRY[411]) ); smfulladder dfa371 (.DATA_A (INT_SUM[505]), .DATA_B (INT_CARRY[396]), .DATA_C (INT_CARRY[397]), .SAVE (INT_SUM[508]), .CARRY (INT_CARRY[412]) ); assign INT_SUM[509] = INT_CARRY[398]; smfulladder dfa372 (.DATA_A (INT_SUM[506]), .DATA_B (INT_SUM[507]), .DATA_C (INT_SUM[508]), .SAVE (INT_SUM[510]), .CARRY (INT_CARRY[413]) ); smfulladder dfa373 (.DATA_A (INT_SUM[509]), .DATA_B (INT_CARRY[399]), .DATA_C (INT_CARRY[400]), .SAVE (INT_SUM[511]), .CARRY (INT_CARRY[414]) ); smfulladder dfa374 (.DATA_A (INT_SUM[510]), .DATA_B (INT_SUM[511]), .DATA_C (INT_CARRY[401]), .SAVE (INT_SUM[512]), .CARRY (INT_CARRY[415]) ); assign INT_SUM[513] = INT_CARRY[402]; smfulladder dfa375 (.DATA_A (INT_SUM[512]), .DATA_B (INT_SUM[513]), .DATA_C (INT_CARRY[403]), .SAVE (INT_SUM[514]), .CARRY (INT_CARRY[404]) ); smffb dla559 (.D(INT_SUM[514]), .clk(clk), .en_d2(en_d2), .Q(SUM[43]) ); smffb dla560 (.D(INT_CARRY[404]), .clk(clk), .en_d2(en_d2), .Q(CARRY[43]) ); smffa dla561 (.D(SUMMAND[474]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[474]) ); smffa dla562 (.D(SUMMAND[475]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[475]) ); smffa dla563 (.D(SUMMAND[476]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[476]) ); smfulladder dfa376 (.DATA_A (LATCHED_PP[474]), .DATA_B (LATCHED_PP[475]), .DATA_C (LATCHED_PP[476]), .SAVE (INT_SUM[515]), .CARRY (INT_CARRY[417]) ); smffa dla564 (.D(SUMMAND[477]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[477]) ); smffa dla565 (.D(SUMMAND[478]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[478]) ); smffa dla566 (.D(SUMMAND[479]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[479]) ); smfulladder dfa377 (.DATA_A (LATCHED_PP[477]), .DATA_B (LATCHED_PP[478]), .DATA_C (LATCHED_PP[479]), .SAVE (INT_SUM[516]), .CARRY (INT_CARRY[418]) ); smffa dla567 (.D(SUMMAND[480]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[480]) ); smffa dla568 (.D(SUMMAND[481]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[481]) ); smffa dla569 (.D(SUMMAND[482]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[482]) ); smfulladder dfa378 (.DATA_A (LATCHED_PP[480]), .DATA_B (LATCHED_PP[481]), .DATA_C (LATCHED_PP[482]), .SAVE (INT_SUM[517]), .CARRY (INT_CARRY[419]) ); smffa dla570 (.D(SUMMAND[483]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[483]) ); smffa dla571 (.D(SUMMAND[484]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[484]) ); smffa dla572 (.D(SUMMAND[485]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[485]) ); smfulladder dfa379 (.DATA_A (LATCHED_PP[483]), .DATA_B (LATCHED_PP[484]), .DATA_C (LATCHED_PP[485]), .SAVE (INT_SUM[518]), .CARRY (INT_CARRY[420]) ); smfulladder dfa380 (.DATA_A (INT_SUM[515]), .DATA_B (INT_SUM[516]), .DATA_C (INT_SUM[517]), .SAVE (INT_SUM[519]), .CARRY (INT_CARRY[421]) ); smfulladder dfa381 (.DATA_A (INT_SUM[518]), .DATA_B (INT_CARRY[405]), .DATA_C (INT_CARRY[406]), .SAVE (INT_SUM[520]), .CARRY (INT_CARRY[422]) ); smfulladder dfa382 (.DATA_A (INT_CARRY[407]), .DATA_B (INT_CARRY[408]), .DATA_C (INT_CARRY[409]), .SAVE (INT_SUM[521]), .CARRY (INT_CARRY[423]) ); smfulladder dfa383 (.DATA_A (INT_SUM[519]), .DATA_B (INT_SUM[520]), .DATA_C (INT_SUM[521]), .SAVE (INT_SUM[522]), .CARRY (INT_CARRY[424]) ); smfulladder dfa384 (.DATA_A (INT_CARRY[410]), .DATA_B (INT_CARRY[411]), .DATA_C (INT_CARRY[412]), .SAVE (INT_SUM[523]), .CARRY (INT_CARRY[425]) ); smfulladder dfa385 (.DATA_A (INT_SUM[522]), .DATA_B (INT_SUM[523]), .DATA_C (INT_CARRY[413]), .SAVE (INT_SUM[524]), .CARRY (INT_CARRY[426]) ); assign INT_SUM[525] = INT_CARRY[414]; smfulladder dfa386 (.DATA_A (INT_SUM[524]), .DATA_B (INT_SUM[525]), .DATA_C (INT_CARRY[415]), .SAVE (INT_SUM[526]), .CARRY (INT_CARRY[416]) ); smffb dla573 (.D(INT_SUM[526]), .clk(clk), .en_d2(en_d2), .Q(SUM[44]) ); smffb dla574 (.D(INT_CARRY[416]), .clk(clk), .en_d2(en_d2), .Q(CARRY[44]) ); smffa dla575 (.D(SUMMAND[486]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[486]) ); smffa dla576 (.D(SUMMAND[487]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[487]) ); smffa dla577 (.D(SUMMAND[488]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[488]) ); smfulladder dfa387 (.DATA_A (LATCHED_PP[486]), .DATA_B (LATCHED_PP[487]), .DATA_C (LATCHED_PP[488]), .SAVE (INT_SUM[527]), .CARRY (INT_CARRY[428]) ); smffa dla578 (.D(SUMMAND[489]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[489]) ); smffa dla579 (.D(SUMMAND[490]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[490]) ); smffa dla580 (.D(SUMMAND[491]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[491]) ); smfulladder dfa388 (.DATA_A (LATCHED_PP[489]), .DATA_B (LATCHED_PP[490]), .DATA_C (LATCHED_PP[491]), .SAVE (INT_SUM[528]), .CARRY (INT_CARRY[429]) ); smffa dla581 (.D(SUMMAND[492]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[492]) ); smffa dla582 (.D(SUMMAND[493]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[493]) ); smffa dla583 (.D(SUMMAND[494]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[494]) ); smfulladder dfa389 (.DATA_A (LATCHED_PP[492]), .DATA_B (LATCHED_PP[493]), .DATA_C (LATCHED_PP[494]), .SAVE (INT_SUM[529]), .CARRY (INT_CARRY[430]) ); smffa dla584 (.D(SUMMAND[495]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[495]) ); smffa dla585 (.D(SUMMAND[496]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[496]) ); smffa dla586 (.D(SUMMAND[497]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[497]) ); smfulladder dfa390 (.DATA_A (LATCHED_PP[495]), .DATA_B (LATCHED_PP[496]), .DATA_C (LATCHED_PP[497]), .SAVE (INT_SUM[530]), .CARRY (INT_CARRY[431]) ); smfulladder dfa391 (.DATA_A (INT_SUM[527]), .DATA_B (INT_SUM[528]), .DATA_C (INT_SUM[529]), .SAVE (INT_SUM[531]), .CARRY (INT_CARRY[432]) ); smfulladder dfa392 (.DATA_A (INT_SUM[530]), .DATA_B (INT_CARRY[417]), .DATA_C (INT_CARRY[418]), .SAVE (INT_SUM[532]), .CARRY (INT_CARRY[433]) ); smhalfadder dha40 (.DATA_A (INT_CARRY[419]), .DATA_B (INT_CARRY[420]), .SAVE (INT_SUM[533]), .CARRY (INT_CARRY[434]) ); smfulladder dfa393 (.DATA_A (INT_SUM[531]), .DATA_B (INT_SUM[532]), .DATA_C (INT_SUM[533]), .SAVE (INT_SUM[534]), .CARRY (INT_CARRY[435]) ); smfulladder dfa394 (.DATA_A (INT_CARRY[421]), .DATA_B (INT_CARRY[422]), .DATA_C (INT_CARRY[423]), .SAVE (INT_SUM[535]), .CARRY (INT_CARRY[436]) ); smfulladder dfa395 (.DATA_A (INT_SUM[534]), .DATA_B (INT_SUM[535]), .DATA_C (INT_CARRY[424]), .SAVE (INT_SUM[536]), .CARRY (INT_CARRY[437]) ); assign INT_SUM[537] = INT_CARRY[425]; smfulladder dfa396 (.DATA_A (INT_SUM[536]), .DATA_B (INT_SUM[537]), .DATA_C (INT_CARRY[426]), .SAVE (INT_SUM[538]), .CARRY (INT_CARRY[427]) ); smffb dla587 (.D(INT_SUM[538]), .clk(clk), .en_d2(en_d2), .Q(SUM[45]) ); smffb dla588 (.D(INT_CARRY[427]), .clk(clk), .en_d2(en_d2), .Q(CARRY[45]) ); smffa dla589 (.D(SUMMAND[498]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[498]) ); smffa dla590 (.D(SUMMAND[499]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[499]) ); smffa dla591 (.D(SUMMAND[500]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[500]) ); smfulladder dfa397 (.DATA_A (LATCHED_PP[498]), .DATA_B (LATCHED_PP[499]), .DATA_C (LATCHED_PP[500]), .SAVE (INT_SUM[539]), .CARRY (INT_CARRY[439]) ); smffa dla592 (.D(SUMMAND[501]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[501]) ); smffa dla593 (.D(SUMMAND[502]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[502]) ); smffa dla594 (.D(SUMMAND[503]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[503]) ); smfulladder dfa398 (.DATA_A (LATCHED_PP[501]), .DATA_B (LATCHED_PP[502]), .DATA_C (LATCHED_PP[503]), .SAVE (INT_SUM[540]), .CARRY (INT_CARRY[440]) ); smffa dla595 (.D(SUMMAND[504]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[504]) ); smffa dla596 (.D(SUMMAND[505]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[505]) ); smffa dla597 (.D(SUMMAND[506]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[506]) ); smfulladder dfa399 (.DATA_A (LATCHED_PP[504]), .DATA_B (LATCHED_PP[505]), .DATA_C (LATCHED_PP[506]), .SAVE (INT_SUM[541]), .CARRY (INT_CARRY[441]) ); smffa dla598 (.D(SUMMAND[507]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[507]) ); assign INT_SUM[542] = LATCHED_PP[507]; smffa dla599 (.D(SUMMAND[508]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[508]) ); assign INT_SUM[543] = LATCHED_PP[508]; smfulladder dfa400 (.DATA_A (INT_SUM[539]), .DATA_B (INT_SUM[540]), .DATA_C (INT_SUM[541]), .SAVE (INT_SUM[544]), .CARRY (INT_CARRY[442]) ); smfulladder dfa401 (.DATA_A (INT_SUM[542]), .DATA_B (INT_SUM[543]), .DATA_C (INT_CARRY[428]), .SAVE (INT_SUM[545]), .CARRY (INT_CARRY[443]) ); smfulladder dfa402 (.DATA_A (INT_CARRY[429]), .DATA_B (INT_CARRY[430]), .DATA_C (INT_CARRY[431]), .SAVE (INT_SUM[546]), .CARRY (INT_CARRY[444]) ); smfulladder dfa403 (.DATA_A (INT_SUM[544]), .DATA_B (INT_SUM[545]), .DATA_C (INT_SUM[546]), .SAVE (INT_SUM[547]), .CARRY (INT_CARRY[445]) ); smfulladder dfa404 (.DATA_A (INT_CARRY[432]), .DATA_B (INT_CARRY[433]), .DATA_C (INT_CARRY[434]), .SAVE (INT_SUM[548]), .CARRY (INT_CARRY[446]) ); smfulladder dfa405 (.DATA_A (INT_SUM[547]), .DATA_B (INT_SUM[548]), .DATA_C (INT_CARRY[435]), .SAVE (INT_SUM[549]), .CARRY (INT_CARRY[447]) ); assign INT_SUM[550] = INT_CARRY[436]; smfulladder dfa406 (.DATA_A (INT_SUM[549]), .DATA_B (INT_SUM[550]), .DATA_C (INT_CARRY[437]), .SAVE (INT_SUM[551]), .CARRY (INT_CARRY[438]) ); smffb dla600 (.D(INT_SUM[551]), .clk(clk), .en_d2(en_d2), .Q(SUM[46]) ); smffb dla601 (.D(INT_CARRY[438]), .clk(clk), .en_d2(en_d2), .Q(CARRY[46]) ); smffa dla602 (.D(SUMMAND[509]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[509]) ); smffa dla603 (.D(SUMMAND[510]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[510]) ); smffa dla604 (.D(SUMMAND[511]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[511]) ); smfulladder dfa407 (.DATA_A (LATCHED_PP[509]), .DATA_B (LATCHED_PP[510]), .DATA_C (LATCHED_PP[511]), .SAVE (INT_SUM[552]), .CARRY (INT_CARRY[449]) ); smffa dla605 (.D(SUMMAND[512]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[512]) ); smffa dla606 (.D(SUMMAND[513]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[513]) ); smffa dla607 (.D(SUMMAND[514]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[514]) ); smfulladder dfa408 (.DATA_A (LATCHED_PP[512]), .DATA_B (LATCHED_PP[513]), .DATA_C (LATCHED_PP[514]), .SAVE (INT_SUM[553]), .CARRY (INT_CARRY[450]) ); smffa dla608 (.D(SUMMAND[515]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[515]) ); smffa dla609 (.D(SUMMAND[516]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[516]) ); smffa dla610 (.D(SUMMAND[517]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[517]) ); smfulladder dfa409 (.DATA_A (LATCHED_PP[515]), .DATA_B (LATCHED_PP[516]), .DATA_C (LATCHED_PP[517]), .SAVE (INT_SUM[554]), .CARRY (INT_CARRY[451]) ); smffa dla611 (.D(SUMMAND[518]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[518]) ); smffa dla612 (.D(SUMMAND[519]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[519]) ); smhalfadder dha41 (.DATA_A (LATCHED_PP[518]), .DATA_B (LATCHED_PP[519]), .SAVE (INT_SUM[555]), .CARRY (INT_CARRY[452]) ); smfulladder dfa410 (.DATA_A (INT_SUM[552]), .DATA_B (INT_SUM[553]), .DATA_C (INT_SUM[554]), .SAVE (INT_SUM[556]), .CARRY (INT_CARRY[453]) ); smfulladder dfa411 (.DATA_A (INT_SUM[555]), .DATA_B (INT_CARRY[439]), .DATA_C (INT_CARRY[440]), .SAVE (INT_SUM[557]), .CARRY (INT_CARRY[454]) ); assign INT_SUM[558] = INT_CARRY[441]; smfulladder dfa412 (.DATA_A (INT_SUM[556]), .DATA_B (INT_SUM[557]), .DATA_C (INT_SUM[558]), .SAVE (INT_SUM[559]), .CARRY (INT_CARRY[455]) ); smfulladder dfa413 (.DATA_A (INT_CARRY[442]), .DATA_B (INT_CARRY[443]), .DATA_C (INT_CARRY[444]), .SAVE (INT_SUM[560]), .CARRY (INT_CARRY[456]) ); smfulladder dfa414 (.DATA_A (INT_SUM[559]), .DATA_B (INT_SUM[560]), .DATA_C (INT_CARRY[445]), .SAVE (INT_SUM[561]), .CARRY (INT_CARRY[457]) ); assign INT_SUM[562] = INT_CARRY[446]; smfulladder dfa415 (.DATA_A (INT_SUM[561]), .DATA_B (INT_SUM[562]), .DATA_C (INT_CARRY[447]), .SAVE (INT_SUM[563]), .CARRY (INT_CARRY[448]) ); smffb dla613 (.D(INT_SUM[563]), .clk(clk), .en_d2(en_d2), .Q(SUM[47]) ); smffb dla614 (.D(INT_CARRY[448]), .clk(clk), .en_d2(en_d2), .Q(CARRY[47]) ); smffa dla615 (.D(SUMMAND[520]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[520]) ); smffa dla616 (.D(SUMMAND[521]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[521]) ); smffa dla617 (.D(SUMMAND[522]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[522]) ); smfulladder dfa416 (.DATA_A (LATCHED_PP[520]), .DATA_B (LATCHED_PP[521]), .DATA_C (LATCHED_PP[522]), .SAVE (INT_SUM[564]), .CARRY (INT_CARRY[459]) ); smffa dla618 (.D(SUMMAND[523]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[523]) ); smffa dla619 (.D(SUMMAND[524]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[524]) ); smffa dla620 (.D(SUMMAND[525]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[525]) ); smfulladder dfa417 (.DATA_A (LATCHED_PP[523]), .DATA_B (LATCHED_PP[524]), .DATA_C (LATCHED_PP[525]), .SAVE (INT_SUM[565]), .CARRY (INT_CARRY[460]) ); smffa dla621 (.D(SUMMAND[526]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[526]) ); smffa dla622 (.D(SUMMAND[527]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[527]) ); smffa dla623 (.D(SUMMAND[528]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[528]) ); smfulladder dfa418 (.DATA_A (LATCHED_PP[526]), .DATA_B (LATCHED_PP[527]), .DATA_C (LATCHED_PP[528]), .SAVE (INT_SUM[566]), .CARRY (INT_CARRY[461]) ); smffa dla624 (.D(SUMMAND[529]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[529]) ); assign INT_SUM[567] = LATCHED_PP[529]; smfulladder dfa419 (.DATA_A (INT_SUM[564]), .DATA_B (INT_SUM[565]), .DATA_C (INT_SUM[566]), .SAVE (INT_SUM[568]), .CARRY (INT_CARRY[462]) ); smfulladder dfa420 (.DATA_A (INT_SUM[567]), .DATA_B (INT_CARRY[449]), .DATA_C (INT_CARRY[450]), .SAVE (INT_SUM[569]), .CARRY (INT_CARRY[463]) ); assign INT_SUM[570] = INT_CARRY[451]; assign INT_SUM[571] = INT_CARRY[452]; smfulladder dfa421 (.DATA_A (INT_SUM[568]), .DATA_B (INT_SUM[569]), .DATA_C (INT_SUM[570]), .SAVE (INT_SUM[572]), .CARRY (INT_CARRY[464]) ); smfulladder dfa422 (.DATA_A (INT_SUM[571]), .DATA_B (INT_CARRY[453]), .DATA_C (INT_CARRY[454]), .SAVE (INT_SUM[573]), .CARRY (INT_CARRY[465]) ); smfulladder dfa423 (.DATA_A (INT_SUM[572]), .DATA_B (INT_SUM[573]), .DATA_C (INT_CARRY[455]), .SAVE (INT_SUM[574]), .CARRY (INT_CARRY[466]) ); assign INT_SUM[575] = INT_CARRY[456]; smfulladder dfa424 (.DATA_A (INT_SUM[574]), .DATA_B (INT_SUM[575]), .DATA_C (INT_CARRY[457]), .SAVE (INT_SUM[576]), .CARRY (INT_CARRY[458]) ); smffb dla625 (.D(INT_SUM[576]), .clk(clk), .en_d2(en_d2), .Q(SUM[48]) ); smffb dla626 (.D(INT_CARRY[458]), .clk(clk), .en_d2(en_d2), .Q(CARRY[48]) ); smffa dla627 (.D(SUMMAND[530]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[530]) ); smffa dla628 (.D(SUMMAND[531]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[531]) ); smffa dla629 (.D(SUMMAND[532]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[532]) ); smfulladder dfa425 (.DATA_A (LATCHED_PP[530]), .DATA_B (LATCHED_PP[531]), .DATA_C (LATCHED_PP[532]), .SAVE (INT_SUM[577]), .CARRY (INT_CARRY[468]) ); smffa dla630 (.D(SUMMAND[533]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[533]) ); smffa dla631 (.D(SUMMAND[534]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[534]) ); smffa dla632 (.D(SUMMAND[535]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[535]) ); smfulladder dfa426 (.DATA_A (LATCHED_PP[533]), .DATA_B (LATCHED_PP[534]), .DATA_C (LATCHED_PP[535]), .SAVE (INT_SUM[578]), .CARRY (INT_CARRY[469]) ); smffa dla633 (.D(SUMMAND[536]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[536]) ); smffa dla634 (.D(SUMMAND[537]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[537]) ); smffa dla635 (.D(SUMMAND[538]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[538]) ); smfulladder dfa427 (.DATA_A (LATCHED_PP[536]), .DATA_B (LATCHED_PP[537]), .DATA_C (LATCHED_PP[538]), .SAVE (INT_SUM[579]), .CARRY (INT_CARRY[470]) ); smffa dla636 (.D(SUMMAND[539]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[539]) ); assign INT_SUM[580] = LATCHED_PP[539]; smfulladder dfa428 (.DATA_A (INT_SUM[577]), .DATA_B (INT_SUM[578]), .DATA_C (INT_SUM[579]), .SAVE (INT_SUM[581]), .CARRY (INT_CARRY[471]) ); smfulladder dfa429 (.DATA_A (INT_SUM[580]), .DATA_B (INT_CARRY[459]), .DATA_C (INT_CARRY[460]), .SAVE (INT_SUM[582]), .CARRY (INT_CARRY[472]) ); assign INT_SUM[583] = INT_CARRY[461]; smfulladder dfa430 (.DATA_A (INT_SUM[581]), .DATA_B (INT_SUM[582]), .DATA_C (INT_SUM[583]), .SAVE (INT_SUM[584]), .CARRY (INT_CARRY[473]) ); smhalfadder dha42 (.DATA_A (INT_CARRY[462]), .DATA_B (INT_CARRY[463]), .SAVE (INT_SUM[585]), .CARRY (INT_CARRY[474]) ); smfulladder dfa431 (.DATA_A (INT_SUM[584]), .DATA_B (INT_SUM[585]), .DATA_C (INT_CARRY[464]), .SAVE (INT_SUM[586]), .CARRY (INT_CARRY[475]) ); assign INT_SUM[587] = INT_CARRY[465]; smfulladder dfa432 (.DATA_A (INT_SUM[586]), .DATA_B (INT_SUM[587]), .DATA_C (INT_CARRY[466]), .SAVE (INT_SUM[588]), .CARRY (INT_CARRY[467]) ); smffb dla637 (.D(INT_SUM[588]), .clk(clk), .en_d2(en_d2), .Q(SUM[49]) ); smffb dla638 (.D(INT_CARRY[467]), .clk(clk), .en_d2(en_d2), .Q(CARRY[49]) ); smffa dla639 (.D(SUMMAND[540]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[540]) ); smffa dla640 (.D(SUMMAND[541]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[541]) ); smffa dla641 (.D(SUMMAND[542]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[542]) ); smfulladder dfa433 (.DATA_A (LATCHED_PP[540]), .DATA_B (LATCHED_PP[541]), .DATA_C (LATCHED_PP[542]), .SAVE (INT_SUM[589]), .CARRY (INT_CARRY[477]) ); smffa dla642 (.D(SUMMAND[543]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[543]) ); smffa dla643 (.D(SUMMAND[544]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[544]) ); smffa dla644 (.D(SUMMAND[545]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[545]) ); smfulladder dfa434 (.DATA_A (LATCHED_PP[543]), .DATA_B (LATCHED_PP[544]), .DATA_C (LATCHED_PP[545]), .SAVE (INT_SUM[590]), .CARRY (INT_CARRY[478]) ); smffa dla645 (.D(SUMMAND[546]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[546]) ); smffa dla646 (.D(SUMMAND[547]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[547]) ); smffa dla647 (.D(SUMMAND[548]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[548]) ); smfulladder dfa435 (.DATA_A (LATCHED_PP[546]), .DATA_B (LATCHED_PP[547]), .DATA_C (LATCHED_PP[548]), .SAVE (INT_SUM[591]), .CARRY (INT_CARRY[479]) ); smfulladder dfa436 (.DATA_A (INT_SUM[589]), .DATA_B (INT_SUM[590]), .DATA_C (INT_SUM[591]), .SAVE (INT_SUM[592]), .CARRY (INT_CARRY[480]) ); smfulladder dfa437 (.DATA_A (INT_CARRY[468]), .DATA_B (INT_CARRY[469]), .DATA_C (INT_CARRY[470]), .SAVE (INT_SUM[593]), .CARRY (INT_CARRY[481]) ); smfulladder dfa438 (.DATA_A (INT_SUM[592]), .DATA_B (INT_SUM[593]), .DATA_C (INT_CARRY[471]), .SAVE (INT_SUM[594]), .CARRY (INT_CARRY[482]) ); assign INT_SUM[595] = INT_CARRY[472]; smfulladder dfa439 (.DATA_A (INT_SUM[594]), .DATA_B (INT_SUM[595]), .DATA_C (INT_CARRY[473]), .SAVE (INT_SUM[596]), .CARRY (INT_CARRY[483]) ); assign INT_SUM[597] = INT_CARRY[474]; smfulladder dfa440 (.DATA_A (INT_SUM[596]), .DATA_B (INT_SUM[597]), .DATA_C (INT_CARRY[475]), .SAVE (INT_SUM[598]), .CARRY (INT_CARRY[476]) ); smffb dla648 (.D(INT_SUM[598]), .clk(clk), .en_d2(en_d2), .Q(SUM[50]) ); smffb dla649 (.D(INT_CARRY[476]), .clk(clk), .en_d2(en_d2), .Q(CARRY[50]) ); smffa dla650 (.D(SUMMAND[549]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[549]) ); smffa dla651 (.D(SUMMAND[550]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[550]) ); smffa dla652 (.D(SUMMAND[551]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[551]) ); smfulladder dfa441 (.DATA_A (LATCHED_PP[549]), .DATA_B (LATCHED_PP[550]), .DATA_C (LATCHED_PP[551]), .SAVE (INT_SUM[599]), .CARRY (INT_CARRY[485]) ); smffa dla653 (.D(SUMMAND[552]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[552]) ); smffa dla654 (.D(SUMMAND[553]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[553]) ); smffa dla655 (.D(SUMMAND[554]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[554]) ); smfulladder dfa442 (.DATA_A (LATCHED_PP[552]), .DATA_B (LATCHED_PP[553]), .DATA_C (LATCHED_PP[554]), .SAVE (INT_SUM[600]), .CARRY (INT_CARRY[486]) ); smffa dla656 (.D(SUMMAND[555]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[555]) ); smffa dla657 (.D(SUMMAND[556]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[556]) ); smffa dla658 (.D(SUMMAND[557]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[557]) ); smfulladder dfa443 (.DATA_A (LATCHED_PP[555]), .DATA_B (LATCHED_PP[556]), .DATA_C (LATCHED_PP[557]), .SAVE (INT_SUM[601]), .CARRY (INT_CARRY[487]) ); smfulladder dfa444 (.DATA_A (INT_SUM[599]), .DATA_B (INT_SUM[600]), .DATA_C (INT_SUM[601]), .SAVE (INT_SUM[602]), .CARRY (INT_CARRY[488]) ); smfulladder dfa445 (.DATA_A (INT_CARRY[477]), .DATA_B (INT_CARRY[478]), .DATA_C (INT_CARRY[479]), .SAVE (INT_SUM[603]), .CARRY (INT_CARRY[489]) ); smfulladder dfa446 (.DATA_A (INT_SUM[602]), .DATA_B (INT_SUM[603]), .DATA_C (INT_CARRY[480]), .SAVE (INT_SUM[604]), .CARRY (INT_CARRY[490]) ); assign INT_SUM[605] = INT_CARRY[481]; smfulladder dfa447 (.DATA_A (INT_SUM[604]), .DATA_B (INT_SUM[605]), .DATA_C (INT_CARRY[482]), .SAVE (INT_SUM[606]), .CARRY (INT_CARRY[491]) ); smhalfadder dha43 (.DATA_A (INT_SUM[606]), .DATA_B (INT_CARRY[483]), .SAVE (INT_SUM[607]), .CARRY (INT_CARRY[484]) ); smffb dla659 (.D(INT_SUM[607]), .clk(clk), .en_d2(en_d2), .Q(SUM[51]) ); smffb dla660 (.D(INT_CARRY[484]), .clk(clk), .en_d2(en_d2), .Q(CARRY[51]) ); smffa dla661 (.D(SUMMAND[558]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[558]) ); smffa dla662 (.D(SUMMAND[559]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[559]) ); smffa dla663 (.D(SUMMAND[560]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[560]) ); smfulladder dfa448 (.DATA_A (LATCHED_PP[558]), .DATA_B (LATCHED_PP[559]), .DATA_C (LATCHED_PP[560]), .SAVE (INT_SUM[608]), .CARRY (INT_CARRY[493]) ); smffa dla664 (.D(SUMMAND[561]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[561]) ); smffa dla665 (.D(SUMMAND[562]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[562]) ); smffa dla666 (.D(SUMMAND[563]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[563]) ); smfulladder dfa449 (.DATA_A (LATCHED_PP[561]), .DATA_B (LATCHED_PP[562]), .DATA_C (LATCHED_PP[563]), .SAVE (INT_SUM[609]), .CARRY (INT_CARRY[494]) ); smffa dla667 (.D(SUMMAND[564]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[564]) ); smffa dla668 (.D(SUMMAND[565]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[565]) ); smfulladder dfa450 (.DATA_A (LATCHED_PP[564]), .DATA_B (LATCHED_PP[565]), .DATA_C (INT_CARRY[485]), .SAVE (INT_SUM[610]), .CARRY (INT_CARRY[495]) ); smhalfadder dha44 (.DATA_A (INT_CARRY[486]), .DATA_B (INT_CARRY[487]), .SAVE (INT_SUM[611]), .CARRY (INT_CARRY[496]) ); smfulladder dfa451 (.DATA_A (INT_SUM[608]), .DATA_B (INT_SUM[609]), .DATA_C (INT_SUM[610]), .SAVE (INT_SUM[612]), .CARRY (INT_CARRY[497]) ); smfulladder dfa452 (.DATA_A (INT_SUM[611]), .DATA_B (INT_CARRY[488]), .DATA_C (INT_CARRY[489]), .SAVE (INT_SUM[613]), .CARRY (INT_CARRY[498]) ); smfulladder dfa453 (.DATA_A (INT_SUM[612]), .DATA_B (INT_SUM[613]), .DATA_C (INT_CARRY[490]), .SAVE (INT_SUM[614]), .CARRY (INT_CARRY[499]) ); smhalfadder dha45 (.DATA_A (INT_SUM[614]), .DATA_B (INT_CARRY[491]), .SAVE (INT_SUM[615]), .CARRY (INT_CARRY[492]) ); smffb dla669 (.D(INT_SUM[615]), .clk(clk), .en_d2(en_d2), .Q(SUM[52]) ); smffb dla670 (.D(INT_CARRY[492]), .clk(clk), .en_d2(en_d2), .Q(CARRY[52]) ); smffa dla671 (.D(SUMMAND[566]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[566]) ); smffa dla672 (.D(SUMMAND[567]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[567]) ); smffa dla673 (.D(SUMMAND[568]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[568]) ); smfulladder dfa454 (.DATA_A (LATCHED_PP[566]), .DATA_B (LATCHED_PP[567]), .DATA_C (LATCHED_PP[568]), .SAVE (INT_SUM[616]), .CARRY (INT_CARRY[501]) ); smffa dla674 (.D(SUMMAND[569]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[569]) ); smffa dla675 (.D(SUMMAND[570]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[570]) ); smffa dla676 (.D(SUMMAND[571]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[571]) ); smfulladder dfa455 (.DATA_A (LATCHED_PP[569]), .DATA_B (LATCHED_PP[570]), .DATA_C (LATCHED_PP[571]), .SAVE (INT_SUM[617]), .CARRY (INT_CARRY[502]) ); smffa dla677 (.D(SUMMAND[572]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[572]) ); assign INT_SUM[618] = LATCHED_PP[572]; smffa dla678 (.D(SUMMAND[573]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[573]) ); assign INT_SUM[619] = LATCHED_PP[573]; smfulladder dfa456 (.DATA_A (INT_SUM[616]), .DATA_B (INT_SUM[617]), .DATA_C (INT_SUM[618]), .SAVE (INT_SUM[620]), .CARRY (INT_CARRY[503]) ); assign INT_SUM[621] = INT_SUM[619]; smfulladder dfa457 (.DATA_A (INT_SUM[620]), .DATA_B (INT_SUM[621]), .DATA_C (INT_CARRY[493]), .SAVE (INT_SUM[622]), .CARRY (INT_CARRY[504]) ); smfulladder dfa458 (.DATA_A (INT_CARRY[494]), .DATA_B (INT_CARRY[495]), .DATA_C (INT_CARRY[496]), .SAVE (INT_SUM[623]), .CARRY (INT_CARRY[505]) ); smfulladder dfa459 (.DATA_A (INT_SUM[622]), .DATA_B (INT_SUM[623]), .DATA_C (INT_CARRY[497]), .SAVE (INT_SUM[624]), .CARRY (INT_CARRY[506]) ); assign INT_SUM[625] = INT_CARRY[498]; smfulladder dfa460 (.DATA_A (INT_SUM[624]), .DATA_B (INT_SUM[625]), .DATA_C (INT_CARRY[499]), .SAVE (INT_SUM[626]), .CARRY (INT_CARRY[500]) ); smffb dla679 (.D(INT_SUM[626]), .clk(clk), .en_d2(en_d2), .Q(SUM[53]) ); smffb dla680 (.D(INT_CARRY[500]), .clk(clk), .en_d2(en_d2), .Q(CARRY[53]) ); smffa dla681 (.D(SUMMAND[574]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[574]) ); smffa dla682 (.D(SUMMAND[575]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[575]) ); smffa dla683 (.D(SUMMAND[576]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[576]) ); smfulladder dfa461 (.DATA_A (LATCHED_PP[574]), .DATA_B (LATCHED_PP[575]), .DATA_C (LATCHED_PP[576]), .SAVE (INT_SUM[627]), .CARRY (INT_CARRY[508]) ); smffa dla684 (.D(SUMMAND[577]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[577]) ); smffa dla685 (.D(SUMMAND[578]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[578]) ); smffa dla686 (.D(SUMMAND[579]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[579]) ); smfulladder dfa462 (.DATA_A (LATCHED_PP[577]), .DATA_B (LATCHED_PP[578]), .DATA_C (LATCHED_PP[579]), .SAVE (INT_SUM[628]), .CARRY (INT_CARRY[509]) ); smffa dla687 (.D(SUMMAND[580]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[580]) ); smfulladder dfa463 (.DATA_A (LATCHED_PP[580]), .DATA_B (INT_CARRY[501]), .DATA_C (INT_CARRY[502]), .SAVE (INT_SUM[629]), .CARRY (INT_CARRY[510]) ); smfulladder dfa464 (.DATA_A (INT_SUM[627]), .DATA_B (INT_SUM[628]), .DATA_C (INT_SUM[629]), .SAVE (INT_SUM[630]), .CARRY (INT_CARRY[511]) ); assign INT_SUM[631] = INT_CARRY[503]; smfulladder dfa465 (.DATA_A (INT_SUM[630]), .DATA_B (INT_SUM[631]), .DATA_C (INT_CARRY[504]), .SAVE (INT_SUM[632]), .CARRY (INT_CARRY[512]) ); assign INT_SUM[633] = INT_CARRY[505]; smfulladder dfa466 (.DATA_A (INT_SUM[632]), .DATA_B (INT_SUM[633]), .DATA_C (INT_CARRY[506]), .SAVE (INT_SUM[634]), .CARRY (INT_CARRY[507]) ); smffb dla688 (.D(INT_SUM[634]), .clk(clk), .en_d2(en_d2), .Q(SUM[54]) ); smffb dla689 (.D(INT_CARRY[507]), .clk(clk), .en_d2(en_d2), .Q(CARRY[54]) ); smffa dla690 (.D(SUMMAND[581]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[581]) ); smffa dla691 (.D(SUMMAND[582]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[582]) ); smffa dla692 (.D(SUMMAND[583]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[583]) ); smfulladder dfa467 (.DATA_A (LATCHED_PP[581]), .DATA_B (LATCHED_PP[582]), .DATA_C (LATCHED_PP[583]), .SAVE (INT_SUM[635]), .CARRY (INT_CARRY[514]) ); smffa dla693 (.D(SUMMAND[584]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[584]) ); smffa dla694 (.D(SUMMAND[585]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[585]) ); smffa dla695 (.D(SUMMAND[586]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[586]) ); smfulladder dfa468 (.DATA_A (LATCHED_PP[584]), .DATA_B (LATCHED_PP[585]), .DATA_C (LATCHED_PP[586]), .SAVE (INT_SUM[636]), .CARRY (INT_CARRY[515]) ); smffa dla696 (.D(SUMMAND[587]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[587]) ); assign INT_SUM[637] = LATCHED_PP[587]; smfulladder dfa469 (.DATA_A (INT_SUM[635]), .DATA_B (INT_SUM[636]), .DATA_C (INT_SUM[637]), .SAVE (INT_SUM[638]), .CARRY (INT_CARRY[516]) ); smfulladder dfa470 (.DATA_A (INT_CARRY[508]), .DATA_B (INT_CARRY[509]), .DATA_C (INT_CARRY[510]), .SAVE (INT_SUM[639]), .CARRY (INT_CARRY[517]) ); smfulladder dfa471 (.DATA_A (INT_SUM[638]), .DATA_B (INT_SUM[639]), .DATA_C (INT_CARRY[511]), .SAVE (INT_SUM[640]), .CARRY (INT_CARRY[518]) ); smhalfadder dha46 (.DATA_A (INT_SUM[640]), .DATA_B (INT_CARRY[512]), .SAVE (INT_SUM[641]), .CARRY (INT_CARRY[513]) ); smffb dla697 (.D(INT_SUM[641]), .clk(clk), .en_d2(en_d2), .Q(SUM[55]) ); smffb dla698 (.D(INT_CARRY[513]), .clk(clk), .en_d2(en_d2), .Q(CARRY[55]) ); smffa dla699 (.D(SUMMAND[588]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[588]) ); smffa dla700 (.D(SUMMAND[589]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[589]) ); smffa dla701 (.D(SUMMAND[590]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[590]) ); smfulladder dfa472 (.DATA_A (LATCHED_PP[588]), .DATA_B (LATCHED_PP[589]), .DATA_C (LATCHED_PP[590]), .SAVE (INT_SUM[642]), .CARRY (INT_CARRY[520]) ); smffa dla702 (.D(SUMMAND[591]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[591]) ); smffa dla703 (.D(SUMMAND[592]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[592]) ); smffa dla704 (.D(SUMMAND[593]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[593]) ); smfulladder dfa473 (.DATA_A (LATCHED_PP[591]), .DATA_B (LATCHED_PP[592]), .DATA_C (LATCHED_PP[593]), .SAVE (INT_SUM[643]), .CARRY (INT_CARRY[521]) ); smfulladder dfa474 (.DATA_A (INT_SUM[642]), .DATA_B (INT_SUM[643]), .DATA_C (INT_CARRY[514]), .SAVE (INT_SUM[644]), .CARRY (INT_CARRY[522]) ); assign INT_SUM[645] = INT_CARRY[515]; smfulladder dfa475 (.DATA_A (INT_SUM[644]), .DATA_B (INT_SUM[645]), .DATA_C (INT_CARRY[516]), .SAVE (INT_SUM[646]), .CARRY (INT_CARRY[523]) ); assign INT_SUM[647] = INT_CARRY[517]; smfulladder dfa476 (.DATA_A (INT_SUM[646]), .DATA_B (INT_SUM[647]), .DATA_C (INT_CARRY[518]), .SAVE (INT_SUM[648]), .CARRY (INT_CARRY[519]) ); smffb dla705 (.D(INT_SUM[648]), .clk(clk), .en_d2(en_d2), .Q(SUM[56]) ); smffb dla706 (.D(INT_CARRY[519]), .clk(clk), .en_d2(en_d2), .Q(CARRY[56]) ); smffa dla707 (.D(SUMMAND[594]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[594]) ); smffa dla708 (.D(SUMMAND[595]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[595]) ); smffa dla709 (.D(SUMMAND[596]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[596]) ); smfulladder dfa477 (.DATA_A (LATCHED_PP[594]), .DATA_B (LATCHED_PP[595]), .DATA_C (LATCHED_PP[596]), .SAVE (INT_SUM[649]), .CARRY (INT_CARRY[525]) ); smffa dla710 (.D(SUMMAND[597]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[597]) ); smffa dla711 (.D(SUMMAND[598]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[598]) ); smffa dla712 (.D(SUMMAND[599]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[599]) ); smfulladder dfa478 (.DATA_A (LATCHED_PP[597]), .DATA_B (LATCHED_PP[598]), .DATA_C (LATCHED_PP[599]), .SAVE (INT_SUM[650]), .CARRY (INT_CARRY[526]) ); smfulladder dfa479 (.DATA_A (INT_SUM[649]), .DATA_B (INT_SUM[650]), .DATA_C (INT_CARRY[520]), .SAVE (INT_SUM[651]), .CARRY (INT_CARRY[527]) ); assign INT_SUM[652] = INT_CARRY[521]; smfulladder dfa480 (.DATA_A (INT_SUM[651]), .DATA_B (INT_SUM[652]), .DATA_C (INT_CARRY[522]), .SAVE (INT_SUM[653]), .CARRY (INT_CARRY[528]) ); smhalfadder dha47 (.DATA_A (INT_SUM[653]), .DATA_B (INT_CARRY[523]), .SAVE (INT_SUM[654]), .CARRY (INT_CARRY[524]) ); smffb dla713 (.D(INT_SUM[654]), .clk(clk), .en_d2(en_d2), .Q(SUM[57]) ); smffb dla714 (.D(INT_CARRY[524]), .clk(clk), .en_d2(en_d2), .Q(CARRY[57]) ); smffa dla715 (.D(SUMMAND[600]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[600]) ); smffa dla716 (.D(SUMMAND[601]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[601]) ); smffa dla717 (.D(SUMMAND[602]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[602]) ); smfulladder dfa481 (.DATA_A (LATCHED_PP[600]), .DATA_B (LATCHED_PP[601]), .DATA_C (LATCHED_PP[602]), .SAVE (INT_SUM[655]), .CARRY (INT_CARRY[530]) ); smffa dla718 (.D(SUMMAND[603]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[603]) ); smffa dla719 (.D(SUMMAND[604]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[604]) ); smhalfadder dha48 (.DATA_A (LATCHED_PP[603]), .DATA_B (LATCHED_PP[604]), .SAVE (INT_SUM[656]), .CARRY (INT_CARRY[531]) ); smfulladder dfa482 (.DATA_A (INT_SUM[655]), .DATA_B (INT_SUM[656]), .DATA_C (INT_CARRY[525]), .SAVE (INT_SUM[657]), .CARRY (INT_CARRY[532]) ); assign INT_SUM[658] = INT_CARRY[526]; smfulladder dfa483 (.DATA_A (INT_SUM[657]), .DATA_B (INT_SUM[658]), .DATA_C (INT_CARRY[527]), .SAVE (INT_SUM[659]), .CARRY (INT_CARRY[533]) ); smhalfadder dha49 (.DATA_A (INT_SUM[659]), .DATA_B (INT_CARRY[528]), .SAVE (INT_SUM[660]), .CARRY (INT_CARRY[529]) ); smffb dla720 (.D(INT_SUM[660]), .clk(clk), .en_d2(en_d2), .Q(SUM[58]) ); smffb dla721 (.D(INT_CARRY[529]), .clk(clk), .en_d2(en_d2), .Q(CARRY[58]) ); smffa dla722 (.D(SUMMAND[605]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[605]) ); smffa dla723 (.D(SUMMAND[606]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[606]) ); smffa dla724 (.D(SUMMAND[607]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[607]) ); smfulladder dfa484 (.DATA_A (LATCHED_PP[605]), .DATA_B (LATCHED_PP[606]), .DATA_C (LATCHED_PP[607]), .SAVE (INT_SUM[661]), .CARRY (INT_CARRY[535]) ); smffa dla725 (.D(SUMMAND[608]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[608]) ); smffa dla726 (.D(SUMMAND[609]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[609]) ); smhalfadder dha50 (.DATA_A (LATCHED_PP[608]), .DATA_B (LATCHED_PP[609]), .SAVE (INT_SUM[662]), .CARRY (INT_CARRY[536]) ); smfulladder dfa485 (.DATA_A (INT_SUM[661]), .DATA_B (INT_SUM[662]), .DATA_C (INT_CARRY[530]), .SAVE (INT_SUM[663]), .CARRY (INT_CARRY[537]) ); assign INT_SUM[664] = INT_CARRY[531]; smfulladder dfa486 (.DATA_A (INT_SUM[663]), .DATA_B (INT_SUM[664]), .DATA_C (INT_CARRY[532]), .SAVE (INT_SUM[665]), .CARRY (INT_CARRY[538]) ); smhalfadder dha51 (.DATA_A (INT_SUM[665]), .DATA_B (INT_CARRY[533]), .SAVE (INT_SUM[666]), .CARRY (INT_CARRY[534]) ); smffb dla727 (.D(INT_SUM[666]), .clk(clk), .en_d2(en_d2), .Q(SUM[59]) ); smffb dla728 (.D(INT_CARRY[534]), .clk(clk), .en_d2(en_d2), .Q(CARRY[59]) ); smffa dla729 (.D(SUMMAND[610]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[610]) ); smffa dla730 (.D(SUMMAND[611]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[611]) ); smffa dla731 (.D(SUMMAND[612]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[612]) ); smfulladder dfa487 (.DATA_A (LATCHED_PP[610]), .DATA_B (LATCHED_PP[611]), .DATA_C (LATCHED_PP[612]), .SAVE (INT_SUM[667]), .CARRY (INT_CARRY[540]) ); smffa dla732 (.D(SUMMAND[613]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[613]) ); smfulladder dfa488 (.DATA_A (LATCHED_PP[613]), .DATA_B (INT_CARRY[535]), .DATA_C (INT_CARRY[536]), .SAVE (INT_SUM[668]), .CARRY (INT_CARRY[541]) ); smfulladder dfa489 (.DATA_A (INT_SUM[667]), .DATA_B (INT_SUM[668]), .DATA_C (INT_CARRY[537]), .SAVE (INT_SUM[669]), .CARRY (INT_CARRY[542]) ); smhalfadder dha52 (.DATA_A (INT_SUM[669]), .DATA_B (INT_CARRY[538]), .SAVE (INT_SUM[670]), .CARRY (INT_CARRY[539]) ); smffb dla733 (.D(INT_SUM[670]), .clk(clk), .en_d2(en_d2), .Q(SUM[60]) ); smffb dla734 (.D(INT_CARRY[539]), .clk(clk), .en_d2(en_d2), .Q(CARRY[60]) ); smffa dla735 (.D(SUMMAND[614]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[614]) ); smffa dla736 (.D(SUMMAND[615]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[615]) ); smffa dla737 (.D(SUMMAND[616]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[616]) ); smfulladder dfa490 (.DATA_A (LATCHED_PP[614]), .DATA_B (LATCHED_PP[615]), .DATA_C (LATCHED_PP[616]), .SAVE (INT_SUM[671]), .CARRY (INT_CARRY[544]) ); smffa dla738 (.D(SUMMAND[617]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[617]) ); assign INT_SUM[672] = LATCHED_PP[617]; smfulladder dfa491 (.DATA_A (INT_SUM[671]), .DATA_B (INT_SUM[672]), .DATA_C (INT_CARRY[540]), .SAVE (INT_SUM[673]), .CARRY (INT_CARRY[545]) ); assign INT_SUM[674] = INT_CARRY[541]; smfulladder dfa492 (.DATA_A (INT_SUM[673]), .DATA_B (INT_SUM[674]), .DATA_C (INT_CARRY[542]), .SAVE (INT_SUM[675]), .CARRY (INT_CARRY[543]) ); smffb dla739 (.D(INT_SUM[675]), .clk(clk), .en_d2(en_d2), .Q(SUM[61]) ); smffb dla740 (.D(INT_CARRY[543]), .clk(clk), .en_d2(en_d2), .Q(CARRY[61]) ); smffa dla741 (.D(SUMMAND[618]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[618]) ); smffa dla742 (.D(SUMMAND[619]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[619]) ); smffa dla743 (.D(SUMMAND[620]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[620]) ); smfulladder dfa493 (.DATA_A (LATCHED_PP[618]), .DATA_B (LATCHED_PP[619]), .DATA_C (LATCHED_PP[620]), .SAVE (INT_SUM[676]), .CARRY (INT_CARRY[547]) ); assign INT_SUM[677] = INT_SUM[676]; assign INT_SUM[678] = INT_CARRY[544]; smfulladder dfa494 (.DATA_A (INT_SUM[677]), .DATA_B (INT_SUM[678]), .DATA_C (INT_CARRY[545]), .SAVE (INT_SUM[679]), .CARRY (INT_CARRY[546]) ); smffb dla744 (.D(INT_SUM[679]), .clk(clk), .en_d2(en_d2), .Q(SUM[62]) ); smffb dla745 (.D(INT_CARRY[546]), .clk(clk), .en_d2(en_d2), .Q(CARRY[62]) ); smffa dla746 (.D(SUMMAND[621]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[621]) ); smffa dla747 (.D(SUMMAND[622]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[622]) ); smffa dla748 (.D(SUMMAND[623]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[623]) ); smfulladder dfa495 (.DATA_A (LATCHED_PP[621]), .DATA_B (LATCHED_PP[622]), .DATA_C (LATCHED_PP[623]), .SAVE (INT_SUM[680]), .CARRY (INT_CARRY[549]) ); assign INT_SUM[681] = INT_CARRY[547]; smhalfadder dha53 (.DATA_A (INT_SUM[680]), .DATA_B (INT_SUM[681]), .SAVE (INT_SUM[682]), .CARRY (INT_CARRY[548]) ); smffb dla749 (.D(INT_SUM[682]), .clk(clk), .en_d2(en_d2), .Q(SUM[63]) ); smffb dla750 (.D(INT_CARRY[548]), .clk(clk), .en_d2(en_d2), .Q(CARRY[63]) ); smffa dla751 (.D(SUMMAND[624]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[624]) ); assign INT_SUM[683] = LATCHED_PP[624]; smffa dla752 (.D(SUMMAND[625]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[625]) ); assign INT_SUM[684] = LATCHED_PP[625]; smfulladder dfa496 (.DATA_A (INT_SUM[683]), .DATA_B (INT_SUM[684]), .DATA_C (INT_CARRY[549]), .SAVE (INT_SUM[685]), .CARRY (INT_CARRY[550]) ); smffb dla753 (.D(INT_SUM[685]), .clk(clk), .en_d2(en_d2), .Q(SUM[64]) ); smffb dla754 (.D(INT_CARRY[550]), .clk(clk), .en_d2(en_d2), .Q(CARRY[64]) ); smffa dla755 (.D(SUMMAND[626]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[626]) ); smffa dla756 (.D(SUMMAND[627]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[627]) ); smhalfadder dha54 (.DATA_A (LATCHED_PP[626]), .DATA_B (LATCHED_PP[627]), .SAVE (INT_SUM[686]), .CARRY (INT_CARRY[551]) ); smffb dla757 (.D(INT_SUM[686]), .clk(clk), .en_d2(en_d2), .Q(SUM[65]) ); smffb dla758 (.D(INT_CARRY[551]), .clk(clk), .en_d2(en_d2), .Q(CARRY[65]) ); smffa dla759 (.D(SUMMAND[628]), .clk(clk), .en_d1(en_d1), .Q(LATCHED_PP[628]) ); assign INT_SUM[687] = LATCHED_PP[628]; smffb dla760 (.D(INT_SUM[687]), .clk(clk), .en_d2(en_d2), .Q(SUM[66]) ); endmodule module smprestage_128 ( A, B, CIN, POUT, GOUT ); input [63:0] A; input [63:0] B; input CIN; output [63:0] POUT; output [63:0] GOUT; smblock0 d10 (A[0], B[0], POUT[0], GOUT[1] ); smblock0 d11 (A[1], B[1], POUT[1], GOUT[2] ); smblock0 d12 (A[2], B[2], POUT[2], GOUT[3] ); smblock0 d13 (A[3], B[3], POUT[3], GOUT[4] ); smblock0 d14 (A[4], B[4], POUT[4], GOUT[5] ); smblock0 d15 (A[5], B[5], POUT[5], GOUT[6] ); smblock0 d16 (A[6], B[6], POUT[6], GOUT[7] ); smblock0 d17 (A[7], B[7], POUT[7], GOUT[8] ); smblock0 d18 (A[8], B[8], POUT[8], GOUT[9] ); smblock0 d19 (A[9], B[9], POUT[9], GOUT[10] ); smblock0 d110 (A[10], B[10], POUT[10], GOUT[11] ); smblock0 d111 (A[11], B[11], POUT[11], GOUT[12] ); smblock0 d112 (A[12], B[12], POUT[12], GOUT[13] ); smblock0 d113 (A[13], B[13], POUT[13], GOUT[14] ); smblock0 d114 (A[14], B[14], POUT[14], GOUT[15] ); smblock0 d115 (A[15], B[15], POUT[15], GOUT[16] ); smblock0 d116 (A[16], B[16], POUT[16], GOUT[17] ); smblock0 d117 (A[17], B[17], POUT[17], GOUT[18] ); smblock0 d118 (A[18], B[18], POUT[18], GOUT[19] ); smblock0 d119 (A[19], B[19], POUT[19], GOUT[20] ); smblock0 d120 (A[20], B[20], POUT[20], GOUT[21] ); smblock0 d121 (A[21], B[21], POUT[21], GOUT[22] ); smblock0 d122 (A[22], B[22], POUT[22], GOUT[23] ); smblock0 d123 (A[23], B[23], POUT[23], GOUT[24] ); smblock0 d124 (A[24], B[24], POUT[24], GOUT[25] ); smblock0 d125 (A[25], B[25], POUT[25], GOUT[26] ); smblock0 d126 (A[26], B[26], POUT[26], GOUT[27] ); smblock0 d127 (A[27], B[27], POUT[27], GOUT[28] ); smblock0 d128 (A[28], B[28], POUT[28], GOUT[29] ); smblock0 d129 (A[29], B[29], POUT[29], GOUT[30] ); smblock0 d130 (A[30], B[30], POUT[30], GOUT[31] ); smblock0 d131 (A[31], B[31], POUT[31], GOUT[32] ); smblock0 d132 (A[32], B[32], POUT[32], GOUT[33] ); smblock0 d133 (A[33], B[33], POUT[33], GOUT[34] ); smblock0 d134 (A[34], B[34], POUT[34], GOUT[35] ); smblock0 d135 (A[35], B[35], POUT[35], GOUT[36] ); smblock0 d136 (A[36], B[36], POUT[36], GOUT[37] ); smblock0 d137 (A[37], B[37], POUT[37], GOUT[38] ); smblock0 d138 (A[38], B[38], POUT[38], GOUT[39] ); smblock0 d139 (A[39], B[39], POUT[39], GOUT[40] ); smblock0 d140 (A[40], B[40], POUT[40], GOUT[41] ); smblock0 d141 (A[41], B[41], POUT[41], GOUT[42] ); smblock0 d142 (A[42], B[42], POUT[42], GOUT[43] ); smblock0 d143 (A[43], B[43], POUT[43], GOUT[44] ); smblock0 d144 (A[44], B[44], POUT[44], GOUT[45] ); smblock0 d145 (A[45], B[45], POUT[45], GOUT[46] ); smblock0 d146 (A[46], B[46], POUT[46], GOUT[47] ); smblock0 d147 (A[47], B[47], POUT[47], GOUT[48] ); smblock0 d148 (A[48], B[48], POUT[48], GOUT[49] ); smblock0 d149 (A[49], B[49], POUT[49], GOUT[50] ); smblock0 d150 (A[50], B[50], POUT[50], GOUT[51] ); smblock0 d151 (A[51], B[51], POUT[51], GOUT[52] ); smblock0 d152 (A[52], B[52], POUT[52], GOUT[53] ); smblock0 d153 (A[53], B[53], POUT[53], GOUT[54] ); smblock0 d154 (A[54], B[54], POUT[54], GOUT[55] ); smblock0 d155 (A[55], B[55], POUT[55], GOUT[56] ); smblock0 d156 (A[56], B[56], POUT[56], GOUT[57] ); smblock0 d157 (A[57], B[57], POUT[57], GOUT[58] ); smblock0 d158 (A[58], B[58], POUT[58], GOUT[59] ); smblock0 d159 (A[59], B[59], POUT[59], GOUT[60] ); smblock0 d160 (A[60], B[60], POUT[60], GOUT[61] ); smblock0 d161 (A[61], B[61], POUT[61], GOUT[62] ); smblock0 d162 (A[62], B[62], POUT[62], GOUT[63] ); sminvblock d2 (CIN, GOUT[0] ); endmodule module smdblc_0_128 ( PIN, GIN, POUT, GOUT ); input [63:0] PIN; input [63:0] GIN; output [63:0] POUT; output [63:0] GOUT; sminvblock d10 (GIN[0], GOUT[0] ); smblock1a d21 (PIN[0], GIN[0], GIN[1], GOUT[1] ); smblock1 d32 (PIN[0], PIN[1], GIN[1], GIN[2], POUT[0], GOUT[2] ); smblock1 d33 (PIN[1], PIN[2], GIN[2], GIN[3], POUT[1], GOUT[3] ); smblock1 d34 (PIN[2], PIN[3], GIN[3], GIN[4], POUT[2], GOUT[4] ); smblock1 d35 (PIN[3], PIN[4], GIN[4], GIN[5], POUT[3], GOUT[5] ); smblock1 d36 (PIN[4], PIN[5], GIN[5], GIN[6], POUT[4], GOUT[6] ); smblock1 d37 (PIN[5], PIN[6], GIN[6], GIN[7], POUT[5], GOUT[7] ); smblock1 d38 (PIN[6], PIN[7], GIN[7], GIN[8], POUT[6], GOUT[8] ); smblock1 d39 (PIN[7], PIN[8], GIN[8], GIN[9], POUT[7], GOUT[9] ); smblock1 d310 (PIN[8], PIN[9], GIN[9], GIN[10], POUT[8], GOUT[10] ); smblock1 d311 (PIN[9], PIN[10], GIN[10], GIN[11], POUT[9], GOUT[11] ); smblock1 d312 (PIN[10], PIN[11], GIN[11], GIN[12], POUT[10], GOUT[12] ); smblock1 d313 (PIN[11], PIN[12], GIN[12], GIN[13], POUT[11], GOUT[13] ); smblock1 d314 (PIN[12], PIN[13], GIN[13], GIN[14], POUT[12], GOUT[14] ); smblock1 d315 (PIN[13], PIN[14], GIN[14], GIN[15], POUT[13], GOUT[15] ); smblock1 d316 (PIN[14], PIN[15], GIN[15], GIN[16], POUT[14], GOUT[16] ); smblock1 d317 (PIN[15], PIN[16], GIN[16], GIN[17], POUT[15], GOUT[17] ); smblock1 d318 (PIN[16], PIN[17], GIN[17], GIN[18], POUT[16], GOUT[18] ); smblock1 d319 (PIN[17], PIN[18], GIN[18], GIN[19], POUT[17], GOUT[19] ); smblock1 d320 (PIN[18], PIN[19], GIN[19], GIN[20], POUT[18], GOUT[20] ); smblock1 d321 (PIN[19], PIN[20], GIN[20], GIN[21], POUT[19], GOUT[21] ); smblock1 d322 (PIN[20], PIN[21], GIN[21], GIN[22], POUT[20], GOUT[22] ); smblock1 d323 (PIN[21], PIN[22], GIN[22], GIN[23], POUT[21], GOUT[23] ); smblock1 d324 (PIN[22], PIN[23], GIN[23], GIN[24], POUT[22], GOUT[24] ); smblock1 d325 (PIN[23], PIN[24], GIN[24], GIN[25], POUT[23], GOUT[25] ); smblock1 d326 (PIN[24], PIN[25], GIN[25], GIN[26], POUT[24], GOUT[26] ); smblock1 d327 (PIN[25], PIN[26], GIN[26], GIN[27], POUT[25], GOUT[27] ); smblock1 d328 (PIN[26], PIN[27], GIN[27], GIN[28], POUT[26], GOUT[28] ); smblock1 d329 (PIN[27], PIN[28], GIN[28], GIN[29], POUT[27], GOUT[29] ); smblock1 d330 (PIN[28], PIN[29], GIN[29], GIN[30], POUT[28], GOUT[30] ); smblock1 d331 (PIN[29], PIN[30], GIN[30], GIN[31], POUT[29], GOUT[31] ); smblock1 d332 (PIN[30], PIN[31], GIN[31], GIN[32], POUT[30], GOUT[32] ); smblock1 d333 (PIN[31], PIN[32], GIN[32], GIN[33], POUT[31], GOUT[33] ); smblock1 d334 (PIN[32], PIN[33], GIN[33], GIN[34], POUT[32], GOUT[34] ); smblock1 d335 (PIN[33], PIN[34], GIN[34], GIN[35], POUT[33], GOUT[35] ); smblock1 d336 (PIN[34], PIN[35], GIN[35], GIN[36], POUT[34], GOUT[36] ); smblock1 d337 (PIN[35], PIN[36], GIN[36], GIN[37], POUT[35], GOUT[37] ); smblock1 d338 (PIN[36], PIN[37], GIN[37], GIN[38], POUT[36], GOUT[38] ); smblock1 d339 (PIN[37], PIN[38], GIN[38], GIN[39], POUT[37], GOUT[39] ); smblock1 d340 (PIN[38], PIN[39], GIN[39], GIN[40], POUT[38], GOUT[40] ); smblock1 d341 (PIN[39], PIN[40], GIN[40], GIN[41], POUT[39], GOUT[41] ); smblock1 d342 (PIN[40], PIN[41], GIN[41], GIN[42], POUT[40], GOUT[42] ); smblock1 d343 (PIN[41], PIN[42], GIN[42], GIN[43], POUT[41], GOUT[43] ); smblock1 d344 (PIN[42], PIN[43], GIN[43], GIN[44], POUT[42], GOUT[44] ); smblock1 d345 (PIN[43], PIN[44], GIN[44], GIN[45], POUT[43], GOUT[45] ); smblock1 d346 (PIN[44], PIN[45], GIN[45], GIN[46], POUT[44], GOUT[46] ); smblock1 d347 (PIN[45], PIN[46], GIN[46], GIN[47], POUT[45], GOUT[47] ); smblock1 d348 (PIN[46], PIN[47], GIN[47], GIN[48], POUT[46], GOUT[48] ); smblock1 d349 (PIN[47], PIN[48], GIN[48], GIN[49], POUT[47], GOUT[49] ); smblock1 d350 (PIN[48], PIN[49], GIN[49], GIN[50], POUT[48], GOUT[50] ); smblock1 d351 (PIN[49], PIN[50], GIN[50], GIN[51], POUT[49], GOUT[51] ); smblock1 d352 (PIN[50], PIN[51], GIN[51], GIN[52], POUT[50], GOUT[52] ); smblock1 d353 (PIN[51], PIN[52], GIN[52], GIN[53], POUT[51], GOUT[53] ); smblock1 d354 (PIN[52], PIN[53], GIN[53], GIN[54], POUT[52], GOUT[54] ); smblock1 d355 (PIN[53], PIN[54], GIN[54], GIN[55], POUT[53], GOUT[55] ); smblock1 d356 (PIN[54], PIN[55], GIN[55], GIN[56], POUT[54], GOUT[56] ); smblock1 d357 (PIN[55], PIN[56], GIN[56], GIN[57], POUT[55], GOUT[57] ); smblock1 d358 (PIN[56], PIN[57], GIN[57], GIN[58], POUT[56], GOUT[58] ); smblock1 d359 (PIN[57], PIN[58], GIN[58], GIN[59], POUT[57], GOUT[59] ); smblock1 d360 (PIN[58], PIN[59], GIN[59], GIN[60], POUT[58], GOUT[60] ); smblock1 d361 (PIN[59], PIN[60], GIN[60], GIN[61], POUT[59], GOUT[61] ); smblock1 d362 (PIN[60], PIN[61], GIN[61], GIN[62], POUT[60], GOUT[62] ); smblock1 d363 (PIN[61], PIN[62], GIN[62], GIN[63], POUT[61], GOUT[63] ); endmodule module smdblc_1_128 ( PIN, GIN, POUT, GOUT ); input [63:0] PIN; input [63:0] GIN; output [63:0] POUT; output [63:0] GOUT; sminvblock d10 (GIN[0], GOUT[0] ); sminvblock d11 (GIN[1], GOUT[1] ); smblock2a d22 (PIN[0], GIN[0], GIN[2], GOUT[2] ); smblock2a d23 (PIN[1], GIN[1], GIN[3], GOUT[3] ); smblock2 d34 (PIN[0], PIN[2], GIN[2], GIN[4], POUT[0], GOUT[4] ); smblock2 d35 (PIN[1], PIN[3], GIN[3], GIN[5], POUT[1], GOUT[5] ); smblock2 d36 (PIN[2], PIN[4], GIN[4], GIN[6], POUT[2], GOUT[6] ); smblock2 d37 (PIN[3], PIN[5], GIN[5], GIN[7], POUT[3], GOUT[7] ); smblock2 d38 (PIN[4], PIN[6], GIN[6], GIN[8], POUT[4], GOUT[8] ); smblock2 d39 (PIN[5], PIN[7], GIN[7], GIN[9], POUT[5], GOUT[9] ); smblock2 d310 (PIN[6], PIN[8], GIN[8], GIN[10], POUT[6], GOUT[10] ); smblock2 d311 (PIN[7], PIN[9], GIN[9], GIN[11], POUT[7], GOUT[11] ); smblock2 d312 (PIN[8], PIN[10], GIN[10], GIN[12], POUT[8], GOUT[12] ); smblock2 d313 (PIN[9], PIN[11], GIN[11], GIN[13], POUT[9], GOUT[13] ); smblock2 d314 (PIN[10], PIN[12], GIN[12], GIN[14], POUT[10], GOUT[14] ); smblock2 d315 (PIN[11], PIN[13], GIN[13], GIN[15], POUT[11], GOUT[15] ); smblock2 d316 (PIN[12], PIN[14], GIN[14], GIN[16], POUT[12], GOUT[16] ); smblock2 d317 (PIN[13], PIN[15], GIN[15], GIN[17], POUT[13], GOUT[17] ); smblock2 d318 (PIN[14], PIN[16], GIN[16], GIN[18], POUT[14], GOUT[18] ); smblock2 d319 (PIN[15], PIN[17], GIN[17], GIN[19], POUT[15], GOUT[19] ); smblock2 d320 (PIN[16], PIN[18], GIN[18], GIN[20], POUT[16], GOUT[20] ); smblock2 d321 (PIN[17], PIN[19], GIN[19], GIN[21], POUT[17], GOUT[21] ); smblock2 d322 (PIN[18], PIN[20], GIN[20], GIN[22], POUT[18], GOUT[22] ); smblock2 d323 (PIN[19], PIN[21], GIN[21], GIN[23], POUT[19], GOUT[23] ); smblock2 d324 (PIN[20], PIN[22], GIN[22], GIN[24], POUT[20], GOUT[24] ); smblock2 d325 (PIN[21], PIN[23], GIN[23], GIN[25], POUT[21], GOUT[25] ); smblock2 d326 (PIN[22], PIN[24], GIN[24], GIN[26], POUT[22], GOUT[26] ); smblock2 d327 (PIN[23], PIN[25], GIN[25], GIN[27], POUT[23], GOUT[27] ); smblock2 d328 (PIN[24], PIN[26], GIN[26], GIN[28], POUT[24], GOUT[28] ); smblock2 d329 (PIN[25], PIN[27], GIN[27], GIN[29], POUT[25], GOUT[29] ); smblock2 d330 (PIN[26], PIN[28], GIN[28], GIN[30], POUT[26], GOUT[30] ); smblock2 d331 (PIN[27], PIN[29], GIN[29], GIN[31], POUT[27], GOUT[31] ); smblock2 d332 (PIN[28], PIN[30], GIN[30], GIN[32], POUT[28], GOUT[32] ); smblock2 d333 (PIN[29], PIN[31], GIN[31], GIN[33], POUT[29], GOUT[33] ); smblock2 d334 (PIN[30], PIN[32], GIN[32], GIN[34], POUT[30], GOUT[34] ); smblock2 d335 (PIN[31], PIN[33], GIN[33], GIN[35], POUT[31], GOUT[35] ); smblock2 d336 (PIN[32], PIN[34], GIN[34], GIN[36], POUT[32], GOUT[36] ); smblock2 d337 (PIN[33], PIN[35], GIN[35], GIN[37], POUT[33], GOUT[37] ); smblock2 d338 (PIN[34], PIN[36], GIN[36], GIN[38], POUT[34], GOUT[38] ); smblock2 d339 (PIN[35], PIN[37], GIN[37], GIN[39], POUT[35], GOUT[39] ); smblock2 d340 (PIN[36], PIN[38], GIN[38], GIN[40], POUT[36], GOUT[40] ); smblock2 d341 (PIN[37], PIN[39], GIN[39], GIN[41], POUT[37], GOUT[41] ); smblock2 d342 (PIN[38], PIN[40], GIN[40], GIN[42], POUT[38], GOUT[42] ); smblock2 d343 (PIN[39], PIN[41], GIN[41], GIN[43], POUT[39], GOUT[43] ); smblock2 d344 (PIN[40], PIN[42], GIN[42], GIN[44], POUT[40], GOUT[44] ); smblock2 d345 (PIN[41], PIN[43], GIN[43], GIN[45], POUT[41], GOUT[45] ); smblock2 d346 (PIN[42], PIN[44], GIN[44], GIN[46], POUT[42], GOUT[46] ); smblock2 d347 (PIN[43], PIN[45], GIN[45], GIN[47], POUT[43], GOUT[47] ); smblock2 d348 (PIN[44], PIN[46], GIN[46], GIN[48], POUT[44], GOUT[48] ); smblock2 d349 (PIN[45], PIN[47], GIN[47], GIN[49], POUT[45], GOUT[49] ); smblock2 d350 (PIN[46], PIN[48], GIN[48], GIN[50], POUT[46], GOUT[50] ); smblock2 d351 (PIN[47], PIN[49], GIN[49], GIN[51], POUT[47], GOUT[51] ); smblock2 d352 (PIN[48], PIN[50], GIN[50], GIN[52], POUT[48], GOUT[52] ); smblock2 d353 (PIN[49], PIN[51], GIN[51], GIN[53], POUT[49], GOUT[53] ); smblock2 d354 (PIN[50], PIN[52], GIN[52], GIN[54], POUT[50], GOUT[54] ); smblock2 d355 (PIN[51], PIN[53], GIN[53], GIN[55], POUT[51], GOUT[55] ); smblock2 d356 (PIN[52], PIN[54], GIN[54], GIN[56], POUT[52], GOUT[56] ); smblock2 d357 (PIN[53], PIN[55], GIN[55], GIN[57], POUT[53], GOUT[57] ); smblock2 d358 (PIN[54], PIN[56], GIN[56], GIN[58], POUT[54], GOUT[58] ); smblock2 d359 (PIN[55], PIN[57], GIN[57], GIN[59], POUT[55], GOUT[59] ); smblock2 d360 (PIN[56], PIN[58], GIN[58], GIN[60], POUT[56], GOUT[60] ); smblock2 d361 (PIN[57], PIN[59], GIN[59], GIN[61], POUT[57], GOUT[61] ); smblock2 d362 (PIN[58], PIN[60], GIN[60], GIN[62], POUT[58], GOUT[62] ); smblock2 d363 (PIN[59], PIN[61], GIN[61], GIN[63], POUT[59], GOUT[63] ); endmodule module smdblc_2_128 ( PIN, GIN, POUT, GOUT ); input [63:0] PIN; input [63:0] GIN; output [63:0] POUT; output [63:0] GOUT; sminvblock d10 (GIN[0], GOUT[0] ); sminvblock d11 (GIN[1], GOUT[1] ); sminvblock d12 (GIN[2], GOUT[2] ); sminvblock d13 (GIN[3], GOUT[3] ); smblock1a d24 (PIN[0], GIN[0], GIN[4], GOUT[4] ); smblock1a d25 (PIN[1], GIN[1], GIN[5], GOUT[5] ); smblock1a d26 (PIN[2], GIN[2], GIN[6], GOUT[6] ); smblock1a d27 (PIN[3], GIN[3], GIN[7], GOUT[7] ); smblock1 d38 (PIN[0], PIN[4], GIN[4], GIN[8], POUT[0], GOUT[8] ); smblock1 d39 (PIN[1], PIN[5], GIN[5], GIN[9], POUT[1], GOUT[9] ); smblock1 d310 (PIN[2], PIN[6], GIN[6], GIN[10], POUT[2], GOUT[10] ); smblock1 d311 (PIN[3], PIN[7], GIN[7], GIN[11], POUT[3], GOUT[11] ); smblock1 d312 (PIN[4], PIN[8], GIN[8], GIN[12], POUT[4], GOUT[12] ); smblock1 d313 (PIN[5], PIN[9], GIN[9], GIN[13], POUT[5], GOUT[13] ); smblock1 d314 (PIN[6], PIN[10], GIN[10], GIN[14], POUT[6], GOUT[14] ); smblock1 d315 (PIN[7], PIN[11], GIN[11], GIN[15], POUT[7], GOUT[15] ); smblock1 d316 (PIN[8], PIN[12], GIN[12], GIN[16], POUT[8], GOUT[16] ); smblock1 d317 (PIN[9], PIN[13], GIN[13], GIN[17], POUT[9], GOUT[17] ); smblock1 d318 (PIN[10], PIN[14], GIN[14], GIN[18], POUT[10], GOUT[18] ); smblock1 d319 (PIN[11], PIN[15], GIN[15], GIN[19], POUT[11], GOUT[19] ); smblock1 d320 (PIN[12], PIN[16], GIN[16], GIN[20], POUT[12], GOUT[20] ); smblock1 d321 (PIN[13], PIN[17], GIN[17], GIN[21], POUT[13], GOUT[21] ); smblock1 d322 (PIN[14], PIN[18], GIN[18], GIN[22], POUT[14], GOUT[22] ); smblock1 d323 (PIN[15], PIN[19], GIN[19], GIN[23], POUT[15], GOUT[23] ); smblock1 d324 (PIN[16], PIN[20], GIN[20], GIN[24], POUT[16], GOUT[24] ); smblock1 d325 (PIN[17], PIN[21], GIN[21], GIN[25], POUT[17], GOUT[25] ); smblock1 d326 (PIN[18], PIN[22], GIN[22], GIN[26], POUT[18], GOUT[26] ); smblock1 d327 (PIN[19], PIN[23], GIN[23], GIN[27], POUT[19], GOUT[27] ); smblock1 d328 (PIN[20], PIN[24], GIN[24], GIN[28], POUT[20], GOUT[28] ); smblock1 d329 (PIN[21], PIN[25], GIN[25], GIN[29], POUT[21], GOUT[29] ); smblock1 d330 (PIN[22], PIN[26], GIN[26], GIN[30], POUT[22], GOUT[30] ); smblock1 d331 (PIN[23], PIN[27], GIN[27], GIN[31], POUT[23], GOUT[31] ); smblock1 d332 (PIN[24], PIN[28], GIN[28], GIN[32], POUT[24], GOUT[32] ); smblock1 d333 (PIN[25], PIN[29], GIN[29], GIN[33], POUT[25], GOUT[33] ); smblock1 d334 (PIN[26], PIN[30], GIN[30], GIN[34], POUT[26], GOUT[34] ); smblock1 d335 (PIN[27], PIN[31], GIN[31], GIN[35], POUT[27], GOUT[35] ); smblock1 d336 (PIN[28], PIN[32], GIN[32], GIN[36], POUT[28], GOUT[36] ); smblock1 d337 (PIN[29], PIN[33], GIN[33], GIN[37], POUT[29], GOUT[37] ); smblock1 d338 (PIN[30], PIN[34], GIN[34], GIN[38], POUT[30], GOUT[38] ); smblock1 d339 (PIN[31], PIN[35], GIN[35], GIN[39], POUT[31], GOUT[39] ); smblock1 d340 (PIN[32], PIN[36], GIN[36], GIN[40], POUT[32], GOUT[40] ); smblock1 d341 (PIN[33], PIN[37], GIN[37], GIN[41], POUT[33], GOUT[41] ); smblock1 d342 (PIN[34], PIN[38], GIN[38], GIN[42], POUT[34], GOUT[42] ); smblock1 d343 (PIN[35], PIN[39], GIN[39], GIN[43], POUT[35], GOUT[43] ); smblock1 d344 (PIN[36], PIN[40], GIN[40], GIN[44], POUT[36], GOUT[44] ); smblock1 d345 (PIN[37], PIN[41], GIN[41], GIN[45], POUT[37], GOUT[45] ); smblock1 d346 (PIN[38], PIN[42], GIN[42], GIN[46], POUT[38], GOUT[46] ); smblock1 d347 (PIN[39], PIN[43], GIN[43], GIN[47], POUT[39], GOUT[47] ); smblock1 d348 (PIN[40], PIN[44], GIN[44], GIN[48], POUT[40], GOUT[48] ); smblock1 d349 (PIN[41], PIN[45], GIN[45], GIN[49], POUT[41], GOUT[49] ); smblock1 d350 (PIN[42], PIN[46], GIN[46], GIN[50], POUT[42], GOUT[50] ); smblock1 d351 (PIN[43], PIN[47], GIN[47], GIN[51], POUT[43], GOUT[51] ); smblock1 d352 (PIN[44], PIN[48], GIN[48], GIN[52], POUT[44], GOUT[52] ); smblock1 d353 (PIN[45], PIN[49], GIN[49], GIN[53], POUT[45], GOUT[53] ); smblock1 d354 (PIN[46], PIN[50], GIN[50], GIN[54], POUT[46], GOUT[54] ); smblock1 d355 (PIN[47], PIN[51], GIN[51], GIN[55], POUT[47], GOUT[55] ); smblock1 d356 (PIN[48], PIN[52], GIN[52], GIN[56], POUT[48], GOUT[56] ); smblock1 d357 (PIN[49], PIN[53], GIN[53], GIN[57], POUT[49], GOUT[57] ); smblock1 d358 (PIN[50], PIN[54], GIN[54], GIN[58], POUT[50], GOUT[58] ); smblock1 d359 (PIN[51], PIN[55], GIN[55], GIN[59], POUT[51], GOUT[59] ); smblock1 d360 (PIN[52], PIN[56], GIN[56], GIN[60], POUT[52], GOUT[60] ); smblock1 d361 (PIN[53], PIN[57], GIN[57], GIN[61], POUT[53], GOUT[61] ); smblock1 d362 (PIN[54], PIN[58], GIN[58], GIN[62], POUT[54], GOUT[62] ); smblock1 d363 (PIN[55], PIN[59], GIN[59], GIN[63], POUT[55], GOUT[63] ); endmodule module smdblc_3_128 ( PIN, GIN, POUT, GOUT ); input [63:0] PIN; input [63:0] GIN; output [63:0] POUT; output [63:0] GOUT; sminvblock d10 (GIN[0], GOUT[0] ); sminvblock d11 (GIN[1], GOUT[1] ); sminvblock d12 (GIN[2], GOUT[2] ); sminvblock d13 (GIN[3], GOUT[3] ); sminvblock d14 (GIN[4], GOUT[4] ); sminvblock d15 (GIN[5], GOUT[5] ); sminvblock d16 (GIN[6], GOUT[6] ); sminvblock d17 (GIN[7], GOUT[7] ); smblock2a d28 (PIN[0], GIN[0], GIN[8], GOUT[8] ); smblock2a d29 (PIN[1], GIN[1], GIN[9], GOUT[9] ); smblock2a d210 (PIN[2], GIN[2], GIN[10], GOUT[10] ); smblock2a d211 (PIN[3], GIN[3], GIN[11], GOUT[11] ); smblock2a d212 (PIN[4], GIN[4], GIN[12], GOUT[12] ); smblock2a d213 (PIN[5], GIN[5], GIN[13], GOUT[13] ); smblock2a d214 (PIN[6], GIN[6], GIN[14], GOUT[14] ); smblock2a d215 (PIN[7], GIN[7], GIN[15], GOUT[15] ); smblock2 d316 (PIN[0], PIN[8], GIN[8], GIN[16], POUT[0], GOUT[16] ); smblock2 d317 (PIN[1], PIN[9], GIN[9], GIN[17], POUT[1], GOUT[17] ); smblock2 d318 (PIN[2], PIN[10], GIN[10], GIN[18], POUT[2], GOUT[18] ); smblock2 d319 (PIN[3], PIN[11], GIN[11], GIN[19], POUT[3], GOUT[19] ); smblock2 d320 (PIN[4], PIN[12], GIN[12], GIN[20], POUT[4], GOUT[20] ); smblock2 d321 (PIN[5], PIN[13], GIN[13], GIN[21], POUT[5], GOUT[21] ); smblock2 d322 (PIN[6], PIN[14], GIN[14], GIN[22], POUT[6], GOUT[22] ); smblock2 d323 (PIN[7], PIN[15], GIN[15], GIN[23], POUT[7], GOUT[23] ); smblock2 d324 (PIN[8], PIN[16], GIN[16], GIN[24], POUT[8], GOUT[24] ); smblock2 d325 (PIN[9], PIN[17], GIN[17], GIN[25], POUT[9], GOUT[25] ); smblock2 d326 (PIN[10], PIN[18], GIN[18], GIN[26], POUT[10], GOUT[26] ); smblock2 d327 (PIN[11], PIN[19], GIN[19], GIN[27], POUT[11], GOUT[27] ); smblock2 d328 (PIN[12], PIN[20], GIN[20], GIN[28], POUT[12], GOUT[28] ); smblock2 d329 (PIN[13], PIN[21], GIN[21], GIN[29], POUT[13], GOUT[29] ); smblock2 d330 (PIN[14], PIN[22], GIN[22], GIN[30], POUT[14], GOUT[30] ); smblock2 d331 (PIN[15], PIN[23], GIN[23], GIN[31], POUT[15], GOUT[31] ); smblock2 d332 (PIN[16], PIN[24], GIN[24], GIN[32], POUT[16], GOUT[32] ); smblock2 d333 (PIN[17], PIN[25], GIN[25], GIN[33], POUT[17], GOUT[33] ); smblock2 d334 (PIN[18], PIN[26], GIN[26], GIN[34], POUT[18], GOUT[34] ); smblock2 d335 (PIN[19], PIN[27], GIN[27], GIN[35], POUT[19], GOUT[35] ); smblock2 d336 (PIN[20], PIN[28], GIN[28], GIN[36], POUT[20], GOUT[36] ); smblock2 d337 (PIN[21], PIN[29], GIN[29], GIN[37], POUT[21], GOUT[37] ); smblock2 d338 (PIN[22], PIN[30], GIN[30], GIN[38], POUT[22], GOUT[38] ); smblock2 d339 (PIN[23], PIN[31], GIN[31], GIN[39], POUT[23], GOUT[39] ); smblock2 d340 (PIN[24], PIN[32], GIN[32], GIN[40], POUT[24], GOUT[40] ); smblock2 d341 (PIN[25], PIN[33], GIN[33], GIN[41], POUT[25], GOUT[41] ); smblock2 d342 (PIN[26], PIN[34], GIN[34], GIN[42], POUT[26], GOUT[42] ); smblock2 d343 (PIN[27], PIN[35], GIN[35], GIN[43], POUT[27], GOUT[43] ); smblock2 d344 (PIN[28], PIN[36], GIN[36], GIN[44], POUT[28], GOUT[44] ); smblock2 d345 (PIN[29], PIN[37], GIN[37], GIN[45], POUT[29], GOUT[45] ); smblock2 d346 (PIN[30], PIN[38], GIN[38], GIN[46], POUT[30], GOUT[46] ); smblock2 d347 (PIN[31], PIN[39], GIN[39], GIN[47], POUT[31], GOUT[47] ); smblock2 d348 (PIN[32], PIN[40], GIN[40], GIN[48], POUT[32], GOUT[48] ); smblock2 d349 (PIN[33], PIN[41], GIN[41], GIN[49], POUT[33], GOUT[49] ); smblock2 d350 (PIN[34], PIN[42], GIN[42], GIN[50], POUT[34], GOUT[50] ); smblock2 d351 (PIN[35], PIN[43], GIN[43], GIN[51], POUT[35], GOUT[51] ); smblock2 d352 (PIN[36], PIN[44], GIN[44], GIN[52], POUT[36], GOUT[52] ); smblock2 d353 (PIN[37], PIN[45], GIN[45], GIN[53], POUT[37], GOUT[53] ); smblock2 d354 (PIN[38], PIN[46], GIN[46], GIN[54], POUT[38], GOUT[54] ); smblock2 d355 (PIN[39], PIN[47], GIN[47], GIN[55], POUT[39], GOUT[55] ); smblock2 d356 (PIN[40], PIN[48], GIN[48], GIN[56], POUT[40], GOUT[56] ); smblock2 d357 (PIN[41], PIN[49], GIN[49], GIN[57], POUT[41], GOUT[57] ); smblock2 d358 (PIN[42], PIN[50], GIN[50], GIN[58], POUT[42], GOUT[58] ); smblock2 d359 (PIN[43], PIN[51], GIN[51], GIN[59], POUT[43], GOUT[59] ); smblock2 d360 (PIN[44], PIN[52], GIN[52], GIN[60], POUT[44], GOUT[60] ); smblock2 d361 (PIN[45], PIN[53], GIN[53], GIN[61], POUT[45], GOUT[61] ); smblock2 d362 (PIN[46], PIN[54], GIN[54], GIN[62], POUT[46], GOUT[62] ); smblock2 d363 (PIN[47], PIN[55], GIN[55], GIN[63], POUT[47], GOUT[63] ); endmodule module smdblc_4_128 ( PIN, GIN, POUT, GOUT ); input [63:0] PIN; input [63:0] GIN; output [63:0] POUT; output [63:0] GOUT; sminvblock d10 (GIN[0], GOUT[0] ); sminvblock d11 (GIN[1], GOUT[1] ); sminvblock d12 (GIN[2], GOUT[2] ); sminvblock d13 (GIN[3], GOUT[3] ); sminvblock d14 (GIN[4], GOUT[4] ); sminvblock d15 (GIN[5], GOUT[5] ); sminvblock d16 (GIN[6], GOUT[6] ); sminvblock d17 (GIN[7], GOUT[7] ); sminvblock d18 (GIN[8], GOUT[8] ); sminvblock d19 (GIN[9], GOUT[9] ); sminvblock d110 (GIN[10], GOUT[10] ); sminvblock d111 (GIN[11], GOUT[11] ); sminvblock d112 (GIN[12], GOUT[12] ); sminvblock d113 (GIN[13], GOUT[13] ); sminvblock d114 (GIN[14], GOUT[14] ); sminvblock d115 (GIN[15], GOUT[15] ); smblock1a d216 (PIN[0], GIN[0], GIN[16], GOUT[16] ); smblock1a d217 (PIN[1], GIN[1], GIN[17], GOUT[17] ); smblock1a d218 (PIN[2], GIN[2], GIN[18], GOUT[18] ); smblock1a d219 (PIN[3], GIN[3], GIN[19], GOUT[19] ); smblock1a d220 (PIN[4], GIN[4], GIN[20], GOUT[20] ); smblock1a d221 (PIN[5], GIN[5], GIN[21], GOUT[21] ); smblock1a d222 (PIN[6], GIN[6], GIN[22], GOUT[22] ); smblock1a d223 (PIN[7], GIN[7], GIN[23], GOUT[23] ); smblock1a d224 (PIN[8], GIN[8], GIN[24], GOUT[24] ); smblock1a d225 (PIN[9], GIN[9], GIN[25], GOUT[25] ); smblock1a d226 (PIN[10], GIN[10], GIN[26], GOUT[26] ); smblock1a d227 (PIN[11], GIN[11], GIN[27], GOUT[27] ); smblock1a d228 (PIN[12], GIN[12], GIN[28], GOUT[28] ); smblock1a d229 (PIN[13], GIN[13], GIN[29], GOUT[29] ); smblock1a d230 (PIN[14], GIN[14], GIN[30], GOUT[30] ); smblock1a d231 (PIN[15], GIN[15], GIN[31], GOUT[31] ); smblock1 d332 (PIN[0], PIN[16], GIN[16], GIN[32], POUT[0], GOUT[32] ); smblock1 d333 (PIN[1], PIN[17], GIN[17], GIN[33], POUT[1], GOUT[33] ); smblock1 d334 (PIN[2], PIN[18], GIN[18], GIN[34], POUT[2], GOUT[34] ); smblock1 d335 (PIN[3], PIN[19], GIN[19], GIN[35], POUT[3], GOUT[35] ); smblock1 d336 (PIN[4], PIN[20], GIN[20], GIN[36], POUT[4], GOUT[36] ); smblock1 d337 (PIN[5], PIN[21], GIN[21], GIN[37], POUT[5], GOUT[37] ); smblock1 d338 (PIN[6], PIN[22], GIN[22], GIN[38], POUT[6], GOUT[38] ); smblock1 d339 (PIN[7], PIN[23], GIN[23], GIN[39], POUT[7], GOUT[39] ); smblock1 d340 (PIN[8], PIN[24], GIN[24], GIN[40], POUT[8], GOUT[40] ); smblock1 d341 (PIN[9], PIN[25], GIN[25], GIN[41], POUT[9], GOUT[41] ); smblock1 d342 (PIN[10], PIN[26], GIN[26], GIN[42], POUT[10], GOUT[42] ); smblock1 d343 (PIN[11], PIN[27], GIN[27], GIN[43], POUT[11], GOUT[43] ); smblock1 d344 (PIN[12], PIN[28], GIN[28], GIN[44], POUT[12], GOUT[44] ); smblock1 d345 (PIN[13], PIN[29], GIN[29], GIN[45], POUT[13], GOUT[45] ); smblock1 d346 (PIN[14], PIN[30], GIN[30], GIN[46], POUT[14], GOUT[46] ); smblock1 d347 (PIN[15], PIN[31], GIN[31], GIN[47], POUT[15], GOUT[47] ); smblock1 d348 (PIN[16], PIN[32], GIN[32], GIN[48], POUT[16], GOUT[48] ); smblock1 d349 (PIN[17], PIN[33], GIN[33], GIN[49], POUT[17], GOUT[49] ); smblock1 d350 (PIN[18], PIN[34], GIN[34], GIN[50], POUT[18], GOUT[50] ); smblock1 d351 (PIN[19], PIN[35], GIN[35], GIN[51], POUT[19], GOUT[51] ); smblock1 d352 (PIN[20], PIN[36], GIN[36], GIN[52], POUT[20], GOUT[52] ); smblock1 d353 (PIN[21], PIN[37], GIN[37], GIN[53], POUT[21], GOUT[53] ); smblock1 d354 (PIN[22], PIN[38], GIN[38], GIN[54], POUT[22], GOUT[54] ); smblock1 d355 (PIN[23], PIN[39], GIN[39], GIN[55], POUT[23], GOUT[55] ); smblock1 d356 (PIN[24], PIN[40], GIN[40], GIN[56], POUT[24], GOUT[56] ); smblock1 d357 (PIN[25], PIN[41], GIN[41], GIN[57], POUT[25], GOUT[57] ); smblock1 d358 (PIN[26], PIN[42], GIN[42], GIN[58], POUT[26], GOUT[58] ); smblock1 d359 (PIN[27], PIN[43], GIN[43], GIN[59], POUT[27], GOUT[59] ); smblock1 d360 (PIN[28], PIN[44], GIN[44], GIN[60], POUT[28], GOUT[60] ); smblock1 d361 (PIN[29], PIN[45], GIN[45], GIN[61], POUT[29], GOUT[61] ); smblock1 d362 (PIN[30], PIN[46], GIN[46], GIN[62], POUT[30], GOUT[62] ); smblock1 d363 (PIN[31], PIN[47], GIN[47], GIN[63], POUT[31], GOUT[63] ); endmodule module smxorstage_128 ( A, B, PBIT, CARRY, SUM ); input [63:0] A; input [63:0] B; input PBIT; input [63:0] CARRY; output [63:0] SUM; smxxor1 d20 (A[0], B[0], CARRY[0], SUM[0] ); smxxor1 d21 (A[1], B[1], CARRY[1], SUM[1] ); smxxor1 d22 (A[2], B[2], CARRY[2], SUM[2] ); smxxor1 d23 (A[3], B[3], CARRY[3], SUM[3] ); smxxor1 d24 (A[4], B[4], CARRY[4], SUM[4] ); smxxor1 d25 (A[5], B[5], CARRY[5], SUM[5] ); smxxor1 d26 (A[6], B[6], CARRY[6], SUM[6] ); smxxor1 d27 (A[7], B[7], CARRY[7], SUM[7] ); smxxor1 d28 (A[8], B[8], CARRY[8], SUM[8] ); smxxor1 d29 (A[9], B[9], CARRY[9], SUM[9] ); smxxor1 d210 (A[10], B[10], CARRY[10], SUM[10] ); smxxor1 d211 (A[11], B[11], CARRY[11], SUM[11] ); smxxor1 d212 (A[12], B[12], CARRY[12], SUM[12] ); smxxor1 d213 (A[13], B[13], CARRY[13], SUM[13] ); smxxor1 d214 (A[14], B[14], CARRY[14], SUM[14] ); smxxor1 d215 (A[15], B[15], CARRY[15], SUM[15] ); smxxor1 d216 (A[16], B[16], CARRY[16], SUM[16] ); smxxor1 d217 (A[17], B[17], CARRY[17], SUM[17] ); smxxor1 d218 (A[18], B[18], CARRY[18], SUM[18] ); smxxor1 d219 (A[19], B[19], CARRY[19], SUM[19] ); smxxor1 d220 (A[20], B[20], CARRY[20], SUM[20] ); smxxor1 d221 (A[21], B[21], CARRY[21], SUM[21] ); smxxor1 d222 (A[22], B[22], CARRY[22], SUM[22] ); smxxor1 d223 (A[23], B[23], CARRY[23], SUM[23] ); smxxor1 d224 (A[24], B[24], CARRY[24], SUM[24] ); smxxor1 d225 (A[25], B[25], CARRY[25], SUM[25] ); smxxor1 d226 (A[26], B[26], CARRY[26], SUM[26] ); smxxor1 d227 (A[27], B[27], CARRY[27], SUM[27] ); smxxor1 d228 (A[28], B[28], CARRY[28], SUM[28] ); smxxor1 d229 (A[29], B[29], CARRY[29], SUM[29] ); smxxor1 d230 (A[30], B[30], CARRY[30], SUM[30] ); smxxor1 d231 (A[31], B[31], CARRY[31], SUM[31] ); smxxor1 d232 (A[32], B[32], CARRY[32], SUM[32] ); smxxor1 d233 (A[33], B[33], CARRY[33], SUM[33] ); smxxor1 d234 (A[34], B[34], CARRY[34], SUM[34] ); smxxor1 d235 (A[35], B[35], CARRY[35], SUM[35] ); smxxor1 d236 (A[36], B[36], CARRY[36], SUM[36] ); smxxor1 d237 (A[37], B[37], CARRY[37], SUM[37] ); smxxor1 d238 (A[38], B[38], CARRY[38], SUM[38] ); smxxor1 d239 (A[39], B[39], CARRY[39], SUM[39] ); smxxor1 d240 (A[40], B[40], CARRY[40], SUM[40] ); smxxor1 d241 (A[41], B[41], CARRY[41], SUM[41] ); smxxor1 d242 (A[42], B[42], CARRY[42], SUM[42] ); smxxor1 d243 (A[43], B[43], CARRY[43], SUM[43] ); smxxor1 d244 (A[44], B[44], CARRY[44], SUM[44] ); smxxor1 d245 (A[45], B[45], CARRY[45], SUM[45] ); smxxor1 d246 (A[46], B[46], CARRY[46], SUM[46] ); smxxor1 d247 (A[47], B[47], CARRY[47], SUM[47] ); smxxor1 d248 (A[48], B[48], CARRY[48], SUM[48] ); smxxor1 d249 (A[49], B[49], CARRY[49], SUM[49] ); smxxor1 d250 (A[50], B[50], CARRY[50], SUM[50] ); smxxor1 d251 (A[51], B[51], CARRY[51], SUM[51] ); smxxor1 d252 (A[52], B[52], CARRY[52], SUM[52] ); smxxor1 d253 (A[53], B[53], CARRY[53], SUM[53] ); smxxor1 d254 (A[54], B[54], CARRY[54], SUM[54] ); smxxor1 d255 (A[55], B[55], CARRY[55], SUM[55] ); smxxor1 d256 (A[56], B[56], CARRY[56], SUM[56] ); smxxor1 d257 (A[57], B[57], CARRY[57], SUM[57] ); smxxor1 d258 (A[58], B[58], CARRY[58], SUM[58] ); smxxor1 d259 (A[59], B[59], CARRY[59], SUM[59] ); smxxor1 d260 (A[60], B[60], CARRY[60], SUM[60] ); smxxor1 d261 (A[61], B[61], CARRY[61], SUM[61] ); smxxor1 d262 (A[62], B[62], CARRY[62], SUM[62] ); smxxor1 d263 (A[63], B[63], CARRY[63], SUM[63] ); endmodule module smdblc_5_128 ( PIN, GIN, POUT, GOUT ); input [63:0] PIN; input [63:0] GIN; output [63:0] POUT; output [63:0] GOUT; sminvblock d10 (GIN[0], GOUT[0] ); sminvblock d11 (GIN[1], GOUT[1] ); sminvblock d12 (GIN[2], GOUT[2] ); sminvblock d13 (GIN[3], GOUT[3] ); sminvblock d14 (GIN[4], GOUT[4] ); sminvblock d15 (GIN[5], GOUT[5] ); sminvblock d16 (GIN[6], GOUT[6] ); sminvblock d17 (GIN[7], GOUT[7] ); sminvblock d18 (GIN[8], GOUT[8] ); sminvblock d19 (GIN[9], GOUT[9] ); sminvblock d110 (GIN[10], GOUT[10] ); sminvblock d111 (GIN[11], GOUT[11] ); sminvblock d112 (GIN[12], GOUT[12] ); sminvblock d113 (GIN[13], GOUT[13] ); sminvblock d114 (GIN[14], GOUT[14] ); sminvblock d115 (GIN[15], GOUT[15] ); sminvblock d116 (GIN[16], GOUT[16] ); sminvblock d117 (GIN[17], GOUT[17] ); sminvblock d118 (GIN[18], GOUT[18] ); sminvblock d119 (GIN[19], GOUT[19] ); sminvblock d120 (GIN[20], GOUT[20] ); sminvblock d121 (GIN[21], GOUT[21] ); sminvblock d122 (GIN[22], GOUT[22] ); sminvblock d123 (GIN[23], GOUT[23] ); sminvblock d124 (GIN[24], GOUT[24] ); sminvblock d125 (GIN[25], GOUT[25] ); sminvblock d126 (GIN[26], GOUT[26] ); sminvblock d127 (GIN[27], GOUT[27] ); sminvblock d128 (GIN[28], GOUT[28] ); sminvblock d129 (GIN[29], GOUT[29] ); sminvblock d130 (GIN[30], GOUT[30] ); sminvblock d131 (GIN[31], GOUT[31] ); smblock2a d232 (PIN[0], GIN[0], GIN[32], GOUT[32] ); smblock2a d233 (PIN[1], GIN[1], GIN[33], GOUT[33] ); smblock2a d234 (PIN[2], GIN[2], GIN[34], GOUT[34] ); smblock2a d235 (PIN[3], GIN[3], GIN[35], GOUT[35] ); smblock2a d236 (PIN[4], GIN[4], GIN[36], GOUT[36] ); smblock2a d237 (PIN[5], GIN[5], GIN[37], GOUT[37] ); smblock2a d238 (PIN[6], GIN[6], GIN[38], GOUT[38] ); smblock2a d239 (PIN[7], GIN[7], GIN[39], GOUT[39] ); smblock2a d240 (PIN[8], GIN[8], GIN[40], GOUT[40] ); smblock2a d241 (PIN[9], GIN[9], GIN[41], GOUT[41] ); smblock2a d242 (PIN[10], GIN[10], GIN[42], GOUT[42] ); smblock2a d243 (PIN[11], GIN[11], GIN[43], GOUT[43] ); smblock2a d244 (PIN[12], GIN[12], GIN[44], GOUT[44] ); smblock2a d245 (PIN[13], GIN[13], GIN[45], GOUT[45] ); smblock2a d246 (PIN[14], GIN[14], GIN[46], GOUT[46] ); smblock2a d247 (PIN[15], GIN[15], GIN[47], GOUT[47] ); smblock2a d248 (PIN[16], GIN[16], GIN[48], GOUT[48] ); smblock2a d249 (PIN[17], GIN[17], GIN[49], GOUT[49] ); smblock2a d250 (PIN[18], GIN[18], GIN[50], GOUT[50] ); smblock2a d251 (PIN[19], GIN[19], GIN[51], GOUT[51] ); smblock2a d252 (PIN[20], GIN[20], GIN[52], GOUT[52] ); smblock2a d253 (PIN[21], GIN[21], GIN[53], GOUT[53] ); smblock2a d254 (PIN[22], GIN[22], GIN[54], GOUT[54] ); smblock2a d255 (PIN[23], GIN[23], GIN[55], GOUT[55] ); smblock2a d256 (PIN[24], GIN[24], GIN[56], GOUT[56] ); smblock2a d257 (PIN[25], GIN[25], GIN[57], GOUT[57] ); smblock2a d258 (PIN[26], GIN[26], GIN[58], GOUT[58] ); smblock2a d259 (PIN[27], GIN[27], GIN[59], GOUT[59] ); smblock2a d260 (PIN[28], GIN[28], GIN[60], GOUT[60] ); smblock2a d261 (PIN[29], GIN[29], GIN[61], GOUT[61] ); smblock2a d262 (PIN[30], GIN[30], GIN[62], GOUT[62] ); smblock2a d263 (PIN[31], GIN[31], GIN[63], GOUT[63] ); endmodule module smdblc_6_128 ( PIN, GIN, POUT, GOUT ); input [63:0] PIN; input [63:0] GIN; output [0:0] POUT; output [63:0] GOUT; assign GOUT[63:0] = GIN[63:0]; endmodule module smboothcoder_34_34 ( OPA, OPB, SUMMAND ); input [33:0] OPA; input [33:0] OPB; output [628:0] SUMMAND; wire [33:0] OPA_; wire [67:0] INT_MULTIPLIER; wire LOGIC_ONE, LOGIC_ZERO; assign LOGIC_ONE = 1'b1; assign LOGIC_ZERO = 1'b0; smdecoder dDEC0 (.INA (LOGIC_ZERO), .INB (OPB[0]), .INC (OPB[1]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]) ); assign OPA_ = ~ OPA; smpp_low dPPL0 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[0]) ); smr_gate dRGATE0 (.INA (LOGIC_ZERO), .INB (OPB[0]), .INC (OPB[1]), .PPBIT (SUMMAND[1]) ); smpp_middle dPPM0 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[2]) ); smpp_middle dPPM1 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[3]) ); smpp_middle dPPM2 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[6]) ); smpp_middle dPPM3 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[8]) ); smpp_middle dPPM4 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[12]) ); smpp_middle dPPM5 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[15]) ); smpp_middle dPPM6 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[20]) ); smpp_middle dPPM7 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[24]) ); smpp_middle dPPM8 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[30]) ); smpp_middle dPPM9 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[35]) ); smpp_middle dPPM10 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[42]) ); smpp_middle dPPM11 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[48]) ); smpp_middle dPPM12 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[56]) ); smpp_middle dPPM13 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[63]) ); smpp_middle dPPM14 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[72]) ); smpp_middle dPPM15 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[80]) ); smpp_middle dPPM16 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[90]) ); smpp_middle dPPM17 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[99]) ); smpp_middle dPPM18 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[110]) ); smpp_middle dPPM19 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[120]) ); smpp_middle dPPM20 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[132]) ); smpp_middle dPPM21 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[143]) ); smpp_middle dPPM22 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[156]) ); smpp_middle dPPM23 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[168]) ); smpp_middle dPPM24 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[182]) ); smpp_middle dPPM25 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[195]) ); smpp_middle dPPM26 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[210]) ); smpp_middle dPPM27 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[224]) ); smpp_middle dPPM28 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[240]) ); smpp_middle dPPM29 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[255]) ); smpp_middle dPPM30 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[272]) ); smpp_middle dPPM31 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[288]) ); smpp_middle dPPM32 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[306]) ); smpp_high dPPH0 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[0]), .TWONEG (INT_MULTIPLIER[1]), .ONEPOS (INT_MULTIPLIER[2]), .ONENEG (INT_MULTIPLIER[3]), .PPBIT (SUMMAND[323]) ); assign SUMMAND[324] = 1'b1; smdecoder dDEC1 (.INA (OPB[1]), .INB (OPB[2]), .INC (OPB[3]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]) ); smpp_low dPPL1 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[4]) ); smr_gate dRGATE1 (.INA (OPB[1]), .INB (OPB[2]), .INC (OPB[3]), .PPBIT (SUMMAND[5]) ); smpp_middle dPPM33 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[7]) ); smpp_middle dPPM34 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[9]) ); smpp_middle dPPM35 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[13]) ); smpp_middle dPPM36 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[16]) ); smpp_middle dPPM37 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[21]) ); smpp_middle dPPM38 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[25]) ); smpp_middle dPPM39 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[31]) ); smpp_middle dPPM40 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[36]) ); smpp_middle dPPM41 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[43]) ); smpp_middle dPPM42 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[49]) ); smpp_middle dPPM43 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[57]) ); smpp_middle dPPM44 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[64]) ); smpp_middle dPPM45 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[73]) ); smpp_middle dPPM46 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[81]) ); smpp_middle dPPM47 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[91]) ); smpp_middle dPPM48 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[100]) ); smpp_middle dPPM49 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[111]) ); smpp_middle dPPM50 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[121]) ); smpp_middle dPPM51 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[133]) ); smpp_middle dPPM52 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[144]) ); smpp_middle dPPM53 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[157]) ); smpp_middle dPPM54 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[169]) ); smpp_middle dPPM55 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[183]) ); smpp_middle dPPM56 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[196]) ); smpp_middle dPPM57 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[211]) ); smpp_middle dPPM58 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[225]) ); smpp_middle dPPM59 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[241]) ); smpp_middle dPPM60 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[256]) ); smpp_middle dPPM61 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[273]) ); smpp_middle dPPM62 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[289]) ); smpp_middle dPPM63 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[307]) ); smpp_middle dPPM64 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[325]) ); smpp_middle dPPM65 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[341]) ); assign SUMMAND[342] = LOGIC_ONE; smpp_high dPPH1 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[4]), .TWONEG (INT_MULTIPLIER[5]), .ONEPOS (INT_MULTIPLIER[6]), .ONENEG (INT_MULTIPLIER[7]), .PPBIT (SUMMAND[358]) ); smdecoder dDEC2 (.INA (OPB[3]), .INB (OPB[4]), .INC (OPB[5]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]) ); smpp_low dPPL2 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[10]) ); smr_gate dRGATE2 (.INA (OPB[3]), .INB (OPB[4]), .INC (OPB[5]), .PPBIT (SUMMAND[11]) ); smpp_middle dPPM66 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[14]) ); smpp_middle dPPM67 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[17]) ); smpp_middle dPPM68 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[22]) ); smpp_middle dPPM69 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[26]) ); smpp_middle dPPM70 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[32]) ); smpp_middle dPPM71 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[37]) ); smpp_middle dPPM72 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[44]) ); smpp_middle dPPM73 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[50]) ); smpp_middle dPPM74 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[58]) ); smpp_middle dPPM75 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[65]) ); smpp_middle dPPM76 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[74]) ); smpp_middle dPPM77 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[82]) ); smpp_middle dPPM78 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[92]) ); smpp_middle dPPM79 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[101]) ); smpp_middle dPPM80 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[112]) ); smpp_middle dPPM81 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[122]) ); smpp_middle dPPM82 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[134]) ); smpp_middle dPPM83 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[145]) ); smpp_middle dPPM84 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[158]) ); smpp_middle dPPM85 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[170]) ); smpp_middle dPPM86 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[184]) ); smpp_middle dPPM87 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[197]) ); smpp_middle dPPM88 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[212]) ); smpp_middle dPPM89 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[226]) ); smpp_middle dPPM90 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[242]) ); smpp_middle dPPM91 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[257]) ); smpp_middle dPPM92 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[274]) ); smpp_middle dPPM93 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[290]) ); smpp_middle dPPM94 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[308]) ); smpp_middle dPPM95 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[326]) ); smpp_middle dPPM96 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[343]) ); smpp_middle dPPM97 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[359]) ); smpp_middle dPPM98 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[374]) ); assign SUMMAND[375] = LOGIC_ONE; smpp_high dPPH2 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[8]), .TWONEG (INT_MULTIPLIER[9]), .ONEPOS (INT_MULTIPLIER[10]), .ONENEG (INT_MULTIPLIER[11]), .PPBIT (SUMMAND[390]) ); smdecoder dDEC3 (.INA (OPB[5]), .INB (OPB[6]), .INC (OPB[7]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]) ); smpp_low dPPL3 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[18]) ); smr_gate dRGATE3 (.INA (OPB[5]), .INB (OPB[6]), .INC (OPB[7]), .PPBIT (SUMMAND[19]) ); smpp_middle dPPM99 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[23]) ); smpp_middle dPPM100 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[27]) ); smpp_middle dPPM101 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[33]) ); smpp_middle dPPM102 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[38]) ); smpp_middle dPPM103 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[45]) ); smpp_middle dPPM104 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[51]) ); smpp_middle dPPM105 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[59]) ); smpp_middle dPPM106 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[66]) ); smpp_middle dPPM107 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[75]) ); smpp_middle dPPM108 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[83]) ); smpp_middle dPPM109 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[93]) ); smpp_middle dPPM110 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[102]) ); smpp_middle dPPM111 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[113]) ); smpp_middle dPPM112 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[123]) ); smpp_middle dPPM113 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[135]) ); smpp_middle dPPM114 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[146]) ); smpp_middle dPPM115 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[159]) ); smpp_middle dPPM116 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[171]) ); smpp_middle dPPM117 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[185]) ); smpp_middle dPPM118 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[198]) ); smpp_middle dPPM119 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[213]) ); smpp_middle dPPM120 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[227]) ); smpp_middle dPPM121 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[243]) ); smpp_middle dPPM122 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[258]) ); smpp_middle dPPM123 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[275]) ); smpp_middle dPPM124 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[291]) ); smpp_middle dPPM125 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[309]) ); smpp_middle dPPM126 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[327]) ); smpp_middle dPPM127 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[344]) ); smpp_middle dPPM128 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[360]) ); smpp_middle dPPM129 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[376]) ); smpp_middle dPPM130 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[391]) ); smpp_middle dPPM131 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[405]) ); assign SUMMAND[406] = LOGIC_ONE; smpp_high dPPH3 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[12]), .TWONEG (INT_MULTIPLIER[13]), .ONEPOS (INT_MULTIPLIER[14]), .ONENEG (INT_MULTIPLIER[15]), .PPBIT (SUMMAND[420]) ); smdecoder dDEC4 (.INA (OPB[7]), .INB (OPB[8]), .INC (OPB[9]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]) ); smpp_low dPPL4 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[28]) ); smr_gate dRGATE4 (.INA (OPB[7]), .INB (OPB[8]), .INC (OPB[9]), .PPBIT (SUMMAND[29]) ); smpp_middle dPPM132 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[34]) ); smpp_middle dPPM133 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[39]) ); smpp_middle dPPM134 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[46]) ); smpp_middle dPPM135 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[52]) ); smpp_middle dPPM136 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[60]) ); smpp_middle dPPM137 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[67]) ); smpp_middle dPPM138 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[76]) ); smpp_middle dPPM139 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[84]) ); smpp_middle dPPM140 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[94]) ); smpp_middle dPPM141 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[103]) ); smpp_middle dPPM142 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[114]) ); smpp_middle dPPM143 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[124]) ); smpp_middle dPPM144 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[136]) ); smpp_middle dPPM145 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[147]) ); smpp_middle dPPM146 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[160]) ); smpp_middle dPPM147 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[172]) ); smpp_middle dPPM148 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[186]) ); smpp_middle dPPM149 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[199]) ); smpp_middle dPPM150 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[214]) ); smpp_middle dPPM151 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[228]) ); smpp_middle dPPM152 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[244]) ); smpp_middle dPPM153 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[259]) ); smpp_middle dPPM154 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[276]) ); smpp_middle dPPM155 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[292]) ); smpp_middle dPPM156 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[310]) ); smpp_middle dPPM157 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[328]) ); smpp_middle dPPM158 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[345]) ); smpp_middle dPPM159 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[361]) ); smpp_middle dPPM160 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[377]) ); smpp_middle dPPM161 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[392]) ); smpp_middle dPPM162 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[407]) ); smpp_middle dPPM163 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[421]) ); smpp_middle dPPM164 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[434]) ); assign SUMMAND[435] = LOGIC_ONE; smpp_high dPPH4 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[16]), .TWONEG (INT_MULTIPLIER[17]), .ONEPOS (INT_MULTIPLIER[18]), .ONENEG (INT_MULTIPLIER[19]), .PPBIT (SUMMAND[448]) ); smdecoder dDEC5 (.INA (OPB[9]), .INB (OPB[10]), .INC (OPB[11]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]) ); smpp_low dPPL5 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[40]) ); smr_gate dRGATE5 (.INA (OPB[9]), .INB (OPB[10]), .INC (OPB[11]), .PPBIT (SUMMAND[41]) ); smpp_middle dPPM165 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[47]) ); smpp_middle dPPM166 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[53]) ); smpp_middle dPPM167 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[61]) ); smpp_middle dPPM168 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[68]) ); smpp_middle dPPM169 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[77]) ); smpp_middle dPPM170 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[85]) ); smpp_middle dPPM171 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[95]) ); smpp_middle dPPM172 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[104]) ); smpp_middle dPPM173 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[115]) ); smpp_middle dPPM174 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[125]) ); smpp_middle dPPM175 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[137]) ); smpp_middle dPPM176 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[148]) ); smpp_middle dPPM177 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[161]) ); smpp_middle dPPM178 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[173]) ); smpp_middle dPPM179 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[187]) ); smpp_middle dPPM180 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[200]) ); smpp_middle dPPM181 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[215]) ); smpp_middle dPPM182 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[229]) ); smpp_middle dPPM183 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[245]) ); smpp_middle dPPM184 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[260]) ); smpp_middle dPPM185 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[277]) ); smpp_middle dPPM186 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[293]) ); smpp_middle dPPM187 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[311]) ); smpp_middle dPPM188 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[329]) ); smpp_middle dPPM189 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[346]) ); smpp_middle dPPM190 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[362]) ); smpp_middle dPPM191 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[378]) ); smpp_middle dPPM192 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[393]) ); smpp_middle dPPM193 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[408]) ); smpp_middle dPPM194 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[422]) ); smpp_middle dPPM195 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[436]) ); smpp_middle dPPM196 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[449]) ); smpp_middle dPPM197 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[461]) ); assign SUMMAND[462] = LOGIC_ONE; smpp_high dPPH5 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[20]), .TWONEG (INT_MULTIPLIER[21]), .ONEPOS (INT_MULTIPLIER[22]), .ONENEG (INT_MULTIPLIER[23]), .PPBIT (SUMMAND[474]) ); smdecoder dDEC6 (.INA (OPB[11]), .INB (OPB[12]), .INC (OPB[13]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]) ); smpp_low dPPL6 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[54]) ); smr_gate dRGATE6 (.INA (OPB[11]), .INB (OPB[12]), .INC (OPB[13]), .PPBIT (SUMMAND[55]) ); smpp_middle dPPM198 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[62]) ); smpp_middle dPPM199 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[69]) ); smpp_middle dPPM200 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[78]) ); smpp_middle dPPM201 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[86]) ); smpp_middle dPPM202 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[96]) ); smpp_middle dPPM203 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[105]) ); smpp_middle dPPM204 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[116]) ); smpp_middle dPPM205 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[126]) ); smpp_middle dPPM206 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[138]) ); smpp_middle dPPM207 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[149]) ); smpp_middle dPPM208 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[162]) ); smpp_middle dPPM209 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[174]) ); smpp_middle dPPM210 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[188]) ); smpp_middle dPPM211 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[201]) ); smpp_middle dPPM212 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[216]) ); smpp_middle dPPM213 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[230]) ); smpp_middle dPPM214 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[246]) ); smpp_middle dPPM215 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[261]) ); smpp_middle dPPM216 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[278]) ); smpp_middle dPPM217 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[294]) ); smpp_middle dPPM218 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[312]) ); smpp_middle dPPM219 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[330]) ); smpp_middle dPPM220 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[347]) ); smpp_middle dPPM221 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[363]) ); smpp_middle dPPM222 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[379]) ); smpp_middle dPPM223 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[394]) ); smpp_middle dPPM224 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[409]) ); smpp_middle dPPM225 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[423]) ); smpp_middle dPPM226 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[437]) ); smpp_middle dPPM227 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[450]) ); smpp_middle dPPM228 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[463]) ); smpp_middle dPPM229 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[475]) ); smpp_middle dPPM230 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[486]) ); assign SUMMAND[487] = LOGIC_ONE; smpp_high dPPH6 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[24]), .TWONEG (INT_MULTIPLIER[25]), .ONEPOS (INT_MULTIPLIER[26]), .ONENEG (INT_MULTIPLIER[27]), .PPBIT (SUMMAND[498]) ); smdecoder dDEC7 (.INA (OPB[13]), .INB (OPB[14]), .INC (OPB[15]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]) ); smpp_low dPPL7 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[70]) ); smr_gate dRGATE7 (.INA (OPB[13]), .INB (OPB[14]), .INC (OPB[15]), .PPBIT (SUMMAND[71]) ); smpp_middle dPPM231 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[79]) ); smpp_middle dPPM232 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[87]) ); smpp_middle dPPM233 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[97]) ); smpp_middle dPPM234 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[106]) ); smpp_middle dPPM235 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[117]) ); smpp_middle dPPM236 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[127]) ); smpp_middle dPPM237 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[139]) ); smpp_middle dPPM238 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[150]) ); smpp_middle dPPM239 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[163]) ); smpp_middle dPPM240 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[175]) ); smpp_middle dPPM241 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[189]) ); smpp_middle dPPM242 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[202]) ); smpp_middle dPPM243 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[217]) ); smpp_middle dPPM244 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[231]) ); smpp_middle dPPM245 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[247]) ); smpp_middle dPPM246 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[262]) ); smpp_middle dPPM247 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[279]) ); smpp_middle dPPM248 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[295]) ); smpp_middle dPPM249 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[313]) ); smpp_middle dPPM250 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[331]) ); smpp_middle dPPM251 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[348]) ); smpp_middle dPPM252 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[364]) ); smpp_middle dPPM253 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[380]) ); smpp_middle dPPM254 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[395]) ); smpp_middle dPPM255 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[410]) ); smpp_middle dPPM256 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[424]) ); smpp_middle dPPM257 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[438]) ); smpp_middle dPPM258 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[451]) ); smpp_middle dPPM259 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[464]) ); smpp_middle dPPM260 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[476]) ); smpp_middle dPPM261 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[488]) ); smpp_middle dPPM262 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[499]) ); smpp_middle dPPM263 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[509]) ); assign SUMMAND[510] = LOGIC_ONE; smpp_high dPPH7 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[28]), .TWONEG (INT_MULTIPLIER[29]), .ONEPOS (INT_MULTIPLIER[30]), .ONENEG (INT_MULTIPLIER[31]), .PPBIT (SUMMAND[520]) ); smdecoder dDEC8 (.INA (OPB[15]), .INB (OPB[16]), .INC (OPB[17]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]) ); smpp_low dPPL8 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[88]) ); smr_gate dRGATE8 (.INA (OPB[15]), .INB (OPB[16]), .INC (OPB[17]), .PPBIT (SUMMAND[89]) ); smpp_middle dPPM264 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[98]) ); smpp_middle dPPM265 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[107]) ); smpp_middle dPPM266 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[118]) ); smpp_middle dPPM267 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[128]) ); smpp_middle dPPM268 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[140]) ); smpp_middle dPPM269 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[151]) ); smpp_middle dPPM270 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[164]) ); smpp_middle dPPM271 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[176]) ); smpp_middle dPPM272 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[190]) ); smpp_middle dPPM273 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[203]) ); smpp_middle dPPM274 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[218]) ); smpp_middle dPPM275 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[232]) ); smpp_middle dPPM276 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[248]) ); smpp_middle dPPM277 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[263]) ); smpp_middle dPPM278 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[280]) ); smpp_middle dPPM279 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[296]) ); smpp_middle dPPM280 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[314]) ); smpp_middle dPPM281 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[332]) ); smpp_middle dPPM282 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[349]) ); smpp_middle dPPM283 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[365]) ); smpp_middle dPPM284 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[381]) ); smpp_middle dPPM285 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[396]) ); smpp_middle dPPM286 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[411]) ); smpp_middle dPPM287 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[425]) ); smpp_middle dPPM288 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[439]) ); smpp_middle dPPM289 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[452]) ); smpp_middle dPPM290 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[465]) ); smpp_middle dPPM291 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[477]) ); smpp_middle dPPM292 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[489]) ); smpp_middle dPPM293 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[500]) ); smpp_middle dPPM294 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[511]) ); smpp_middle dPPM295 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[521]) ); smpp_middle dPPM296 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[530]) ); assign SUMMAND[531] = LOGIC_ONE; smpp_high dPPH8 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[32]), .TWONEG (INT_MULTIPLIER[33]), .ONEPOS (INT_MULTIPLIER[34]), .ONENEG (INT_MULTIPLIER[35]), .PPBIT (SUMMAND[540]) ); smdecoder dDEC9 (.INA (OPB[17]), .INB (OPB[18]), .INC (OPB[19]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]) ); smpp_low dPPL9 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[108]) ); smr_gate dRGATE9 (.INA (OPB[17]), .INB (OPB[18]), .INC (OPB[19]), .PPBIT (SUMMAND[109]) ); smpp_middle dPPM297 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[119]) ); smpp_middle dPPM298 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[129]) ); smpp_middle dPPM299 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[141]) ); smpp_middle dPPM300 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[152]) ); smpp_middle dPPM301 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[165]) ); smpp_middle dPPM302 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[177]) ); smpp_middle dPPM303 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[191]) ); smpp_middle dPPM304 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[204]) ); smpp_middle dPPM305 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[219]) ); smpp_middle dPPM306 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[233]) ); smpp_middle dPPM307 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[249]) ); smpp_middle dPPM308 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[264]) ); smpp_middle dPPM309 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[281]) ); smpp_middle dPPM310 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[297]) ); smpp_middle dPPM311 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[315]) ); smpp_middle dPPM312 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[333]) ); smpp_middle dPPM313 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[350]) ); smpp_middle dPPM314 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[366]) ); smpp_middle dPPM315 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[382]) ); smpp_middle dPPM316 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[397]) ); smpp_middle dPPM317 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[412]) ); smpp_middle dPPM318 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[426]) ); smpp_middle dPPM319 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[440]) ); smpp_middle dPPM320 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[453]) ); smpp_middle dPPM321 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[466]) ); smpp_middle dPPM322 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[478]) ); smpp_middle dPPM323 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[490]) ); smpp_middle dPPM324 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[501]) ); smpp_middle dPPM325 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[512]) ); smpp_middle dPPM326 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[522]) ); smpp_middle dPPM327 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[532]) ); smpp_middle dPPM328 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[541]) ); smpp_middle dPPM329 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[549]) ); assign SUMMAND[550] = LOGIC_ONE; smpp_high dPPH9 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[36]), .TWONEG (INT_MULTIPLIER[37]), .ONEPOS (INT_MULTIPLIER[38]), .ONENEG (INT_MULTIPLIER[39]), .PPBIT (SUMMAND[558]) ); smdecoder dDEC10 (.INA (OPB[19]), .INB (OPB[20]), .INC (OPB[21]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]) ); smpp_low dPPL10 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[130]) ); smr_gate dRGATE10 (.INA (OPB[19]), .INB (OPB[20]), .INC (OPB[21]), .PPBIT (SUMMAND[131]) ); smpp_middle dPPM330 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[142]) ); smpp_middle dPPM331 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[153]) ); smpp_middle dPPM332 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[166]) ); smpp_middle dPPM333 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[178]) ); smpp_middle dPPM334 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[192]) ); smpp_middle dPPM335 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[205]) ); smpp_middle dPPM336 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[220]) ); smpp_middle dPPM337 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[234]) ); smpp_middle dPPM338 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[250]) ); smpp_middle dPPM339 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[265]) ); smpp_middle dPPM340 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[282]) ); smpp_middle dPPM341 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[298]) ); smpp_middle dPPM342 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[316]) ); smpp_middle dPPM343 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[334]) ); smpp_middle dPPM344 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[351]) ); smpp_middle dPPM345 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[367]) ); smpp_middle dPPM346 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[383]) ); smpp_middle dPPM347 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[398]) ); smpp_middle dPPM348 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[413]) ); smpp_middle dPPM349 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[427]) ); smpp_middle dPPM350 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[441]) ); smpp_middle dPPM351 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[454]) ); smpp_middle dPPM352 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[467]) ); smpp_middle dPPM353 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[479]) ); smpp_middle dPPM354 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[491]) ); smpp_middle dPPM355 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[502]) ); smpp_middle dPPM356 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[513]) ); smpp_middle dPPM357 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[523]) ); smpp_middle dPPM358 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[533]) ); smpp_middle dPPM359 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[542]) ); smpp_middle dPPM360 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[551]) ); smpp_middle dPPM361 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[559]) ); smpp_middle dPPM362 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[566]) ); assign SUMMAND[567] = LOGIC_ONE; smpp_high dPPH10 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[40]), .TWONEG (INT_MULTIPLIER[41]), .ONEPOS (INT_MULTIPLIER[42]), .ONENEG (INT_MULTIPLIER[43]), .PPBIT (SUMMAND[574]) ); smdecoder dDEC11 (.INA (OPB[21]), .INB (OPB[22]), .INC (OPB[23]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]) ); smpp_low dPPL11 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[154]) ); smr_gate dRGATE11 (.INA (OPB[21]), .INB (OPB[22]), .INC (OPB[23]), .PPBIT (SUMMAND[155]) ); smpp_middle dPPM363 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[167]) ); smpp_middle dPPM364 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[179]) ); smpp_middle dPPM365 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[193]) ); smpp_middle dPPM366 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[206]) ); smpp_middle dPPM367 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[221]) ); smpp_middle dPPM368 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[235]) ); smpp_middle dPPM369 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[251]) ); smpp_middle dPPM370 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[266]) ); smpp_middle dPPM371 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[283]) ); smpp_middle dPPM372 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[299]) ); smpp_middle dPPM373 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[317]) ); smpp_middle dPPM374 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[335]) ); smpp_middle dPPM375 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[352]) ); smpp_middle dPPM376 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[368]) ); smpp_middle dPPM377 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[384]) ); smpp_middle dPPM378 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[399]) ); smpp_middle dPPM379 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[414]) ); smpp_middle dPPM380 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[428]) ); smpp_middle dPPM381 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[442]) ); smpp_middle dPPM382 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[455]) ); smpp_middle dPPM383 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[468]) ); smpp_middle dPPM384 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[480]) ); smpp_middle dPPM385 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[492]) ); smpp_middle dPPM386 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[503]) ); smpp_middle dPPM387 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[514]) ); smpp_middle dPPM388 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[524]) ); smpp_middle dPPM389 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[534]) ); smpp_middle dPPM390 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[543]) ); smpp_middle dPPM391 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[552]) ); smpp_middle dPPM392 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[560]) ); smpp_middle dPPM393 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[568]) ); smpp_middle dPPM394 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[575]) ); smpp_middle dPPM395 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[581]) ); assign SUMMAND[582] = LOGIC_ONE; smpp_high dPPH11 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[44]), .TWONEG (INT_MULTIPLIER[45]), .ONEPOS (INT_MULTIPLIER[46]), .ONENEG (INT_MULTIPLIER[47]), .PPBIT (SUMMAND[588]) ); smdecoder dDEC12 (.INA (OPB[23]), .INB (OPB[24]), .INC (OPB[25]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]) ); smpp_low dPPL12 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[180]) ); smr_gate dRGATE12 (.INA (OPB[23]), .INB (OPB[24]), .INC (OPB[25]), .PPBIT (SUMMAND[181]) ); smpp_middle dPPM396 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[194]) ); smpp_middle dPPM397 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[207]) ); smpp_middle dPPM398 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[222]) ); smpp_middle dPPM399 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[236]) ); smpp_middle dPPM400 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[252]) ); smpp_middle dPPM401 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[267]) ); smpp_middle dPPM402 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[284]) ); smpp_middle dPPM403 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[300]) ); smpp_middle dPPM404 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[318]) ); smpp_middle dPPM405 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[336]) ); smpp_middle dPPM406 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[353]) ); smpp_middle dPPM407 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[369]) ); smpp_middle dPPM408 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[385]) ); smpp_middle dPPM409 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[400]) ); smpp_middle dPPM410 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[415]) ); smpp_middle dPPM411 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[429]) ); smpp_middle dPPM412 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[443]) ); smpp_middle dPPM413 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[456]) ); smpp_middle dPPM414 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[469]) ); smpp_middle dPPM415 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[481]) ); smpp_middle dPPM416 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[493]) ); smpp_middle dPPM417 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[504]) ); smpp_middle dPPM418 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[515]) ); smpp_middle dPPM419 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[525]) ); smpp_middle dPPM420 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[535]) ); smpp_middle dPPM421 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[544]) ); smpp_middle dPPM422 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[553]) ); smpp_middle dPPM423 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[561]) ); smpp_middle dPPM424 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[569]) ); smpp_middle dPPM425 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[576]) ); smpp_middle dPPM426 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[583]) ); smpp_middle dPPM427 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[589]) ); smpp_middle dPPM428 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[594]) ); assign SUMMAND[595] = LOGIC_ONE; smpp_high dPPH12 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[48]), .TWONEG (INT_MULTIPLIER[49]), .ONEPOS (INT_MULTIPLIER[50]), .ONENEG (INT_MULTIPLIER[51]), .PPBIT (SUMMAND[600]) ); smdecoder dDEC13 (.INA (OPB[25]), .INB (OPB[26]), .INC (OPB[27]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]) ); smpp_low dPPL13 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[208]) ); smr_gate dRGATE13 (.INA (OPB[25]), .INB (OPB[26]), .INC (OPB[27]), .PPBIT (SUMMAND[209]) ); smpp_middle dPPM429 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[223]) ); smpp_middle dPPM430 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[237]) ); smpp_middle dPPM431 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[253]) ); smpp_middle dPPM432 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[268]) ); smpp_middle dPPM433 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[285]) ); smpp_middle dPPM434 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[301]) ); smpp_middle dPPM435 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[319]) ); smpp_middle dPPM436 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[337]) ); smpp_middle dPPM437 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[354]) ); smpp_middle dPPM438 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[370]) ); smpp_middle dPPM439 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[386]) ); smpp_middle dPPM440 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[401]) ); smpp_middle dPPM441 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[416]) ); smpp_middle dPPM442 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[430]) ); smpp_middle dPPM443 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[444]) ); smpp_middle dPPM444 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[457]) ); smpp_middle dPPM445 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[470]) ); smpp_middle dPPM446 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[482]) ); smpp_middle dPPM447 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[494]) ); smpp_middle dPPM448 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[505]) ); smpp_middle dPPM449 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[516]) ); smpp_middle dPPM450 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[526]) ); smpp_middle dPPM451 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[536]) ); smpp_middle dPPM452 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[545]) ); smpp_middle dPPM453 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[554]) ); smpp_middle dPPM454 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[562]) ); smpp_middle dPPM455 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[570]) ); smpp_middle dPPM456 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[577]) ); smpp_middle dPPM457 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[584]) ); smpp_middle dPPM458 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[590]) ); smpp_middle dPPM459 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[596]) ); smpp_middle dPPM460 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[601]) ); smpp_middle dPPM461 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[605]) ); assign SUMMAND[606] = LOGIC_ONE; smpp_high dPPH13 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[52]), .TWONEG (INT_MULTIPLIER[53]), .ONEPOS (INT_MULTIPLIER[54]), .ONENEG (INT_MULTIPLIER[55]), .PPBIT (SUMMAND[610]) ); smdecoder dDEC14 (.INA (OPB[27]), .INB (OPB[28]), .INC (OPB[29]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]) ); smpp_low dPPL14 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[238]) ); smr_gate dRGATE14 (.INA (OPB[27]), .INB (OPB[28]), .INC (OPB[29]), .PPBIT (SUMMAND[239]) ); smpp_middle dPPM462 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[254]) ); smpp_middle dPPM463 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[269]) ); smpp_middle dPPM464 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[286]) ); smpp_middle dPPM465 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[302]) ); smpp_middle dPPM466 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[320]) ); smpp_middle dPPM467 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[338]) ); smpp_middle dPPM468 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[355]) ); smpp_middle dPPM469 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[371]) ); smpp_middle dPPM470 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[387]) ); smpp_middle dPPM471 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[402]) ); smpp_middle dPPM472 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[417]) ); smpp_middle dPPM473 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[431]) ); smpp_middle dPPM474 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[445]) ); smpp_middle dPPM475 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[458]) ); smpp_middle dPPM476 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[471]) ); smpp_middle dPPM477 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[483]) ); smpp_middle dPPM478 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[495]) ); smpp_middle dPPM479 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[506]) ); smpp_middle dPPM480 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[517]) ); smpp_middle dPPM481 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[527]) ); smpp_middle dPPM482 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[537]) ); smpp_middle dPPM483 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[546]) ); smpp_middle dPPM484 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[555]) ); smpp_middle dPPM485 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[563]) ); smpp_middle dPPM486 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[571]) ); smpp_middle dPPM487 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[578]) ); smpp_middle dPPM488 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[585]) ); smpp_middle dPPM489 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[591]) ); smpp_middle dPPM490 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[597]) ); smpp_middle dPPM491 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[602]) ); smpp_middle dPPM492 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[607]) ); smpp_middle dPPM493 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[611]) ); smpp_middle dPPM494 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[614]) ); assign SUMMAND[615] = LOGIC_ONE; smpp_high dPPH14 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[56]), .TWONEG (INT_MULTIPLIER[57]), .ONEPOS (INT_MULTIPLIER[58]), .ONENEG (INT_MULTIPLIER[59]), .PPBIT (SUMMAND[618]) ); smdecoder dDEC15 (.INA (OPB[29]), .INB (OPB[30]), .INC (OPB[31]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]) ); smpp_low dPPL15 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[270]) ); smr_gate dRGATE15 (.INA (OPB[29]), .INB (OPB[30]), .INC (OPB[31]), .PPBIT (SUMMAND[271]) ); smpp_middle dPPM495 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[287]) ); smpp_middle dPPM496 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[303]) ); smpp_middle dPPM497 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[321]) ); smpp_middle dPPM498 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[339]) ); smpp_middle dPPM499 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[356]) ); smpp_middle dPPM500 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[372]) ); smpp_middle dPPM501 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[388]) ); smpp_middle dPPM502 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[403]) ); smpp_middle dPPM503 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[418]) ); smpp_middle dPPM504 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[432]) ); smpp_middle dPPM505 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[446]) ); smpp_middle dPPM506 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[459]) ); smpp_middle dPPM507 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[472]) ); smpp_middle dPPM508 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[484]) ); smpp_middle dPPM509 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[496]) ); smpp_middle dPPM510 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[507]) ); smpp_middle dPPM511 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[518]) ); smpp_middle dPPM512 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[528]) ); smpp_middle dPPM513 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[538]) ); smpp_middle dPPM514 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[547]) ); smpp_middle dPPM515 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[556]) ); smpp_middle dPPM516 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[564]) ); smpp_middle dPPM517 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[572]) ); smpp_middle dPPM518 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[579]) ); smpp_middle dPPM519 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[586]) ); smpp_middle dPPM520 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[592]) ); smpp_middle dPPM521 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[598]) ); smpp_middle dPPM522 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[603]) ); smpp_middle dPPM523 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[608]) ); smpp_middle dPPM524 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[612]) ); smpp_middle dPPM525 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[616]) ); smpp_middle dPPM526 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[619]) ); smpp_middle dPPM527 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[621]) ); assign SUMMAND[622] = LOGIC_ONE; smpp_high dPPH15 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[60]), .TWONEG (INT_MULTIPLIER[61]), .ONEPOS (INT_MULTIPLIER[62]), .ONENEG (INT_MULTIPLIER[63]), .PPBIT (SUMMAND[624]) ); smdecoder dDEC16 (.INA (OPB[31]), .INB (OPB[32]), .INC (OPB[33]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]) ); smpp_low dPPL16 (.INA (OPA[0]), .INB (OPA_[0]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[304]) ); smr_gate dRGATE16 (.INA (OPB[31]), .INB (OPB[32]), .INC (OPB[33]), .PPBIT (SUMMAND[305]) ); smpp_middle dPPM528 (.INA (OPA[0]), .INB (OPA_[0]), .INC (OPA[1]), .IND (OPA_[1]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[322]) ); smpp_middle dPPM529 (.INA (OPA[1]), .INB (OPA_[1]), .INC (OPA[2]), .IND (OPA_[2]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[340]) ); smpp_middle dPPM530 (.INA (OPA[2]), .INB (OPA_[2]), .INC (OPA[3]), .IND (OPA_[3]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[357]) ); smpp_middle dPPM531 (.INA (OPA[3]), .INB (OPA_[3]), .INC (OPA[4]), .IND (OPA_[4]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[373]) ); smpp_middle dPPM532 (.INA (OPA[4]), .INB (OPA_[4]), .INC (OPA[5]), .IND (OPA_[5]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[389]) ); smpp_middle dPPM533 (.INA (OPA[5]), .INB (OPA_[5]), .INC (OPA[6]), .IND (OPA_[6]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[404]) ); smpp_middle dPPM534 (.INA (OPA[6]), .INB (OPA_[6]), .INC (OPA[7]), .IND (OPA_[7]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[419]) ); smpp_middle dPPM535 (.INA (OPA[7]), .INB (OPA_[7]), .INC (OPA[8]), .IND (OPA_[8]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[433]) ); smpp_middle dPPM536 (.INA (OPA[8]), .INB (OPA_[8]), .INC (OPA[9]), .IND (OPA_[9]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[447]) ); smpp_middle dPPM537 (.INA (OPA[9]), .INB (OPA_[9]), .INC (OPA[10]), .IND (OPA_[10]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[460]) ); smpp_middle dPPM538 (.INA (OPA[10]), .INB (OPA_[10]), .INC (OPA[11]), .IND (OPA_[11]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[473]) ); smpp_middle dPPM539 (.INA (OPA[11]), .INB (OPA_[11]), .INC (OPA[12]), .IND (OPA_[12]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[485]) ); smpp_middle dPPM540 (.INA (OPA[12]), .INB (OPA_[12]), .INC (OPA[13]), .IND (OPA_[13]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[497]) ); smpp_middle dPPM541 (.INA (OPA[13]), .INB (OPA_[13]), .INC (OPA[14]), .IND (OPA_[14]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[508]) ); smpp_middle dPPM542 (.INA (OPA[14]), .INB (OPA_[14]), .INC (OPA[15]), .IND (OPA_[15]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[519]) ); smpp_middle dPPM543 (.INA (OPA[15]), .INB (OPA_[15]), .INC (OPA[16]), .IND (OPA_[16]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[529]) ); smpp_middle dPPM544 (.INA (OPA[16]), .INB (OPA_[16]), .INC (OPA[17]), .IND (OPA_[17]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[539]) ); smpp_middle dPPM545 (.INA (OPA[17]), .INB (OPA_[17]), .INC (OPA[18]), .IND (OPA_[18]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[548]) ); smpp_middle dPPM546 (.INA (OPA[18]), .INB (OPA_[18]), .INC (OPA[19]), .IND (OPA_[19]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[557]) ); smpp_middle dPPM547 (.INA (OPA[19]), .INB (OPA_[19]), .INC (OPA[20]), .IND (OPA_[20]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[565]) ); smpp_middle dPPM548 (.INA (OPA[20]), .INB (OPA_[20]), .INC (OPA[21]), .IND (OPA_[21]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[573]) ); smpp_middle dPPM549 (.INA (OPA[21]), .INB (OPA_[21]), .INC (OPA[22]), .IND (OPA_[22]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[580]) ); smpp_middle dPPM550 (.INA (OPA[22]), .INB (OPA_[22]), .INC (OPA[23]), .IND (OPA_[23]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[587]) ); smpp_middle dPPM551 (.INA (OPA[23]), .INB (OPA_[23]), .INC (OPA[24]), .IND (OPA_[24]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[593]) ); smpp_middle dPPM552 (.INA (OPA[24]), .INB (OPA_[24]), .INC (OPA[25]), .IND (OPA_[25]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[599]) ); smpp_middle dPPM553 (.INA (OPA[25]), .INB (OPA_[25]), .INC (OPA[26]), .IND (OPA_[26]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[604]) ); smpp_middle dPPM554 (.INA (OPA[26]), .INB (OPA_[26]), .INC (OPA[27]), .IND (OPA_[27]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[609]) ); smpp_middle dPPM555 (.INA (OPA[27]), .INB (OPA_[27]), .INC (OPA[28]), .IND (OPA_[28]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[613]) ); smpp_middle dPPM556 (.INA (OPA[28]), .INB (OPA_[28]), .INC (OPA[29]), .IND (OPA_[29]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[617]) ); smpp_middle dPPM557 (.INA (OPA[29]), .INB (OPA_[29]), .INC (OPA[30]), .IND (OPA_[30]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[620]) ); smpp_middle dPPM558 (.INA (OPA[30]), .INB (OPA_[30]), .INC (OPA[31]), .IND (OPA_[31]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[623]) ); smpp_middle dPPM559 (.INA (OPA[31]), .INB (OPA_[31]), .INC (OPA[32]), .IND (OPA_[32]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[625]) ); smpp_middle dPPM560 (.INA (OPA[32]), .INB (OPA_[32]), .INC (OPA[33]), .IND (OPA_[33]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[626]) ); assign SUMMAND[627] = LOGIC_ONE; smpp_high dPPH16 (.INA (OPA[33]), .INB (OPA_[33]), .TWOPOS (INT_MULTIPLIER[64]), .TWONEG (INT_MULTIPLIER[65]), .ONEPOS (INT_MULTIPLIER[66]), .ONENEG (INT_MULTIPLIER[67]), .PPBIT (SUMMAND[628]) ); endmodule // Simple cells module smpp_low ( ONEPOS, ONENEG, TWONEG, INA, INB, PPBIT ); input ONEPOS; input ONENEG; input TWONEG; input INA; input INB; output PPBIT; assign PPBIT = (ONEPOS & INA) | (ONENEG & INB) | TWONEG; endmodule module smpp_middle ( ONEPOS, ONENEG, TWOPOS, TWONEG, INA, INB, INC, IND, PPBIT ); input ONEPOS; input ONENEG; input TWOPOS; input TWONEG; input INA; input INB; input INC; input IND; output PPBIT; assign PPBIT = ~ (( ~ (INA & TWOPOS)) & ( ~ (INB & TWONEG)) & ( ~ (INC & ONEPOS)) & ( ~ (IND & ONENEG))); endmodule module smpp_high ( ONEPOS, ONENEG, TWOPOS, TWONEG, INA, INB, PPBIT ); input ONEPOS; input ONENEG; input TWOPOS; input TWONEG; input INA; input INB; output PPBIT; assign PPBIT = ~ ((INA & ONEPOS) | (INB & ONENEG) | (INA & TWOPOS) | (INB & TWONEG)); endmodule module smr_gate ( INA, INB, INC, PPBIT ); input INA; input INB; input INC; output PPBIT; assign PPBIT = ( ~ (INA & INB)) & INC; endmodule module smdecoder ( INA, INB, INC, TWOPOS, TWONEG, ONEPOS, ONENEG ); input INA; input INB; input INC; output TWOPOS; output TWONEG; output ONEPOS; output ONENEG; assign TWOPOS = ~ ( ~ (INA & INB & ( ~ INC))); assign TWONEG = ~ ( ~ (( ~ INA) & ( ~ INB) & INC)); assign ONEPOS = (( ~ INA) & INB & ( ~ INC)) | (( ~ INC) & ( ~ INB) & INA); assign ONENEG = (INA & ( ~ INB) & INC) | (INC & INB & ( ~ INA)); endmodule module smfulladder ( DATA_A, DATA_B, DATA_C, SAVE, CARRY ); input DATA_A; input DATA_B; input DATA_C; output SAVE; output CARRY; wire TMP; assign TMP = DATA_A ^ DATA_B; assign SAVE = TMP ^ DATA_C; assign CARRY = ~ (( ~ (TMP & DATA_C)) & ( ~ (DATA_A & DATA_B))); endmodule module smhalfadder ( DATA_A, DATA_B, SAVE, CARRY ); input DATA_A; input DATA_B; output SAVE; output CARRY; assign SAVE = DATA_A ^ DATA_B; assign CARRY = DATA_A & DATA_B; endmodule module smffa ( input clk, input en_d1, input D, output reg Q ); always @ (posedge clk) begin Q <= D; end endmodule module smffb ( input clk, input en_d2, input D, output reg Q ); always @ (posedge clk) begin Q <= D; end endmodule module sminvblock ( GIN, GOUT ); input GIN; output GOUT; assign GOUT = ~ GIN; endmodule module smxxor1 ( A, B, GIN, SUM ); input A; input B; input GIN; output SUM; assign SUM = ( ~ (A ^ B)) ^ GIN; endmodule module smblock0 ( A, B, POUT, GOUT ); input A; input B; output POUT; output GOUT; assign POUT = ~ (A | B); assign GOUT = ~ (A & B); endmodule module smblock1 ( PIN1, PIN2, GIN1, GIN2, POUT, GOUT ); input PIN1; input PIN2; input GIN1; input GIN2; output POUT; output GOUT; assign POUT = ~ (PIN1 | PIN2); assign GOUT = ~ (GIN2 & (PIN2 | GIN1)); endmodule module smblock2 ( PIN1, PIN2, GIN1, GIN2, POUT, GOUT ); input PIN1; input PIN2; input GIN1; input GIN2; output POUT; output GOUT; assign POUT = ~ (PIN1 & PIN2); assign GOUT = ~ (GIN2 | (PIN2 & GIN1)); endmodule module smblock1a ( PIN2, GIN1, GIN2, GOUT ); input PIN2; input GIN1; input GIN2; output GOUT; assign GOUT = ~ (GIN2 & (PIN2 | GIN1)); endmodule module smblock2a ( PIN2, GIN1, GIN2, GOUT ); input PIN2; input GIN1; input GIN2; output GOUT; assign GOUT = ~ (GIN2 | (PIN2 & GIN1)); endmodule // Local Variables: // compile-command: "vlint --brief --nowarn=MULTMF,MODLNM t_math_wallace_mul.v" // End: verilator-3.874/test_regress/t/t_lint_latch_bad.v0000664000177100017500000000075512525171734022156 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs bl, cl, bc, cc, // Inputs a ); input logic a; output logic bl; output logic cl; always_latch begin bl <= a; // No warning cl = a; end output logic bc; output logic cc; always_comb begin bc <= a; // Warning cc = a; end endmodule verilator-3.874/test_regress/t/t_tri_dangle.pl0000775000177100017500000000071712473477707021521 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_vecgen1.pl0000775000177100017500000000103312473477707021562 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_clk_vecgen1.v"); compile ( v_flags2 => ['+define+T_TEST1',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_under.pl0000775000177100017500000000072212473477707021535 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_wild.v0000664000177100017500000000576212473477707021177 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; reg [63:0] sum; reg out1; reg [4:0] out2; sub sub (.in(crc[23:0]), .out1(out1), .out2(out2)); always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%x sum=%x out=%x,%x\n",$time, cyc, crc, sum, out1,out2); cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= {sum[62:0], sum[63]^sum[2]^sum[0]} ^ {58'h0,out1,out2}; if (cyc==0) begin // Setup crc <= 64'h00000000_00000097; sum <= 64'h0; end else if (cyc==90) begin if (sum !== 64'hf0afc2bfa78277c5) $stop; end else if (cyc==91) begin end else if (cyc==92) begin end else if (cyc==93) begin end else if (cyc==94) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub (/*AUTOARG*/ // Outputs out1, out2, // Inputs in ); input [23:0] in; output reg out1; output reg [4:0] out2; always @* begin // Test empty cases casez (in[0]) endcase casez (in) 24'b0000_0000_0000_0000_0000_0000 : {out1,out2} = {1'b0,5'h00}; 24'b????_????_????_????_????_???1 : {out1,out2} = {1'b1,5'h00}; 24'b????_????_????_????_????_??10 : {out1,out2} = {1'b1,5'h01}; 24'b????_????_????_????_????_?100 : {out1,out2} = {1'b1,5'h02}; 24'b????_????_????_????_????_1000 : {out1,out2} = {1'b1,5'h03}; 24'b????_????_????_????_???1_0000 : {out1,out2} = {1'b1,5'h04}; 24'b????_????_????_????_??10_0000 : {out1,out2} = {1'b1,5'h05}; 24'b????_????_????_????_?100_0000 : {out1,out2} = {1'b1,5'h06}; 24'b????_????_????_????_1000_0000 : {out1,out2} = {1'b1,5'h07}; // Same pattern, but reversed to test we work OK. 24'b1000_0000_0000_0000_0000_0000 : {out1,out2} = {1'b1,5'h17}; 24'b?100_0000_0000_0000_0000_0000 : {out1,out2} = {1'b1,5'h16}; 24'b??10_0000_0000_0000_0000_0000 : {out1,out2} = {1'b1,5'h15}; 24'b???1_0000_0000_0000_0000_0000 : {out1,out2} = {1'b1,5'h14}; 24'b????_1000_0000_0000_0000_0000 : {out1,out2} = {1'b1,5'h13}; 24'b????_?100_0000_0000_0000_0000 : {out1,out2} = {1'b1,5'h12}; 24'b????_??10_0000_0000_0000_0000 : {out1,out2} = {1'b1,5'h11}; 24'b????_???1_0000_0000_0000_0000 : {out1,out2} = {1'b1,5'h10}; 24'b????_????_1000_0000_0000_0000 : {out1,out2} = {1'b1,5'h0f}; 24'b????_????_?100_0000_0000_0000 : {out1,out2} = {1'b1,5'h0e}; 24'b????_????_??10_0000_0000_0000 : {out1,out2} = {1'b1,5'h0d}; 24'b????_????_???1_0000_0000_0000 : {out1,out2} = {1'b1,5'h0c}; 24'b????_????_????_1000_0000_0000 : {out1,out2} = {1'b1,5'h0b}; 24'b????_????_????_?100_0000_0000 : {out1,out2} = {1'b1,5'h0a}; 24'b????_????_????_??10_0000_0000 : {out1,out2} = {1'b1,5'h09}; 24'b????_????_????_???1_0000_0000 : {out1,out2} = {1'b1,5'h08}; endcase end endmodule verilator-3.874/test_regress/t/t_struct_unaligned.v0000664000177100017500000000132112473477707022602 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: // Test an error where a shift amount was out of bounds and the compiler treats the // value as undefined (Issue #803) // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jeff Bush. module t (/*AUTOARG*/ // Inputs clk ); input clk; struct packed { logic flag; logic [130:0] data; } foo[1]; integer cyc=0; // Test loop always @ (posedge clk) begin cyc <= cyc + 1; foo[0].data <= 0; foo[0].flag <= !foo[0].flag; if (cyc==10) begin if (foo[0].data != 0) begin $display("bad data value %x", foo[0].data); $stop; end $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_interface1_modport.pl0000775000177100017500000000072712473477707023177 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_final.v0000664000177100017500000000111112473477707020316 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Charlie Brej. module submodule (); // This bug only appears when not inlining // verilator no_inline_module initial begin $write("d"); end final begin $write("d"); end endmodule module t (); generate for (genvar i = 0; i < 100; i = i + 1) begin : module_set submodule u_submodule (); end endgenerate initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_sys_file_scan_input.dat0000664000177100017500000000000612473477707023572 0ustar wsnyderwsnyder1 2 3 verilator-3.874/test_regress/t/t_math_reverse.pl0000775000177100017500000000071712473477707022075 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_unoptflat_simple_3_bad.pl0000775000177100017500000000076212473477707024026 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_unoptflat_simple_3.v"); # Compile only compile ( fails => 1 ); ok(1); 1; verilator-3.874/test_regress/t/t_param_named_2.pl0000775000177100017500000000071712473477707022076 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_preproc_noline.v0000664000177100017500000000050112473477707022245 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define CHECK text \ multiline Hello in t_preproc_psl.v `ifdef NEVER not `else yes `endif Multi `CHECK line // Did we end up right? Line: `__LINE__ verilator-3.874/test_regress/t/t_var_dotted.v0000664000177100017500000001224512473477707021372 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); // verilator lint_off MULTIDRIVEN wire [31:0] outb0c0; wire [31:0] outb0c1; wire [31:0] outb1c0; wire [31:0] outb1c1; reg [7:0] lclmem [7:0]; ma ma0 (.outb0c0(outb0c0), .outb0c1(outb0c1), .outb1c0(outb1c0), .outb1c1(outb1c1) ); global_mod #(32'hf00d) global_cell (); global_mod #(32'hf22d) global_cell2 (); input clk; integer cyc=1; always @ (posedge clk) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("[%0t] cyc%0d: %0x %0x %0x %0x\n", $time, cyc, outb0c0, outb0c1, outb1c0, outb1c1); `endif if (cyc==2) begin if (global_cell.globali != 32'hf00d) $stop; if (global_cell2.globali != 32'hf22d) $stop; if (outb0c0 != 32'h00) $stop; if (outb0c1 != 32'h01) $stop; if (outb1c0 != 32'h10) $stop; if (outb1c1 != 32'h11) $stop; end if (cyc==3) begin // Can we scope down and read and write vars? ma0.mb0.mc0.out <= ma0.mb0.mc0.out + 32'h100; ma0.mb0.mc1.out <= ma0.mb0.mc1.out + 32'h100; ma0.mb1.mc0.out <= ma0.mb1.mc0.out + 32'h100; ma0.mb1.mc1.out <= ma0.mb1.mc1.out + 32'h100; end if (cyc==4) begin // Can we do dotted's inside array sels? ma0.rmtmem[ma0.mb0.mc0.out[2:0]] = 8'h12; lclmem[ma0.mb0.mc0.out[2:0]] = 8'h24; if (outb0c0 != 32'h100) $stop; if (outb0c1 != 32'h101) $stop; if (outb1c0 != 32'h110) $stop; if (outb1c1 != 32'h111) $stop; end if (cyc==5) begin if (ma0.rmtmem[ma0.mb0.mc0.out[2:0]] != 8'h12) $stop; if (lclmem[ma0.mb0.mc0.out[2:0]] != 8'h24) $stop; if (outb0c0 != 32'h1100) $stop; if (outb0c1 != 32'h2101) $stop; if (outb1c0 != 32'h2110) $stop; if (outb1c1 != 32'h3111) $stop; end if (cyc==6) begin if (outb0c0 != 32'h31100) $stop; if (outb0c1 != 32'h02101) $stop; if (outb1c0 != 32'h42110) $stop; if (outb1c1 != 32'h03111) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule `ifdef USE_INLINE_MID `define INLINE_MODULE /*verilator inline_module*/ `define INLINE_MID_MODULE /*verilator no_inline_module*/ `else `ifdef USE_INLINE `define INLINE_MODULE /*verilator inline_module*/ `define INLINE_MID_MODULE /*verilator inline_module*/ `else `define INLINE_MODULE /*verilator public_module*/ `define INLINE_MID_MODULE /*verilator public_module*/ `endif `endif module global_mod; `INLINE_MODULE parameter INITVAL = 0; integer globali; initial globali = INITVAL; endmodule module ma ( output wire [31:0] outb0c0, output wire [31:0] outb0c1, output wire [31:0] outb1c0, output wire [31:0] outb1c1 ); `INLINE_MODULE reg [7:0] rmtmem [7:0]; mb #(0) mb0 (.outc0(outb0c0), .outc1(outb0c1)); mb #(1) mb1 (.outc0(outb1c0), .outc1(outb1c1)); endmodule module mb ( output wire [31:0] outc0, output wire [31:0] outc1 ); `INLINE_MID_MODULE parameter P2 = 0; mc #(P2,0) mc0 (.out(outc0)); mc #(P2,1) mc1 (.out(outc1)); global_mod #(32'hf33d) global_cell2 (); wire reach_up_clk = t.clk; always @(reach_up_clk) begin if (P2==0) begin // Only for mb0 if (outc0 !== t.ma0.mb0.mc0.out) $stop; // Top module name and lower instances if (outc0 !== ma0.mb0.mc0.out) $stop; // Upper module name and lower instances if (outc0 !== ma .mb0.mc0.out) $stop; // Upper module name and lower instances if (outc0 !== mb.mc0.out) $stop; // This module name and lower instances if (outc0 !== mb0.mc0.out) $stop; // Upper instance name and lower instances if (outc0 !== mc0.out) $stop; // Lower instances if (outc1 !== t.ma0.mb0.mc1.out) $stop; // Top module name and lower instances if (outc1 !== ma0.mb0.mc1.out) $stop; // Upper module name and lower instances if (outc1 !== ma .mb0.mc1.out) $stop; // Upper module name and lower instances if (outc1 !== mb.mc1.out) $stop; // This module name and lower instances if (outc1 !== mb0.mc1.out) $stop; // Upper instance name and lower instances if (outc1 !== mc1.out) $stop; // Lower instances end end endmodule module mc (output reg [31:0] out); `INLINE_MODULE parameter P2 = 0; parameter P3 = 0; initial begin out = {24'h0,P2[3:0],P3[3:0]}; //$write("%m P2=%0x p3=%0x out=%x\n",P2, P3, out); end // Can we look from the top module name down? wire [31:0] reach_up_cyc = t.cyc; always @ (posedge t.clk) begin //$write("[%0t] %m: Got reachup, cyc=%0d\n", $time, reach_up_cyc); if (reach_up_cyc==2) begin if (global_cell.globali != 32'hf00d) $stop; if (global_cell2.globali != 32'hf33d) $stop; end if (reach_up_cyc==4) begin out[15:12] <= {P2[3:0]+P3[3:0]+4'd1}; end if (reach_up_cyc==5) begin // Can we set another instance? if (P3==1) begin // Without this, there are two possible correct answers... mc0.out[19:16] <= {mc0.out[19:16]+P2[3:0]+P3[3:0]+4'd2}; $display("%m Set %x->%x %x %x %x %x",mc0.out, {mc0.out[19:16]+P2[3:0]+P3[3:0]+4'd2}, mc0.out[19:16],P2[3:0],P3[3:0],4'd2); end end end endmodule verilator-3.874/test_regress/t/t_param_ceil.pl0000775000177100017500000000071712473477707021505 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_enum_int.pl0000775000177100017500000000071712473477707021227 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_plusargs.pl0000775000177100017500000000040312473477707022137 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } compile ( v_flags2 => ['-v', 't/t_flag_libinc.v'], ); execute ( check_finished=>1, all_run_flags => ['+PLUS +INT=1234 +STRSTR'], ); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_bound.pl0000775000177100017500000000072212473477707021741 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_cdc_async_bad.v0000664000177100017500000000404412473477707021771 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs q0, q1, q2, q3, q4, q5, q6a, q6b, // Inputs clk, d, rst0_n ); input clk; input d; // OK -- from primary input rst0_n; output wire q0; Flop flop0 (.q(q0), .rst_n(rst0_n), .clk(clk), .d(d)); // OK -- from flop reg rst1_n; always @ (posedge clk) rst1_n <= rst0_n; output wire q1; Flop flop1 (.q(q1), .rst_n(rst1_n), .clk(clk), .d(d)); // Bad - logic wire rst2_bad_n = rst0_n | rst1_n; output wire q2; Flop flop2 (.q(q2), .rst_n(rst2_bad_n), .clk(clk), .d(d)); // Bad - logic in submodule wire rst3_bad_n; Sub sub (.z(rst3_bad_n), .a(rst0_n), .b(rst1_n)); output wire q3; Flop flop3 (.q(q3), .rst_n(rst3_bad_n), .clk(clk), .d(d)); // OK - bit selection reg [3:0] rst4_n; always @ (posedge clk) rst4_n <= {4{rst0_n}}; output wire q4; Flop flop4 (.q(q4), .rst_n(rst4_n[1]), .clk(clk), .d(d)); // Bad - logic, but waived // verilator lint_off CDCRSTLOGIC wire rst5_waive_n = rst0_n & rst1_n; // verilator lint_on CDCRSTLOGIC output wire q5; Flop flop5 (.q(q5), .rst_n(rst5_waive_n), .clk(clk), .d(d)); // Bad - for graph test - logic feeds two signals, three destinations wire rst6_bad_n = rst0_n ^ rst1_n; wire rst6a_bad_n = rst6_bad_n ^ $c1("0"); // $c prevents optimization wire rst6b_bad_n = rst6_bad_n ^ $c1("1"); output wire q6a; output wire q6b; Flop flop6a (.q(q6a), .rst_n(rst6a_bad_n), .clk(clk), .d(d)); Flop flop6v (.q(q6b), .rst_n(rst6b_bad_n), .clk(clk), .d(d)); initial begin $display("%%Error: Not a runnable test"); $stop; end endmodule module Flop ( input clk, input d, input rst_n, output q); always @ (posedge clk or negedge rst_n) begin if (!rst_n) q <= 1'b0; else q <= d; end endmodule module Sub (input a, b, output z); wire z = a|b; endmodule verilator-3.874/test_regress/t/t_help.pl0000775000177100017500000000145012473477707020334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); foreach my $prog ( "../bin/verilator", "../bin/verilator_coverage", "../bin/verilator_difftree", "../bin/verilator_profcfunc", ) { $Self->_run(fails=>1, cmd=>["perl",$prog, "--help"], logfile=>"$Self->{obj_dir}/t_help.log", tee=>0, ); file_grep ("$Self->{obj_dir}/t_help.log", qr/DISTRIBUTION/i); } ok(1); 1; verilator-3.874/test_regress/t/t_order_clkinst.v0000664000177100017500000000444512473477707022104 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // verilator lint_off COMBDLY // verilator lint_off UNOPT // verilator lint_off UNOPTFLAT reg c1_start; initial c1_start = 0; wire [31:0] c1_count; comb_loop c1 (.count(c1_count), .start(c1_start)); wire s2_start = (c1_count==0 && c1_start); wire [31:0] s2_count; seq_loop s2 (.count(s2_count), .start(s2_start)); wire c3_start = (s2_count[0]); wire [31:0] c3_count; comb_loop c3 (.count(c3_count), .start(c3_start)); reg [7:0] cyc; initial cyc=0; always @ (posedge clk) begin //$write("[%0t] %x counts %x %x %x\n",$time,cyc,c1_count,s2_count,c3_count); cyc <= cyc + 8'd1; case (cyc) 8'd00: begin c1_start <= 1'b0; end 8'd01: begin c1_start <= 1'b1; end default: ; endcase case (cyc) 8'd02: begin if (c1_count!=32'h3) $stop; if (s2_count!=32'h3) $stop; if (c3_count!=32'h6) $stop; end 8'd03: begin $write("*-* All Finished *-*\n"); $finish; end default: ; endcase end endmodule module comb_loop (/*AUTOARG*/ // Outputs count, // Inputs start ); input start; output reg [31:0] count; initial count = 0; reg [31:0] runnerm1, runner; initial runner = 0; always @ (start) begin if (start) begin runner = 3; end end always @ (/*AS*/runner) begin runnerm1 = runner - 32'd1; end always @ (/*AS*/runnerm1) begin if (runner > 0) begin count = count + 1; runner = runnerm1; $write ("%m count=%d runner =%x\n",count, runnerm1); end end endmodule module seq_loop (/*AUTOARG*/ // Outputs count, // Inputs start ); input start; output reg [31:0] count; initial count = 0; reg [31:0] runnerm1, runner; initial runner = 0; always @ (start) begin if (start) begin runner <= 3; end end always @ (/*AS*/runner) begin runnerm1 = runner - 32'd1; end always @ (/*AS*/runnerm1) begin if (runner > 0) begin count = count + 1; runner <= runnerm1; $write ("%m count=%d runner<=%x\n",count, runnerm1); end end endmodule verilator-3.874/test_regress/t/t_func_bad2.pl0000775000177100017500000000105512473477707021230 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( fails=>$Self->{v3}, expect=> '%Error: t/t_func_bad2.v:\d+: Unsupported: Recursive function or task call %Error: Exiting due to', ); ok(1); 1; verilator-3.874/test_regress/t/t_embed1_wrap.v0000664000177100017500000000455612473477707021433 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t_embed1_wrap (/*AUTOARG*/ // Outputs bit_out, vec_out, wide_out, did_init_out, // Inputs clk, bit_in, vec_in, wide_in, is_ref ); /*AUTOINOUTMODULE("t_embed1_child")*/ // Beginning of automatic in/out/inouts (from specific module) output bit_out; output [30:0] vec_out; output [123:0] wide_out; output did_init_out; input clk; input bit_in; input [30:0] vec_in; input [123:0] wide_in; input is_ref; // End of automatics `ifdef verilator // Import $t_embed_child__initial etc as a DPI function `endif //TODO would like __'s as in {PREFIX}__initial but presently illegal for users to do this import "DPI-C" context function void t_embed_child_initial(); import "DPI-C" context function void t_embed_child_final(); import "DPI-C" context function void t_embed_child_eval(); import "DPI-C" context function void t_embed_child_io_eval ( //TODO we support bit, but not logic input bit clk, input bit bit_in, input bit [30:0] vec_in, input bit [123:0] wide_in, input bit is_ref, output bit bit_out, output bit [30:0] vec_out, output bit [123:0] wide_out, output bit did_init_out); initial begin // Load all values t_embed_child_initial(); end // Only if system verilog, and if a "final" block in the code final begin t_embed_child_final(); end bit _temp_bit_out; bit _temp_did_init_out; bit [30:0] _temp_vec_out; bit [123:0] _temp_wide_out; always @* begin t_embed_child_io_eval( clk, bit_in, vec_in, wide_in, is_ref, _temp_bit_out, _temp_vec_out, _temp_wide_out, _temp_did_init_out ); // TODO might eliminate these temporaries bit_out = _temp_bit_out; did_init_out = _temp_did_init_out; end // Send all variables every cycle, // or have a sensitivity routine for each? // How to make sure we call eval at end of variable changes? // #0 (though not verilator compatible!) // TODO for now, we know what changes when always @ (posedge clk) begin vec_out <= _temp_vec_out; wide_out <= _temp_wide_out; end endmodule verilator-3.874/test_regress/t/t_interface_down_inld.pl0000775000177100017500000000110312473477707023374 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_D'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_public_sig.pl0000775000177100017500000000156512473477707022711 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_trace_public.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["--trace --exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/t_trace_public.out"); # vcd_identical doesn't detect "$var a.b;" vs "$scope module a; $var b;" file_grep ("$Self->{obj_dir}/simx.vcd", qr/module glbl/i); ok(1); 1; verilator-3.874/test_regress/t/t_sys_time.v0000664000177100017500000000114112473477707021064 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] time64; // Test loop always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin end else if (cyc<10) begin end else if (cyc<90) begin time64 = $time; if ($stime != time64[31:0]) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_select_plusloop.v0000664000177100017500000000340312473477707022447 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [31:0] narrow; reg [63:0] quad; reg [127:0] wide; integer cyc; initial cyc=0; reg [7:0] crc; reg [6:0] index; always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%b n=%x\n",$time, cyc, crc, narrow); cyc <= cyc + 1; if (cyc==0) begin // Setup narrow <= 32'h0; quad <= 64'h0; wide <= 128'h0; crc <= 8'hed; index <= 7'h0; end else if (cyc<90) begin index <= index + 7'h2; crc <= {crc[6:0], ~^ {crc[7],crc[5],crc[4],crc[3]}}; // verilator lint_off WIDTH if (index < 9'd20) narrow[index +: 3] <= crc[2:0]; if (index < 9'd60) quad [index +: 3] <= crc[2:0]; if (index < 9'd120) wide [index +: 3] <= crc[2:0]; // narrow[index[3:0]] <= ~narrow[index[3:0]]; quad [~index[3:0]]<= ~quad [~index[3:0]]; wide [~index[3:0]] <= ~wide [~index[3:0]]; // verilator lint_on WIDTH end else if (cyc==90) begin wide[12 +: 4] <=4'h6; quad[12 +: 4] <=4'h6; narrow[12 +: 4] <=4'h6; wide[42 +: 4] <=4'h6; quad[42 +: 4] <=4'h6; wide[82 +: 4] <=4'h6; end else if (cyc==91) begin wide[0] <=1'b1; quad[0] <=1'b1; narrow[0] <=1'b1; wide[41] <=1'b1; quad[41] <=1'b1; wide[81] <=1'b1; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%b n=%x q=%x w=%x\n",$time, cyc, crc, narrow, quad, wide); if (crc != 8'b01111001) $stop; if (narrow != 32'h001661c7) $stop; if (quad != 64'h16d49b6f64266039) $stop; if (wide != 128'h012fd26d265b266ff6d49b6f64266039) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_enum_public.pl0000775000177100017500000000115412473477707021707 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. if ($Self->{vlt}) { compile ( verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], make_top_shell => 0, make_main => 0, ); } else { compile ( ); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_signed.v0000664000177100017500000001316112473477707021517 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; by_width #(1) w1 (.clk(clk)); by_width #(31) w31 (.clk(clk)); by_width #(32) w32 (.clk(clk)); by_width #(33) w33 (.clk(clk)); by_width #(63) w63 (.clk(clk)); by_width #(64) w64 (.clk(clk)); by_width #(65) w65 (.clk(clk)); by_width #(95) w95 (.clk(clk)); by_width #(96) w96 (.clk(clk)); by_width #(97) w97 (.clk(clk)); reg signed [15:0] a; reg signed [4:0] b; reg signed [15:0] sr,srs,sl,sls; reg [15:0] b_s; reg [15:0] b_us; task check_s(input signed [7:0] i, input [7:0] expval); //$display("check_s %x\n", i); if (i !== expval) $stop; endtask task check_us(input signed [7:0] i, input [7:0] expval); //$display("check_us %x\n", i); if (i !== expval) $stop; endtask always @* begin sr = a>>b; srs = copy_signed(a)>>>b; sl = a<>>4; // Signed b_us = b[4:0]>>>4; // Unsigned, due to extract check_s ( 3'b111, 8'h07); check_s (3'sb111, 8'hff); check_us( 3'b111, 8'h07); check_us(3'sb111, 8'hff); // Note we sign extend ignoring function's input requirements // verilator lint_on WIDTH end reg signed [32:0] bug349; initial begin end integer i; initial begin if ((-1 >>> 3) != -1) $stop; // Decimals are signed // verilator lint_off WIDTH if ((3'b111 >>> 3) != 0) $stop; // Based numbers are unsigned if ((3'sb111 >>> 3) != -1) $stop; // Signed based numbers // verilator lint_on WIDTH if ( (3'sb000 > 3'sb000)) $stop; if (!(3'sb000 > 3'sb111)) $stop; if ( (3'sb111 > 3'sb000)) $stop; if ( (3'sb000 < 3'sb000)) $stop; if ( (3'sb000 < 3'sb111)) $stop; if (!(3'sb111 < 3'sb000)) $stop; if (!(3'sb000 >= 3'sb000)) $stop; if (!(3'sb000 >= 3'sb111)) $stop; if ( (3'sb111 >= 3'sb000)) $stop; if (!(3'sb000 <= 3'sb000)) $stop; if ( (3'sb000 <= 3'sb111)) $stop; if (!(3'sb111 <= 3'sb000)) $stop; // When we multiply overflow, the sign bit stays correct. if ( (4'sd2*4'sd8) != 4'd0) $stop; // From the spec: // verilator lint_off WIDTH i = -12 /3; if (i !== 32'hfffffffc) $stop; i = -'d12 /3; if (i !== 32'h55555551) $stop; i = -'sd12 /3; if (i !== 32'hfffffffc) $stop; i = -4'sd12 /3; if (i !== 32'h00000001) $stop; // verilator lint_on WIDTH // verilator lint_off WIDTH bug349 = 4'sb1111 - 1'b1; if (bug349 != 32'he) $stop; end function signed [15:0] copy_signed; input [15:0] ai; copy_signed = ai; endfunction integer cyc; initial cyc=0; wire [31:0] ucyc = cyc; always @ (posedge clk) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("%x %x %x %x %x %x %x\n", cyc, sr,srs,sl,sls, b_s,b_us); `endif case (cyc) 0: begin a <= 16'sh8b1b; b <= 5'sh1f; // -1 end 1: begin // Check spaces in constants a <= 16 'sh 8b1b; b <= 5'sh01; // -1 end 2: begin a <= 16'sh8b1b; b <= 5'sh1e; // shift AMOUNT is really unsigned if (ucyc / 1 != 32'd2) $stop; if (ucyc / 2 != 32'd1) $stop; if (ucyc * 1 != 32'd2) $stop; if (ucyc * 2 != 32'd4) $stop; if (ucyc * 3 != 32'd6) $stop; if (cyc * 32'sd1 != 32'sd2) $stop; if (cyc * 32'sd2 != 32'sd4) $stop; if (cyc * 32'sd3 != 32'sd6) $stop; end 3: begin a <= 16'sh0048; b <= 5'sh1f; if (ucyc * 1 != 32'd3) $stop; if (ucyc * 2 != 32'd6) $stop; if (ucyc * 3 != 32'd9) $stop; if (ucyc * 4 != 32'd12) $stop; if (cyc * 32'sd1 != 32'sd3) $stop; if (cyc * 32'sd2 != 32'sd6) $stop; if (cyc * 32'sd3 != 32'sd9) $stop; end 4: begin a <= 16'sh4154; b <= 5'sh02; end 5: begin a <= 16'shc3e8; b <= 5'sh12; end 6: begin a <= 16'sh488b; b <= 5'sh02; end 9: begin $write("*-* All Finished *-*\n"); $finish; end default: ; endcase case (cyc) 0: ; 1: if ({sr,srs,sl,sls,b_s,b_us}!==96'sh0000_ffff_0000_0000_ffff_0001) $stop; 2: if ({sr,srs,sl,sls,b_s,b_us}!==96'sh458d_c58d_1636_1636_0000_0000) $stop; 3: if ({sr,srs,sl,sls,b_s,b_us}!==96'sh0000_ffff_0000_0000_ffff_0001) $stop; 4: if ({sr,srs,sl,sls,b_s,b_us}!==96'sh0000_0000_0000_0000_ffff_0001) $stop; 5: if ({sr,srs,sl,sls,b_s,b_us}!==96'sh1055_1055_0550_0550_0000_0000) $stop; 6: if ({sr,srs,sl,sls,b_s,b_us}!==96'sh0000_ffff_0000_0000_ffff_0001) $stop; 7: if ({sr,srs,sl,sls,b_s,b_us}!==96'sh1222_1222_222c_222c_0000_0000) $stop; 8: ; 9: ; endcase end endmodule module by_width ( input clk ); parameter WIDTH=1; reg signed i1; reg signed [62:0] i63; reg signed [64:0] i65; // verilator lint_off WIDTH wire signed [WIDTH-1:0] i1extp /*verilator public*/ = i1; wire signed [WIDTH-1:0] i1ext = i1; wire signed [WIDTH-1:0] i63ext = i63; wire signed [WIDTH-1:0] i65ext = i65; // verilator lint_on WIDTH integer cyc; initial cyc=0; always @ (posedge clk) begin cyc <= cyc + 1; i1 <= cyc[0]; i63 <= {63{cyc[0]}}; i65 <= {65{cyc[0]}}; case (cyc) 1: begin if (i1extp != {WIDTH{1'b0}}) $stop; if (i1ext != {WIDTH{1'b0}}) $stop; if (i63ext != {WIDTH{1'b0}}) $stop; if (i65ext != {WIDTH{1'b0}}) $stop; end 2: begin if (i1extp != {WIDTH{1'b1}}) $stop; if (i1ext != {WIDTH{1'b1}}) $stop; if (i63ext != {WIDTH{1'b1}}) $stop; if (i65ext != {WIDTH{1'b1}}) $stop; end default: ; endcase end endmodule verilator-3.874/test_regress/t/t_langext_3.pl0000775000177100017500000000075512473477707021277 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # This is a compile only test. compile ( v_flags2 => ["+1364-2005ext+v"], ); ok(1); 1; verilator-3.874/test_regress/t/t_case_x.v0000664000177100017500000000237312473477707020502 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005-2007 by Wilson Snyder. module t (/*AUTOARG*/); reg [3:0] value; reg [3:0] valuex; // verilator lint_off CASEOVERLAP // verilator lint_off CASEWITHX // verilator lint_off CASEX // Note for Verilator Xs must become zeros, or the Xs may match. initial begin value = 4'b1001; valuex = 4'b1xxx; case (value) 4'b1xxx: $stop; 4'b1???: $stop; 4'b1001: ; default: $stop; endcase case (valuex) 4'b1???: $stop; 4'b1xxx: ; 4'b1001: ; 4'b1000: ; // 1xxx is mapped to this by Verilator -x-assign 0 default: $stop; endcase // casex (value) 4'b100x: ; default: $stop; endcase casex (value) 4'b100?: ; default: $stop; endcase casex (valuex) 4'b100x: ; default: $stop; endcase casex (valuex) 4'b100?: ; default: $stop; endcase // casez (value) 4'bxxxx: $stop; 4'b100?: ; default: $stop; endcase casez (valuex) 4'b1xx?: ; 4'b100?: ; // 1xxx is mapped to this by Verilator -x-assign 0 default: $stop; endcase $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_flag_topmodule_inline.v0000664000177100017500000000077712473477707023605 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module a; a2 a2 (.tmp(1'b0)); initial begin $write("Bad top modules\n"); $stop; end endmodule module a2 (input tmp); l3 l3 (.tmp(tmp)); endmodule module b; l3 l3 (.tmp(1'b1)); endmodule module l3 (input tmp); initial begin if (tmp) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_flag_werror.v0000664000177100017500000000036712473477707021552 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/); // Width error below wire [3:0] foo = 6'h2e; endmodule verilator-3.874/test_regress/t/t_gate_elim.v0000664000177100017500000000423312473477707021163 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg b; wire vconst1 = 1'b0; wire vconst2 = !(vconst1); wire vconst3 = !vconst2; wire vconst = vconst3; wire qa; wire qb; wire qc; wire qd; wire qe; ta ta (.b(b), .vconst(vconst), .q(qa)); tb tb (.clk(clk), .vconst(vconst), .q(qb)); tc tc (.b(b), .vconst(vconst), .q(qc)); td td (.b(b), .vconst(vconst), .q(qd)); te te (.clk(clk), .b(b), .vconst(vconst), .q(qe)); always @ (posedge clk) begin `ifdef TEST_VERBOSE $display("%b",{qa,qb,qc,qd,qe}); `endif if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin b <= 1'b1; end if (cyc==2) begin if (qa!=1'b1) $stop; if (qb!=1'b0) $stop; if (qd!=1'b0) $stop; b <= 1'b0; end if (cyc==3) begin if (qa!=1'b0) $stop; if (qb!=1'b0) $stop; if (qd!=1'b0) $stop; if (qe!=1'b0) $stop; b <= 1'b1; end if (cyc==4) begin if (qa!=1'b1) $stop; if (qb!=1'b0) $stop; if (qd!=1'b0) $stop; if (qe!=1'b1) $stop; b <= 1'b0; end if (cyc==5) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module ta ( input vconst, input b, output reg q); always @ (/*AS*/b or vconst) begin q = vconst | b; end endmodule module tb ( input vconst, input clk, output reg q); always @ (posedge clk) begin q <= vconst; end endmodule module tc ( input vconst, input b, output reg q); always @ (posedge vconst) begin q <= b; $stop; end endmodule module td ( input vconst, input b, output reg q); always @ (/*AS*/vconst) begin q = vconst; end endmodule module te ( input clk, input vconst, input b, output reg q); reg qmid; always @ (posedge vconst or posedge clk) begin qmid <= b; end always @ (posedge clk or posedge vconst) begin q <= qmid; end endmodule verilator-3.874/test_regress/t/t_display_time.v0000664000177100017500000000161112473477707021715 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. `timescale 1ns/1ns module t; initial begin // Display formatting $write; // Check missing arguments work $write("default: [%0t] 0t time [%t] No0 time\n",$time,$time); `ifndef verilator // Unsupported $timeformat(-9, 0, "", 0); $write("-9,0,,0: [%0t] 0t time [%t] No0 time\n",$time,$time); $timeformat(-9, 0, "", 10); $write("-9,0,,10: [%0t] 0t time [%t] No0 time\n",$time,$time); $timeformat(-9, 0, "ns", 5); $write("-9,0,ns,5: [%0t] 0t time [%t] No0 time\n",$time,$time); $timeformat(-9, 3, "ns", 8); $write("-9,3,ns,8: [%0t] 0t time [%t] No0 time\n",$time,$time); `endif $write("\n"); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_func_dotted_inl2.pl0000775000177100017500000000104312473477707022624 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_func_dotted.v"); compile ( v_flags2 => ['+define+USE_INLINE_MID',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_implicit_port.pl0000775000177100017500000000077612473477707023322 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( v_flags2 => ["-Wno-IMPLICIT"], ); ok(1); 1; verilator-3.874/test_regress/t/t_order_multialways.pl0000775000177100017500000000071712473477707023157 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_debug_sigsegv_bt_bad.pl0000775000177100017500000000130712473477707023515 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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. $ENV{VERILATOR_TEST_NO_GDB} and $Self->skip("Skipping due to VERILATOR_TEST_NO_GDB"); compile ( v_flags2 => ["--lint-only --debug --gdbbt --debug-sigsegv"], fails=>$Self->{v3}, expect=> '.* Program received signal SIGSEGV, Segmentation fault. .*in V3Options::.* .*%Error: Command Failed.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_interface1.v0000664000177100017500000000143312473477707021255 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // Very simple test for interface pathclearing interface ifc; logic [3:0] value; endinterface module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc itop(); sub c1 (.isub(itop), .i_value(4'h4)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==20) begin if (c1.i_value != 4) $stop; // 'Normal' crossref just for comparison if (itop.value != 4) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub ( ifc isub, input logic [3:0] i_value ); always @* begin isub.value = i_value; end endmodule : sub verilator-3.874/test_regress/t/t_gen_cond_bitrange.pl0000775000177100017500000000071712473477707023040 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_real_abs.v0000664000177100017500000000221212473477707022013 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. //bug591 module t (/*AUTOARG*/); function real ABS (real num); ABS = (num < 0) ? -num : num; endfunction function logic range_chk; input real last; input real period; input real cmp; range_chk = 0; if ( last >= 0 ) begin if ( ABS(last - period) > cmp ) begin range_chk = 1; end end endfunction function integer ceil; input num; real num; if (num > $rtoi(num)) ceil = $rtoi(num) + 1; else // verilator lint_off REALCVT ceil = num; // verilator lint_on REALCVT endfunction initial begin if (range_chk(-1.1, 2.2, 3.3) != 1'b0) $stop; if (range_chk(1.1, 2.2, 0.3) != 1'b1) $stop; if (range_chk(1.1, 2.2, 2.3) != 1'b0) $stop; if (range_chk(2.2, 1.1, 0.3) != 1'b1) $stop; if (range_chk(2.2, 1.1, 2.3) != 1'b0) $stop; if (ceil(-2.1) != -2) $stop; if (ceil(2.1) != 3) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_vlcov_merge.out0000664000177100017500000000046012473477707022105 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint0ffile1.sphl159' 0 C 'CoverPoint1ffile1.sphl159' 1 C 'CoverPoint2ffile1.sphl159' 20 C 'CoverPoint3ffile1.sphl159' 0 C 'CoverPoint4ffile1.sphl159' 1 C 'CoverPoint5ffile1.sphl159' 9 C 'CoverPoint6ffile1.sphl159' 22 verilator-3.874/test_regress/t/t_mem_packed_bad.pl0000775000177100017500000000124212473477707022276 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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"); compile ( verilator_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_mem_packed_bad.v:\d+: Unsupported: Assignment between unpacked arrays of different dimensions %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_multi_io.pl0000775000177100017500000000110612525171734022046 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( # Disable inlining, this test is trivial without it verilator_flags2 => ["-Oi --trace"], verilator_flags3 => [], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gate_basic.v0000664000177100017500000000370512473477707021321 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [31:0] a; reg [31:0] b; wire [2:0] bf; buf BF0 (bf[0], a[0]), BF1 (bf[1], a[1]), BF2 (bf[2], a[2]); // verilator lint_off IMPLICIT not #(0.108) NT0 (nt0, a[0]); and #1 AN0 (an0, a[0], b[0]); nand #(2,3) ND0 (nd0, a[0], b[0], b[1]); or OR0 (or0, a[0], b[0]); nor NR0 (nr0, a[0], b[0], b[2]); xor (xo0, a[0], b[0]); xnor (xn0, a[0], b[0], b[2]); // verilator lint_on IMPLICIT parameter BITS=32; wire [BITS-1:0] ba; buf BARRAY [BITS-1:0] (ba, a); `ifdef verilator specify specparam CDS_LIBNAME = "foobar"; (nt0 *> nt0) = (0, 0); endspecify specify // delay parameters specparam a$A1$Y = 1.0, b$A0$Z = 1.0; // path delays (A1 *> Q) = (a$A1$Y, a$A1$Y); (A0 *> Q) = (b$A0$Y, a$A0$Z); endspecify `endif always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin a <= 32'h18f6b034; b <= 32'h834bf892; end if (cyc==2) begin a <= 32'h529ab56f; b <= 32'h7835a237; if (bf !== 3'b100) $stop; if (nt0 !== 1'b1) $stop; if (an0 !== 1'b0) $stop; if (nd0 !== 1'b1) $stop; if (or0 !== 1'b0) $stop; if (nr0 !== 1'b1) $stop; if (xo0 !== 1'b0) $stop; if (xn0 !== 1'b1) $stop; if (ba != 32'h18f6b034) $stop; end if (cyc==3) begin if (bf !== 3'b111) $stop; if (nt0 !== 1'b0) $stop; if (an0 !== 1'b1) $stop; if (nd0 !== 1'b0) $stop; if (or0 !== 1'b1) $stop; if (nr0 !== 1'b0) $stop; if (xo0 !== 1'b0) $stop; if (xn0 !== 1'b0) $stop; end if (cyc==4) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_math_pow.pl0000775000177100017500000000071712473477707021227 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_defparam.v0000664000177100017500000000146112473477707021645 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter PAR = 3; wire [31:0] o1a,o1b; m1 #(0) m1a(.o(o1a)); m1 #(1) m1b(.o(o1b)); always @ (posedge clk) begin if (o1a != 8) $stop; if (o1b != 4) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module m1 (output wire [31:0] o); parameter W = 0; generate if (W == 0) begin m2 m2 (.o(o)); defparam m2.PAR2 = 8; end else begin m2 m2 (.o(o)); defparam m2.PAR2 = 4; end endgenerate endmodule module m2 (output wire [31:0] o); parameter PAR2 = 10; assign o = PAR2; endmodule verilator-3.874/test_regress/t/t_dpi_import.v0000664000177100017500000002046212525171614021367 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. `ifdef VCS `define NO_SHORTREAL `endif `ifdef NC `define NO_SHORTREAL `endif `ifdef VERILATOR // Unsupported `define NO_SHORTREAL `endif module t (/*AUTOARG*/ // Inputs clk ); input clk; // Allowed import return types: // void, byte, shortint, int, longint, real, shortreal, chandle, and string // Scalar bit and logic // // Allowed argument types: // Same as above plus packed arrays import "DPI-C" pure function bit dpii_f_bit (input bit i); import "DPI-C" pure function bit [8-1:0] dpii_f_bit8 (input bit [8-1:0] i); import "DPI-C" pure function bit [9-1:0] dpii_f_bit9 (input bit [9-1:0] i); import "DPI-C" pure function bit [16-1:0] dpii_f_bit16 (input bit [16-1:0] i); import "DPI-C" pure function bit [17-1:0] dpii_f_bit17 (input bit [17-1:0] i); import "DPI-C" pure function bit [32-1:0] dpii_f_bit32 (input bit [32-1:0] i); // Illegal to return > 32 bits, so we use longint import "DPI-C" pure function longint dpii_f_bit33 (input bit [33-1:0] i); import "DPI-C" pure function longint dpii_f_bit64 (input bit [64-1:0] i); import "DPI-C" pure function int dpii_f_int (input int i); import "DPI-C" pure function byte dpii_f_byte (input byte i); import "DPI-C" pure function shortint dpii_f_shortint (input shortint i); import "DPI-C" pure function longint dpii_f_longint (input longint i); import "DPI-C" pure function chandle dpii_f_chandle (input chandle i); import "DPI-C" pure function string dpii_f_string (input string i); import "DPI-C" pure function real dpii_f_real (input real i); `ifndef NO_SHORTREAL import "DPI-C" pure function shortreal dpii_f_shortreal(input shortreal i); `endif import "DPI-C" pure function void dpii_v_bit (input bit i, output bit o); import "DPI-C" pure function void dpii_v_int (input int i, output int o); import "DPI-C" pure function void dpii_v_byte (input byte i, output byte o); import "DPI-C" pure function void dpii_v_shortint (input shortint i, output shortint o); import "DPI-C" pure function void dpii_v_longint (input longint i, output longint o); import "DPI-C" pure function void dpii_v_chandle (input chandle i, output chandle o); import "DPI-C" pure function void dpii_v_string (input string i, output string o); import "DPI-C" pure function void dpii_v_real (input real i, output real o); import "DPI-C" pure function void dpii_v_uint (input int unsigned i, output int unsigned o); import "DPI-C" pure function void dpii_v_ushort (input shortint unsigned i, output shortint unsigned o); import "DPI-C" pure function void dpii_v_ulong (input longint unsigned i, output longint unsigned o); `ifndef NO_SHORTREAL import "DPI-C" pure function void dpii_v_shortreal(input shortreal i, output shortreal o); `endif import "DPI-C" pure function void dpii_v_bit64 (input bit [64-1:0] i, output bit [64-1:0] o); import "DPI-C" pure function void dpii_v_bit95 (input bit [95-1:0] i, output bit [95-1:0] o); import "DPI-C" pure function void dpii_v_bit96 (input bit [96-1:0] i, output bit [96-1:0] o); import "DPI-C" pure function int dpii_f_strlen (input string i); import "DPI-C" function void dpii_f_void (); // Try a task import "DPI-C" task dpii_t_void (); import "DPI-C" context task dpii_t_void_context (); import "DPI-C" task dpii_t_int (input int i, output int o); // Try non-pure, aliasing with name import "DPI-C" dpii_fa_bit = function int oth_f_int1(input int i); import "DPI-C" dpii_fa_bit = function int oth_f_int2(input int i); bit i_b, o_b; bit [7:0] i_b8; bit [8:0] i_b9; bit [15:0] i_b16; bit [16:0] i_b17; bit [31:0] i_b32; bit [32:0] i_b33, o_b33; bit [63:0] i_b64, o_b64; bit [94:0] i_b95, o_b95; bit [95:0] i_b96, o_b96; int i_i, o_i; byte i_y, o_y; shortint i_s, o_s; longint i_l, o_l; int unsigned i_iu, o_iu; shortint unsigned i_su, o_su; longint unsigned i_lu, o_lu; // verilator lint_off UNDRIVEN chandle i_c, o_c; string i_n, o_n; // verilator lint_on UNDRIVEN real i_d, o_d; `ifndef NO_SHORTREAL shortreal i_f, o_f; `endif bit [94:0] wide; bit [6*8:1] string6; initial begin wide = 95'h15caff7a73c48afee4ffcb57; i_b = 1'b1; i_b8 = {1'b1,wide[8-2:0]}; i_b9 = {1'b1,wide[9-2:0]}; i_b16 = {1'b1,wide[16-2:0]}; i_b17 = {1'b1,wide[17-2:0]}; i_b32 = {1'b1,wide[32-2:0]}; i_b33 = {1'b1,wide[33-2:0]}; i_b64 = {1'b1,wide[64-2:0]}; i_b95 = {1'b1,wide[95-2:0]}; i_b96 = {1'b1,wide[96-2:0]}; i_i = {1'b1,wide[32-2:0]}; i_iu= {1'b1,wide[32-2:0]}; i_y = {1'b1,wide[8-2:0]}; i_s = {1'b1,wide[16-2:0]}; i_su= {1'b1,wide[16-2:0]}; i_l = {1'b1,wide[64-2:0]}; i_lu= {1'b1,wide[64-2:0]}; i_d = 32.1; `ifndef NO_SHORTREAL i_f = 30.2; `endif if (dpii_f_bit (i_b) !== ~i_b) $stop; if (dpii_f_bit8 (i_b8) !== ~i_b8) $stop; if (dpii_f_bit9 (i_b9) !== ~i_b9) $stop; if (dpii_f_bit16 (i_b16) !== ~i_b16) $stop; if (dpii_f_bit17 (i_b17) !== ~i_b17) $stop; if (dpii_f_bit32 (i_b32) !== ~i_b32) $stop; // These return different sizes, so we need to truncate // verilator lint_off WIDTH o_b33 = dpii_f_bit33 (i_b33); o_b64 = dpii_f_bit64 (i_b64); // verilator lint_on WIDTH if (o_b33 !== ~i_b33) $stop; if (o_b64 !== ~i_b64) $stop; if (dpii_f_bit (i_b) !== ~i_b) $stop; if (dpii_f_int (i_i) !== ~i_i) $stop; if (dpii_f_byte (i_y) !== ~i_y) $stop; if (dpii_f_shortint (i_s) !== ~i_s) $stop; if (dpii_f_longint (i_l) !== ~i_l) $stop; if (dpii_f_chandle (i_c) !== i_c) $stop; if (dpii_f_string (i_n) != i_n) $stop; if (dpii_f_real (i_d) != i_d+1.5) $stop; `ifndef NO_SHORTREAL if (dpii_f_shortreal(i_f) != i_f+1.5) $stop; `endif dpii_v_bit (i_b,o_b); if (o_b !== ~i_b) $stop; dpii_v_int (i_i,o_i); if (o_i !== ~i_i) $stop; dpii_v_byte (i_y,o_y); if (o_y !== ~i_y) $stop; dpii_v_shortint (i_s,o_s); if (o_s !== ~i_s) $stop; dpii_v_longint (i_l,o_l); if (o_l !== ~i_l) $stop; dpii_v_uint (i_iu,o_iu); if (o_iu !== ~i_iu) $stop; dpii_v_ushort (i_su,o_su); if (o_su !== ~i_su) $stop; dpii_v_ulong (i_lu,o_lu); if (o_lu !== ~i_lu) $stop; dpii_v_chandle (i_c,o_c); if (o_c !== i_c) $stop; dpii_v_string (i_n,o_n); if (o_n != i_n) $stop; dpii_v_real (i_d,o_d); if (o_d != i_d+1.5) $stop; `ifndef NO_SHORTREAL dpii_v_shortreal(i_f,o_f); if (o_f != i_f+1.5) $stop; `endif dpii_v_bit64 (i_b64,o_b64); if (o_b64 !== ~i_b64) $stop; dpii_v_bit95 (i_b95,o_b95); if (o_b95 !== ~i_b95) $stop; dpii_v_bit96 (i_b96,o_b96); if (o_b96 !== ~i_b96) $stop; if (dpii_f_strlen ("")!=0) $stop; if (dpii_f_strlen ("s")!=1) $stop; if (dpii_f_strlen ("st")!=2) $stop; if (dpii_f_strlen ("str")!=3) $stop; if (dpii_f_strlen ("stri")!=4) $stop; if (dpii_f_strlen ("string_l")!=8) $stop; if (dpii_f_strlen ("string_len")!=10) $stop; string6 = "hello6"; `ifdef VERILATOR string6 = $c48(string6); // Don't optimize away - want to see the constant conversion function `endif if (dpii_f_strlen (string6) != 6) $stop; dpii_f_void(); dpii_t_void(); dpii_t_void_context(); i_i = 32'h456789ab; dpii_t_int (i_i,o_i); if (o_b !== ~i_b) $stop; // Check alias if (oth_f_int1(32'd123) !== ~32'd123) $stop; if (oth_f_int2(32'd124) !== ~32'd124) $stop; $write("*-* All Finished *-*\n"); $finish; end always @ (posedge clk) begin i_b <= ~i_b; // This once mis-threw a BLKSEQ warning dpii_v_bit (i_b,o_b); if (o_b !== ~i_b) $stop; end endmodule verilator-3.874/test_regress/t/t_package_twodeep.v0000664000177100017500000000103712473477707022356 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett // see bug 591 package pkg2; parameter PARAM2 = 16; endpackage // pkg2 package pkg1; import pkg2::*; parameter PARAM1 = 8; endpackage // pkg1 module t import pkg1::*; // Test SV 2012 import format (/*AUTOARG*/ // Inputs clk ); input clk; reg [PARAM1:0] bus1; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_for_funcbound.v0000664000177100017500000000262712473477707022073 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer j; integer hit_count; reg [63:0] cam_lookup_hit_vector; strings strings (); task show; input [8*8-1:0] str; reg [7:0] char; integer loc; begin $write("[%0t] ",$time); strings.stringStart(8*8-1); for (char = strings.stringByte(str); !strings.isNull(char); char = strings.stringByte(str)) begin $write("%c",char); end $write("\n"); end endtask integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin show("hello\000xx"); end if (cyc==2) begin show("world\000xx"); end if (cyc==4) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module strings; // **NOT** reentrant, just a test! integer index; task stringStart; input [31:0] bits; begin index = (bits-1)/8; end endtask function isNull; input [7:0] chr; isNull = (chr == 8'h0); endfunction function [7:0] stringByte; input [8*8-1:0] str; begin if (index<=0) stringByte=8'h0; else stringByte = str[index*8 +: 8]; index = index - 1; end endfunction endmodule verilator-3.874/test_regress/t/t_tri_array.v0000664000177100017500000000311312473477707021225 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; parameter NPAD = 4; tri pad [NPAD-1:0]; // Array wire [NPAD-1:0] data0 = crc[0 +: 4]; wire [NPAD-1:0] data1 = crc[8 +: 4]; wire [NPAD-1:0] en = crc[16 +: 4]; for (genvar g=0; g{cycles} = $Self->{benchmark}||0; $Self->{cycles} = 100 if $Self->{cycles}<100; $Self->{sim_time} = $Self->{cycles}*100; compile ( v_flags2 => ["+define+SIM_CYCLES=$Self->{cycles}"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_dtree_inla.pl0000775000177100017500000000107712473477707022554 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_dtree.v"); compile ( v_flags2 => ['+define+INLINE_A'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_orig.pl0000775000177100017500000000071712473477707021344 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vlcov_data_b.dat0000664000177100017500000000026712473477707022166 0ustar wsnyderwsnyder# SystemC::Coverage-3 C 'CoverPoint2ffile1.sphl159' 10 C 'CoverPoint3ffile1.sphl159' 0 C 'CoverPoint4ffile1.sphl159' 1 C 'CoverPoint5ffile1.sphl159' 9 verilator-3.874/test_regress/t/t_preproc_def09.pl0000775000177100017500000000130212473477707022041 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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 $stdout_filename = "$Self->{obj_dir}/$Self->{name}__test.vpp"; compile ( verilator_flags2 => ['-E'], verilator_make_gcc=>0, stdout_filename => $stdout_filename, ); ok(files_identical($stdout_filename, "t/$Self->{name}.out")); 1; verilator-3.874/test_regress/t/t_lint_blksync_bad.pl0000775000177100017500000000217312473477707022710 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only -Wwarn-BLKSEQ -Wwarn-COMBDLY"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning-BLKSEQ: t/t_lint_blksync_bad.v:\d+: Blocking assignments \(=\) in sequential \(flop or latch\) block; suggest delayed assignments \(<=\). %Warning-BLKSEQ: Use .* to disable this message. %Warning-COMBDLY: t/t_lint_blksync_bad.v:\d+: Delayed assignments \(<=\) in non-clocked \(non flop or latch\) block; suggest blocking assignments \(=\). %Warning-COMBDLY: \*\*\* See the manual before disabling this, %Warning-COMBDLY: else you may end up with different sim results. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_wideconst.pl0000775000177100017500000000076212473477707022445 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( verilator_flags2 => ['-public'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_msvc_64.v0000664000177100017500000000273312473477707021532 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [89:0] in; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [89:0] out; // From test of Test.v wire [44:0] line0; wire [44:0] line1; // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[89:0]), .line0 (line0[44:0]), .line1 (line1[44:0]), // Inputs .clk (clk), .in (in[89:0])); // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d in=%x out=%x\n",$time, cyc, in, out); `endif cyc <= cyc + 1; if (cyc==0) begin // Setup in <= 90'h3FFFFFFFFFFFFFFFFFFFFFF; end else if (cyc==10) begin if (in==out) begin $write("*-* All Finished *-*\n"); $finish; end else begin $write("*-* Failed!! *-*\n"); $finish; end end end endmodule module Test (/*AUTOARG*/ // Outputs line0, line1, out, // Inputs clk, in ); input clk; input [89:0] in; output reg [44:0] line0; output reg [44:0] line1; output reg [89:0] out; assign {line0,line1} = in; always @(posedge clk) begin out <= {line0,line1}; end endmodule verilator-3.874/test_regress/t/t_select_bad_range2.pl0000775000177100017500000000117412473477707022732 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Warning-SELRANGE: t/t_select_bad_range2.v:\d+: Selection index out of range: 3:2 outside 1:0 %Warning-SELRANGE: Use .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_param_if_blk.pl0000775000177100017500000000072212473477707022013 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_pipe_filter.out0000664000177100017500000000202012473477707022071 0ustar wsnyderwsnyder`line 1 "t/t_pipe_filter.v" 1 `line 3 "t/t_pipe_filter.v" 0 `line 6 "t/t_pipe_filter.v" 0 `line 10 "t/t_pipe_filter.v" 0 example line 10; example line 11; `line 13 "t/t_pipe_filter.v" 0 `line 13 "t/t_pipe_filter.v" 0 `line 1 "t/t_pipe_filter_inc.vh" 1 int lint_off_line_7 = 1; `line 2 "t/t_pipe_filter_inc.vh" 0 int lint_off_line_8 = 1; `line 5 "t/t_pipe_filter_inc.vh" 0 `line 8 "t/t_pipe_filter_inc.vh" 0 inc line 6; inc line 7; inc line 8; inc line 9; `line 13 "t/t_pipe_filter_inc.vh" 2 `line 13 "t/t_pipe_filter.v" 0 `line 14 "t/t_pipe_filter.v" 0 `line 15 "t/t_pipe_filter.v" 0 `line 1 "t/t_pipe_filter_inc.vh" 1 int lint_off_line_7 = 1; `line 2 "t/t_pipe_filter_inc.vh" 0 int lint_off_line_8 = 1; `line 5 "t/t_pipe_filter_inc.vh" 0 `line 8 "t/t_pipe_filter_inc.vh" 0 inc line 6; inc line 7; inc line 8; inc line 9; `line 13 "t/t_pipe_filter_inc.vh" 2 `line 15 "t/t_pipe_filter.v" 0 `line 17 "t/t_pipe_filter.v" 0 example line 15; example line 16; `line 20 "t/t_pipe_filter.v" 2 verilator-3.874/test_regress/t/t_trace_cat_reopen_0000.out0000664000177100017500000000533012473477707023532 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Sat Feb 23 20:40:11 2013 $end $timescale 1ns $end $scope module top $end $var wire 1 $ clk $end $scope module v $end $var wire 1 $ clk $end $var wire 32 # cyc [31:0] $end $upscope $end $upscope $end $enddefinitions $end #0 b00000000000000000000000000000001 # 1$ #1 0$ #2 b00000000000000000000000000000010 # 1$ #3 0$ #4 b00000000000000000000000000000011 # 1$ #5 0$ #6 b00000000000000000000000000000100 # 1$ #7 0$ #8 b00000000000000000000000000000101 # 1$ #9 0$ #10 b00000000000000000000000000000110 # 1$ #11 0$ #12 b00000000000000000000000000000111 # 1$ #13 0$ #14 b00000000000000000000000000001000 # 1$ #15 0$ #16 b00000000000000000000000000001001 # 1$ #17 0$ #18 b00000000000000000000000000001010 # 1$ #19 0$ #20 b00000000000000000000000000001011 # 1$ #21 0$ #22 b00000000000000000000000000001100 # 1$ #23 0$ #24 b00000000000000000000000000001101 # 1$ #25 0$ #26 b00000000000000000000000000001110 # 1$ #27 0$ #28 b00000000000000000000000000001111 # 1$ #29 0$ #30 b00000000000000000000000000010000 # 1$ #31 0$ #32 b00000000000000000000000000010001 # 1$ #33 0$ #34 b00000000000000000000000000010010 # 1$ #35 0$ #36 b00000000000000000000000000010011 # 1$ #37 0$ #38 b00000000000000000000000000010100 # 1$ #39 0$ #40 b00000000000000000000000000010101 # 1$ #41 0$ #42 b00000000000000000000000000010110 # 1$ #43 0$ #44 b00000000000000000000000000010111 # 1$ #45 0$ #46 b00000000000000000000000000011000 # 1$ #47 0$ #48 b00000000000000000000000000011001 # 1$ #49 0$ #50 b00000000000000000000000000011010 # 1$ #51 0$ #52 b00000000000000000000000000011011 # 1$ #53 0$ #54 b00000000000000000000000000011100 # 1$ #55 0$ #56 b00000000000000000000000000011101 # 1$ #57 0$ #58 b00000000000000000000000000011110 # 1$ #59 0$ #60 b00000000000000000000000000011111 # 1$ #61 0$ #62 b00000000000000000000000000100000 # 1$ #63 0$ #64 b00000000000000000000000000100001 # 1$ #65 0$ #66 b00000000000000000000000000100010 # 1$ #67 0$ #68 b00000000000000000000000000100011 # 1$ #69 0$ #70 b00000000000000000000000000100100 # 1$ #71 0$ #72 b00000000000000000000000000100101 # 1$ #73 0$ #74 b00000000000000000000000000100110 # 1$ #75 0$ #76 b00000000000000000000000000100111 # 1$ #77 0$ #78 b00000000000000000000000000101000 # 1$ #79 0$ #80 b00000000000000000000000000101001 # 1$ #81 0$ #82 b00000000000000000000000000101010 # 1$ #83 0$ #84 b00000000000000000000000000101011 # 1$ #85 0$ #86 b00000000000000000000000000101100 # 1$ #87 0$ #88 b00000000000000000000000000101101 # 1$ #89 0$ #90 b00000000000000000000000000101110 # 1$ #91 0$ #92 b00000000000000000000000000101111 # 1$ #93 0$ #94 b00000000000000000000000000110000 # 1$ #95 0$ #96 b00000000000000000000000000110001 # 1$ #97 0$ #98 b00000000000000000000000000110010 # 1$ #99 0$ verilator-3.874/test_regress/t/t_select_index.v0000664000177100017500000000203412473477707021700 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. module t(/*AUTOARG*/ // Inputs clk ); // surefire lint_off NBAJAM input clk; reg [7:0] _ranit; reg [2:0] a; reg [7:0] vvector; reg [7:0] vvector_flip; // surefire lint_off STMINI initial _ranit = 0; always @ (posedge clk) begin a <= a + 3'd1; vvector[a] <= 1'b1; // This should use "old" value for a vvector_flip[~a] <= 1'b1; // This should use "old" value for a // //======== if (_ranit==8'd0) begin _ranit <= 8'd1; $write("[%0t] t_select_index: Running\n", $time); vvector <= 0; vvector_flip <= 0; a <= 3'b1; end else _ranit <= _ranit + 8'd1; // if (_ranit==8'd3) begin $write("%x %x\n",vvector,vvector_flip); if (vvector !== 8'b0000110) $stop; if (vvector_flip !== 8'b0110_0000) $stop; // $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_mem_iforder.v0000664000177100017500000000411612473477707021525 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; reg [31:0] sum; wire [15:0] out0; wire [15:0] out1; wire [15:0] inData = crc[15:0]; wire wr0a = crc[16]; wire wr0b = crc[17]; wire wr1a = crc[18]; wire wr1b = crc[19]; fifo fifo ( // Outputs .out0 (out0[15:0]), .out1 (out1[15:0]), // Inputs .clk (clk), .wr0a (wr0a), .wr0b (wr0b), .wr1a (wr1a), .wr1b (wr1b), .inData (inData[15:0])); always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%x q=%x\n",$time, cyc, crc, sum); cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 32'h0; end else if (cyc>10 && cyc<90) begin sum <= {sum[30:0],sum[31]} ^ {out1, out0}; end else if (cyc==99) begin if (sum !== 32'he8bbd130) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module fifo (/*AUTOARG*/ // Outputs out0, out1, // Inputs clk, wr0a, wr0b, wr1a, wr1b, inData ); input clk; input wr0a; input wr0b; input wr1a; input wr1b; input [15:0] inData; output [15:0] out0; output [15:0] out1; reg [15:0] mem [1:0]; reg [15:0] memtemp2 [1:0]; reg [15:0] memtemp3 [1:0]; assign out0 = {mem[0] ^ memtemp2[0]}; assign out1 = {mem[1] ^ memtemp3[1]}; always @(posedge clk) begin // These mem assignments must be done in order after processing if (wr0a) begin memtemp2[0] <= inData; mem[0] <= inData; end if (wr0b) begin memtemp3[0] <= inData; mem[0] <= ~inData; end if (wr1a) begin memtemp3[1] <= inData; mem[1] <= inData; end if (wr1b) begin memtemp2[1] <= inData; mem[1] <= ~inData; end end endmodule verilator-3.874/test_regress/t/t_sys_readmem_bad_end.mem0000664000177100017500000000050312473477707023506 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test data file // // Copyright 2006 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. 00 01 10 // Missing additional data verilator-3.874/test_regress/t/t_assert_cover_off.pl0000775000177100017500000000101012473477707022725 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_assert_cover.v"); compile ( v_flags2 => [], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_lib.pl0000775000177100017500000000077312473477707021174 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ['-v', 't/t_func_lib_sub.v'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vpi_get.v0000664000177100017500000000351512473477707020674 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2010 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. `ifdef USE_VPI_NOT_DPI //We call it via $c so we can verify DPI isn't required - see bug572 `else import "DPI-C" context function integer mon_check(); `endif module t (/*AUTOARG*/ // Inputs input clk /*verilator public_flat_rd */, // test ports input [15:0] testin /*verilator public_flat_rd */, output [23:0] testout /*verilator public_flat_rw @(posedge clk) */ ); `ifdef VERILATOR `systemc_header extern "C" int mon_check(); `verilog `endif reg onebit /*verilator public_flat_rw @(posedge clk) */; reg [2:1] twoone /*verilator public_flat_rw @(posedge clk) */; reg onetwo [1:2] /*verilator public_flat_rw @(posedge clk) */; reg [2:1] fourthreetwoone[4:3] /*verilator public_flat_rw @(posedge clk) */; integer status; `ifdef iverilog // stop icarus optimizing signals away wire redundant = onebit | onetwo[1] | twoone | fourthreetwoone[3]; `endif wire subin /*verilator public_flat_rd*/; wire subout /*verilator public_flat_rd*/; sub sub(.*); // Test loop initial begin `ifdef VERILATOR status = $c32("mon_check()"); `endif `ifdef iverilog status = $mon_check(); `endif `ifndef USE_VPI_NOT_DPI status = mon_check(); `endif if (status!=0) begin $write("%%Error: t_vpi_var.cpp:%0d: C Test failed\n", status); $stop; end $write("*-* All Finished *-*\n"); $finish; end endmodule : t module sub ( input subin /*verilator public_flat_rd*/, output subout /*verilator public_flat_rd*/ ); endmodule : sub verilator-3.874/test_regress/t/t_preproc_undefineall.v0000664000177100017500000000073212473477707023255 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; `define UDALL `ifndef PREDEF_COMMAND_LINE `error "Test setup error, PREDEF_COMMAND_LINE pre-missing" `endif `undefineall `ifdef UDALL `error "undefineall failed" `endif `ifndef PREDEF_COMMAND_LINE `error "Deleted too much, no PREDEF_COMMAND_LINE" `endif initial begin $finish; end endmodule verilator-3.874/test_regress/t/t_vpi_memory.pl0000775000177100017500000000135412473477707021575 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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. compile ( make_top_shell => 0, make_main => 0, make_pli => 1, iv_flags2 => ["-g2005-sv -D USE_VPI_NOT_DPI"], v_flags2 => ["+define+USE_VPI_NOT_DPI"], verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --no-l2name $Self->{t_dir}/t_vpi_memory.cpp"], ); execute ( iv_pli => 1, check_finished=>1 ); ok(1); 1; verilator-3.874/test_regress/t/t_math_signed_wire.pl0000775000177100017500000000072212473477707022715 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_cat_reopen_0100.out0000664000177100017500000000510212473477707023530 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Sat Feb 23 20:40:11 2013 $end $timescale 1ns $end $scope module top $end $var wire 1 $ clk $end $scope module v $end $var wire 1 $ clk $end $var wire 32 # cyc [31:0] $end $upscope $end $upscope $end $enddefinitions $end #100 b00000000000000000000000000110011 # 1$ #101 0$ #102 b00000000000000000000000000110100 # 1$ #103 0$ #104 b00000000000000000000000000110101 # 1$ #105 0$ #106 b00000000000000000000000000110110 # 1$ #107 0$ #108 b00000000000000000000000000110111 # 1$ #109 0$ #110 b00000000000000000000000000111000 # 1$ #111 0$ #112 b00000000000000000000000000111001 # 1$ #113 0$ #114 b00000000000000000000000000111010 # 1$ #115 0$ #116 b00000000000000000000000000111011 # 1$ #117 0$ #118 b00000000000000000000000000111100 # 1$ #119 0$ #120 b00000000000000000000000000111101 # 1$ #121 0$ #122 b00000000000000000000000000111110 # 1$ #123 0$ #124 b00000000000000000000000000111111 # 1$ #125 0$ #126 b00000000000000000000000001000000 # 1$ #127 0$ #128 b00000000000000000000000001000001 # 1$ #129 0$ #130 b00000000000000000000000001000010 # 1$ #131 0$ #132 b00000000000000000000000001000011 # 1$ #133 0$ #134 b00000000000000000000000001000100 # 1$ #135 0$ #136 b00000000000000000000000001000101 # 1$ #137 0$ #138 b00000000000000000000000001000110 # 1$ #139 0$ #140 b00000000000000000000000001000111 # 1$ #141 0$ #142 b00000000000000000000000001001000 # 1$ #143 0$ #144 b00000000000000000000000001001001 # 1$ #145 0$ #146 b00000000000000000000000001001010 # 1$ #147 0$ #148 b00000000000000000000000001001011 # 1$ #149 0$ #150 b00000000000000000000000001001100 # 1$ #151 0$ #152 b00000000000000000000000001001101 # 1$ #153 0$ #154 b00000000000000000000000001001110 # 1$ #155 0$ #156 b00000000000000000000000001001111 # 1$ #157 0$ #158 b00000000000000000000000001010000 # 1$ #159 0$ #160 b00000000000000000000000001010001 # 1$ #161 0$ #162 b00000000000000000000000001010010 # 1$ #163 0$ #164 b00000000000000000000000001010011 # 1$ #165 0$ #166 b00000000000000000000000001010100 # 1$ #167 0$ #168 b00000000000000000000000001010101 # 1$ #169 0$ #170 b00000000000000000000000001010110 # 1$ #171 0$ #172 b00000000000000000000000001010111 # 1$ #173 0$ #174 b00000000000000000000000001011000 # 1$ #175 0$ #176 b00000000000000000000000001011001 # 1$ #177 0$ #178 b00000000000000000000000001011010 # 1$ #179 0$ #180 b00000000000000000000000001011011 # 1$ #181 0$ #182 b00000000000000000000000001011100 # 1$ #183 0$ #184 b00000000000000000000000001011101 # 1$ #185 0$ #186 b00000000000000000000000001011110 # 1$ #187 0$ #188 b00000000000000000000000001011111 # 1$ #189 0$ verilator-3.874/test_regress/t/t_leak.pl0000775000177100017500000000115312473477707020320 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_missing.v0000664000177100017500000000246212473477707021541 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t; // verilator lint_off PINMISSING `ifdef T_GEN_MISSING_BAD foobar #(.FOO_TYPE(1)) foobar; // This means we should instatiate missing module `elsif T_GEN_MISSING foobar #(.FOO_TYPE(0)) foobar; // This means we should instatiate foo0 `else `error "Bad Test" `endif endmodule module foobar #( parameter FOO_START = 0, FOO_NUM = 2, FOO_TYPE = 1 ) ( input wire[FOO_NUM-1:0] foo, output wire[FOO_NUM-1:0] bar); generate begin: g genvar j; for (j = FOO_START; j < FOO_NUM+FOO_START; j = j + 1) begin: foo_inst; if (FOO_TYPE == 0) begin: foo_0 // instatiate foo0 foo0 i_foo(.x(foo[j]), .y(bar[j])); end if (FOO_TYPE == 1) begin: foo_1 // instatiate foo1 foo_not_needed i_foo(.x(foo[j]), .y(bar[j])); end end end endgenerate endmodule module foo0(input wire x, output wire y); assign y = ~x; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_array_query.pl0000775000177100017500000000072212473477707021750 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_enumeration.v0000664000177100017500000002773012473477707021572 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cnt = 0; integer mod = 0; // event counter always @ (posedge clk) if (cnt==20) begin cnt <= 0; mod <= mod + 1; end else begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if (mod==3) begin $write("*-* All Finished *-*\n"); $finish; end // anonymous type variable declaration enum logic [2:0] {red=1, orange, yellow, green, blue, indigo, violet} rainbow7; // named type typedef enum logic {OFF, ON} t_switch; t_switch switch; // numbering examples enum integer {father, mother, son[2], daughter, gerbil, dog[3]=10, cat[3:5]=20, car[3:1]=30} family; // test of raibow7 type always @ (posedge clk) if (mod==0) begin // write value to array if (cnt== 0) begin rainbow7 <= rainbow7.first(); // check number if (rainbow7.num() !== 7 ) begin $display("%d", rainbow7.num() ); $stop(); end if (rainbow7 !== 3'bxxx ) begin $display("%b", rainbow7 ); $stop(); end end else if (cnt== 1) begin if (rainbow7 !== 3'd1 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== red ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.next(); end else if (cnt== 2) begin if (rainbow7 !== 3'd2 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== orange ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.next(); end else if (cnt== 3) begin if (rainbow7 !== 3'd3 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== yellow ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.next(); end else if (cnt== 4) begin if (rainbow7 !== 3'd4 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== green ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.next(); end else if (cnt== 5) begin if (rainbow7 !== 3'd5 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== blue ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.next(); end else if (cnt== 6) begin if (rainbow7 !== 3'd6 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== indigo ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.next(); end else if (cnt== 7) begin if (rainbow7 !== 3'd7 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== violet ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.next(); end else if (cnt== 8) begin if (rainbow7 !== 3'd1 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== red ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.next(); end end else if (mod==1) begin // write value to array if (cnt== 0) begin rainbow7 <= rainbow7.last(); // check number if (rainbow7.num() !== 7 ) begin $display("%d", rainbow7.num() ); $stop(); end end else if (cnt== 1) begin if (rainbow7 !== 3'd7 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== violet ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.prev(); end else if (cnt== 2) begin if (rainbow7 !== 3'd6 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== indigo ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.prev(); end else if (cnt== 3) begin if (rainbow7 !== 3'd5 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== blue ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.prev(); end else if (cnt== 4) begin if (rainbow7 !== 3'd4 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== green ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.prev(); end else if (cnt== 5) begin if (rainbow7 !== 3'd3 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== yellow ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.prev(); end else if (cnt== 6) begin if (rainbow7 !== 3'd2 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== orange ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.prev(); end else if (cnt== 7) begin if (rainbow7 !== 3'd1 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== red ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.prev(); end else if (cnt== 8) begin if (rainbow7 !== 3'd7 ) begin $display("%b", rainbow7 ); $stop(); end if (rainbow7 !== violet ) begin $display("%b", rainbow7 ); $stop(); end rainbow7 <= rainbow7.prev(); end end // test of t_switch type always @ (posedge clk) if (mod==0) begin // write value to array if (cnt== 0) begin switch <= switch.first(); // check number if (switch.num() !== 2 ) begin $display("%d", switch.num() ); $stop(); end if (switch !== 1'bx) begin $display("%b", switch ); $stop(); end end else if (cnt== 1) begin if (switch !== 1'b0) begin $display("%b", switch ); $stop(); end if (switch !== OFF ) begin $display("%b", switch ); $stop(); end switch <= switch.next(); end else if (cnt== 2) begin if (switch !== 1'b1) begin $display("%b", switch ); $stop(); end if (switch !== ON ) begin $display("%b", switch ); $stop(); end switch <= switch.next(); end else if (cnt== 3) begin if (switch !== 1'b0) begin $display("%b", switch ); $stop(); end if (switch !== OFF ) begin $display("%b", switch ); $stop(); end switch <= switch.next(); end end else if (mod==1) begin // write value to array if (cnt== 0) begin rainbow7 <= rainbow7.last(); // check number if (switch.num() !== 2 ) begin $display("%d", switch.num() ); $stop(); end end else if (cnt== 1) begin if (switch !== 1'b1) begin $display("%b", switch ); $stop(); end if (switch !== ON ) begin $display("%b", switch ); $stop(); end switch <= switch.prev(); end else if (cnt== 2) begin if (switch !== 1'b0) begin $display("%b", switch ); $stop(); end if (switch !== OFF ) begin $display("%b", switch ); $stop(); end switch <= switch.prev(); end else if (cnt== 3) begin if (switch !== 1'b1) begin $display("%b", switch ); $stop(); end if (switch !== ON ) begin $display("%b", switch ); $stop(); end switch <= switch.prev(); end end // test of raibow7 type always @ (posedge clk) if (mod==0) begin // write value to array if (cnt== 0) begin family <= family.first(); // check number if (family.num() !== 15 ) begin $display("%d", family.num() ); $stop(); end if (family !== 32'dx ) begin $display("%b", family ); $stop(); end end else if (cnt== 1) begin if (family !== 0 ) begin $display("%b", family ); $stop(); end if (family !== father ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 2) begin if (family !== 1 ) begin $display("%b", family ); $stop(); end if (family !== mother ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 3) begin if (family !== 2 ) begin $display("%b", family ); $stop(); end if (family !== son0 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 4) begin if (family !== 3 ) begin $display("%b", family ); $stop(); end if (family !== son1 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 5) begin if (family !== 4 ) begin $display("%b", family ); $stop(); end if (family !== daughter ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 6) begin if (family !== 5 ) begin $display("%b", family ); $stop(); end if (family !== gerbil ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 7) begin if (family !== 10 ) begin $display("%b", family ); $stop(); end if (family !== dog0 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 8) begin if (family !== 11 ) begin $display("%b", family ); $stop(); end if (family !== dog1 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 9) begin if (family !== 12 ) begin $display("%b", family ); $stop(); end if (family !== dog2 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 10) begin if (family !== 20 ) begin $display("%b", family ); $stop(); end if (family !== cat3 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 11) begin if (family !== 21 ) begin $display("%b", family ); $stop(); end if (family !== cat4 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 12) begin if (family !== 22 ) begin $display("%b", family ); $stop(); end if (family !== cat5 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 13) begin if (family !== 30 ) begin $display("%b", family ); $stop(); end if (family !== car3 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 14) begin if (family !== 31 ) begin $display("%b", family ); $stop(); end if (family !== car2 ) begin $display("%b", family ); $stop(); end family <= family.next(); end else if (cnt== 15) begin if (family !== 32 ) begin $display("%b", family ); $stop(); end if (family !== car1 ) begin $display("%b", family ); $stop(); end family <= family.next(); end end endmodule verilator-3.874/test_regress/t/t_dpi_dup_bad.pl0000775000177100017500000000143612473477707021642 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Error: t/t_dpi_dup_bad.v:\d+: Duplicate declaration of DPI function with different formal arguments: v.oth_f_int2 %Error: t/t_dpi_dup_bad.v:\d+: ... New prototype: pure int dpii_fa_bit \(int, int\) %Error: t/t_dpi_dup_bad.v:\d+: ... Original prototype: int dpii_fa_bit \(int\) %Error: Exiting due to .*' ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_dpulse.pl0000775000177100017500000000071712473477707021536 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_export.v0000664000177100017500000000444412473477707021416 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. module t; sub a (.inst(1)); sub b (.inst(2)); // Returns integer line number, or -1 for all ok import "DPI-C" context function int dpix_run_tests(); export "DPI-C" task dpix_t_int; task dpix_t_int(input int i, output int o); o = ~i; endtask export "DPI-C" dpix_t_renamed = task dpix_t_ren; task dpix_t_ren(input int i, output int o); o = i+2; endtask export "DPI-C" function dpix_int123; function int dpix_int123(); dpix_int123 = 32'h123; endfunction export "DPI-C" function dpix_f_bit; export "DPI-C" function dpix_f_bit15; export "DPI-C" function dpix_f_int; export "DPI-C" function dpix_f_byte; export "DPI-C" function dpix_f_shortint; export "DPI-C" function dpix_f_longint; export "DPI-C" function dpix_f_chandle; function bit dpix_f_bit (bit i); dpix_f_bit = ~i; endfunction function bit [14:0] dpix_f_bit15 (bit [14:0] i); dpix_f_bit15 = ~i; endfunction function int dpix_f_int (int i); dpix_f_int = ~i; endfunction function byte dpix_f_byte (byte i); dpix_f_byte = ~i; endfunction function shortint dpix_f_shortint(shortint i); dpix_f_shortint = ~i; endfunction function longint dpix_f_longint (longint i); dpix_f_longint = ~i; endfunction function chandle dpix_f_chandle (chandle i); dpix_f_chandle = i; endfunction export "DPI-C" task dpix_t_bit95; task dpix_t_bit95(input bit [94:0] i, output bit [94:0] o); o = ~i; endtask export "DPI-C" task dpix_t_bit96; task dpix_t_bit96(input bit [95:0] i, output bit [95:0] o); o = ~i; endtask int lineno; initial begin lineno = dpix_run_tests(); if (lineno != -1) begin $display("[%0t] %%Error: t_dpix_ort_c.c:%0d: dpix_run_tests returned an error", $time, lineno); $stop; end $write("*-* All Finished *-*\n"); $finish; end endmodule module sub (input int inst); export "DPI-C" function dpix_sub_inst; function int dpix_sub_inst (int i); dpix_sub_inst = inst + i; endfunction endmodule verilator-3.874/test_regress/t/t_math_pow.v0000664000177100017500000000472412473477707021060 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. `ifdef VERILATOR `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) `else `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); end while(0) `endif module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [60:0] p; reg [60:0] a; reg [20:0] b; reg [60:0] shifted; always @* begin p = a[60:0] ** b[20:0]; shifted = 2 ** b[20:0]; end integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("%0x %x %x\n", cyc, p, shifted); `endif // Constant versions `checkh(61'h1 ** 21'h31, 61'h1); `checkh(61'h2 ** 21'h10, 61'h10000); `checkh(61'd10 ** 21'h3, 61'h3e8); `checkh(61'h3 ** 21'h7, 61'h88b); `ifndef VCS `checkh(61'h7ab3811219 ** 21'ha6e30, 61'h01ea58c703687e81); `endif if (cyc==1) begin a <= 61'h0; b <= 21'h0; end if (cyc==2) begin a <= 61'h0; b <= 21'h3; end if (cyc==3) begin a <= 61'h1; b <= 21'h31; end if (cyc==4) begin a <= 61'h2; b <= 21'h10; end if (cyc==5) begin a <= 61'd10; b <= 21'd3; end if (cyc==6) begin a <= 61'd3; b <= 21'd7; end if (cyc==7) begin a <= 61'h7ab3811219; b <= 21'ha6e30; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end case (cyc) 32'd00: ; 32'd01: ; 32'd02: ; // 0^x is indeterminate 32'd03: ; // 0^x is indeterminate 32'd04: `checkh(p, 61'h1); 32'd05: `checkh(p, 61'h10000); 32'd06: `checkh(p, 61'h3e8); 32'd07: `checkh(p, 61'h88b); 32'd08: `checkh(p, 61'h01ea58c703687e81); 32'd09: `checkh(p, 61'h01ea58c703687e81); default: $stop; endcase case (cyc) 32'd00: ; 32'd01: ; 32'd02: `checkh(shifted, 61'h0000000000000001); 32'd03: `checkh(shifted, 61'h0000000000000008); 32'd04: `checkh(shifted, 61'h0002000000000000); 32'd05: `checkh(shifted, 61'h0000000000010000); 32'd06: `checkh(shifted, 61'h0000000000000008); 32'd07: `checkh(shifted, 61'h0000000000000080); 32'd08: `checkh(shifted, 61'h0000000000000000); 32'd09: `checkh(shifted, 61'h0000000000000000); default: $stop; endcase end endmodule verilator-3.874/test_regress/t/t_select_lhs_oob.v0000664000177100017500000000410712473477707022221 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [6:0] mem1d; reg [6:0] mem2d [5:0]; reg [6:0] mem3d [4:0][5:0]; integer i,j,k; // Four different test cases for out of bounds // = // <= // Continuous assigns // Output pin interconnect (also covers cont assigns) // Each with both bit selects and array selects initial begin mem1d[0] = 1'b0; i=7; mem1d[i] = 1'b1; if (mem1d[0] !== 1'b0) $stop; // for (i=0; i<8; i=i+1) begin for (j=0; j<8; j=j+1) begin for (k=0; k<8; k=k+1) begin mem1d[k] = k[0]; mem2d[j][k] = j[0]+k[0]; mem3d[i][j][k] = i[0]+j[0]+k[0]; end end end for (i=0; i<5; i=i+1) begin for (j=0; j<6; j=j+1) begin for (k=0; k<7; k=k+1) begin if (mem1d[k] !== k[0]) $stop; if (mem2d[j][k] !== j[0]+k[0]) $stop; if (mem3d[i][j][k] !== i[0]+j[0]+k[0]) $stop; end end end end integer wi; wire [31:0] wd = cyc; reg [31:0] reg2d[6:0]; always @ (posedge clk) reg2d[wi[2:0]] <= wd; always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d reg2d[%0d]=%0x wd=%0x\n",$time, cyc, wi[2:0], reg2d[wi[2:0]], wd); `endif cyc <= cyc + 1; if (cyc<10) begin wi <= 0; end else if (cyc==10) begin wi <= 1; end else if (cyc==11) begin if (reg2d[0] !== 10) $stop; wi <= 6; end else if (cyc==12) begin if (reg2d[0] !== 10) $stop; if (reg2d[1] !== 11) $stop; wi <= 7; // Will be ignored end else if (cyc==13) begin if (reg2d[0] !== 10) $stop; if (reg2d[1] !== 11) $stop; if (reg2d[6] !== 12) $stop; end else if (cyc==14) begin if (reg2d[0] !== 10) $stop; if (reg2d[1] !== 11) $stop; if (reg2d[6] !== 12) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_order_2d.v0000664000177100017500000000371612525171734020727 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire input_signal = crc[0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire output_signal; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .output_signal (output_signal), // Inputs .input_signal (input_signal)); // Aggregate outputs into a single result vector wire [63:0] result = {63'h0, output_signal}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h765b2e12b25ec97b if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( input input_signal, output output_signal ); // bug872 // verilator lint_off UNOPTFLAT wire some_signal[1:0][1:0]; assign some_signal[0][0] = input_signal; assign some_signal[0][1] = some_signal[0][0]; assign some_signal[1][0] = some_signal[0][1]; assign some_signal[1][1] = some_signal[1][0]; assign output_signal = some_signal[1][1]; endmodule verilator-3.874/test_regress/t/t_select_bad_range3.pl0000775000177100017500000000117512525171734022721 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Warning-SELRANGE: t/t_select_bad_range3.v:\d+: Selection index out of range: 13 outside 12:10 %Warning-SELRANGE: Use .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_real.v0000664000177100017500000001003112525171734021147 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2011 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. `define is_near_real(a,b) ($abs((a)-(b)) < (((a)/(b))*0.0001)) module t (/*AUTOARG*/ // Inputs clk ); input clk; integer i; reg [63:0] b; real r, r2; integer cyc=0; realtime uninit; initial if (uninit != 0.0) $stop; sub_cast_bug374 sub (.cyc5(cyc[4:0]), .*); initial begin if (1_00_0.0_1 != 1000.01) $stop; // rtoi truncates if ($rtoi(36.7) != 36) $stop; if ($rtoi(36.5) != 36) $stop; if ($rtoi(36.4) != 36) $stop; // casting rounds if ((integer '(36.7)) != 37) $stop; if ((integer '(36.5)) != 37) $stop; if ((integer '(36.4)) != 36) $stop; // assignment rounds // verilator lint_off REALCVT i = 36.7; if (i != 37) $stop; i = 36.5; if (i != 37) $stop; i = 36.4; if (i != 36) $stop; r = 10'd38; if (r!=38.0) $stop; // verilator lint_on REALCVT // operators if ((-(1.5)) != -1.5) $stop; if ((+(1.5)) != 1.5) $stop; if (((1.5)+(1.25)) != 2.75) $stop; if (((1.5)-(1.25)) != 0.25) $stop; if (((1.5)*(1.25)) != 1.875) $stop; if (((1.5)/(1.25)) != 1.2) $stop; // if (((1.5)==(2)) != 1'b0) $stop; // note 2 becomes real 2.0 if (((1.5)!=(2)) != 1'b1) $stop; if (((1.5)> (2)) != 1'b0) $stop; if (((1.5)>=(2)) != 1'b0) $stop; if (((1.5)< (2)) != 1'b1) $stop; if (((1.5)<=(2)) != 1'b1) $stop; if (((1.5)==(1.5)) != 1'b1) $stop; if (((1.5)!=(1.5)) != 1'b0) $stop; if (((1.5)> (1.5)) != 1'b0) $stop; if (((1.5)>=(1.5)) != 1'b1) $stop; if (((1.5)< (1.5)) != 1'b0) $stop; if (((1.5)<=(1.5)) != 1'b1) $stop; if (((1.6)==(1.5)) != 1'b0) $stop; if (((1.6)!=(1.5)) != 1'b1) $stop; if (((1.6)> (1.5)) != 1'b1) $stop; if (((1.6)>=(1.5)) != 1'b1) $stop; if (((1.6)< (1.5)) != 1'b0) $stop; if (((1.6)<=(1.5)) != 1'b0) $stop; // if (((0.0)?(2.0):(1.1)) != 1.1) $stop; if (((1.5)?(2.0):(1.1)) != 2.0) $stop; // if (!1.7) $stop; if (!(!0.0)) $stop; if (1.8 && 0.0) $stop; if (!(1.8 || 0.0)) $stop; // i=0; for (r=1.0; r<2.0; r=r+0.1) i++; if (i!=10) $stop; end // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; if (cyc==0) begin // Setup end else if (cyc<90) begin if ($time != {32'h0, $rtoi($realtime)}) $stop; if ($itor(cyc) != cyc) $stop; //Unsup: if ((real `($time)) != $realtime) $stop; r = $itor(cyc*2); i = $rtoi(r); if (i!=cyc*2) $stop; // r = $itor(cyc)/1.5; b = $realtobits(r); r2 = $bitstoreal(b); if (r != r2) $stop; // // Trust the integer math as a comparison r = $itor(cyc); if ($rtoi(-r) != -cyc) $stop; if ($rtoi(+r) != cyc) $stop; if ($rtoi(r+2.0) != (cyc+2)) $stop; if ($rtoi(r-2.0) != (cyc-2)) $stop; if ($rtoi(r*2.0) != (cyc*2)) $stop; if ($rtoi(r/2.0) != (cyc/2)) $stop; r2 = (2.0/(r-60)); // When zero, result indeterminate, but no crash // r2 = $itor(cyc); case (r) (r2-1.0): $stop; r2: ; default: $stop; endcase // r = $itor(cyc); if ((r==50.0) != (cyc==50)) $stop; if ((r!=50.0) != (cyc!=50)) $stop; if ((r> 50.0) != (cyc> 50)) $stop; if ((r>=50.0) != (cyc>=50)) $stop; if ((r< 50.0) != (cyc< 50)) $stop; if ((r<=50.0) != (cyc<=50)) $stop; // if ($rtoi((r-50.0) ? 10.0 : 20.0) != (((cyc-50)!=0) ? 10 : 20)) $stop; // if ((!(r-50.0)) != (!((cyc-50) != 0))) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub_cast_bug374(input clk, input [4:0] cyc5); integer i; always @(posedge clk) begin i <= integer'(cyc5); end endmodule verilator-3.874/test_regress/t/t_case_genx_bad.pl0000775000177100017500000000117012473477707022145 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_case_genx_bad.v:\d+: Use of x/\? constant in generate case statement, \(no such thing as \'generate casez\'\) %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_pullup.pl0000775000177100017500000000116512473477707021606 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_assign.pl0000775000177100017500000000074112473477707021523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( ); ok(1); 1; verilator-3.874/test_regress/t/t_const_dec_mixed_bad.pl0000775000177100017500000000114212473477707023337 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_const_dec_mixed_bad.v:\d+: Mixing X/Z/\? with digits not legal in decimal constant: x_1 %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_param_concat_bad.pl0000775000177100017500000000150512473477707022642 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_param_concat.v"); compile ( fails=>1, expect=> '%Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in concatenations. %Warning-WIDTHCONCAT: Use "/\* verilator lint_off WIDTHCONCAT \*/" and lint_on around source to disable this message. %Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in replications. .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_gate_implicit.v0000664000177100017500000000343712473477707022054 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire RBL2; // From t of Test.v // End of automatics wire RWL1 = crc[2]; wire RWL2 = crc[3]; Test t (/*AUTOINST*/ // Outputs .RBL2 (RBL2), // Inputs .RWL1 (RWL1), .RWL2 (RWL2)); // Aggregate outputs into a single result vector wire [63:0] result = {63'h0, RBL2}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hb6d6b86aa20a882a if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( output RBL2, input RWL1, RWL2); // verilator lint_off IMPLICIT not I1 (RWL2_n, RWL2); bufif1 I2 (RBL2, n3, 1'b1); Mxor I3 (n3, RWL1, RWL2_n); // verilator lint_on IMPLICIT endmodule module Mxor (output out, input a, b); assign out = (a ^ b); endmodule verilator-3.874/test_regress/t/t_var_assign_landr.v0000664000177100017500000000472612473477707022560 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Use this file as a template for submitting bugs, etc. // This module takes a single clock input, and should either // $write("*-* All Finished *-*\n"); // $finish; // on success, or $stop. // // The code as shown applies a random vector to the Test // module, then calculates a CRC on the Test module's outputs. // // **If you do not wish for your code to be released to the public // please note it here, otherwise:** // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by ____YOUR_NAME_HERE____. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [255:0] sum; // Take CRC data and apply to testblock inputs wire [127:0] in = {~crc[63:0], crc[63:0]}; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [127:0] o1; // From test of Test.v wire [127:0] o2; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .o1 (o1[127:0]), .o2 (o2[127:0]), // Inputs .in (in[127:0])); // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x %x\n",$time, cyc, crc, o1, o2); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= {o1,o2} ^ {sum[254:0],sum[255]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 256'h008a080aaa000000140550404115dc7b008a080aaae7c8cd897bc1ca49c9350a if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs o1, o2, // Inputs in ); input [127:0] in; output logic [127:0] o1; output logic [127:0] o2; always_comb begin: b_test logic [127:0] tmpp; logic [127:0] tmp; tmp = '0; tmpp = '0; tmp[63:0] = in[63:0]; tmpp[63:0] = in[63:0]; tmpp[63:0] = {tmp[0+:32], tmp[32+:32]}; tmp[63:0] = {tmp[0+:32], tmp[32+:32]}; o1 = tmp; o2 = tmpp; end endmodule verilator-3.874/test_regress/t/t_dedupe_clk_gate.v0000664000177100017500000000256312473477707022340 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Dedupe optimization test. // // This file ONLY is placed into the Public Domain, for any use, // without warranty. // Contributed 2012 by Varun Koyyalagunta, Centaur Technology. module t(res,d,clk,en); output res; input d,en,clk; wire q0,q1,q2,q3; flop_gated_latch f0(q0,d,clk,en); flop_gated_latch f1(q1,d,clk,en); flop_gated_flop f2(q2,d,clk,en); flop_gated_flop f3(q3,d,clk,en); assign res = (q0 + q1) * (q2 - q3); endmodule module flop_gated_latch(q,d,clk,en); input d, clk, en; output q; wire gated_clock; clock_gate_latch clock_gate(gated_clock, clk, en); always @(posedge gated_clock) begin q <= d; end endmodule module flop_gated_flop(q,d,clk,en); input d, clk, en; output q; wire gated_clock; clock_gate_flop clock_gate(gated_clock, clk, en); always @(posedge gated_clock) begin q <= d; end endmodule module clock_gate_latch (gated_clk, clk, clken); output gated_clk; input clk, clken; reg clken_latched /*verilator clock_enable*/; assign gated_clk = clk & clken_latched ; wire clkb = ~clk; always @(clkb or clken) if(clkb) clken_latched = clken; endmodule module clock_gate_flop (gated_clk, clk, clken); output gated_clk; input clk, clken; reg clken_r /*verilator clock_enable*/; assign gated_clk = clk & clken_r ; always @(negedge clk) clken_r <= clken; endmodule verilator-3.874/test_regress/t/t_select_lhs_oob2.v0000664000177100017500000000621512473477707022305 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [63:0] out; // From test of Test.v // End of automatics wire reset_l = ~(cyc<15); wire [63:0] d = crc[63:0]; wire [8:0] t_wa = crc[8:0]; wire [8:0] t_addr = {crc[18:17],3'b0,crc[13:10]}; Test test (/*AUTOINST*/ // Outputs .out (out[63:0]), // Inputs .clk (clk), .reset_l (reset_l), .t_wa (t_wa[8:0]), .d (d[63:0]), .t_addr (t_addr[8:0])); // Aggregate outputs into a single result vector wire [63:0] result = {out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h421a41d1541ea652 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, reset_l, t_wa, d, t_addr ); input clk; input reset_l; reg [63:0] m_w0 [47:0]; reg [63:0] m_w1 [23:0]; reg [63:0] m_w2 [23:0]; reg [63:0] m_w3 [23:0]; reg [63:0] m_w4 [23:0]; reg [63:0] m_w5 [23:0]; input [8:0] t_wa; input [63:0] d; always @ (posedge clk) begin if (~reset_l) begin : blk integer i; for (i=0; i<48; i=i+1) begin m_w0[i] <= 64'h0; end for (i=0; i<24; i=i+1) begin m_w1[i] <= 64'h0; m_w2[i] <= 64'h0; m_w3[i] <= 64'h0; m_w4[i] <= 64'h0; m_w5[i] <= 64'h0; end end else begin casez (t_wa[8:6]) 3'd0: m_w0[t_wa[5:0]] <= d; 3'd1: m_w1[t_wa[4:0]] <= d; 3'd2: m_w2[t_wa[4:0]] <= d; 3'd3: m_w3[t_wa[4:0]] <= d; 3'd4: m_w4[t_wa[4:0]] <= d; default: m_w5[t_wa[4:0]] <= d; endcase end end input [8:0] t_addr; wire [63:0] t_w0 = m_w0[t_addr[5:0]]; wire [63:0] t_w1 = m_w1[t_addr[4:0]]; wire [63:0] t_w2 = m_w2[t_addr[4:0]]; wire [63:0] t_w3 = m_w3[t_addr[4:0]]; wire [63:0] t_w4 = m_w4[t_addr[4:0]]; wire [63:0] t_w5 = m_w5[t_addr[4:0]]; output reg [63:0] out; always @* begin casez (t_addr[8:6]) 3'd0: out = t_w0; 3'd1: out = t_w1; 3'd2: out = t_w2; 3'd3: out = t_w3; 3'd4: out = t_w4; default: out = t_w5; endcase end endmodule verilator-3.874/test_regress/t/t_flag_define.v0000664000177100017500000000232612473477707021461 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder `define STRINGIFY(x) `"x`" module t; initial begin `ifdef D1A if (`STRINGIFY(`D4B) !== "") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D2A if (`STRINGIFY(`D2A) !== "VALA") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D3A if (`STRINGIFY(`D4B) !== "") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D3B if (`STRINGIFY(`D4B) !== "") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D4A if (`STRINGIFY(`D4A) !== "VALA") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D4B if (`STRINGIFY(`D4B) !== "") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D5A if (`STRINGIFY(`D5A) !== "VALA") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif `ifdef D5A if (`STRINGIFY(`D5B) !== "VALB") $stop; `else $write("%%Error: Missing define\n"); $stop; `endif $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_var_dotted_inl2.pl0000775000177100017500000000104212473477707022460 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_var_dotted.v"); compile ( v_flags2 => ['+define+USE_INLINE_MID',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_bind2.v0000664000177100017500000000407312473477707020235 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Ed Lander. // verilator lint_off WIDTH `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [7:0] p1; reg [7:0] p2; reg [7:0] p3; initial begin p1 = 8'h01; p2 = 8'h02; p3 = 8'h03; end parameter int param1 = 8'h11; parameter int param2 = 8'h12; parameter int param3 = 8'h13; targetmod i_targetmod (/*AUTOINST*/ // Inputs .clk (clk)); //Binding i_targetmod to mycheck --instantiates i_mycheck inside i_targetmod //param1 not over-riden (as mycheck) (=> 0x31) //param2 explicitly bound to targetmod value (=> 0x22) //param3 explicitly bound to top value (=> 0x13) //p1 implictly bound (.*), takes value from targetmod (=> 0x04) //p2 explictly bound to targetmod (=> 0x05) //p3 explictly bound to top (=> 0x03) // Alternative unsupported form is i_targetmod bind targetmod mycheck #( .param2(param2), .param3(param3) ) i_mycheck (.p2(p2), .p3(p3), .*); endmodule module targetmod (input clk); reg [7:0] p1; reg [7:0] p2; reg [7:0] p3; parameter int param1 = 8'h21; parameter int param2 = 8'h22; parameter int param3 = 8'h23; initial begin p1 = 8'h04; p2 = 8'h05; p3 = 8'h06; end endmodule module mycheck (/*AUTOARG*/ // Inputs clk, p1, p2, p3 ); input clk; input [7:0] p1; input [7:0] p2; input [7:0] p3; parameter int param1 = 8'h31; parameter int param2 = 8'h32; parameter int param3 = 8'h33; always @ (posedge clk) begin `checkh(param1,8'h31); `checkh(param2,8'h22); `checkh(param3,8'h23); `checkh(p1,8'h04); `checkh(p2,8'h05); `checkh(p3,8'h06); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_interface_down_inla.pl0000775000177100017500000000110312473477707023371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_A'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_powerdn.pl0000775000177100017500000000072212473477707021714 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished => 1 ); ok(1); 1; verilator-3.874/test_regress/t/t_order_clkinst.pl0000775000177100017500000000105112473477707022243 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/); compile ( ); execute ( check_finished => !$fail, fails => $fail, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_multidim.pl0000775000177100017500000000071712473477707022073 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_pipe_exit_bad.pl0000775000177100017500000000146512473477707022206 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010-2011 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->skip("Verilator only test") if !$Self->{vlt}; top_filename("t/t_pipe_filter.v"); compile ( verilator_flags2 => ['-E --pipe-filter \'perl t/t_pipe_exit_bad.pf\' '], verilator_make_gcc=>0, stdout_filename => $stdout_filename, fails=>1, expect=> '%Error: t_pipe_exit_bad.pf: Intentional bad exit status... %Error: File not found: t/t_pipe_filter.v %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_strwidth.pl0000775000177100017500000000074612473477707022274 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( v_flags2 => [], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_const_part.v0000664000177100017500000000120112525172076022546 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Wilson Snyder. module t; function integer bottom_4bits; input [7:0] i; bottom_4bits = 0; bottom_4bits[3:0] = i[3:0]; endfunction function integer bottom_2_unknown; input [7:0] i; // bottom_4bits = 0; 'x bottom_2_unknown[1:0] = i[1:0]; endfunction localparam p = bottom_4bits(8'h13); localparam bu = bottom_2_unknown(8'h13); initial begin if (p != 3) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_xml_first.v0000664000177100017500000000145312473477707021245 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs q, // Inputs clk, d ); input clk; input [3:0] d; output wire [3:0] q; logic [3:0] between; mod1 cell1 (.q(between), /*AUTOINST*/ // Inputs .clk (clk), .d (d[3:0])); mod2 cell2 (.d(between), /*AUTOINST*/ // Outputs .q (q[3:0]), // Inputs .clk (clk)); endmodule module mod1 ( input clk, input [3:0] d, output logic [3:0] q ); always @(posedge clk) q <= d; endmodule module mod2 ( input clk, input [3:0] d, output wire [3:0] q ); assign q = d; endmodule verilator-3.874/test_regress/t/t_flag_define.pl0000775000177100017500000000077512473477707021640 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. compile ( v_flags2 => ["-f t/t_flag_define.vc"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_for_init_bug.v0000664000177100017500000000137612473477707021710 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs priority_mask, // Inputs muxed_requests ); parameter ARW = 7; // verilator lint_off UNOPTFLAT integer i,j; output reg [ARW-1:0] priority_mask; input [ARW-1:0] muxed_requests; always @* begin for (i=ARW-1;i>0;i=i-1) begin priority_mask[i]=1'b0; // vvvv=== note j=j not j=i; was bug for( j=j;j>=0;j=j-1) priority_mask[i]=priority_mask[j] | muxed_requests[j]; end //Bit zero is always enabled priority_mask[0]=1'b0; end endmodule // Local Variables: // verilog-auto-inst-param-value: t // End: verilator-3.874/test_regress/t/t_lint_input_eq_bad.pl0000775000177100017500000000132412473477707023064 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Error: t/t_lint_input_eq_bad.v:\d+: Unsupported: Default value on module input: i2 %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_dos.v0000775000177100017500000000066512473477707020032 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. // This file has DOS carrage returns in it! module t (/*AUTOARG*/ // Inputs clk ); input clk; always @ (posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule // This file has DOS carrage returns in it! verilator-3.874/test_regress/t/t_var_bad_sv.v0000664000177100017500000000032612473477707021342 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; reg do; mod mod (.do(bar)); endmodule verilator-3.874/test_regress/t/t_inst_tree_inl1_pub0.pl0000775000177100017500000000112712473477707023252 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_tree.v"); compile ( v_flags2 => ['+define+USE_INLINE', '+define+NOUSE_PUBLIC'], ); execute ( check_finished=>1, expect=> '\] (%m|.*v\.ps): Clocked ', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_signed4.pl0000775000177100017500000000072212473477707021753 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_ldflags.v0000664000177100017500000000123712473477707021643 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2010 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. import "DPI-C" pure function void dpii_a_library(); import "DPI-C" pure function void dpii_c_library(); import "DPI-C" pure function void dpii_so_library(); module t (); initial begin dpii_a_library(); // From .a file dpii_c_library(); // From .cpp file dpii_so_library(); // From .so file $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_order_multialways.v0000664000177100017500000000234612473477707023006 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [31:0] in_a; reg [31:0] in_b; reg [31:0] e,f,g,h; always @ (/*AS*/in_a) begin e = in_a; f = {e[15:0], e[31:16]}; g = {f[15:0], f[31:16]}; h = {g[15:0], g[31:16]}; end // verilator lint_off UNOPTFLAT reg [31:0] e2,f2,g2,h2; always @ (/*AS*/f2) begin h2 = {g2[15:0], g2[31:16]}; g2 = {f2[15:0], f2[31:16]}; end always @ (/*AS*/in_a) begin f2 = {e2[15:0], e2[31:16]}; e2 = in_a; end // verilator lint_on UNOPTFLAT integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; //$write("%d %x %x\n", cyc, h, h2); if (h != h2) $stop; if (cyc==1) begin in_a <= 32'h89a14fab; in_b <= 32'h7ab512fa; end if (cyc==2) begin in_a <= 32'hf4c11a42; in_b <= 32'h359967c6; if (h != 32'h4fab89a1) $stop; end if (cyc==3) begin if (h != 32'h1a42f4c1) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_param_first.v0000664000177100017500000001073412473477707021547 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t(/*AUTOARG*/ // Inputs clk ); input clk; reg _ranit; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [4:0] par1; // From a1 of t_param_first_a.v wire [4:0] par2; // From a2 of t_param_first_a.v wire [4:0] par3; // From a3 of t_param_first_a.v wire [4:0] par4; // From a4 of t_param_first_a.v wire [1:0] varwidth1; // From a1 of t_param_first_a.v wire [2:0] varwidth2; // From a2 of t_param_first_a.v wire [3:0] varwidth3; // From a3 of t_param_first_a.v wire [3:0] varwidth4; // From a4 of t_param_first_a.v // End of automatics /*t_param_first_a AUTO_TEMPLATE ( .par (par@[])); .varwidth (varwidth@[])); */ parameter XX = 2'bXX; parameter THREE = 3; t_param_first_a #(1,5) a1 ( // Outputs .varwidth (varwidth1[1:0]), /*AUTOINST*/ // Outputs .par (par1[4:0])); // Templated t_param_first_a #(2,5) a2 ( // Outputs .varwidth (varwidth2[2:0]), /*AUTOINST*/ // Outputs .par (par2[4:0])); // Templated t_param_first_a #(THREE,5) a3 ( // Outputs .varwidth (varwidth3[3:0]), /*AUTOINST*/ // Outputs .par (par3[4:0])); // Templated t_param_first_a #(THREE,5) a4 ( // Outputs .varwidth (varwidth4[3:0]), /*AUTOINST*/ // Outputs .par (par4[4:0])); // Templated parameter THREE_BITS_WIDE = 3'b011; parameter THREE_2WIDE = 2'b11; parameter ALSO_THREE_WIDE = THREE_BITS_WIDE; parameter THREEPP_32_WIDE = 2*8*2+3; parameter THREEPP_3_WIDE = 3'd4*3'd4*3'd2+3'd3; // Yes folks VCS says 3 bits wide // Width propagation doesn't care about LHS vs RHS // But the width of a RHS/LHS on a upper node does affect lower nodes; // Thus must double-descend in width analysis. // VCS 7.0.1 is broken on this test! parameter T10 = (3'h7+3'h7)+4'h0; //initial if (T10!==4'd14) $stop; parameter T11 = 4'h0+(3'h7+3'h7); //initial if (T11!==4'd14) $stop; // Parameters assign LHS is affectively width zero. parameter T12 = THREE_2WIDE + THREE_2WIDE; initial if (T12!==2'd2) $stop; parameter T13 = THREE_2WIDE + 3; initial if (T13!==32'd6) $stop; // Must be careful about LSB's with extracts parameter [39:8] T14 = 32'h00_1234_56; initial if (T14[24:16]!==9'h34) $stop; // parameter THREEPP_32P_WIDE = 3'd4*3'd4*2+3'd3; parameter THREE_32_WIDE = 3%32; parameter THIRTYTWO = 2; // Param is 32 bits parameter [40:0] WIDEPARAM = 41'h12_3456789a; parameter [40:0] WIDEPARAM2 = WIDEPARAM; reg [7:0] eightb; reg [3:0] fourb; wire [7:0] eight = 8'b00010000; wire [1:0] eight2two = eight[THREE_32_WIDE+1:THREE_32_WIDE]; wire [2:0] threebits = ALSO_THREE_WIDE; // surefire lint_off CWCCXX initial _ranit = 0; always @ (posedge clk) begin if (!_ranit) begin _ranit <= 1; $write("[%0t] t_param: Running\n", $time); // $write(" %d %d %d\n", par1,par2,par3); if (par1!==5'd1) $stop; if (par2!==5'd2) $stop; if (par3!==5'd3) $stop; if (par4!==5'd3) $stop; if (varwidth1!==2'd2) $stop; if (varwidth2!==3'd2) $stop; if (varwidth3!==4'd2) $stop; if (varwidth4!==4'd2) $stop; if (threebits !== 3'b011) $stop; if (eight !== 8'b00010000) $stop; if (eight2two !== 2'b10) $stop; $write(" Params = %b %b\n %b %b\n", THREEPP_32_WIDE,THREEPP_3_WIDE, THIRTYTWO, THREEPP_32P_WIDE); if (THREEPP_32_WIDE !== 32'h23) $stop; if (THREEPP_3_WIDE !== 3'h3) $stop; if (THREEPP_32P_WIDE !== 32'h23) $stop; if (THIRTYTWO[1:0] !== 2'h2) $stop; if (THIRTYTWO !== 32'h2) $stop; if (THIRTYTWO !== 2) $stop; if ((THIRTYTWO[1:0]+2'b00) !== 2'b10) $stop; if ({1'b1,{THIRTYTWO[1:0]+2'b00}} !== 3'b110) $stop; if (XX===0 || XX===1 || XX===2 || XX===3) $stop; // Paradoxical but right, since 1'bx!=0 && !=1 // // Example of assignment LHS affecting expression widths. // verilator lint_off WIDTH // surefire lint_off ASWCMB // surefire lint_off ASWCBB eightb = (4'd8+4'd8)/4'd4; if (eightb!==8'd4) $stop; fourb = (4'd8+4'd8)/4'd4; if (fourb!==4'd0) $stop; fourb = (4'd8+8)/4'd4; if (fourb!==4'd4) $stop; // verilator lint_on WIDTH // surefire lint_on ASWCMB // surefire lint_on ASWCBB // $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_genvar_misuse_bad.v0000664000177100017500000000051312473477707022707 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. // See bug408 module top ( output logic [1:0] q, input logic [1:0] d, input logic clk ); genvar i; assign q[i] = d[i]; endmodule verilator-3.874/test_regress/t/t_var_bad_sameas.pl0000775000177100017500000000246712473477707022344 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( fails=>1, expect=> '%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has the same name as variable: varfirst %Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration %Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task has the same name as (variable|cell): varfirst %Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration %Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Variable has same name as cell: cellfirst %Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task has the same name as cell: cellfirst %Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration %Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Variable has same name as task: taskfirst %Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has the same name as task: taskfirst %Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_local.v0000664000177100017500000000116412473477707021160 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; localparam N = 31; wire [31:0] vec; generate genvar g; // bug461 begin : topgen for (g=0; g{obj_dir}/$Self->{name}.v"); # Rather then having to maintain a new .v and .out, simply add returns # to all lines of the existing t_preproc test. $Self->{golden_out} = "$Self->{obj_dir}/$Self->{name}.out"; { my $wholefile = file_contents("$Self->{t_dir}/t_preproc.v"); $wholefile =~ s/\n/\r\n/og; write_wholefile("$Self->{obj_dir}/$Self->{name}.v", $wholefile); } { my $wholefile = file_contents("$Self->{t_dir}/t_preproc.out"); $wholefile =~ s!t/t_preproc.v!$Self->{obj_dir}/t_preproc_dos.v!og; # Fix `line's write_wholefile($Self->{golden_out}, $wholefile); } do 't/t_preproc.pl'; 1; verilator-3.874/test_regress/t/t_lint_repeat_bad.pl0000775000177100017500000000137212473477707022523 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Warning-WIDTH: t/t_lint_repeat_bad.v:17: Operator ASSIGNW expects 1 bits on the Assign RHS, but Assign RHS's VARREF 'a' generates 2 bits. %Warning-WIDTH: Use \"\/\* verilator lint_off WIDTH \*\/\" and lint_on around source to disable this message. %Error: Exiting due to 1 warning} ); ok(1); 1; verilator-3.874/test_regress/t/t_var_pins_sc_uint.pl0000775000177100017500000000470312473477707022755 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc --pins-sc-uint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o128;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o513;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.874/test_regress/t/t_order_multidriven.pl0000775000177100017500000000120312473477707023135 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2013 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"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["--trace --exe $Self->{t_dir}/t_order_multidriven.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_life.v0000664000177100017500000000443612473477707021031 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // Life analysis checks reg [15:0] life; // Ding case reg [7:0] din; reg [15:0] fixin; always @* begin fixin = {din[7:0],din[7:0]}; case (din[1:0]) 2'b00: begin fixin = {fixin[14:0], 1'b1}; if (cyc==101) $display("Prevent ?: optimization a"); end 2'b01: begin fixin = {fixin[13:0], 2'b11}; if (cyc==101) $display("Prevent ?: optimization b"); end 2'b10: begin fixin = {fixin[12:0], 3'b111}; if (cyc==101) $display("Prevent ?: optimization c"); end 2'b11: begin fixin = {fixin[11:0], 4'b1111}; if (cyc==101) $display("Prevent ?: optimization d"); end endcase end always @ (posedge clk) begin if (cyc!=0) begin cyc<=cyc+1; if (cyc==1) begin life = 16'h8000; // Dropped life = 16'h0010; // Used below if (life != 16'h0010) $stop; // life = 16'h0020; // Used below if ($time < 10000) if (life != 16'h0020) $stop; // life = 16'h8000; // Dropped if ($time > 100000) begin if ($time != 0) $stop; // Prevent conversion to ?: life = 16'h1030; end else life = 16'h0030; if (life != 16'h0030) $stop; // life = 16'h0040; // Not dropped, no else below if ($time > 100000) life = 16'h1040; if (life != 16'h0040) $stop; // life = 16'h8000; // Dropped if ($time > 100000) begin life = 16'h1050; if (life != 0) $stop; // Ignored, as set is first end else begin if ($time > 100010) life = 16'h1050; else life = 16'h0050; end if (life != 16'h0050) $stop; end if (cyc==2) begin din <= 8'haa; end if (cyc==3) begin din <= 8'hfb; if (fixin != 16'h5557) $stop; end if (cyc==4) begin din <= 8'h5c; if (fixin != 16'hbfbf) $stop; end if (cyc==5) begin din <= 8'hed; if (fixin != 16'hb8b9) $stop; end if (cyc==6) begin if (fixin != 16'hb7b7) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_clk_gater.v0000664000177100017500000000635512473477707021177 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; reg reset; reg enable; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v // End of automatics // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; Test test (/*AUTOINST*/ // Outputs .out (out[31:0]), // Inputs .clk (clk), .reset (reset), .enable (enable), .in (in[31:0])); wire [63:0] result = {32'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; reset <= (cyc < 5); enable <= cyc[4] || (cyc < 2); if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; `define EXPECTED_SUM 64'h01e1553da1dcf3af if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, reset, enable, in ); input clk; input reset; input enable; input [31:0] in; output [31:0] out; // No gating reg [31:0] d10; always @(posedge clk) begin d10 <= in; end reg displayit; `ifdef VERILATOR // Harder test initial displayit = $c1("0"); // Something that won't optimize away `else initial displayit = '0; `endif // Obvious gating + PLI reg [31:0] d20; always @(posedge clk) begin if (enable) begin d20 <= d10; // Obvious gating if (displayit) begin $display("hello!"); // Must glob with other PLI statements end end end // Reset means second-level gating reg [31:0] d30, d31a, d31b, d32; always @(posedge clk) begin d32 <= d31b; if (reset) begin d30 <= 32'h0; d31a <= 32'h0; d31b <= 32'h0; d32 <= 32'h0; // Overlaps above, just to make things interesting end else begin // Mix two outputs d30 <= d20; if (enable) begin d31a <= d30; d31b <= d31a; end end end // Multiple ORs for gater reg [31:0] d40a,d40b; always @(posedge clk) begin if (reset) begin d40a <= 32'h0; d40b <= 32'h0; end if (enable) begin d40a <= d32; d40b <= d40a; end end // Non-optimizable reg [31:0] d91, d92; reg [31:0] inverted; always @(posedge clk) begin inverted = ~d40b; if (reset) begin d91 <= 32'h0; end else begin if (enable) begin d91 <= inverted; end else begin d92 <= inverted ^ 32'h12341234; // Inverted gating condition end end end wire [31:0] out = d91 ^ d92; endmodule verilator-3.874/test_regress/t/t_math_imm2.pl0000775000177100017500000000116012473477707021257 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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->skip("Verilator only test") if !$Self->{vlt}; compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_runtime_range.v0000664000177100017500000000335412473477707023436 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (clk); input clk; reg [43:0] mi; reg [5:0] index; integer indexi; reg read; initial begin // Static mi = 44'b01010101010101010101010101010101010101010101; if (mi[0] !== 1'b1) $stop; if (mi[1 -: 2] !== 2'b01) $stop; `ifdef VERILATOR // verilator lint_off SELRANGE if (mi[-1] !== 1'bx && mi[-1] !== 1'b0) $stop; if (mi[0 -: 2] !== 2'b1x && 1'b0) $stop; if (mi[-1 -: 2] !== 2'bxx && 1'b0) $stop; // verilator lint_on SELRANGE `else if (mi[-1] !== 1'bx) $stop; if (mi[0 -: 2] !== 2'b1x) $stop; if (mi[-1 -: 2] !== 2'bxx) $stop; `endif end integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin mi = 44'h123; end if (cyc==2) begin index = 6'd43; indexi = 43; end if (cyc==3) begin read = mi[index]; if (read!==1'b0) $stop; read = mi[indexi]; if (read!==1'b0) $stop; end if (cyc==4) begin index = 6'd44; indexi = 44; end if (cyc==5) begin read = mi[index]; $display("-Illegal read value: %x",read); //if (read!==1'b1 && read!==1'bx) $stop; read = mi[indexi]; $display("-Illegal read value: %x",read); //if (read!==1'b1 && read!==1'bx) $stop; end if (cyc==6) begin indexi = -1; end if (cyc==7) begin read = mi[indexi]; $display("-Illegal read value: %x",read); //if (read!==1'b1 && read!==1'bx) $stop; end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_case_reducer.v0000664000177100017500000002546112473477707021667 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [7:0] operand_a = crc[7:0]; wire [7:0] operand_b = crc[15:8]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [6:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[6:0]), // Inputs .clk (clk), .operand_a (operand_a[7:0]), .operand_b (operand_b[7:0])); // Aggregate outputs into a single result vector wire [63:0] result = {57'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h8a78c2ec4946ac38 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( // Inputs input wire clk, input wire [7:0] operand_a, // operand a input wire [7:0] operand_b, // operand b // Outputs output wire [6:0] out ); wire [6:0] clz_a; wire [6:0] clz_b; clz u_clz_a ( // Inputs .data_i (operand_a), .out (clz_a)); clz u_clz_b ( // Inputs .data_i (operand_b), .out (clz_b)); assign out = clz_a - clz_b; `ifdef TEST_VERBOSE always @(posedge clk) $display("Out(%x) = clz_a(%x) - clz_b(%x)", out, clz_a, clz_b); `endif endmodule `define def_0000_001x 8'b0000_0010, 8'b0000_0011 `define def_0000_01xx 8'b0000_0100, 8'b0000_0101, 8'b0000_0110, 8'b0000_0111 `define def_0000_10xx 8'b0000_1000, 8'b0000_1001, 8'b0000_1010, 8'b0000_1011 `define def_0000_11xx 8'b0000_1100, 8'b0000_1101, 8'b0000_1110, 8'b0000_1111 `define def_0000_1xxx `def_0000_10xx, `def_0000_11xx `define def_0001_00xx 8'b0001_0000, 8'b0001_0001, 8'b0001_0010, 8'b0001_0011 `define def_0001_01xx 8'b0001_0100, 8'b0001_0101, 8'b0001_0110, 8'b0001_0111 `define def_0001_10xx 8'b0001_1000, 8'b0001_1001, 8'b0001_1010, 8'b0001_1011 `define def_0001_11xx 8'b0001_1100, 8'b0001_1101, 8'b0001_1110, 8'b0001_1111 `define def_0010_00xx 8'b0010_0000, 8'b0010_0001, 8'b0010_0010, 8'b0010_0011 `define def_0010_01xx 8'b0010_0100, 8'b0010_0101, 8'b0010_0110, 8'b0010_0111 `define def_0010_10xx 8'b0010_1000, 8'b0010_1001, 8'b0010_1010, 8'b0010_1011 `define def_0010_11xx 8'b0010_1100, 8'b0010_1101, 8'b0010_1110, 8'b0010_1111 `define def_0011_00xx 8'b0011_0000, 8'b0011_0001, 8'b0011_0010, 8'b0011_0011 `define def_0011_01xx 8'b0011_0100, 8'b0011_0101, 8'b0011_0110, 8'b0011_0111 `define def_0011_10xx 8'b0011_1000, 8'b0011_1001, 8'b0011_1010, 8'b0011_1011 `define def_0011_11xx 8'b0011_1100, 8'b0011_1101, 8'b0011_1110, 8'b0011_1111 `define def_0100_00xx 8'b0100_0000, 8'b0100_0001, 8'b0100_0010, 8'b0100_0011 `define def_0100_01xx 8'b0100_0100, 8'b0100_0101, 8'b0100_0110, 8'b0100_0111 `define def_0100_10xx 8'b0100_1000, 8'b0100_1001, 8'b0100_1010, 8'b0100_1011 `define def_0100_11xx 8'b0100_1100, 8'b0100_1101, 8'b0100_1110, 8'b0100_1111 `define def_0101_00xx 8'b0101_0000, 8'b0101_0001, 8'b0101_0010, 8'b0101_0011 `define def_0101_01xx 8'b0101_0100, 8'b0101_0101, 8'b0101_0110, 8'b0101_0111 `define def_0101_10xx 8'b0101_1000, 8'b0101_1001, 8'b0101_1010, 8'b0101_1011 `define def_0101_11xx 8'b0101_1100, 8'b0101_1101, 8'b0101_1110, 8'b0101_1111 `define def_0110_00xx 8'b0110_0000, 8'b0110_0001, 8'b0110_0010, 8'b0110_0011 `define def_0110_01xx 8'b0110_0100, 8'b0110_0101, 8'b0110_0110, 8'b0110_0111 `define def_0110_10xx 8'b0110_1000, 8'b0110_1001, 8'b0110_1010, 8'b0110_1011 `define def_0110_11xx 8'b0110_1100, 8'b0110_1101, 8'b0110_1110, 8'b0110_1111 `define def_0111_00xx 8'b0111_0000, 8'b0111_0001, 8'b0111_0010, 8'b0111_0011 `define def_0111_01xx 8'b0111_0100, 8'b0111_0101, 8'b0111_0110, 8'b0111_0111 `define def_0111_10xx 8'b0111_1000, 8'b0111_1001, 8'b0111_1010, 8'b0111_1011 `define def_0111_11xx 8'b0111_1100, 8'b0111_1101, 8'b0111_1110, 8'b0111_1111 `define def_1000_00xx 8'b1000_0000, 8'b1000_0001, 8'b1000_0010, 8'b1000_0011 `define def_1000_01xx 8'b1000_0100, 8'b1000_0101, 8'b1000_0110, 8'b1000_0111 `define def_1000_10xx 8'b1000_1000, 8'b1000_1001, 8'b1000_1010, 8'b1000_1011 `define def_1000_11xx 8'b1000_1100, 8'b1000_1101, 8'b1000_1110, 8'b1000_1111 `define def_1001_00xx 8'b1001_0000, 8'b1001_0001, 8'b1001_0010, 8'b1001_0011 `define def_1001_01xx 8'b1001_0100, 8'b1001_0101, 8'b1001_0110, 8'b1001_0111 `define def_1001_10xx 8'b1001_1000, 8'b1001_1001, 8'b1001_1010, 8'b1001_1011 `define def_1001_11xx 8'b1001_1100, 8'b1001_1101, 8'b1001_1110, 8'b1001_1111 `define def_1010_00xx 8'b1010_0000, 8'b1010_0001, 8'b1010_0010, 8'b1010_0011 `define def_1010_01xx 8'b1010_0100, 8'b1010_0101, 8'b1010_0110, 8'b1010_0111 `define def_1010_10xx 8'b1010_1000, 8'b1010_1001, 8'b1010_1010, 8'b1010_1011 `define def_1010_11xx 8'b1010_1100, 8'b1010_1101, 8'b1010_1110, 8'b1010_1111 `define def_1011_00xx 8'b1011_0000, 8'b1011_0001, 8'b1011_0010, 8'b1011_0011 `define def_1011_01xx 8'b1011_0100, 8'b1011_0101, 8'b1011_0110, 8'b1011_0111 `define def_1011_10xx 8'b1011_1000, 8'b1011_1001, 8'b1011_1010, 8'b1011_1011 `define def_1011_11xx 8'b1011_1100, 8'b1011_1101, 8'b1011_1110, 8'b1011_1111 `define def_1100_00xx 8'b1100_0000, 8'b1100_0001, 8'b1100_0010, 8'b1100_0011 `define def_1100_01xx 8'b1100_0100, 8'b1100_0101, 8'b1100_0110, 8'b1100_0111 `define def_1100_10xx 8'b1100_1000, 8'b1100_1001, 8'b1100_1010, 8'b1100_1011 `define def_1100_11xx 8'b1100_1100, 8'b1100_1101, 8'b1100_1110, 8'b1100_1111 `define def_1101_00xx 8'b1101_0000, 8'b1101_0001, 8'b1101_0010, 8'b1101_0011 `define def_1101_01xx 8'b1101_0100, 8'b1101_0101, 8'b1101_0110, 8'b1101_0111 `define def_1101_10xx 8'b1101_1000, 8'b1101_1001, 8'b1101_1010, 8'b1101_1011 `define def_1101_11xx 8'b1101_1100, 8'b1101_1101, 8'b1101_1110, 8'b1101_1111 `define def_1110_00xx 8'b1110_0000, 8'b1110_0001, 8'b1110_0010, 8'b1110_0011 `define def_1110_01xx 8'b1110_0100, 8'b1110_0101, 8'b1110_0110, 8'b1110_0111 `define def_1110_10xx 8'b1110_1000, 8'b1110_1001, 8'b1110_1010, 8'b1110_1011 `define def_1110_11xx 8'b1110_1100, 8'b1110_1101, 8'b1110_1110, 8'b1110_1111 `define def_1111_00xx 8'b1111_0000, 8'b1111_0001, 8'b1111_0010, 8'b1111_0011 `define def_1111_01xx 8'b1111_0100, 8'b1111_0101, 8'b1111_0110, 8'b1111_0111 `define def_1111_10xx 8'b1111_1000, 8'b1111_1001, 8'b1111_1010, 8'b1111_1011 `define def_1111_11xx 8'b1111_1100, 8'b1111_1101, 8'b1111_1110, 8'b1111_1111 `define def_0001_xxxx `def_0001_00xx, `def_0001_01xx, `def_0001_10xx, `def_0001_11xx `define def_0010_xxxx `def_0010_00xx, `def_0010_01xx, `def_0010_10xx, `def_0010_11xx `define def_0011_xxxx `def_0011_00xx, `def_0011_01xx, `def_0011_10xx, `def_0011_11xx `define def_0100_xxxx `def_0100_00xx, `def_0100_01xx, `def_0100_10xx, `def_0100_11xx `define def_0101_xxxx `def_0101_00xx, `def_0101_01xx, `def_0101_10xx, `def_0101_11xx `define def_0110_xxxx `def_0110_00xx, `def_0110_01xx, `def_0110_10xx, `def_0110_11xx `define def_0111_xxxx `def_0111_00xx, `def_0111_01xx, `def_0111_10xx, `def_0111_11xx `define def_1000_xxxx `def_1000_00xx, `def_1000_01xx, `def_1000_10xx, `def_1000_11xx `define def_1001_xxxx `def_1001_00xx, `def_1001_01xx, `def_1001_10xx, `def_1001_11xx `define def_1010_xxxx `def_1010_00xx, `def_1010_01xx, `def_1010_10xx, `def_1010_11xx `define def_1011_xxxx `def_1011_00xx, `def_1011_01xx, `def_1011_10xx, `def_1011_11xx `define def_1100_xxxx `def_1100_00xx, `def_1100_01xx, `def_1100_10xx, `def_1100_11xx `define def_1101_xxxx `def_1101_00xx, `def_1101_01xx, `def_1101_10xx, `def_1101_11xx `define def_1110_xxxx `def_1110_00xx, `def_1110_01xx, `def_1110_10xx, `def_1110_11xx `define def_1111_xxxx `def_1111_00xx, `def_1111_01xx, `def_1111_10xx, `def_1111_11xx `define def_1xxx_xxxx `def_1000_xxxx, `def_1001_xxxx, `def_1010_xxxx, `def_1011_xxxx, \ `def_1100_xxxx, `def_1101_xxxx, `def_1110_xxxx, `def_1111_xxxx `define def_01xx_xxxx `def_0100_xxxx, `def_0101_xxxx, `def_0110_xxxx, `def_0111_xxxx `define def_001x_xxxx `def_0010_xxxx, `def_0011_xxxx module clz( input wire [7:0] data_i, output wire [6:0] out ); // ----------------------------- // Reg declarations // ----------------------------- reg [2:0] clz_byte0; reg [2:0] clz_byte1; reg [2:0] clz_byte2; reg [2:0] clz_byte3; always @* case (data_i) `def_1xxx_xxxx : clz_byte0 = 3'b000; `def_01xx_xxxx : clz_byte0 = 3'b001; `def_001x_xxxx : clz_byte0 = 3'b010; `def_0001_xxxx : clz_byte0 = 3'b011; `def_0000_1xxx : clz_byte0 = 3'b100; `def_0000_01xx : clz_byte0 = 3'b101; `def_0000_001x : clz_byte0 = 3'b110; 8'b0000_0001 : clz_byte0 = 3'b111; 8'b0000_0000 : clz_byte0 = 3'b111; default : clz_byte0 = 3'bxxx; endcase always @* case (data_i) `def_1xxx_xxxx : clz_byte1 = 3'b000; `def_01xx_xxxx : clz_byte1 = 3'b001; `def_001x_xxxx : clz_byte1 = 3'b010; `def_0001_xxxx : clz_byte1 = 3'b011; `def_0000_1xxx : clz_byte1 = 3'b100; `def_0000_01xx : clz_byte1 = 3'b101; `def_0000_001x : clz_byte1 = 3'b110; 8'b0000_0001 : clz_byte1 = 3'b111; 8'b0000_0000 : clz_byte1 = 3'b111; default : clz_byte1 = 3'bxxx; endcase always @* case (data_i) `def_1xxx_xxxx : clz_byte2 = 3'b000; `def_01xx_xxxx : clz_byte2 = 3'b001; `def_001x_xxxx : clz_byte2 = 3'b010; `def_0001_xxxx : clz_byte2 = 3'b011; `def_0000_1xxx : clz_byte2 = 3'b100; `def_0000_01xx : clz_byte2 = 3'b101; `def_0000_001x : clz_byte2 = 3'b110; 8'b0000_0001 : clz_byte2 = 3'b111; 8'b0000_0000 : clz_byte2 = 3'b111; default : clz_byte2 = 3'bxxx; endcase always @* case (data_i) `def_1xxx_xxxx : clz_byte3 = 3'b000; `def_01xx_xxxx : clz_byte3 = 3'b001; `def_001x_xxxx : clz_byte3 = 3'b010; `def_0001_xxxx : clz_byte3 = 3'b011; `def_0000_1xxx : clz_byte3 = 3'b100; `def_0000_01xx : clz_byte3 = 3'b101; `def_0000_001x : clz_byte3 = 3'b110; 8'b0000_0001 : clz_byte3 = 3'b111; 8'b0000_0000 : clz_byte3 = 3'b111; default : clz_byte3 = 3'bxxx; endcase assign out = {4'b0000, clz_byte1}; endmodule // clz verilator-3.874/test_regress/t/t_langext_2.pl0000775000177100017500000000076112473477707021273 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # This is a compile only test. compile ( v_flags2 => ["+systemverilogext+v"], ); ok(1); 1; verilator-3.874/test_regress/t/t_select_param.v0000664000177100017500000000066512473477707021701 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; parameter [ BMSB : BLSB ] B = A[23:20]; // 3 parameter A = 32'h12345678; parameter BLSB = A[16+:4]; // 4 parameter BMSB = A[7:4]; // 7 initial begin if (B !== 4'h3) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_lint_incabspath.v0000664000177100017500000000031212473477707022371 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. `include "/dev/null" module t; endmodule verilator-3.874/test_regress/t/t_display_signed_noopt.pl0000775000177100017500000000250512473477707023623 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_display_signed.v"); compile ( verilator_flags2 => ["-O0"], ); execute ( check_finished=>1, expect=> quotemeta( '[0] lp %x=0bbccc %x=0bbccc %o=2736314 %b=010111011110011001100 %0d=769228 %d= 769228 [0] ln %x=1bbccc %x=1bbccc %o=6736314 %b=110111011110011001100 %0d=-279348 %d= -279348 [0] qp %x=001bbbbcccc %x=001bbbbcccc %o=00067356746314 %b=00000000110111011101110111100110011001100 %0d=7444614348 %d= 7444614348 [0] qn %x=101bbbbcccc %x=101bbbbcccc %o=20067356746314 %b=10000000110111011101110111100110011001100 %0d=-1092067013428 %d=-1092067013428 [0] wp %x=000bc1234567812345678 %x=000bc1234567812345678 %o=000570110642547402215053170 %b=000000000101111000001001000110100010101100111100000010010001101000101011001111000 [0] wn %x=000bc1234577812345678 %x=000bc1234577812345678 %o=000570110642567402215053170 %b=000000000101111000001001000110100010101110111100000010010001101000101011001111000 '), ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_slot.cpp0000664000177100017500000000235612473477707021375 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- #include #include #include "Vt_mem_slot.h" unsigned int Array[3]; unsigned int StepSim (Vt_mem_slot *sim, unsigned int slot, unsigned int bit, unsigned int val, unsigned int rslot) { #ifdef TEST_VERBOSE printf ("StepSim: slot=%d bit=%d val=%d rslot=%d\n", slot, bit, val, rslot); #endif sim->SlotIdx = slot; sim->BitToChange = bit; sim->BitVal = val; sim->SlotToReturn = rslot; sim->Clk = 0; sim->eval(); sim->Clk = 1; sim->eval(); if (sim->OutputVal != Array[rslot]) { printf ("%%Error: got %x - expected %x\n", sim->OutputVal, Array[rslot]); exit (1); } if (val) Array[slot] |= (1 << bit); else Array[slot] &= ~(1 << bit); return sim->OutputVal; } int main (int argc, char *argv[]) { Vt_mem_slot *sim = new Vt_mem_slot; int slot, bit, i; Verilated::debug(0); /* clear all bits in the array */ for (slot = 0; slot < 3; slot++) for (bit = 0; bit < 2; bit++) StepSim (sim, slot, bit, 0, 0); printf ("\nTesting\n"); for (i = 0; i < 100; i++) StepSim (sim, random() % 3, random() % 2, random() % 2, random() % 3); printf ("*-* All Finished *-*\n"); } verilator-3.874/test_regress/t/t_select_bound2.v0000664000177100017500000000424312473477707021766 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. // bug823 module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [6:0] in = crc[6:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [3:0] mask; // From test of Test.v wire [3:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[3:0]), .mask (mask[3:0]), // Inputs .clk (clk), .in (in[6:0])); // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, out & mask}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x out=%b mask=%b\n",$time, cyc, crc, out, mask); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h4e9d3a74e9d3f656 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, mask, // Inputs clk, in ); input clk; input [6:0] in; // Note much wider than any index output reg [3:0] out; output reg [3:0] mask; localparam [15:5] p = 11'h1ac; always @(posedge clk) begin // verilator lint_off WIDTH out <= p[15 + in -: 5]; // verilator lint_on WIDTH mask[3] <= ((15 + in - 5) < 12); mask[2] <= ((15 + in - 5) < 13); mask[1] <= ((15 + in - 5) < 14); mask[0] <= ((15 + in - 5) < 15); end endmodule verilator-3.874/test_regress/t/t_flag_nomod_bad.pl0000775000177100017500000000113012473477707022312 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Error: No top level module found %Error: Exiting due to', ); ok(1); 1; verilator-3.874/test_regress/t/t_uniqueif_fail2.pl0000775000177100017500000000144012473477707022305 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_uniqueif.v"); compile ( v_flags2 => ['+define+FAILING_ASSERTION2'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], fails => $Self->{nc}, ); execute ( fails => $Self->{vlt}, expect=> '.*%Error: t_uniqueif.v:\d+: Assertion failed in top.v: \'unique if\' statement violated %Error: t/t_uniqueif.v:\d+: Verilog \$stop .*', ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_for.pl0000775000177100017500000000071712473477707021030 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_down_inlc.pl0000775000177100017500000000110312473477707023373 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_C'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_noinl.pl0000775000177100017500000000071712473477707021543 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_bound2.pl0000775000177100017500000000072212473477707022135 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sv_cpu.v0000664000177100017500000000644512473477707020543 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: System Verilog test of a complete CPU // // This code instantiates and runs a simple CPU written in System Verilog. // // This file ONLY is placed into the Public Domain, for any use, without // warranty. // Contributed 2012 by M W Lund, Atmel Corporation and Jeremy Bennett, Embecosm. module t (/*AUTOARG*/ // Inputs clk ); input clk; /*AUTOWIRE*/ // ************************************************************************** // Regs and Wires // ************************************************************************** reg rst; integer rst_count; integer clk_count; testbench testbench_i (/*AUTOINST*/ // Inputs .clk (clk), .rst (rst)); // ************************************************************************** // Reset Generation // ************************************************************************** initial begin rst = 1'b1; rst_count = 0; end always @( posedge clk ) begin if (rst_count < 2) begin rst_count++; end else begin rst = 1'b0; end end // ************************************************************************** // Drive simulation for 500 clock cycles // ************************************************************************** initial begin `ifdef TEST_VERBOSE $display( "[testbench] - Start of simulation ----------------------- " ); `endif clk_count = 0; end always @( posedge clk ) begin if (90 == clk_count) begin $finish (); end else begin clk_count++; end end final begin `ifdef TEST_VERBOSE $display( "[testbench] - End of simulation ------------------------- " ); `endif $write("*-* All Finished *-*\n"); end endmodule module testbench (/*AUTOARG*/ // Inputs clk, rst ); input clk; input rst; // ************************************************************************** // Local parameters // ************************************************************************** localparam NUMPADS = $size( pinout ); // ************************************************************************** // Regs and Wires // ************************************************************************** // **** Pinout **** `ifdef VERILATOR // see t_tri_array wire [NUMPADS:1] pad; // GPIO Pads (PORT{A,...,R}). `else wire pad [1:NUMPADS]; // GPIO Pads (PORT{A,...,R}). `endif // ************************************************************************** // Regs and Wires, Automatics // ************************************************************************** /*AUTOWIRE*/ // ************************************************************************** // Includes (Testbench extensions) // ************************************************************************** // N/A // ************************************************************************** // Chip Instance // ************************************************************************** chip i_chip ( /*AUTOINST*/ // Inouts .pad (pad[NUMPADS:1]), // Inputs .clk (clk), .rst (rst)); endmodule // test // Local Variables: // verilog-library-directories:("." "t_sv_cpu_code") // End: verilator-3.874/test_regress/t/t_cdc_async_bad.pl0000775000177100017500000000216612473477707022145 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2009 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. compile ( v_flags => ['--cdc'], verilator_make_gcc => 0, fails => 1, expect=> '%Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst2_bad_n %Warning-CDCRSTLOGIC: Use "/\* verilator lint_off CDCRSTLOGIC \*/" and lint_on around source to disable this message. %Warning-CDCRSTLOGIC: See details in obj_dir/t_cdc_async_bad/Vt_cdc_async_bad__cdc.txt %Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst6a_bad_n %Warning-CDCRSTLOGIC: t/t_cdc_async_bad.v:\d+: Logic in path that feeds async reset, via signal: v.rst6b_bad_n %Error: Exiting due to.*', ); file_grep ("$Self->{obj_dir}/V$Self->{name}__cdc.txt", qr/CDC Report/); ok(1); 1; verilator-3.874/test_regress/t/t_for_break.pl0000775000177100017500000000071712473477707021343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_misarray_bad.v0000664000177100017500000000140112473477707022721 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic foo; initial foo = 0; // dut #(.W(4)) udut(.*); dut #(.W(4)) udut(.clk(clk), .foo(foo)); // Should be a non-internal error, as assigning logic to logic array endmodule module dut #(parameter W = 1) (input logic clk, input logic foo[W-1:0]); genvar i; generate for (i = 0; i < W; i++) begin suba ua(.clk(clk), .foo(foo[i])); end endgenerate endmodule module suba (input logic clk, input logic foo); always @(posedge clk) $display("foo=%b", foo); endmodule verilator-3.874/test_regress/t/t_lint_implicit_def_bad.pl0000775000177100017500000000165112473477707023673 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( verilator_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME"], fails=>1, expect=> '%Warning-IMPLICIT: t/t_lint_implicit_def_bad.v:\d+: Signal definition not found, creating implicitly: imp_warn %Warning-IMPLICIT: Use "/\* verilator lint_off IMPLICIT \*/" and lint_on around source to disable this message. %Error: t/t_lint_implicit_def_bad.v:\d+: Signal definition not found, and implicit disabled with `default_nettype: imp_err %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_gen.pl0000775000177100017500000000072712473477707022203 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_noinl.v0000664000177100017500000000477612473477707021403 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; wire [31:0] inp = crc[31:0]; wire reset = (cyc < 5); /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] outp; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .outp (outp[31:0]), // Inputs .reset (reset), .clk (clk), .inp (inp[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, outp}; // What checksum will we end up with `define EXPECTED_SUM 64'ha7f0a34f9cf56ccb // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs outp, // Inputs reset, clk, inp ); input reset; input clk; input [31:0] inp; output [31:0] outp; function [31:0] no_inline_function; input [31:0] var1; input [31:0] var2; /*verilator no_inline_task*/ reg [31*2:0] product1 ; reg [31*2:0] product2 ; integer i; reg [31:0] tmp; begin product2 = {(31*2+1){1'b0}}; for (i = 0; i < 32; i = i + 1) if (var2[i]) begin product1 = { {31*2+1-32{1'b0}}, var1} << i; product2 = product2 ^ product1; end no_inline_function = 0; for (i= 0; i < 31; i = i + 1 ) no_inline_function[i+1] = no_inline_function[i] ^ product2[i] ^ var1[i]; end endfunction reg [31:0] outp; reg [31:0] inp_d; always @( posedge clk ) begin if( reset ) begin outp <= 0; end else begin inp_d <= inp; outp <= no_inline_function(inp, inp_d); end end endmodule verilator-3.874/test_regress/t/t_var_types.v0000664000177100017500000001745312473477707021261 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/); // IEEE: integer_atom_type byte d_byte; shortint d_shortint; int d_int; longint d_longint; integer d_integer; time d_time; chandle d_chandle; // IEEE: integer_atom_type bit d_bit; logic d_logic; reg d_reg; bit [1:0] d_bit2; logic [1:0] d_logic2; reg [1:0] d_reg2; // IEEE: non_integer_type //UNSUP shortreal d_shortreal; real d_real; realtime d_realtime; // Declarations using var var byte v_b; `ifndef VCS var [2:0] v_b3; var signed [2:0] v_bs; `endif // verilator lint_off WIDTH localparam p_implicit = {96{1'b1}}; localparam [89:0] p_explicit = {96{1'b1}}; localparam byte p_byte = {96{1'b1}}; localparam shortint p_shortint = {96{1'b1}}; localparam int p_int = {96{1'b1}}; localparam longint p_longint = {96{1'b1}}; localparam integer p_integer = {96{1'b1}}; localparam reg p_reg = {96{1'b1}}; localparam bit p_bit = {96{1'b1}}; localparam logic p_logic = {96{1'b1}}; localparam reg [0:0] p_reg1 = {96{1'b1}}; localparam bit [0:0] p_bit1 = {96{1'b1}}; localparam logic [0:0] p_logic1= {96{1'b1}}; localparam reg [1:0] p_reg2 = {96{1'b1}}; localparam bit [1:0] p_bit2 = {96{1'b1}}; localparam logic [1:0] p_logic2= {96{1'b1}}; // verilator lint_on WIDTH byte v_byte[2]; shortint v_shortint[2]; int v_int[2]; longint v_longint[2]; integer v_integer[2]; time v_time[2]; chandle v_chandle[2]; bit v_bit[2]; logic v_logic[2]; reg v_reg[2]; real v_real[2]; realtime v_realtime[2]; // We do this in two steps so we can check that initialization inside functions works properly // verilator lint_off WIDTH function f_implicit; reg lv_implicit; f_implicit = lv_implicit; endfunction function [89:0] f_explicit; reg [89:0] lv_explicit; f_explicit = lv_explicit; endfunction function byte f_byte; byte lv_byte; f_byte = lv_byte; endfunction function shortint f_shortint; shortint lv_shortint; f_shortint = lv_shortint; endfunction function int f_int; int lv_int; f_int = lv_int; endfunction function longint f_longint; longint lv_longint; f_longint = lv_longint; endfunction function integer f_integer; integer lv_integer; f_integer = lv_integer; endfunction function reg f_reg; reg lv_reg; f_reg = lv_reg; endfunction function bit f_bit; bit lv_bit; f_bit = lv_bit; endfunction function logic f_logic; logic lv_logic; f_logic = lv_logic; endfunction function reg [0:0] f_reg1; reg [0:0] lv_reg1; f_reg1 = lv_reg1; endfunction function bit [0:0] f_bit1; bit [0:0] lv_bit1; f_bit1 = lv_bit1; endfunction function logic [0:0] f_logic1; logic [0:0] lv_logic1; f_logic1 = lv_logic1; endfunction function reg [1:0] f_reg2; reg [1:0] lv_reg2; f_reg2 = lv_reg2; endfunction function bit [1:0] f_bit2; bit [1:0] lv_bit2; f_bit2 = lv_bit2; endfunction function logic [1:0] f_logic2; logic [1:0] lv_logic2; f_logic2 = lv_logic2; endfunction function time f_time; time lv_time; f_time = lv_time; endfunction function chandle f_chandle; chandle lv_chandle; f_chandle = lv_chandle; endfunction // verilator lint_on WIDTH `ifdef verilator // For verilator zeroinit detection to work properly, we need to x-rand-reset to all 1s. This is the default! `define XINIT 1'b1 `define ALL_TWOSTATE 1'b1 `else `define XINIT 1'bx `define ALL_TWOSTATE 1'b0 `endif `define CHECK_ALL(name,nbits,issigned,twostate,zeroinit) \ if (zeroinit ? ((name & 1'b1)!==1'b0) : ((name & 1'b1)!==`XINIT)) \ begin $display("%%Error: Bad zero/X init for %s: %b",`"name`",name); $stop; end \ name = {96{1'b1}}; \ if (name !== {(nbits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \ if (issigned ? (name > 0) : (name < 0)) begin $display("%%Error: Bad signed for %s",`"name`"); $stop; end \ name = {96{1'bx}}; \ if (name !== {(nbits){`ALL_TWOSTATE ? `XINIT : (twostate ? 1'b0 : `XINIT)}}) \ begin $display("%%Error: Bad twostate for %s: %b",`"name`",name); $stop; end \ initial begin // verilator lint_off WIDTH // verilator lint_off UNSIGNED // name b sign twost 0init `CHECK_ALL(d_byte ,8 ,1'b1,1'b1,1'b1); `CHECK_ALL(d_shortint ,16,1'b1,1'b1,1'b1); `CHECK_ALL(d_int ,32,1'b1,1'b1,1'b1); `CHECK_ALL(d_longint ,64,1'b1,1'b1,1'b1); `CHECK_ALL(d_integer ,32,1'b1,1'b0,1'b0); `CHECK_ALL(d_time ,64,1'b0,1'b0,1'b0); `CHECK_ALL(d_bit ,1 ,1'b0,1'b1,1'b1); `CHECK_ALL(d_logic ,1 ,1'b0,1'b0,1'b0); `CHECK_ALL(d_reg ,1 ,1'b0,1'b0,1'b0); `CHECK_ALL(d_bit2 ,2 ,1'b0,1'b1,1'b1); `CHECK_ALL(d_logic2 ,2 ,1'b0,1'b0,1'b0); `CHECK_ALL(d_reg2 ,2 ,1'b0,1'b0,1'b0); // verilator lint_on WIDTH // verilator lint_on UNSIGNED // Can't CHECK_ALL(d_chandle), as many operations not legal on chandles `ifdef VERILATOR // else indeterminate if ($bits(d_chandle) !== 64) $stop; `endif `define CHECK_P(name,nbits) \ if (name !== {(nbits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \ // name b `CHECK_P(p_implicit ,96); `CHECK_P(p_implicit[0] ,1 ); `CHECK_P(p_explicit ,90); `CHECK_P(p_explicit[0] ,1 ); `CHECK_P(p_byte ,8 ); `CHECK_P(p_byte[0] ,1 ); `CHECK_P(p_shortint ,16); `CHECK_P(p_shortint[0] ,1 ); `CHECK_P(p_int ,32); `CHECK_P(p_int[0] ,1 ); `CHECK_P(p_longint ,64); `CHECK_P(p_longint[0] ,1 ); `CHECK_P(p_integer ,32); `CHECK_P(p_integer[0] ,1 ); `CHECK_P(p_bit ,1 ); `CHECK_P(p_logic ,1 ); `CHECK_P(p_reg ,1 ); `CHECK_P(p_bit1 ,1 ); `CHECK_P(p_logic1 ,1 ); `CHECK_P(p_reg1 ,1 ); `CHECK_P(p_bit1[0] ,1 ); `CHECK_P(p_logic1[0] ,1 ); `CHECK_P(p_reg1[0] ,1 ); `CHECK_P(p_bit2 ,2 ); `CHECK_P(p_logic2 ,2 ); `CHECK_P(p_reg2 ,2 ); `define CHECK_B(varname,nbits) \ if ($bits(varname) !== nbits) begin $display("%%Error: Bad size for %s",`"varname`"); $stop; end \ `CHECK_B(v_byte[1] ,8 ); `CHECK_B(v_shortint[1] ,16); `CHECK_B(v_int[1] ,32); `CHECK_B(v_longint[1] ,64); `CHECK_B(v_integer[1] ,32); `CHECK_B(v_time[1] ,64); //`CHECK_B(v_chandle[1] `CHECK_B(v_bit[1] ,1 ); `CHECK_B(v_logic[1] ,1 ); `CHECK_B(v_reg[1] ,1 ); //`CHECK_B(v_real[1] ,64); // $bits not allowed //`CHECK_B(v_realtime[1] ,64); // $bits not allowed `define CHECK_F(fname,nbits,zeroinit) \ if ($bits(fname()) !== nbits) begin $display("%%Error: Bad size for %s",`"fname`"); $stop; end \ // name b 0init `CHECK_F(f_implicit ,1 ,1'b0); // Note 1 bit, not 96 `CHECK_F(f_explicit ,90,1'b0); `CHECK_F(f_byte ,8 ,1'b1); `CHECK_F(f_shortint ,16,1'b1); `CHECK_F(f_int ,32,1'b1); `CHECK_F(f_longint ,64,1'b1); `CHECK_F(f_integer ,32,1'b0); `CHECK_F(f_time ,64,1'b0); `ifdef VERILATOR // else indeterminate `CHECK_F(f_chandle ,64,1'b0); `endif `CHECK_F(f_bit ,1 ,1'b1); `CHECK_F(f_logic ,1 ,1'b0); `CHECK_F(f_reg ,1 ,1'b0); `CHECK_F(f_bit1 ,1 ,1'b1); `CHECK_F(f_logic1 ,1 ,1'b0); `CHECK_F(f_reg1 ,1 ,1'b0); `CHECK_F(f_bit2 ,2 ,1'b1); `CHECK_F(f_logic2 ,2 ,1'b0); `CHECK_F(f_reg2 ,2 ,1'b0); // For unpacked types we don't want width warnings for unsized numbers that fit d_byte = 2; d_shortint= 2; d_int = 2; d_longint = 2; d_integer = 2; // Special check d_time = $time; if ($time !== d_time) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_enum_name2.pl0000775000177100017500000000072212525171734021420 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_comma_inl1.pl0000775000177100017500000000103612525171734022445 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_inst_comma.v"); compile ( v_flags2 => ['+define+USE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_vecgen2.pl0000775000177100017500000000103312473477707021563 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_clk_vecgen1.v"); compile ( v_flags2 => ['+define+T_TEST2',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_packed_sysfunct.pl0000775000177100017500000000071712473477707024202 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_ccall.pl0000775000177100017500000000071712473477707021524 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gated_clk_1.v0000664000177100017500000000271312473477707021373 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test of gated clock detection // // The code as shown generates a result by a delayed assignment from PC. The // creation of the result is from a clock gated from the clock that sets // PC. Howevever since they are essentially the same clock, the result should // be delayed by one cycle. // // Standard Verilator treats them as different clocks, so the result stays in // step with the PC. An event drive simulator always allows the clock to win. // // The problem is caused by the extra loop added by Verilator to the // evaluation of all internally generated clocks (effectively removed by // marking the clock enable). // // This test is added to facilitate experiments with solutions. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jeremy Bennett . module t (/*AUTOARG*/ // Inputs clk ); input clk; reg gated_clk_en = 1'b0 ; reg [1:0] pc = 2'b0; reg [1:0] res = 2'b0; wire gated_clk = gated_clk_en & clk; always @(posedge clk) begin pc <= pc + 1; gated_clk_en <= 1'b1; end always @(posedge gated_clk) begin res <= pc; end always @(posedge clk) begin if (pc == 2'b11) begin // Correct behaviour is that res should be lagging pc in the count // by one cycle if (res == 2'b10) begin $write("*-* All Finished *-*\n"); $finish; end else begin $stop; end end end endmodule verilator-3.874/test_regress/t/t_var_nonamebegin.v0000664000177100017500000000224212473477707022365 0ustar wsnyderwsnydermodule t (/*AUTOARG*/ // Inputs clk, reset_l ); input clk; input reset_l; reg inmod; generate if (1) begin // Traces as genblk1.ingen integer ingen; initial $display("ingen: {mod}.genblk1 %m"); end endgenerate integer rawmod; initial begin begin integer upa; begin : d3nameda // %m='.d3nameda' var=_unnamed#.d3nameda.b1 integer d3a; $display("d3a: {mod}.d3nameda %m"); end end end initial begin integer b2; $display("b2: {mod} %m"); begin : b3named integer b3n; $display("b3n: {mod}.b3named: %m"); end if (1) begin integer b3; $display("b3: {mod} %m"); if (1) begin begin begin begin integer b4; $display("b4: {mod} %m"); end end end end else begin integer b4; $display("bb %m"); end end else begin integer b4; $display("b4 %m"); end tsk; $write("*-* All Finished *-*\n"); $finish; end task tsk; integer t1; $display("t1 {mod}.tsk %m"); begin integer t2; $display("t2 {mod}.tsk %m"); end endtask endmodule verilator-3.874/test_regress/t/t_interface_gen2.v0000664000177100017500000000312612473477707022110 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // Very simple test for interface pathclearing module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc #(2) itopa(); ifc #(4) itopb(); sub ca (.isub(itopa), .clk); sub cb (.isub(itopb), .clk); always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d result=%b %b\n",$time, cyc, itopa.valueo, itopb.valueo); `endif cyc <= cyc + 1; itopa.valuei <= cyc[1:0]; itopb.valuei <= cyc[3:0]; if (cyc==1) begin if (itopa.WIDTH != 2) $stop; if (itopb.WIDTH != 4) $stop; if ($bits(itopa.valueo) != 2) $stop; if ($bits(itopb.valueo) != 4) $stop; if ($bits(itopa.out_modport.valueo) != 2) $stop; if ($bits(itopb.out_modport.valueo) != 4) $stop; end if (cyc==4) begin if (itopa.valueo != 2'b11) $stop; if (itopb.valueo != 4'b0011) $stop; end if (cyc==5) begin if (itopa.valueo != 2'b00) $stop; if (itopb.valueo != 4'b0100) $stop; end if (cyc==20) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule interface ifc #(parameter WIDTH = 1); // verilator lint_off MULTIDRIVEN logic [WIDTH-1:0] valuei; logic [WIDTH-1:0] valueo; // verilator lint_on MULTIDRIVEN modport out_modport (input valuei, output valueo); endinterface // Note not parameterized module sub ( ifc.out_modport isub, input clk ); always @(posedge clk) isub.valueo <= isub.valuei + 1; endmodule verilator-3.874/test_regress/t/t_select_plusloop.pl0000775000177100017500000000071712473477707022625 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_for_loop.pl0000775000177100017500000000071712473477707021230 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_bench_mux4k.v0000664000177100017500000001065012473477707021444 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks. // // This implements a 4096:1 mux via two stages of 64:1 muxing. // change these two parameters to see the speed differences //`define DATA_WIDTH 12 //`define MUX2_SIZE 32 `define DATA_WIDTH 2 `define MUX2_SIZE 8 // if you change these, then the testbench will break `define ADDR_WIDTH 12 `define MUX1_SIZE 64 // Total of DATA_WIDTH*MUX2_SIZE*(MUX1_SIZE+1) instantiations of mux64 module t (/*AUTOARG*/ // Inputs clk ); input clk; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [`DATA_WIDTH-1:0] datao; // From mux4096 of mux4096.v // End of automatics reg [`DATA_WIDTH*`MUX1_SIZE*`MUX2_SIZE-1:0] datai; reg [`ADDR_WIDTH-1:0] addr; // Mux: takes in addr and datai and outputs datao mux4096 mux4096 (/*AUTOINST*/ // Outputs .datao (datao[`DATA_WIDTH-1:0]), // Inputs .datai (datai[`DATA_WIDTH*`MUX1_SIZE*`MUX2_SIZE-1:0]), .addr (addr[`ADDR_WIDTH-1:0])); // calculate what the answer should be from datai. This is bit // tricky given the way datai gets sliced. datai is in bit // planes where all the LSBs are contiguous and then the next bit. reg [`DATA_WIDTH-1:0] datao_check; integer j; always @(datai or addr) begin for(j=0;j<`DATA_WIDTH;j=j+1) begin /* verilator lint_off WIDTH */ datao_check[j] = datai >> ((`MUX1_SIZE*`MUX2_SIZE*j)+addr); /* verilator lint_on WIDTH */ end end // Run the test loop. This just increments the address integer i, result; always @ (posedge clk) begin // initial the input data with random values if (addr == 0) begin result = 1; datai = 0; for(i=0; i<`MUX1_SIZE*`MUX2_SIZE; i=i+1) begin /* verilator lint_off WIDTH */ datai = (datai << `DATA_WIDTH) | ($random & {`DATA_WIDTH{1'b1}}); /* verilator lint_on WIDTH */ end end addr <= addr + 1; if (datao_check != datao) begin result = 0; $stop; end $write("Addr=%d datao_check=%d datao=%d\n", addr, datao_check, datao); // only run the first 10 addresses for now if (addr > 10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module mux4096 (input [`DATA_WIDTH*`MUX1_SIZE*`MUX2_SIZE-1:0] datai, input [`ADDR_WIDTH-1:0] addr, output [`DATA_WIDTH-1:0] datao ); // DATA_WIDTH instantiations of mux4096_1bit mux4096_1bit mux4096_1bit[`DATA_WIDTH-1:0] (.addr(addr), .datai(datai), .datao(datao) ); endmodule module mux4096_1bit (input [`MUX1_SIZE*`MUX2_SIZE-1:0] datai, input [`ADDR_WIDTH-1:0] addr, output datao ); // address decoding wire [3:0] A = (4'b1) << addr[1:0]; wire [3:0] B = (4'b1) << addr[3:2]; wire [3:0] C = (4'b1) << addr[5:4]; wire [3:0] D = (4'b1) << addr[7:6]; wire [3:0] E = (4'b1) << addr[9:8]; wire [3:0] F = (4'b1) << addr[11:10]; wire [`MUX2_SIZE-1:0] data0; // DATA_WIDTH*(MUX2_SIZE)*MUX1_SIZE instantiations of mux64 // first stage of 64:1 muxing mux64 #(.MUX_SIZE(`MUX1_SIZE)) mux1[`MUX2_SIZE-1:0] (.A(A), .B(B), .C(C), .datai(datai), .datao(data0)); // DATA_WIDTH*MUX2_SIZE instantiations of mux64 // second stage of 64:1 muxing mux64 #(.MUX_SIZE(`MUX2_SIZE)) mux2 (.A(D), .B(E), .C(F), .datai(data0), .datao(datao)); endmodule module mux64 #(parameter MUX_SIZE=64) (input [3:0] A, input [3:0] B, input [3:0] C, input [MUX_SIZE-1:0] datai, output datao ); wire [63:0] colSelA = { 16{ A[3:0] }}; wire [63:0] colSelB = { 4{ {4{B[3]}}, {4{B[2]}}, {4{B[1]}}, {4{B[0]}}}}; wire [63:0] colSelC = { {16{C[3]}}, {16{C[2]}}, {16{C[1]}}, {16{C[0]}}}; wire [MUX_SIZE-1:0] data_bus; // Note each of these becomes a separate wire. //.colSelA(colSelA[MUX_SIZE-1:0]), //.colSelB(colSelB[MUX_SIZE-1:0]), //.colSelC(colSelC[MUX_SIZE-1:0]), drv drv[MUX_SIZE-1:0] (.colSelA(colSelA[MUX_SIZE-1:0]), .colSelB(colSelB[MUX_SIZE-1:0]), .colSelC(colSelC[MUX_SIZE-1:0]), .datai(datai), .datao(data_bus) ); assign datao = |data_bus; endmodule module drv (input colSelA, input colSelB, input colSelC, input datai, output datao ); assign datao = colSelC & colSelB & colSelA & datai; endmodule verilator-3.874/test_regress/t/t_struct_port.v0000664000177100017500000000423112473477707021623 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. typedef struct packed { bit b9; byte b1; bit b0; } pack_t; module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs pack_t in; always @* in = crc[9:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) pack_t out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out), // Inputs .in (in)); // Aggregate outputs into a single result vector wire [63:0] result = {54'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x in=%x result=%x\n",$time, cyc, crc, in, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h99c434d9b08c2a8a if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( input pack_t in, output pack_t out); always @* begin out = in; out.b1 = in.b1 + 1; out.b0 = 1'b1; end endmodule // Local Variables: // verilog-typedef-regexp: "_t$" // End: verilator-3.874/test_regress/t/t_assert_basic_cover.pl0000775000177100017500000000150212473477707023242 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_assert_basic.v"); compile ( verilator_flags2 => ['--assert --cc --coverage-user'], ); execute ( check_finished=>1, ); #Needs work print "-Info: NOT checking for coverage\n"; #file_grep ($Self->{coverage_filename}, qr/t=>'psl_cover',o=>'cover',c=>2\);/); #file_grep ($Self->{coverage_filename}, qr/DefaultClock.*,c=>1\);/); #file_grep ($Self->{coverage_filename}, qr/ToggleLogIf.*,c=>9\);/); ok(1); 1; verilator-3.874/test_regress/t/t_var_tieout.pl0000775000177100017500000000071712473477707021572 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_sel_range.v0000664000177100017500000000152512473477707022355 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // bug477 module t ( input rst_n, input clk, output out ); submod #(.STAGES(5)) u2(.*); endmodule module submod (/*AUTOARG*/ // Outputs out, // Inputs rst_n, clk ); parameter STAGES = 4; input rst_n; input clk; output out; reg [STAGES-1:0] r_rst; generate // for i=0..5 (5+1-1) for (genvar i=0; i1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_chain.pl0000775000177100017500000000072212473477707021647 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_dupitems.pl0000775000177100017500000000071712473477707022236 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_const_overflow_bad.pl0000775000177100017500000000153512473477707023267 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_const_overflow_bad.v:\d+: Too many digits for 94 bit number: 94\'d123456789012345678901234567890 %Error: t/t_const_overflow_bad.v:\d+: Too many digits for 8 bit number: 8\'habc %Error: t/t_const_overflow_bad.v:\d+: Too many digits for 6 bit number: 6\'o1234 %Error: t/t_const_overflow_bad.v:\d+: Too many digits for 3 bit number: 3\'b1111 %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_var_local.pl0000775000177100017500000000071712473477707021353 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_bad_hide.v0000664000177100017500000000066312473477707021627 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; // Check that the lint_on is obeyed. // verilator lint_off VARHIDDEN // verilator lint_on VARHIDDEN integer top; task x; output top; begin end endtask initial begin begin: lower integer top; end end endmodule verilator-3.874/test_regress/t/t_func_bad.v0000664000177100017500000000156012473477707020776 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; initial begin if (add(3'd1) != 0) $stop; // Too few args if (add(3'd1, 3'd2, 3'd3) != 0) $stop; // Too many args x; // Too few args if (hasout(3'd1) != 0) $stop; // outputs // f(.j(1), .no_such(2)); // Name mismatch f(.dup(1), .dup(3)); // Duplicate f(1,2,3); // Too many end function [2:0] add; input [2:0] from1; input [2:0] from2; begin add = from1 + from2; end endfunction task x; output y; begin end endtask function hasout; output [2:0] illegal_output; hasout = 0; endfunction function int f( int j = 1, int dup = 0 ); return (j<<16) | dup; endfunction endmodule verilator-3.874/test_regress/t/t_case_66bits.v0000664000177100017500000000071512473477707021346 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [65:0] idx /*verilator public*/; initial idx = 1; always @(posedge clk) begin case(idx) 1: idx = 100; 100: begin $write("*-* All Finished *-*\n"); $finish; end default: $stop; endcase end endmodule verilator-3.874/test_regress/t/t_dpi_name_bad.v0000664000177100017500000000066012473477707021617 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. module t (); // Can't handle logic (yet?) import "DPI-C" function int \badly.named (int i); initial begin $stop; end endmodule verilator-3.874/test_regress/t/t_metacmt_onoff.v0000664000177100017500000000054312473477707022056 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module module t; // Test turning on and off a message on the same line; only middle reg shouldn't warn reg [0:1] show1; /*verilator lint_off LITENDIAN*/ reg [0:2] ign2; /*verilator lint_on LITENDIAN*/ reg [0:3] show3; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_package_export.pl0000775000177100017500000000120012473477707022371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug592"); $Self->{vcs} and $Self->unsupported("VCS unsupported"); compile ( v_flags2 => ['+define+T_PACKAGE_EXPORT',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_onehot.v0000664000177100017500000000434012473477707021523 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [2:0] in = (crc[1:0]==0 ? 3'd0 : crc[1:0]==0 ? 3'd1 : crc[1:0]==0 ? 3'd2 : 3'd4); /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[31:0]), // Inputs .clk (clk), .in (in[2:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h704ca23e2a83e1c5 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); // Replace this module with the device under test. // // Change the code in the t module to apply values to the inputs and // merge the output values into the result vector. input clk; input [2:0] in; output reg [31:0] out; localparam ST_0 = 0; localparam ST_1 = 1; localparam ST_2 = 2; always @(posedge clk) begin case (1'b1) // synopsys parallel_case in[ST_0]: out <= 32'h1234; in[ST_1]: out <= 32'h4356; in[ST_2]: out <= 32'h9874; default: out <= 32'h1; endcase end endmodule verilator-3.874/test_regress/t/t_func_first.v0000664000177100017500000000123612473477707021377 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [7:0] cyc; initial cyc=0; reg set_in_task; always @ (posedge clk) begin if (cyc == 8'd0) begin cyc <= 8'd1; set_in_task <= 0; end if (cyc == 8'd1) begin cyc <= 8'h2; ttask; end if (cyc == 8'd2) begin if (!set_in_task) $stop; cyc <= 8'hf; $write("*-* All Finished *-*\n"); $finish; end end task ttask; begin set_in_task <= 1'b1; end endtask endmodule verilator-3.874/test_regress/t/TestVpi.h0000664000177100017500000000257212473477707020276 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2013-2014 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "vpi_user.h" //====================================================================== class TestVpiHandle { /// For testing, etc, wrap vpiHandle in an auto-releasing class vpiHandle m_handle; bool m_free; public: TestVpiHandle() : m_handle(NULL), m_free(true) { } TestVpiHandle(vpiHandle h) : m_handle(h), m_free(true) { } ~TestVpiHandle() { if (m_handle && m_free) { vpi_free_object(m_handle); m_handle=NULL; } } // icarus has yet to catch up with 1800-2009 operator vpiHandle () const { return m_handle; } inline TestVpiHandle& operator= (vpiHandle h) { m_handle = h; return *this; } TestVpiHandle& nofree() { m_free = false; return *this; } }; verilator-3.874/test_regress/t/t_mod_dup_bad.pl0000775000177100017500000000124712473477707021645 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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->skip("Verilator only test") if !$Self->{vlt}; compile ( fails=>1, expect=> '%Error-MODDUP: t/t_mod_dup_bad.v:\d+: Duplicate declaration of module: a %Error-MODDUP: t/t_mod_dup_bad.v:\d+: ... Location of original declaration .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_const.v0000664000177100017500000001122512525171734021360 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [39:0] con1,con2, con3; reg [31:0] w32; reg [31:0] v32 [2]; // surefire lint_off UDDSCN reg [200:0] conw3, conw4; // surefire lint_on UDDSCN reg [16*8-1:0] con__ascii; reg [31:0] win; // Test casting is proper on narrow->wide->narrow conversions // verilator lint_off WIDTH wire [49:0] wider = ({18'h0, win} | (1'b1<<32)) - 50'h111; wire [31:0] wider2 = ({win} | (1'b1<<32)) - 50'd111; // verilator lint_on WIDTH wire [31:0] narrow = wider[31:0]; wire [31:0] narrow2 = wider2[31:0]; // surefire lint_off ASWEMB // surefire lint_off ASWCMB // surefire lint_off CWECBB // surefire lint_off CWECSB // surefire lint_off STMINI integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin $write("[%0t] t_const: Running\n",$time); con1 = 4_0'h1000_0010; // Odd but legal _ in width con2 = 40'h10_0000_0010; con3 = con1 + 40'h10_1100_0101; if (con1[31:0]!== 32'h1000_0010 || con1[39:32]!==0) $stop; $display("%x %x %x\n", con2, con2[31:0], con2[39:32]); if (con2[31:0]!== 32'h10 || con2[39:32]!==8'h10) $stop; if (con3[31:0]!==32'h2100_0111 || con3[39:32]!==8'h10) $stop; // verilator lint_off WIDTH con1 = 10'h10 + 40'h80_1100_0131; // verilator lint_on WIDTH con2 = 40'h80_0000_0000 + 40'h13_7543_0107; if (con1[31:0]!== 32'h1100_0141 || con1[39:32]!==8'h80) $stop; if (con2[31:0]!== 32'h7543_0107 || con2[39:32]!==8'h93) $stop; // verilator lint_off WIDTH conw3 = 94'h000a_5010_4020_3030_2040_1050; // verilator lint_on WIDTH if (conw3[31:00]!== 32'h2040_1050 || conw3[63:32]!== 32'h4020_3030 || conw3[95:64]!== 32'h000a_5010 || conw3[128:96]!==33'h0) $stop; $display("%x... %x\n", conw3[15:0], ~| conw3[15:0]); if ((~| conw3[15:0]) !== 1'h0) $stop; if ((~& conw3[15:0]) !== 1'h1) $stop; // verilator lint_off WIDTH conw4 = 112'h7010_602a_5030_4040_3050_2060_1070; // verilator lint_on WIDTH if (conw4[31:00]!== 32'h2060_1070 || conw4[63:32]!== 32'h4040_3050 || conw4[95:64]!== 32'h602a_5030 || conw4[127:96]!==32'h7010) $stop; // conw4 = 144'h7000_7000_7010_602a_5030_4040_3050_2060_1070; w32 = 12; win <= 12; if ((32'hffff0000 >> w32) != 32'h 000ffff0) $stop; con__ascii = "abcdefghijklmnop"; if ( con__ascii !== {"abcd","efgh","ijkl","mnop"}) $stop; con__ascii = "abcdefghijklm"; if ( con__ascii !== {24'h0,"a","bcde","fghi","jklm"}) $stop; if ( 3'dx !== 3'hx) $stop; // Wide decimal if ( 94'd12345678901234567890123456789 != 94'h27e41b3246bec9b16e398115) $stop; if (-94'sd123456789012345678901234567 != 94'h3f99e1020ea70d57d360b479) $stop; // Increments w32 = 12; w32++; if (w32 != 13) $stop; w32 = 12; ++w32; if (w32 != 13) $stop; w32 = 12; w32--; if (w32 != 11) $stop; w32 = 12; --w32; if (w32 != 11) $stop; w32 = 12; w32 += 2; if (w32 != 14) $stop; w32 = 12; w32 -= 2; if (w32 != 10) $stop; w32 = 12; w32 *= 2; if (w32 != 24) $stop; w32 = 12; w32 /= 2; if (w32 != 6) $stop; w32 = 12; w32 &= 6; if (w32 != 4) $stop; w32 = 12; w32 |= 15; if (w32 != 15) $stop; w32 = 12; w32 ^= 15; if (w32 != 3) $stop; w32 = 12; w32 >>= 1; if (w32 != 6) $stop; w32 = 12; w32 <<= 1; if (w32 != 24) $stop; // Increments v32[1] = 12; v32[1]++; if (v32[1] != 13) $stop; v32[1] = 12; ++v32[1]; if (v32[1] != 13) $stop; v32[1] = 12; v32[1]--; if (v32[1] != 11) $stop; v32[1] = 12; --v32[1]; if (v32[1] != 11) $stop; v32[1] = 12; v32[1] += 2; if (v32[1] != 14) $stop; v32[1] = 12; v32[1] -= 2; if (v32[1] != 10) $stop; v32[1] = 12; v32[1] *= 2; if (v32[1] != 24) $stop; v32[1] = 12; v32[1] /= 2; if (v32[1] != 6) $stop; v32[1] = 12; v32[1] &= 6; if (v32[1] != 4) $stop; v32[1] = 12; v32[1] |= 15; if (v32[1] != 15) $stop; v32[1] = 12; v32[1] ^= 15; if (v32[1] != 3) $stop; v32[1] = 12; v32[1] >>= 1; if (v32[1] != 6) $stop; v32[1] = 12; v32[1] <<= 1; if (v32[1] != 24) $stop; end if (cyc==2) begin win <= 32'h123123; if (narrow !== 32'hfffffefb) $stop; if (narrow2 !== 32'hffffff9d) $stop; end if (cyc==3) begin if (narrow !== 32'h00123012) $stop; if (narrow2 !== 32'h001230b4) $stop; end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_dpi_var.v0000664000177100017500000000433612473477707020665 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2010 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. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; wire monclk = ~clk; int in; int fr_a; int fr_b; int fr_chk; sub sub (.*); // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d in=%x fr_a=%x b=%x fr_chk=%x\n",$time, cyc, in, fr_a, fr_b, fr_chk); `endif cyc <= cyc + 1; in <= {in[30:0], in[31]^in[2]^in[0]}; if (cyc==0) begin // Setup in <= 32'hd70a4497; end else if (cyc<3) begin end else if (cyc<10) begin if (fr_chk != fr_a) $stop; if (fr_chk != fr_b) $stop; end else if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end always @(posedge t.monclk) begin mon_eval(); end endmodule import "DPI-C" context function void mon_scope_name (input string formatted /*verilator sformat*/ ); import "DPI-C" context function void mon_register_b(string name, int isOut); import "DPI-C" context function void mon_register_done(); import "DPI-C" context function void mon_eval(); module sub (/*AUTOARG*/ // Outputs fr_a, fr_b, fr_chk, // Inputs in ); `systemc_imp_header void mon_class_name(const char* namep); void mon_register_a(const char* namep, void* sigp, bool isOut); `verilog input int in /*verilator public_flat_rd*/; output int fr_a /*verilator public_flat_rw @(posedge t.monclk)*/; output int fr_b /*verilator public_flat_rw @(posedge t.monclk)*/; output int fr_chk; always @* fr_chk = in + 1; initial begin // Test the naming $c("mon_class_name(name());"); mon_scope_name("%m"); // Scheme A - pass pointer directly $c("mon_register_a(\"in\",&",in,",false);"); $c("mon_register_a(\"fr_a\",&",fr_a,",true);"); // Scheme B - use VPIish callbacks to see what signals exist mon_register_b("in", 0); mon_register_b("fr_b", 1); mon_register_done(); end endmodule verilator-3.874/test_regress/t/t_order_wireloop.pl0000775000177100017500000000133612525171734022427 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2005 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. compile ( fails=>$Self->{v3}, # Used to be %Error: t/t_order_wireloop.v:\d+: Wire inputs its own output, creating circular logic .wire x=x. # However we no longer gate optimize this expect=> '%Warning-UNOPT: t/t_order_wireloop.v:\d+: Signal unoptimizable: Feedback to public clock or circular logic: bar ', ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_gen.pl0000775000177100017500000000071712473477707021040 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_converge_run_bad.pl0000775000177100017500000000114412473477707024133 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2007 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. top_filename("t/t_unopt_converge.v"); compile ( v_flags2 => ['+define+ALLOW_UNOPT'], ); execute ( fails=>1, expect=> '%Error: \S+:\d+: Verilated model didn\'t converge', ) if $Self->{vlt}; ok(1); 1; verilator-3.874/test_regress/t/t_tri_graph.v0000664000177100017500000000075212473477707021216 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Unsupported tristate constructur error // // This is a compile only regression test of tristate handling for bug514 // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [11:0] ck; assign ck[1:0] = {1'bz,{1{1'b0}}}; test i_test (.clk (ck[1:0])); endmodule module test (clk); output wire [1:0] clk; endmodule // test verilator-3.874/test_regress/t/t_sys_plusargs.v0000664000177100017500000000207712473477707021777 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; integer p_i; reg [7*8:1] p_str; initial begin if ($test$plusargs("PLUS")!==1) $stop; if ($test$plusargs("PLUSNOT")!==0) $stop; if ($test$plusargs("PL")!==1) $stop; //if ($test$plusargs("")!==1) $stop; // Simulators differ in this answer if ($test$plusargs("NOTTHERE")!==0) $stop; p_i = 10; if ($value$plusargs("NOTTHERE%d", p_i)!==0) $stop; if (p_i !== 10) $stop; if ($value$plusargs("INT=%d", p_i)!==1) $stop; if (p_i !== 32'd1234) $stop; if ($value$plusargs("INT=%H", p_i)!==1) $stop; // tests uppercase % also if (p_i !== 32'h1234) $stop; if ($value$plusargs("INT=%o", p_i)!==1) $stop; if (p_i !== 32'o1234) $stop; if ($value$plusargs("IN%s", p_str)!==1) $stop; $display("str='%s'",p_str); if (p_str !== "T=1234") $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_clk_condflop.v0000664000177100017500000000464112473477707021675 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (clk); input clk; reg [0:0] d1; reg [2:0] d3; reg [7:0] d8; wire [0:0] q1; wire [2:0] q3; wire [7:0] q8; // verilator lint_off UNOPTFLAT reg ena; // verilator lint_on UNOPTFLAT condff #(12) condff (.clk(clk), .sen(1'b0), .ena(ena), .d({d8,d3,d1}), .q({q8,q3,q1})); integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin //$write("%x %x %x %x\n", cyc, q8, q3, q1); cyc <= cyc + 1; if (cyc==1) begin d1 <= 1'b1; d3<=3'h1; d8<=8'h11; ena <= 1'b1; end if (cyc==2) begin d1 <= 1'b0; d3<=3'h2; d8<=8'h33; ena <= 1'b0; end if (cyc==3) begin d1 <= 1'b1; d3<=3'h3; d8<=8'h44; ena <= 1'b1; if (q8 != 8'h11) $stop; end if (cyc==4) begin d1 <= 1'b1; d3<=3'h4; d8<=8'h77; ena <= 1'b1; if (q8 != 8'h11) $stop; end if (cyc==5) begin d1 <= 1'b1; d3<=3'h0; d8<=8'h88; ena <= 1'b1; if (q8 != 8'h44) $stop; end if (cyc==6) begin if (q8 != 8'h77) $stop; end if (cyc==7) begin if (q8 != 8'h88) $stop; end // if (cyc==20) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module condff (clk, sen, ena, d, q); parameter WIDTH = 1; input clk; input sen; input ena; input [WIDTH-1:0] d; output [WIDTH-1:0] q; condffimp #(.WIDTH(WIDTH)) imp (.clk(clk), .sen(sen), .ena(ena), .d(d), .q(q)); endmodule module condffimp (clk, sen, ena, d, q); parameter WIDTH = 1; input clk; input sen; input ena; input [WIDTH-1:0] d; output reg [WIDTH-1:0] q; wire gatedclk; clockgate clockgate (.clk(clk), .sen(sen), .ena(ena), .gatedclk(gatedclk)); always @(posedge gatedclk) begin if (gatedclk === 1'bX) begin q <= {WIDTH{1'bX}}; end else begin q <= d; end end endmodule module clockgate (clk, sen, ena, gatedclk); input clk; input sen; input ena; output gatedclk; reg ena_b; wire gatedclk = clk & ena_b; // verilator lint_off COMBDLY always @(clk or ena or sen) begin if (~clk) begin ena_b <= ena | sen; end else begin if ((clk^sen)===1'bX) ena_b <= 1'bX; end end // verilator lint_on COMBDLY endmodule verilator-3.874/test_regress/t/t_dpi_accessors_macros_inc.vh0000664000177100017500000000167112473477707024426 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Generic accessor macros for test of DPI accessors // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // // Contributed by Jeremy Bennett and Jie Xu // // See t_dpi_accessors.v for details of the test. This file should be included // by the top level module to define the generic accessor macros. // Accessor macros, to keep stuff concise `define R_ACCESS(type_spec, name, expr) \ export "DPI-C" function name``_read; \ function type_spec name``_read; \ name``_read = (expr); \ endfunction `define W_ACCESS(type_spec, name, expr) \ export "DPI-C" function name``_write; \ task name``_write; \ input bit type_spec in; \ expr = in; \ endtask `define RW_ACCESS(type_spec, name, expr) \ `R_ACCESS (type_spec, name, expr); \ `W_ACCESS (type_spec, name, expr) verilator-3.874/test_regress/t/t_detectarray_3.v0000664000177100017500000000140712473477707021766 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Simple test of unoptflat // // Trigger the DETECTARRAY error on packed structure. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jie Xu. localparam ID_MSB = 1; module t (/*AUTOARG*/ // Inputs clk, res ); input clk; output [8:0][8:0] res; logic a = 1'b1; logic [8:0] b [8:0]; // where the error is reported logic [8:0][8:0] c; // where the error is reported // following just to make c as circular assign c[0] = c[0] | a << 1; assign b[0] = b[0] | a << 2; assign res[0] = c[0]; assign res[1] = b[0]; always @(posedge clk or negedge clk) begin if (res != 0) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_bitsel_struct2.pl0000775000177100017500000000072212473477707022355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_emit_constw.pl0000775000177100017500000000075712473477707021750 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ['--Ox'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_blocking.v0000664000177100017500000000363212473477707021027 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer _mode; initial _mode=0; reg [7:0] a; reg [7:0] b; reg [7:0] c; reg [7:0] mode_d1r; reg [7:0] mode_d2r; reg [7:0] mode_d3r; // surefire lint_off ITENST // surefire lint_off STMINI // surefire lint_off NBAJAM always @ (posedge clk) begin // filp-flops with asynchronous reset if (0) begin _mode <= 0; end else begin _mode <= _mode + 1; if (_mode==0) begin $write("[%0t] t_blocking: Running\n", $time); a <= 8'd0; b <= 8'd0; c <= 8'd0; end else if (_mode==1) begin if (a !== 8'd0) $stop; if (b !== 8'd0) $stop; if (c !== 8'd0) $stop; a <= b; b <= 8'd1; c <= b; if (a !== 8'd0) $stop; if (b !== 8'd0) $stop; if (c !== 8'd0) $stop; end else if (_mode==2) begin if (a !== 8'd0) $stop; if (b !== 8'd1) $stop; if (c !== 8'd0) $stop; a <= b; b <= 8'd2; c <= b; if (a !== 8'd0) $stop; if (b !== 8'd1) $stop; if (c !== 8'd0) $stop; end else if (_mode==3) begin if (a !== 8'd1) $stop; if (b !== 8'd2) $stop; if (c !== 8'd1) $stop; end else if (_mode==4) begin if (mode_d3r != 8'd1) $stop; $write("*-* All Finished *-*\n"); $finish; end end end always @ (posedge clk) begin mode_d3r <= mode_d2r; mode_d2r <= mode_d1r; mode_d1r <= _mode[7:0]; end reg [14:10] bits; // surefire lint_off SEQASS always @ (posedge clk) begin if (_mode==1) begin bits[14:13] <= 2'b11; bits[12] <= 1'b1; end if (_mode==2) begin bits[11:10] <= 2'b10; bits[13] <= 0; end if (_mode==3) begin if (bits !== 5'b10110) $stop; end end endmodule verilator-3.874/test_regress/t/t_hierarchy_identifier_bad.v0000664000177100017500000000210012473477707024212 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter SIZE = 8; integer cnt = 0; logic [SIZE-1:0] vld_for; logic vld_if = 1'b0; logic vld_else = 1'b0; genvar i; // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if (cnt==SIZE) begin : if_cnt_finish $write("*-* All Finished *-*\n"); $finish; end : if_cnt_finish_bad generate for (i=0; i0) begin : generate_if_if always @ (posedge clk) vld_if <= 1'b1; end : generate_if_if_bad else begin : generate_if_else always @ (posedge clk) vld_else <= 1'b1; end : generate_if_else_bad endgenerate endmodule : t_bad verilator-3.874/test_regress/t/t_gen_cond_bitrange_bad.v0000664000177100017500000000457412473477707023502 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test for short-circuiting in generate "if" // that should not work. // // The given generate loops should attempt to access invalid bits of mask and // trigger errors. // is defined by SIZE. However since the loop range is larger, this only works // if short-circuited evaluation of the generate loop is in place. // This file ONLY is placed into the Public Domain, for any use, without // warranty, 2012 by Jeremy Bennett. `define MAX_SIZE 3 module t (/*AUTOARG*/ // Inputs clk ); input clk; // Set the parameters, so that we use a size less than MAX_SIZE test_gen #(.SIZE (2), .MASK (2'b11)) i_test_gen (.clk (clk)); // This is only a compilation test, so we can immediately finish always @(posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule // t module test_gen #( parameter SIZE = `MAX_SIZE, MASK = `MAX_SIZE'b0) (/*AUTOARG*/ // Inputs clk ); input clk; // Generate blocks that all have errors in applying short-circuting to // generate "if" conditionals. // Attempt to access invalid bits of MASK in different ways generate genvar g; for (g = 0; g < `MAX_SIZE; g = g + 1) begin if ((g < (SIZE + 1)) && MASK[g]) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Logical AND generate if MASK [%1d] = %d\n", g, MASK[g]); `endif end end end endgenerate generate for (g = 0; g < `MAX_SIZE; g = g + 1) begin if ((g < SIZE) && MASK[g + 1]) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Logical AND generate if MASK [%1d] = %d\n", g, MASK[g]); `endif end end end endgenerate // Attempt to short-circuit bitwise AND generate for (g = 0; g < `MAX_SIZE; g = g + 1) begin if ((g < (SIZE)) & MASK[g]) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Bitwise AND generate if MASK [%1d] = %d\n", g, MASK[g]); `endif end end end endgenerate // Attempt to short-circuit bitwise OR generate for (g = 0; g < `MAX_SIZE; g = g + 1) begin if (!((g >= SIZE) | ~MASK[g])) begin always @(posedge clk) begin `ifdef TEST_VERBOSE $write ("Bitwise OR generate if MASK [%1d] = %d\n", g, MASK[g]); `endif end end end endgenerate endmodule verilator-3.874/test_regress/t/t_inst_sv.v0000664000177100017500000000300212473477707020713 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); `ifdef verilator // Otherwise need it in every module, including test, but that'll make a mess timeunit 1ns; timeprecision 1ns; `endif input clk; integer cyc; initial cyc=1; supply0 [1:0] low; supply1 [1:0] high; reg [7:0] isizedwire; reg ionewire; wire oonewire; wire [7:0] osizedreg; // From sub of t_inst_v2k_sub.v t_inst sub ( .osizedreg, .oonewire, // Inputs .isizedwire (isizedwire[7:0]), .* //.ionewire (ionewire) ); always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin ionewire <= 1'b1; isizedwire <= 8'd8; end if (cyc==2) begin if (low != 2'b00) $stop; if (high != 2'b11) $stop; if (oonewire !== 1'b1) $stop; if (isizedwire !== 8'd8) $stop; end if (cyc==3) begin ionewire <= 1'b0; isizedwire <= 8'd7; end if (cyc==4) begin if (oonewire !== 1'b0) $stop; if (isizedwire !== 8'd7) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule module t_inst ( output reg [7:0] osizedreg, output wire oonewire /*verilator public*/, input [7:0] isizedwire, input wire ionewire ); assign oonewire = ionewire; always @* begin osizedreg = isizedwire; end endmodule verilator-3.874/test_regress/t/t_func_lib_sub.pl0000775000177100017500000000075012473477707022040 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( ); # No execute ok(1); 1; verilator-3.874/test_regress/t/t_trace_cat_renew_0000.out0000664000177100017500000000533012473477707023362 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Sat Feb 23 20:40:11 2013 $end $timescale 1ns $end $scope module top $end $var wire 1 $ clk $end $scope module v $end $var wire 1 $ clk $end $var wire 32 # cyc [31:0] $end $upscope $end $upscope $end $enddefinitions $end #0 b00000000000000000000000000000001 # 1$ #1 0$ #2 b00000000000000000000000000000010 # 1$ #3 0$ #4 b00000000000000000000000000000011 # 1$ #5 0$ #6 b00000000000000000000000000000100 # 1$ #7 0$ #8 b00000000000000000000000000000101 # 1$ #9 0$ #10 b00000000000000000000000000000110 # 1$ #11 0$ #12 b00000000000000000000000000000111 # 1$ #13 0$ #14 b00000000000000000000000000001000 # 1$ #15 0$ #16 b00000000000000000000000000001001 # 1$ #17 0$ #18 b00000000000000000000000000001010 # 1$ #19 0$ #20 b00000000000000000000000000001011 # 1$ #21 0$ #22 b00000000000000000000000000001100 # 1$ #23 0$ #24 b00000000000000000000000000001101 # 1$ #25 0$ #26 b00000000000000000000000000001110 # 1$ #27 0$ #28 b00000000000000000000000000001111 # 1$ #29 0$ #30 b00000000000000000000000000010000 # 1$ #31 0$ #32 b00000000000000000000000000010001 # 1$ #33 0$ #34 b00000000000000000000000000010010 # 1$ #35 0$ #36 b00000000000000000000000000010011 # 1$ #37 0$ #38 b00000000000000000000000000010100 # 1$ #39 0$ #40 b00000000000000000000000000010101 # 1$ #41 0$ #42 b00000000000000000000000000010110 # 1$ #43 0$ #44 b00000000000000000000000000010111 # 1$ #45 0$ #46 b00000000000000000000000000011000 # 1$ #47 0$ #48 b00000000000000000000000000011001 # 1$ #49 0$ #50 b00000000000000000000000000011010 # 1$ #51 0$ #52 b00000000000000000000000000011011 # 1$ #53 0$ #54 b00000000000000000000000000011100 # 1$ #55 0$ #56 b00000000000000000000000000011101 # 1$ #57 0$ #58 b00000000000000000000000000011110 # 1$ #59 0$ #60 b00000000000000000000000000011111 # 1$ #61 0$ #62 b00000000000000000000000000100000 # 1$ #63 0$ #64 b00000000000000000000000000100001 # 1$ #65 0$ #66 b00000000000000000000000000100010 # 1$ #67 0$ #68 b00000000000000000000000000100011 # 1$ #69 0$ #70 b00000000000000000000000000100100 # 1$ #71 0$ #72 b00000000000000000000000000100101 # 1$ #73 0$ #74 b00000000000000000000000000100110 # 1$ #75 0$ #76 b00000000000000000000000000100111 # 1$ #77 0$ #78 b00000000000000000000000000101000 # 1$ #79 0$ #80 b00000000000000000000000000101001 # 1$ #81 0$ #82 b00000000000000000000000000101010 # 1$ #83 0$ #84 b00000000000000000000000000101011 # 1$ #85 0$ #86 b00000000000000000000000000101100 # 1$ #87 0$ #88 b00000000000000000000000000101101 # 1$ #89 0$ #90 b00000000000000000000000000101110 # 1$ #91 0$ #92 b00000000000000000000000000101111 # 1$ #93 0$ #94 b00000000000000000000000000110000 # 1$ #95 0$ #96 b00000000000000000000000000110001 # 1$ #97 0$ #98 b00000000000000000000000000110010 # 1$ #99 0$ verilator-3.874/test_regress/t/t_unroll_signed.v0000664000177100017500000000616212473477707022104 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // Check empty blocks task EmptyFor; /* verilator public */ integer i; begin for (i = 0; i < 2; i = i+1) begin end end endtask // Check look unroller reg signed signed_tests_only = 1'sb1; integer total; integer i; reg [31:0] iu; reg [31:0] dly_to_insure_was_unrolled [1:0]; reg [2:0] i3; integer cyc; initial cyc=0; always @ (posedge clk) begin cyc <= cyc + 1; case (cyc) 1: begin // >= signed total = 0; for (i=5; i>=0; i=i-1) begin total = total - i -1; dly_to_insure_was_unrolled[i] <= i; end if (total != -21) $stop; end 2: begin // > signed total = 0; for (i=5; i>0; i=i-1) begin total = total - i -1; dly_to_insure_was_unrolled[i] <= i; end if (total != -20) $stop; end 3: begin // < signed total = 0; for (i=1; i<5; i=i+1) begin total = total - i -1; dly_to_insure_was_unrolled[i] <= i; end if (total != -14) $stop; end 4: begin // <= signed total = 0; for (i=1; i<=5; i=i+1) begin total = total - i -1; dly_to_insure_was_unrolled[i] <= i; end if (total != -20) $stop; end // UNSIGNED 5: begin // >= unsigned total = 0; for (iu=5; iu>=1; iu=iu-1) begin total = total - iu -1; dly_to_insure_was_unrolled[iu] <= iu; end if (total != -20) $stop; end 6: begin // > unsigned total = 0; for (iu=5; iu>1; iu=iu-1) begin total = total - iu -1; dly_to_insure_was_unrolled[iu] <= iu; end if (total != -18) $stop; end 7: begin // < unsigned total = 0; for (iu=1; iu<5; iu=iu+1) begin total = total - iu -1; dly_to_insure_was_unrolled[iu] <= iu; end if (total != -14) $stop; end 8: begin // <= unsigned total = 0; for (iu=1; iu<=5; iu=iu+1) begin total = total - iu -1; dly_to_insure_was_unrolled[iu] <= iu; end if (total != -20) $stop; end //=== 9: begin // mostly cover a small index total = 0; for (i3=3'd0; i3<3'd7; i3=i3+3'd1) begin total = total - {29'd0,i3} -1; dly_to_insure_was_unrolled[i3[0]] <= 0; end if (total != -28) $stop; end //=== 10: begin // mostly cover a small index total = 0; for (i3=0; i3<3'd7; i3=i3+3'd1) begin total = total - {29'd0,i3} -1; dly_to_insure_was_unrolled[i3[0]] <= 0; end if (total != -28) $stop; end //=== 11: begin // width violation on <, causes extend total = 0; for (i3=3'd0; i3<7; i3=i3+1) begin total = total - {29'd0,i3} -1; dly_to_insure_was_unrolled[i3[0]] <= 0; end if (total != -28) $stop; end //=== // width violation on <, causes extend signed // Unsupported as yet //=== 19: begin $write("*-* All Finished *-*\n"); $finish; end default: ; endcase end endmodule verilator-3.874/test_regress/t/t_dpi_qw.v0000664000177100017500000000155512473477707020524 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. module t; wire [39:0] out; sub a(.value(out)); import "DPI-C" context function void poke_value(input int i); initial begin poke_value(32'hdeadbeef); if (out !== 40'hdeadbeef) begin $display("[%0t] %%Error: t_dpi_qw: failed", $time); $stop; end $write("*-* All Finished *-*\n"); $finish; end endmodule module sub(value); parameter WIDTH = 40; output [WIDTH-1:0] value; reg [WIDTH-1:0] value; task set_value(input bit [WIDTH-1:0] v); value = v; endtask export "DPI-C" task set_value; endmodule verilator-3.874/test_regress/t/t_math_concat64.v0000664000177100017500000001524612473477707021675 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [127:0] i; wire [127:0] q1; wire [127:0] q32; wire [127:0] q64; wire [63:0] q64_low; assign q1 = { i[24*4], i[25*4], i[26*4], i[27*4], i[28*4], i[29*4], i[30*4], i[31*4], i[16*4], i[17*4], i[18*4], i[19*4], i[20*4], i[21*4], i[22*4], i[23*4], i[8*4], i[9*4], i[10*4], i[11*4], i[12*4], i[13*4], i[14*4], i[15*4], i[0*4], i[1*4], i[2*4], i[3*4], i[4*4], i[5*4], i[6*4], i[7*4], i[24*4+1], i[25*4+1], i[26*4+1], i[27*4+1], i[28*4+1], i[29*4+1], i[30*4+1], i[31*4+1], i[16*4+1], i[17*4+1], i[18*4+1], i[19*4+1], i[20*4+1], i[21*4+1], i[22*4+1], i[23*4+1], i[8*4+1], i[9*4+1], i[10*4+1], i[11*4+1], i[12*4+1], i[13*4+1], i[14*4+1], i[15*4+1], i[0*4+1], i[1*4+1], i[2*4+1], i[3*4+1], i[4*4+1], i[5*4+1], i[6*4+1], i[7*4+1], i[24*4+2], i[25*4+2], i[26*4+2], i[27*4+2], i[28*4+2], i[29*4+2], i[30*4+2], i[31*4+2], i[16*4+2], i[17*4+2], i[18*4+2], i[19*4+2], i[20*4+2], i[21*4+2], i[22*4+2], i[23*4+2], i[8*4+2], i[9*4+2], i[10*4+2], i[11*4+2], i[12*4+2], i[13*4+2], i[14*4+2], i[15*4+2], i[0*4+2], i[1*4+2], i[2*4+2], i[3*4+2], i[4*4+2], i[5*4+2], i[6*4+2], i[7*4+2], i[24*4+3], i[25*4+3], i[26*4+3], i[27*4+3], i[28*4+3], i[29*4+3], i[30*4+3], i[31*4+3], i[16*4+3], i[17*4+3], i[18*4+3], i[19*4+3], i[20*4+3], i[21*4+3], i[22*4+3], i[23*4+3], i[8*4+3], i[9*4+3], i[10*4+3], i[11*4+3], i[12*4+3], i[13*4+3], i[14*4+3], i[15*4+3], i[0*4+3], i[1*4+3], i[2*4+3], i[3*4+3], i[4*4+3], i[5*4+3], i[6*4+3], i[7*4+3]}; assign q64[127:64] = { i[24*4], i[25*4], i[26*4], i[27*4], i[28*4], i[29*4], i[30*4], i[31*4], i[16*4], i[17*4], i[18*4], i[19*4], i[20*4], i[21*4], i[22*4], i[23*4], i[8*4], i[9*4], i[10*4], i[11*4], i[12*4], i[13*4], i[14*4], i[15*4], i[0*4], i[1*4], i[2*4], i[3*4], i[4*4], i[5*4], i[6*4], i[7*4], i[24*4+1], i[25*4+1], i[26*4+1], i[27*4+1], i[28*4+1], i[29*4+1], i[30*4+1], i[31*4+1], i[16*4+1], i[17*4+1], i[18*4+1], i[19*4+1], i[20*4+1], i[21*4+1], i[22*4+1], i[23*4+1], i[8*4+1], i[9*4+1], i[10*4+1], i[11*4+1], i[12*4+1], i[13*4+1], i[14*4+1], i[15*4+1], i[0*4+1], i[1*4+1], i[2*4+1], i[3*4+1], i[4*4+1], i[5*4+1], i[6*4+1], i[7*4+1]}; assign q64[63:0] = { i[24*4+2], i[25*4+2], i[26*4+2], i[27*4+2], i[28*4+2], i[29*4+2], i[30*4+2], i[31*4+2], i[16*4+2], i[17*4+2], i[18*4+2], i[19*4+2], i[20*4+2], i[21*4+2], i[22*4+2], i[23*4+2], i[8*4+2], i[9*4+2], i[10*4+2], i[11*4+2], i[12*4+2], i[13*4+2], i[14*4+2], i[15*4+2], i[0*4+2], i[1*4+2], i[2*4+2], i[3*4+2], i[4*4+2], i[5*4+2], i[6*4+2], i[7*4+2], i[24*4+3], i[25*4+3], i[26*4+3], i[27*4+3], i[28*4+3], i[29*4+3], i[30*4+3], i[31*4+3], i[16*4+3], i[17*4+3], i[18*4+3], i[19*4+3], i[20*4+3], i[21*4+3], i[22*4+3], i[23*4+3], i[8*4+3], i[9*4+3], i[10*4+3], i[11*4+3], i[12*4+3], i[13*4+3], i[14*4+3], i[15*4+3], i[0*4+3], i[1*4+3], i[2*4+3], i[3*4+3], i[4*4+3], i[5*4+3], i[6*4+3], i[7*4+3]}; assign q64_low = { i[24*4+2], i[25*4+2], i[26*4+2], i[27*4+2], i[28*4+2], i[29*4+2], i[30*4+2], i[31*4+2], i[16*4+2], i[17*4+2], i[18*4+2], i[19*4+2], i[20*4+2], i[21*4+2], i[22*4+2], i[23*4+2], i[8*4+2], i[9*4+2], i[10*4+2], i[11*4+2], i[12*4+2], i[13*4+2], i[14*4+2], i[15*4+2], i[0*4+2], i[1*4+2], i[2*4+2], i[3*4+2], i[4*4+2], i[5*4+2], i[6*4+2], i[7*4+2], i[24*4+3], i[25*4+3], i[26*4+3], i[27*4+3], i[28*4+3], i[29*4+3], i[30*4+3], i[31*4+3], i[16*4+3], i[17*4+3], i[18*4+3], i[19*4+3], i[20*4+3], i[21*4+3], i[22*4+3], i[23*4+3], i[8*4+3], i[9*4+3], i[10*4+3], i[11*4+3], i[12*4+3], i[13*4+3], i[14*4+3], i[15*4+3], i[0*4+3], i[1*4+3], i[2*4+3], i[3*4+3], i[4*4+3], i[5*4+3], i[6*4+3], i[7*4+3]}; assign q32[127:96] = { i[24*4], i[25*4], i[26*4], i[27*4], i[28*4], i[29*4], i[30*4], i[31*4], i[16*4], i[17*4], i[18*4], i[19*4], i[20*4], i[21*4], i[22*4], i[23*4], i[8*4], i[9*4], i[10*4], i[11*4], i[12*4], i[13*4], i[14*4], i[15*4], i[0*4], i[1*4], i[2*4], i[3*4], i[4*4], i[5*4], i[6*4], i[7*4]}; assign q32[95:64] = { i[24*4+1], i[25*4+1], i[26*4+1], i[27*4+1], i[28*4+1], i[29*4+1], i[30*4+1], i[31*4+1], i[16*4+1], i[17*4+1], i[18*4+1], i[19*4+1], i[20*4+1], i[21*4+1], i[22*4+1], i[23*4+1], i[8*4+1], i[9*4+1], i[10*4+1], i[11*4+1], i[12*4+1], i[13*4+1], i[14*4+1], i[15*4+1], i[0*4+1], i[1*4+1], i[2*4+1], i[3*4+1], i[4*4+1], i[5*4+1], i[6*4+1], i[7*4+1]}; assign q32[63:32] = { i[24*4+2], i[25*4+2], i[26*4+2], i[27*4+2], i[28*4+2], i[29*4+2], i[30*4+2], i[31*4+2], i[16*4+2], i[17*4+2], i[18*4+2], i[19*4+2], i[20*4+2], i[21*4+2], i[22*4+2], i[23*4+2], i[8*4+2], i[9*4+2], i[10*4+2], i[11*4+2], i[12*4+2], i[13*4+2], i[14*4+2], i[15*4+2], i[0*4+2], i[1*4+2], i[2*4+2], i[3*4+2], i[4*4+2], i[5*4+2], i[6*4+2], i[7*4+2]}; assign q32[31:0] = { i[24*4+3], i[25*4+3], i[26*4+3], i[27*4+3], i[28*4+3], i[29*4+3], i[30*4+3], i[31*4+3], i[16*4+3], i[17*4+3], i[18*4+3], i[19*4+3], i[20*4+3], i[21*4+3], i[22*4+3], i[23*4+3], i[8*4+3], i[9*4+3], i[10*4+3], i[11*4+3], i[12*4+3], i[13*4+3], i[14*4+3], i[15*4+3], i[0*4+3], i[1*4+3], i[2*4+3], i[3*4+3], i[4*4+3], i[5*4+3], i[6*4+3], i[7*4+3]}; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("%x %x\n", q1, i); `endif if (cyc==1) begin i <= 128'hed388e646c843d35de489bab2413d770; end if (cyc==2) begin i <= 128'h0e17c88f3d5fe51a982646c8e2bd68c3; if (q1 != 128'h06f0b17c6551e269e3ab07723b26fb10) $stop; if (q1 != q32) $stop; if (q1 != q64) $stop; if (q1[63:0] != q64_low) $stop; end if (cyc==3) begin i <= 128'he236ddfddddbdad20a48e039c9f395b8; if (q1 != 128'h8c6f018c8a992c979a3e7859f29ac36d) $stop; if (q1 != q32) $stop; if (q1 != q64) $stop; if (q1[63:0] != q64_low) $stop; end if (cyc==4) begin i <= 128'h45e0eb7642b148537491f3da147e7f26; if (q1 != 128'hf45fc07e4fa8524cf9571425f17f9ad7) $stop; if (q1 != q32) $stop; if (q1 != q64) $stop; if (q1[63:0] != q64_low) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_inst_dtree_inlad.pl0000775000177100017500000000112012473477707022705 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_dtree.v"); compile ( v_flags2 => ['+define+INLINE_A +define+INLINE_D'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_iforder.pl0000775000177100017500000000072412473477707021677 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_rsvd_port.v0000664000177100017500000000062412473477707022127 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs bool ); input bool; // BAD reg vector; // OK, as not public reg switch /*verilator public*/; // Bad initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_select_little.v0000664000177100017500000000421512473477707022071 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // verilator lint_off LITENDIAN wire [10:41] sel2 = crc[31:0]; wire [10:100] sel3 = {crc[26:0],crc}; wire out20 = sel2[{1'b0,crc[3:0]} + 11]; wire [3:0] out21 = sel2[13 : 16]; wire [3:0] out22 = sel2[{1'b0,crc[3:0]} + 20 +: 4]; wire [3:0] out23 = sel2[{1'b0,crc[3:0]} + 20 -: 4]; wire out30 = sel3[{2'b0,crc[3:0]} + 11]; wire [3:0] out31 = sel3[13 : 16]; wire [3:0] out32 = sel3[crc[5:0] + 20 +: 4]; wire [3:0] out33 = sel3[crc[5:0] + 20 -: 4]; // Aggregate outputs into a single result vector wire [63:0] result = {38'h0, out20, out21, out22, out23, out30, out31, out32, out33}; reg [19:50] sel1; initial begin // Path clearing // 122333445 // 826048260 sel1 = 32'h12345678; if (sel1 != 32'h12345678) $stop; if (sel1[47 : 50] != 4'h8) $stop; if (sel1[31 : 34] != 4'h4) $stop; if (sel1[27 +: 4] != 4'h3) $stop; //==[27:30], in memory as [23:20] if (sel1[26 -: 4] != 4'h2) $stop; //==[23:26], in memory as [27:24] end // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] sels=%x,%x,%x,%x %x,%x,%x,%x\n",$time, out20,out21,out22,out23, out30,out31,out32,out33); $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; `define EXPECTED_SUM 64'h28bf65439eb12c00 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_trace_cat.v0000664000177100017500000000046212473477707021162 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t ( input wire clk ); integer cyc; initial cyc = 0; always @ (posedge clk) begin cyc <= cyc + 1; end endmodule verilator-3.874/test_regress/t/t_dpi_var.pl0000775000177100017500000000110212473477707021022 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe --no-l2name $Self->{t_dir}/t_dpi_var.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_unoptflat_simple.v0000664000177100017500000000111512473477707022616 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Simple test of unoptflat // // Simple demonstration of an UNOPTFLAT combinatorial loop, using just 2 bits. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [1:0] x = { x[0], clk }; initial begin x = 0; end always @(posedge clk or negedge clk) begin `ifdef TEST_VERBOSE $write("x = %x\n", x); `endif if (x[1] != 0) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_vlt_warn.pl0000775000177100017500000000112112473477707021233 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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->skip("Verilator only test") if !$Self->{vlt}; compile ( make_top_shell => 0, make_main => 0, verilator_make_gcc => 0, v_flags2 => ["--lint-only t/t_vlt_warn.vlt"], ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_public_func.pl0000775000177100017500000000137312473477707023057 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_trace_public.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["-DPUB_FUNC --trace --exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/t_trace_public.out"); ok(1); 1; verilator-3.874/test_regress/t/t_clk_latchgate.v0000664000177100017500000001130712473477707022022 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. // // -------------------------------------------------------- // Bug Description: // // Issue: The gated clock gclk_vld[0] toggles but dvld[0] // input to the flop does not propagate to the output // signal entry_vld[0] correctly. The value that propagates // is the new value of dvld[0] not the one just before the // posedge of gclk_vld[0]. // -------------------------------------------------------- // Define to see the bug with test failing with gated clock 'gclk_vld' // Comment out the define to see the test passing with ungated clock 'clk' `define GATED_CLK_TESTCASE 1 // A side effect of the problem is this warning, disabled by default //verilator lint_on IMPERFECTSCH // Test Bench module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; // Take CRC data and apply to testblock inputs wire [7:0] dvld = crc[7:0]; wire [7:0] ff_en_e1 = crc[15:8]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [7:0] entry_vld; // From test of Test.v wire [7:0] ff_en_vld; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .ff_en_vld (ff_en_vld[7:0]), .entry_vld (entry_vld[7:0]), // Inputs .clk (clk), .dvld (dvld[7:0]), .ff_en_e1 (ff_en_e1[7:0])); reg err_code; reg ffq_clk_active; reg [7:0] prv_dvld; initial begin err_code = 0; ffq_clk_active = 0; end always @ (posedge clk) begin prv_dvld = test.dvld; end always @ (negedge test.ff_entry_dvld_0.clk) begin ffq_clk_active = 1; if (test.entry_vld[0] !== prv_dvld[0]) err_code = 1; end // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x ",$time, cyc, crc); $display(" en=%b fen=%b d=%b ev=%b", test.flop_en_vld[0], test.ff_en_vld[0], test.dvld[0], test.entry_vld[0]); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc<3) begin crc <= 64'h5aef0c8d_d70a4497; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x\n",$time, cyc, crc); if (ffq_clk_active == 0) begin $display ("----"); $display ("%%Error: TESTCASE FAILED with no Clock arriving at FFQs"); $display ("----"); $stop; end else if (err_code) begin $display ("----"); $display ("%%Error: TESTCASE FAILED with invalid propagation of 'd' to 'q' of FFQs"); $display ("----"); $stop; end else begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module llq (clk, d, q); parameter WIDTH = 32; input clk; input [WIDTH-1:0] d; output [WIDTH-1:0] q; reg [WIDTH-1:0] qr; /* verilator lint_off COMBDLY */ always @(clk or d) if (clk == 1'b0) qr <= d; /* verilator lint_on COMBDLY */ assign q = qr; endmodule module ffq (clk, d, q); parameter WIDTH = 32; input clk; input [WIDTH-1:0] d; output [WIDTH-1:0] q; reg [WIDTH-1:0] qr; always @(posedge clk) qr <= d; assign q = qr; endmodule // DUT module module Test (/*AUTOARG*/ // Outputs ff_en_vld, entry_vld, // Inputs clk, dvld, ff_en_e1 ); input clk; input [7:0] dvld; input [7:0] ff_en_e1; output [7:0] ff_en_vld; output wire [7:0] entry_vld; wire [7:0] gclk_vld; wire [7:0] ff_en_vld /*verilator clock_enable*/; reg [7:0] flop_en_vld; always @(posedge clk) flop_en_vld <= ff_en_e1; // clock gating `ifdef GATED_CLK_TESTCASE assign gclk_vld = {8{clk}} & ff_en_vld; `else assign gclk_vld = {8{clk}}; `endif // latch for avoiding glitch on the clock gating control llq #(8) dp_ff_en_vld (.clk(clk), .d(flop_en_vld), .q(ff_en_vld)); // flops that use the gated clock signal ffq #(1) ff_entry_dvld_0 (.clk(gclk_vld[0]), .d(dvld[0]), .q(entry_vld[0])); ffq #(1) ff_entry_dvld_1 (.clk(gclk_vld[1]), .d(dvld[1]), .q(entry_vld[1])); ffq #(1) ff_entry_dvld_2 (.clk(gclk_vld[2]), .d(dvld[2]), .q(entry_vld[2])); ffq #(1) ff_entry_dvld_3 (.clk(gclk_vld[3]), .d(dvld[3]), .q(entry_vld[3])); ffq #(1) ff_entry_dvld_4 (.clk(gclk_vld[4]), .d(dvld[4]), .q(entry_vld[4])); ffq #(1) ff_entry_dvld_5 (.clk(gclk_vld[5]), .d(dvld[5]), .q(entry_vld[5])); ffq #(1) ff_entry_dvld_6 (.clk(gclk_vld[6]), .d(dvld[6]), .q(entry_vld[6])); ffq #(1) ff_entry_dvld_7 (.clk(gclk_vld[7]), .d(dvld[7]), .q(entry_vld[7])); endmodule verilator-3.874/test_regress/t/t_array_query.v0000664000177100017500000000225412473477707021601 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: System Verilog test of array querying functions. // // This code instantiates a module that calls the various array querying // functions. // // This file ONLY is placed into the Public Domain, for any use, without // warranty. // Contributed 2012 by Jeremy Bennett, Embecosm. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire a = clk; wire b = 1'b0; reg c; array_test array_test_i (/*AUTOINST*/ // Inputs .clk (clk)); endmodule // Check the array sizing functions work correctly. module array_test #( parameter LEFT = 5, RIGHT = 55) (/*AUTOARG*/ // Inputs clk ); input clk; // verilator lint_off LITENDIAN reg [7:0] a [LEFT:RIGHT]; // verilator lint_on LITENDIAN integer l; integer r; integer s; always @(posedge clk) begin l = $left (a); r = $right (a); s = $size (a); `ifdef TEST_VERBOSE $write ("$left (a) = %d, $right (a) = %d, $size (a) = %d\n", l, r, s); `endif if ((l != LEFT) || (r != RIGHT) || (s != (RIGHT - LEFT + 1))) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_flag_topmod2_bad.v0000664000177100017500000000071712473477707022423 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module a_top; a a (); initial begin $write("Bad top modules\n"); $stop; end endmodule module a; b b (); c c (); d d (); endmodule module b; endmodule module c; endmodule module d; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_math_width.pl0000775000177100017500000000072212473477707021535 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_readmem.pl0000775000177100017500000000071712473477707021721 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_packed_value_list.pl0000775000177100017500000000071712473477707024473 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_werror_bad2.pl0000775000177100017500000000135312473477707022607 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_flag_werror.v"); compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, verilator_flags=> [qw(-cc -Werror-WIDTH)], expect=> q{%Error-WIDTH: t/t_flag_werror.v:\d+: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS.s CONST '6'h2e' generates 6 bits. %Error: Exiting due to}, ) if $Self->{v3}; ok(1); 1; verilator-3.874/test_regress/t/t_embed1_c.cpp0000664000177100017500000000770712473477707021222 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2011-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include "svdpi.h" #include "../t_embed1_child/Vt_embed1_child.h" //====================================================================== #if defined(VERILATOR) # include "Vt_embed1__Dpi.h" #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #include "verilated.h" #ifdef NEED_EXTERNS extern "C" { extern void t_embed_child_initial(); extern void t_embed_child_final(); extern void t_embed_child_eval(); extern void t_embed_child_io_eval(); // TODO real function params here } #endif //====================================================================== extern int T_Embed_Child_Unique; int T_Embed_Child_Unique = 0; // Address used for uniqueness Vt_embed1_child* __get_modelp() { svScope scope = svGetScope(); if (!scope) { vl_fatal(__FILE__,__LINE__,__FILE__,"svGetScope failed"); return NULL; } void* __modelp = svGetUserData(scope, &T_Embed_Child_Unique); if (!__modelp) { // Create the model const char* scopenamep = svGetNameFromScope(scope); if (!scopenamep) vl_fatal(__FILE__,__LINE__,__FILE__,"svGetNameFromScope failed"); __modelp = new Vt_embed1_child(scopenamep); if (svPutUserData(scope, &T_Embed_Child_Unique, __modelp)) { vl_fatal(__FILE__,__LINE__,__FILE__,"svPutUserData failed"); } } return (Vt_embed1_child*)(__modelp); } void t_embed_child_initial() { VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_initial\n"); ); Vt_embed1_child* __modelp = __get_modelp(); __modelp->eval(); } void t_embed_child_final() { VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_final\n"); ); Vt_embed1_child* __modelp = __get_modelp(); __modelp->final(); } void t_embed_child_eval() { VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_eval\n"); ); Vt_embed1_child* __modelp = __get_modelp(); __modelp->eval(); } void t_embed_child_io_eval (unsigned char clk, unsigned char bit_in, const svBitVecVal* vec_in, const svBitVecVal* wide_in, unsigned char is_ref, unsigned char* bit_out, svBitVecVal* vec_out, svBitVecVal* wide_out, unsigned char* did_init_out) { VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_io_eval\n"); ); Vt_embed1_child* __modelp = __get_modelp(); VL_DEBUG_IF(VL_PRINTF("[%0ld] in clk=%x b=%x V=%x R=%x\n", (long int) (VL_TIME_Q()), clk, bit_in, vec_in[0], is_ref);); __modelp->clk = clk; __modelp->bit_in = bit_in; __modelp->vec_in = vec_in[0]; __modelp->wide_in[0] = wide_in[0]; __modelp->wide_in[1] = wide_in[1]; __modelp->wide_in[2] = wide_in[2]; __modelp->wide_in[3] = wide_in[3]; __modelp->is_ref = is_ref; // __modelp->eval(); // TODO maybe we should look at a "change detect" to know if we need to copy // out the variables; can return this value to the caller verilog code too // *bit_out = __modelp->bit_out; vec_out[0] = __modelp->vec_out; wide_out[0] = __modelp->wide_out[0]; wide_out[1] = __modelp->wide_out[1]; wide_out[2] = __modelp->wide_out[2]; wide_out[3] = __modelp->wide_out[3]; *did_init_out = __modelp->did_init_out; VL_DEBUG_IF(VL_PRINTF("[%0ld] out b=%x V=%x DI=%x\n", (long int)(VL_TIME_Q()), *bit_out, *vec_out, *did_init_out);); } verilator-3.874/test_regress/t/t_sys_plusargs_bad.v0000664000177100017500000000074412473477707022604 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; integer p_i; initial begin // BAD: Missing argument if ($value$plusargs("NOTTHERE", p_i)!==0) $stop; // BAD: Bad letter if ($value$plusargs("INT=%z", p_i)!==0) $stop; // BAD: Multi letter if ($value$plusargs("INT=%x%x", p_i)!==0) $stop; $stop; end endmodule verilator-3.874/test_regress/t/t_param_package.v0000664000177100017500000000064212473477707022010 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module module t; Test0 t0 (.val0('0)); Test1 t1 (.val1('0)); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule package params; parameter P = 7; endpackage module Test0 (val0); parameter Z = 1; input [Z : 0] val0; endmodule module Test1 (val1); input logic [params::P : 0] val1; // Fully qualified parameter endmodule verilator-3.874/test_regress/t/t_param_long.v0000664000177100017500000002132112473477707021351 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); parameter PAR = 3; input clk; defparam i.L00 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L01 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L02 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L03 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L04 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L05 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L06 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L07 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L08 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L09 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L0A = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L0B = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L0C = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L0D = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L0E = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L0F = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L10 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L11 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L12 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L13 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L14 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L15 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L16 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L17 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L18 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L19 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L1A = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L1B = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L1C = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L1D = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L1E = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L1F = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L20 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L21 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L22 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L23 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L24 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L25 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L26 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L27 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L28 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L29 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L2A = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L2B = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L2C = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L2D = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L2E = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L2F = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L30 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L31 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L32 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L33 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L34 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L35 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L36 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L37 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L38 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L39 = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L3A = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L3B = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L3C = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L3D = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L3E = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.L3F = 256'h000012300000000000000000000000000000000000000000000000000000cdef; defparam i.A0 = "HELLO_WORLD_BOY_THIS_IS_LONG"; defparam i.A1 = "HELLO_WORLD_BOY_THIS_IS_LONG"; defparam i.A2 = "HELLO_WORLD_BOY_THIS_IS_LONG"; i i (.clk(clk)); integer cyc=1; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==1) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module i (/*AUTOARG*/ // Inputs clk ); // verilator public_module input clk; parameter [255:0] L00 = 256'h0; parameter [255:0] L01 = 256'h0; parameter [255:0] L02 = 256'h0; parameter [255:0] L03 = 256'h0; parameter [255:0] L04 = 256'h0; parameter [255:0] L05 = 256'h0; parameter [255:0] L06 = 256'h0; parameter [255:0] L07 = 256'h0; parameter [255:0] L08 = 256'h0; parameter [255:0] L09 = 256'h0; parameter [255:0] L0A = 256'h0; parameter [255:0] L0B = 256'h0; parameter [255:0] L0C = 256'h0; parameter [255:0] L0D = 256'h0; parameter [255:0] L0E = 256'h0; parameter [255:0] L0F = 256'h0; parameter [255:0] L10 = 256'h0; parameter [255:0] L11 = 256'h0; parameter [255:0] L12 = 256'h0; parameter [255:0] L13 = 256'h0; parameter [255:0] L14 = 256'h0; parameter [255:0] L15 = 256'h0; parameter [255:0] L16 = 256'h0; parameter [255:0] L17 = 256'h0; parameter [255:0] L18 = 256'h0; parameter [255:0] L19 = 256'h0; parameter [255:0] L1A = 256'h0; parameter [255:0] L1B = 256'h0; parameter [255:0] L1C = 256'h0; parameter [255:0] L1D = 256'h0; parameter [255:0] L1E = 256'h0; parameter [255:0] L1F = 256'h0; parameter [255:0] L20 = 256'h0; parameter [255:0] L21 = 256'h0; parameter [255:0] L22 = 256'h0; parameter [255:0] L23 = 256'h0; parameter [255:0] L24 = 256'h0; parameter [255:0] L25 = 256'h0; parameter [255:0] L26 = 256'h0; parameter [255:0] L27 = 256'h0; parameter [255:0] L28 = 256'h0; parameter [255:0] L29 = 256'h0; parameter [255:0] L2A = 256'h0; parameter [255:0] L2B = 256'h0; parameter [255:0] L2C = 256'h0; parameter [255:0] L2D = 256'h0; parameter [255:0] L2E = 256'h0; parameter [255:0] L2F = 256'h0; parameter [255:0] L30 = 256'h0; parameter [255:0] L31 = 256'h0; parameter [255:0] L32 = 256'h0; parameter [255:0] L33 = 256'h0; parameter [255:0] L34 = 256'h0; parameter [255:0] L35 = 256'h0; parameter [255:0] L36 = 256'h0; parameter [255:0] L37 = 256'h0; parameter [255:0] L38 = 256'h0; parameter [255:0] L39 = 256'h0; parameter [255:0] L3A = 256'h0; parameter [255:0] L3B = 256'h0; parameter [255:0] L3C = 256'h0; parameter [255:0] L3D = 256'h0; parameter [255:0] L3E = 256'h0; parameter [255:0] L3F = 256'h0; parameter [255:0] A0 = 256'h0; parameter [255:0] A1 = 256'h0; parameter [255:0] A2 = 256'h0; always @ (posedge clk) begin end endmodule verilator-3.874/test_regress/t/t_func_tie_bad.pl0000775000177100017500000000113412473477707022005 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2011 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_func_tie_bad.v:\d+: Function/task output connected to constant instead of variable: b %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_lib.v0000664000177100017500000000041012473477707021007 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. module t; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_vpi_memory.v0000664000177100017500000000247312473477707021427 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2010 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. `ifdef USE_VPI_NOT_DPI //We call it via $c so we can verify DPI isn't required - see bug572 `else import "DPI-C" context function integer mon_check(); `endif module t (/*AUTOARG*/ // Inputs clk ); `ifdef VERILATOR `systemc_header extern "C" int mon_check(); `verilog `endif input clk; reg [31:0] mem0 [16:1] /*verilator public_flat_rw @(posedge clk) */; integer i, status; // Test loop initial begin `ifdef VERILATOR status = $c32("mon_check()"); `endif `ifdef iverilog status = $mon_check(); `endif `ifndef USE_VPI_NOT_DPI status = mon_check(); `endif if (status!=0) begin $write("%%Error: t_vpi_var.cpp:%0d: C Test failed\n", status); $stop; end for (i = 16; i > 0; i--) if (mem0[i] !== i) begin $write("%%Error: %d : GOT = %d EXP = %d\n", i, mem0[i], i); status = 1; end if (status!=0) begin $write("%%Error: t_vpi_var.cpp:%0d: C Test failed\n", status); $stop; end $write("*-* All Finished *-*\n"); $finish; end endmodule : t verilator-3.874/test_regress/t/t_inst_overwide.v0000664000177100017500000000212312473477707022112 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs outc_w30, outd_w73, // Inputs clk, ina_w1, inb_w61 ); input clk; input ina_w1; input [60:0] inb_w61; output [29:0] outc_w30; output [72:0] outd_w73; sub sub ( // Outputs .outy_w92 (outc_w30), // .large => (small) .outz_w22 (outd_w73), // .small => (large) // Inputs .clk (clk), .inw_w31 (ina_w1), // .large <= (small) .inx_w11 (inb_w61) // .small <= (large) ); endmodule module sub (/*AUTOARG*/ // Outputs outy_w92, outz_w22, // Inputs clk, inw_w31, inx_w11 ); input clk; input [30:0] inw_w31; input [10:0] inx_w11; output reg [91:0] outy_w92 /*verilator public*/; output reg [21:0] outz_w22 /*verilator public*/; always @(posedge clk) begin outy_w92 <= {inw_w31[29:0],inw_w31[29:0],inw_w31[29:0],2'b00}; outz_w22 <= {inx_w11[10:0],inx_w11[10:0]}; end endmodule // regfile verilator-3.874/test_regress/t/t_mem_first.v0000664000177100017500000000602212525171734021205 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer _mode; initial _mode = 0; // verilator lint_off LITENDIAN reg [7:0] mem_narrow [0:31]; //surefire lint_off_line RD_WRT WRTWRT NBAJAM reg [77:0] mem_wide [1024:0]; //surefire lint_off_line RD_WRT WRTWRT NBAJAM reg [7:0] mem_dly_narrow [0:1]; //surefire lint_off_line RD_WRT WRTWRT NBAJAM reg [77:0] mem_dly_wide [1:0]; //surefire lint_off_line RD_WRT WRTWRT NBAJAM reg [34:0] vec_wide; // verilator lint_on LITENDIAN reg [31:0] wrd0 [15:0]; wire [3:0] sel = 4'h3; wire [31:0] selout = wrd0[sel]; // Must take LSBs into account in bit extract widths. wire [15:14] sixt = 2'b10; // surefire lint_off_line ASWCBB wire [16:14] sixt2 = 3'b110; // surefire lint_off_line ASWCBB wire [3:0] sixfrom = 13; wire [4:0] sixfrom2 = 16; wire sixtext = sixt[sixfrom]; wire sixtext2 = sixt2[sixfrom2]; // Non-power of 2 memory overwriting checks reg [2:0] np2_mem [5:0] /*verilator public*/; reg [2:0] np2_guard [7:6] /*verilator public*/; integer i; always @ (posedge clk) begin if (_mode!=0) begin wrd0[0] = 32'h1; // for (i=0; i<32; i=i+1) begin //surefire lint_off_line STMFOR mem_narrow[i] = i[7:0]; mem_wide[i] = {i[7:0],70'hfeed}; end // for (i=0; i<32; i=i+1) begin //surefire lint_off_line STMFOR if (mem_narrow[i] !== i[7:0]) $stop; if (mem_wide[i] !== {i[7:0],70'hfeed}) $stop; end // vec_wide <= 0; // np2_guard[6] = 0; np2_guard[7] = 0; // $write("selout %b %b %b\n", selout, sixtext, sixtext2); end if (_mode == 1) begin _mode <= 2; // i=0; mem_dly_narrow[0] <= ~i[7:0]; mem_dly_wide[0] <= {~i[7:0],70'hface}; i=1; mem_dly_narrow[i] <= ~i[7:0]; mem_dly_wide[i] <= {~i[7:0],70'hface}; // for (i=0; i<16; i=i+1) begin //surefire lint_off_line STMFOR // verilator lint_off width np2_mem[i] = i[2:0]; // surefire lint_off_line ASWSBB // verilator lint_on width if (np2_guard[6]!=0 || np2_guard[7]!=0) $stop; end // verilator lint_off SELRANGE if (np2_mem[6] !== np2_mem[7]) begin $write("Mem[6]!=Mem[7] during randomize...\n"); //$stop; // Random value, so this can happen end // verilator lint_on SELRANGE //if (np2_mem[8] !== np2_mem[9]) $stop; // Enhancement: Illegal indexes, make sure map to X's // vec_wide[32:31] <= 2'b11; vec_wide[34] <= 1'b1; $display("%x",vec_wide); end if (_mode == 2) begin _mode <= 3; // for (i=0; i<2; i=i+1) begin //surefire lint_off_line STMFOR if (mem_dly_narrow[i] !== ~i[7:0]) $stop; if (mem_dly_wide[i] !== {~i[7:0],70'hface}) $stop; end // //$write ("VW %x %x\n", vec_wide[34:32], vec_wide[31:0]); if (vec_wide != {4'b101_1,31'd0}) $stop; // $write("*-* All Finished *-*\n"); $finish; end _mode <= _mode + 1; end endmodule verilator-3.874/test_regress/t/t_alw_split.v0000664000177100017500000000734312473477707021240 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [15:0] m_din; // OK reg [15:0] a_split_1, a_split_2; always @ (/*AS*/m_din) begin a_split_1 = m_din; a_split_2 = m_din; end // OK reg [15:0] b_split_1, b_split_2; always @ (/*AS*/m_din) begin b_split_1 = m_din; b_split_2 = b_split_1; end // Not OK reg [15:0] c_split_1, c_split_2; always @ (/*AS*/m_din) begin c_split_1 = m_din; c_split_2 = c_split_1; c_split_1 = ~m_din; end // OK reg [15:0] d_split_1, d_split_2; always @ (posedge clk) begin d_split_1 <= m_din; d_split_2 <= d_split_1; d_split_1 <= ~m_din; end // Not OK always @ (posedge clk) begin $write(" foo %x", m_din); $write(" bar %x\n", m_din); end // Not OK reg [15:0] e_split_1, e_split_2; always @ (posedge clk) begin e_split_1 = m_din; e_split_2 = e_split_1; end // Not OK reg [15:0] f_split_1, f_split_2; always @ (posedge clk) begin f_split_2 = f_split_1; f_split_1 = m_din; end // Not Ok reg [15:0] l_split_1, l_split_2; always @ (posedge clk) begin l_split_2 <= l_split_1; l_split_1 <= l_split_2 | m_din; end // OK reg [15:0] z_split_1, z_split_2; always @ (posedge clk) begin z_split_1 <= 0; z_split_1 <= ~m_din; end always @ (posedge clk) begin z_split_2 <= 0; z_split_2 <= z_split_1; end always @ (posedge clk) begin if (cyc!=0) begin cyc<=cyc+1; if (cyc==1) begin m_din <= 16'hfeed; end if (cyc==3) begin end if (cyc==4) begin m_din <= 16'he11e; //$write(" A %x %x\n", a_split_1, a_split_2); if (!(a_split_1==16'hfeed && a_split_2==16'hfeed)) $stop; if (!(b_split_1==16'hfeed && b_split_2==16'hfeed)) $stop; if (!(c_split_1==16'h0112 && c_split_2==16'hfeed)) $stop; if (!(d_split_1==16'h0112 && d_split_2==16'h0112)) $stop; if (!(e_split_1==16'hfeed && e_split_2==16'hfeed)) $stop; if (!(f_split_1==16'hfeed && f_split_2==16'hfeed)) $stop; if (!(z_split_1==16'h0112 && z_split_2==16'h0112)) $stop; end if (cyc==5) begin m_din <= 16'he22e; if (!(a_split_1==16'he11e && a_split_2==16'he11e)) $stop; if (!(b_split_1==16'he11e && b_split_2==16'he11e)) $stop; if (!(c_split_1==16'h1ee1 && c_split_2==16'he11e)) $stop; if (!(d_split_1==16'h0112 && d_split_2==16'h0112)) $stop; if (!(z_split_1==16'h0112 && z_split_2==16'h0112)) $stop; // Two valid orderings, as we don't know which posedge clk gets evaled first if (!(e_split_1==16'hfeed && e_split_2==16'hfeed) && !(e_split_1==16'he11e && e_split_2==16'he11e)) $stop; if (!(f_split_1==16'hfeed && f_split_2==16'hfeed) && !(f_split_1==16'he11e && f_split_2==16'hfeed)) $stop; end if (cyc==6) begin m_din <= 16'he33e; if (!(a_split_1==16'he22e && a_split_2==16'he22e)) $stop; if (!(b_split_1==16'he22e && b_split_2==16'he22e)) $stop; if (!(c_split_1==16'h1dd1 && c_split_2==16'he22e)) $stop; if (!(d_split_1==16'h1ee1 && d_split_2==16'h0112)) $stop; if (!(z_split_1==16'h1ee1 && d_split_2==16'h0112)) $stop; // Two valid orderings, as we don't know which posedge clk gets evaled first if (!(e_split_1==16'he11e && e_split_2==16'he11e) && !(e_split_1==16'he22e && e_split_2==16'he22e)) $stop; if (!(f_split_1==16'he11e && f_split_2==16'hfeed) && !(f_split_1==16'he22e && f_split_2==16'he11e)) $stop; end if (cyc==7) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_typedef_signed.pl0000775000177100017500000000071712473477707022402 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_for_break.v0000664000177100017500000000716612473477707021177 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [3:0] l_stop = crc[3:0]; wire [3:0] l_break = crc[7:4]; wire [3:0] l_continue = crc[11:8]; /*AUTOWIRE*/ wire [15:0] out0 = Test0(l_stop, l_break, l_continue); wire [15:0] out1 = Test1(l_stop, l_break, l_continue); wire [15:0] out2 = Test2(l_stop, l_break, l_continue); wire [15:0] out3 = Test3(l_stop, l_break, l_continue); // Aggregate outputs into a single result vector wire [63:0] result = {out3,out2,out1,out0}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin if (out0!==out1) $stop; if (out0!==out2) $stop; if (out0!==out3) $stop; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h293e9f9798e97da0 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end function [15:0] Test0; input [3:0] loop_stop; input [3:0] loop_break; input [3:0] loop_continue; integer i; reg broken; Test0 = 0; broken = 0; begin for (i=1; i<20; i=i+1) begin if (!broken) begin Test0 = Test0 + 1; if (i[3:0] != loop_continue) begin // continue if (i[3:0] == loop_break) begin broken = 1'b1; end if (!broken) begin Test0 = Test0 + i[15:0]; end end end end end endfunction function [15:0] Test1; input [3:0] loop_stop; input [3:0] loop_break; input [3:0] loop_continue; integer i; Test1 = 0; begin : outer_block for (i=1; i<20; i=i+1) begin : inner_block Test1 = Test1 + 1; // continue, IE jump to end-of-inner_block. Must be inside inner_block. if (i[3:0] == loop_continue) disable inner_block; // break, IE jump to end-of-outer_block. Must be inside outer_block. if (i[3:0] == loop_break) disable outer_block; Test1 = Test1 + i[15:0]; end : inner_block end : outer_block endfunction function [15:0] Test2; input [3:0] loop_stop; input [3:0] loop_break; input [3:0] loop_continue; integer i; Test2 = 0; begin for (i=1; i<20; i=i+1) begin Test2 = Test2 + 1; if (i[3:0] == loop_continue) continue; if (i[3:0] == loop_break) break; Test2 = Test2 + i[15:0]; end end endfunction function [15:0] Test3; input [3:0] loop_stop; input [3:0] loop_break; input [3:0] loop_continue; integer i; Test3 = 0; begin for (i=1; i<20; i=i+1) begin Test3 = Test3 + 1; if (i[3:0] == loop_continue) continue; // return, IE jump to end-of-function optionally setting return value if (i[3:0] == loop_break) return Test3; Test3 = Test3 + i[15:0]; end end endfunction endmodule verilator-3.874/test_regress/t/t_clk_condflop.pl0000775000177100017500000000072212473477707022042 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished => 1 ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_array_inl0.pl0000775000177100017500000000104012473477707022474 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_inst_array.v"); compile ( v_flags2 => ['+define+NOUSE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/bootstrap.pl0000775000177100017500000000121712473477707021077 0ustar wsnyderwsnyder#!/usr/bin/perl # DESCRIPTION: Verilator: Verilog Test driver bootstrapper # # Copyright 2008 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. # This is exec'ed by every test that is run standalone (called from the # shell as ./t_test_name.pl) use FindBin; use Cwd qw(chdir); my @args = @ARGV; chdir("$FindBin::Bin/.."); $ENV{PWD} = Cwd::getcwd(); # Else chdir leaves the .. which confuses later commands @args = map { s!.*test_regress/!!; $_; } @args; exec("./driver.pl", @args); die; verilator-3.874/test_regress/t/t_func_sum.pl0000775000177100017500000000071712473477707021230 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_return.pl0000775000177100017500000000071712473477707021743 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_index2.pl0000775000177100017500000000102412473477707022131 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], make_top_shell => 0, make_main => 0, verilator_make_gcc => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_public_trace.pl0000775000177100017500000000124112473477707023051 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. my $pubtask = ($Self->{v3} && verilator_version() =~ /\(public_tasks\)/); # TBD top_filename("t/t_func_public.v"); compile ( verilator_flags2 => [($pubtask?'-DVERILATOR_PUBLIC_TASKS':''), "--trace"], fails => $fail, ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_cond_const.pl0000775000177100017500000000100012473477707022355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--language 1364-2001"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_const.pl0000775000177100017500000000071712473477707021407 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_implicit_port.v0000664000177100017500000000106212473477707023136 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic oe; read r (.clk(clk), .data( ( ( oe == 1'd001 ) && implicit_write ) ) ); set s (.clk(clk), .enable(implicit_write)); read u (.clk(clk), .data(~implicit_also)); endmodule module set ( input clk, output enable ); assign enable = 1'b0; endmodule module read ( input clk, input data ); endmodule verilator-3.874/test_regress/t/t_dpi_accessors.v0000664000177100017500000000453112473477707022057 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test for using DPI as general accessors // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // // Contributed by Jeremy Bennett and Jie Xul // // This test exercises the use of DPI to access signals and registers in a // module hierarchy in a uniform fashion. See the discussion at // // http://www.veripool.org/boards/3/topics/show/752-Verilator-Command-line-specification-of-public-access-to-variables // // We need to test read and write access to: // - scalars // - vectors // - array elements // - slices of vectors or array elements // // We need to test that writing to non-writable elements generates an error. // // This Verilog would run forever. It will be stopped externally by the C++ // instantiating program. // Define the width of registers and size of memory we use `define REG_WIDTH 8 `define MEM_SIZE 256 // Top module defines the accessors and instantiates a sub-module with // substantive content. module t (/*AUTOARG*/ // Inputs clk ); input clk; `include "t_dpi_accessors_macros_inc.vh" `include "t_dpi_accessors_inc.vh" // Put the serious stuff in a sub-module, so we can check hierarchical // access works OK. test_sub i_test_sub (.clk (clk)); endmodule // t // A sub-module with all sorts of goodies we would like to access module test_sub (/*AUTOARG*/ // Inputs clk ); input clk; integer i; // General counter // Elements we would like to access from outside reg a; reg [`REG_WIDTH - 1:0] b; reg [`REG_WIDTH - 1:0] mem [`MEM_SIZE - 1:0]; wire c; wire [`REG_WIDTH - 1:0] d; reg [`REG_WIDTH - 1:0] e; reg [`REG_WIDTH - 1:0] f; // Drive our wires from our registers assign c = ~a; assign d = ~b; // Initial values for registers and array initial begin a = 0; b = `REG_WIDTH'h0; for (i = 0; i < `MEM_SIZE; i++) begin mem[i] = i [`REG_WIDTH - 1:0]; end e = 0; f = 0; end // Wipe out one memory cell in turn on the positive clock edge, restoring // the previous element. We toggle the wipeout value. always @(posedge clk) begin mem[b] <= {`REG_WIDTH {a}}; mem[b - 1] <= b - 1; a <= ~a; b <= b + 1; end endmodule // test_sub verilator-3.874/test_regress/t/t_flag_language.pl0000775000177100017500000000033012473477707022154 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } compile ( verilator_flags2 => ['--language 1364-2001'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_ldflags.pl0000775000177100017500000000226712473477707022020 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); $Self->_run (cmd=>["cd $Self->{obj_dir}" ." && c++ -c ../../t/t_flag_ldflags_a.cpp" ." && ar r t_flag_ldflags_a.a t_flag_ldflags_a.o" ." && ranlib t_flag_ldflags_a.a "], check_finished=>0); $Self->_run (cmd=>["cd $Self->{obj_dir}" ." && c++ -fPIC -c ../../t/t_flag_ldflags_so.cpp" ." && c++ -shared -o t_flag_ldflags_so.so -lc t_flag_ldflags_so.o"], check_finished=>0); compile ( # Pass multiple -D's so we check quoting works properly v_flags2 => ["-CFLAGS '-DCFLAGS_FROM_CMDLINE -DCFLAGS2_FROM_CMDLINE' ", "t/t_flag_ldflags_c.cpp", "t_flag_ldflags_a.a", "t_flag_ldflags_so.so",], ); execute ( check_finished=>1, run_env => "LD_LIBRARY_PATH=$Self->{obj_dir}", ); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_bound.v0000664000177100017500000000120712473477707021567 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jue Xu. // bug630 module t ( clk, out ); input clk; output out; reg a; reg b; typedef struct packed { logic config_a; logic config_b; } param_t; // verilator lint_off UNOPTFLAT param_t conf [1:2] ; // verilator lint_on UNOPTFLAT always @ (posedge clk) begin conf[2].config_b <= a; $write("*-* All Finished *-*\n"); $finish; end always @ (posedge conf[2].config_b) begin a = conf[2].config_a; end endmodule verilator-3.874/test_regress/t/t_alw_split.pl0000775000177100017500000000112612473477707021402 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--stats"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Split always\s+(\d+)/i, 6); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_sign_extend.v0000664000177100017500000001111112525247644022537 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This test demonstrates an issue with sign extension. // Assigning to localparms larger than 32 bits broke in 3.862 // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Mike Thyer. module t (/*AUTOARG*/ // Inputs clk ); input clk; localparam [ 0:0] one1_lp = 1; localparam [ 1:0] one2_lp = 1; localparam [ 2:0] one3_lp = 1; localparam [ 3:0] one4_lp = 1; localparam [ 4:0] one5_lp = 1; localparam [ 5:0] one6_lp = 1; localparam [ 6:0] one7_lp = 1; localparam [ 7:0] one8_lp = 1; localparam [ 8:0] one9_lp = 1; localparam [ 9:0] one10_lp = 1; localparam [19:0] one20_lp = 1; localparam [29:0] one30_lp = 1; localparam [30:0] one31_lp = 1; localparam [31:0] one32_lp = 1; localparam [32:0] one33_lp = 1; localparam [33:0] one34_lp = 1; localparam [34:0] one35_lp = 1; localparam [35:0] one36_lp = 1; localparam [36:0] one37_lp = 1; localparam [37:0] one38_lp = 1; localparam [38:0] one39_lp = 1; localparam [39:0] one40_lp = 1; localparam [49:0] one50_lp = 1; localparam [59:0] one60_lp = 1; localparam [60:0] one61_lp = 1; localparam [61:0] one62_lp = 1; localparam [62:0] one63_lp = 1; localparam [63:0] one64_lp = 1; localparam [64:0] one65_lp = 1; localparam [65:0] one66_lp = 1; localparam [66:0] one67_lp = 1; localparam [67:0] one68_lp = 1; localparam [68:0] one69_lp = 1; localparam [69:0] one70_lp = 1; bit all_ok = 1; initial begin `ifdef TEST_VERBOSE $display("one1_lp : %x %d", one1_lp, one1_lp==1); $display("one2_lp : %x %d", one2_lp, one2_lp==1); $display("one3_lp : %x %d", one3_lp, one3_lp==1); $display("one4_lp : %x %d", one4_lp, one4_lp==1); $display("one5_lp : %x %d", one5_lp, one5_lp==1); $display("one6_lp : %x %d", one6_lp, one6_lp==1); $display("one7_lp : %x %d", one7_lp, one7_lp==1); $display("one8_lp : %x %d", one8_lp, one8_lp==1); $display("one9_lp : %x %d", one9_lp, one9_lp==1); $display("one10_lp: %x %d", one10_lp, one10_lp==1); $display("one20_lp: %x %d", one20_lp, one20_lp==1); $display("one30_lp: %x %d", one30_lp, one30_lp==1); $display("one31_lp: %x %d", one31_lp, one31_lp==1); $display("one32_lp: %x %d", one32_lp, one32_lp==1); $display("one33_lp: %x %d", one33_lp, one33_lp==1); $display("one34_lp: %x %d", one34_lp, one34_lp==1); $display("one35_lp: %x %d", one35_lp, one35_lp==1); $display("one36_lp: %x %d", one36_lp, one36_lp==1); $display("one37_lp: %x %d", one37_lp, one37_lp==1); $display("one38_lp: %x %d", one38_lp, one38_lp==1); $display("one39_lp: %x %d", one39_lp, one39_lp==1); $display("one40_lp: %x %d", one40_lp, one40_lp==1); $display("one50_lp: %x %d", one50_lp, one50_lp==1); $display("one60_lp: %x %d", one60_lp, one60_lp==1); $display("one61_lp: %x %d", one61_lp, one61_lp==1); $display("one62_lp: %x %d", one62_lp, one62_lp==1); $display("one63_lp: %x %d", one63_lp, one63_lp==1); $display("one64_lp: %x %d", one64_lp, one64_lp==1); $display("one65_lp: %x %d", one65_lp, one65_lp==1); $display("one66_lp: %x %d", one66_lp, one66_lp==1); $display("one67_lp: %x %d", one67_lp, one67_lp==1); $display("one68_lp: %x %d", one68_lp, one68_lp==1); $display("one69_lp: %x %d", one69_lp, one69_lp==1); $display("one70_lp: %x %d", one70_lp, one70_lp==1); `endif all_ok &= one1_lp == 1; all_ok &= one2_lp == 1; all_ok &= one3_lp == 1; all_ok &= one4_lp == 1; all_ok &= one5_lp == 1; all_ok &= one6_lp == 1; all_ok &= one7_lp == 1; all_ok &= one8_lp == 1; all_ok &= one9_lp == 1; all_ok &= one10_lp == 1; all_ok &= one20_lp == 1; all_ok &= one30_lp == 1; all_ok &= one31_lp == 1; all_ok &= one32_lp == 1; all_ok &= one33_lp == 1; all_ok &= one34_lp == 1; all_ok &= one35_lp == 1; all_ok &= one36_lp == 1; all_ok &= one37_lp == 1; all_ok &= one38_lp == 1; all_ok &= one39_lp == 1; all_ok &= one40_lp == 1; all_ok &= one50_lp == 1; all_ok &= one60_lp == 1; all_ok &= one61_lp == 1; all_ok &= one62_lp == 1; all_ok &= one63_lp == 1; all_ok &= one64_lp == 1; all_ok &= one65_lp == 1; all_ok &= one66_lp == 1; all_ok &= one67_lp == 1; all_ok &= one68_lp == 1; all_ok &= one69_lp == 1; all_ok &= one70_lp == 1; if (!all_ok) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_langext_2.v0000664000177100017500000000216312473477707021120 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // A test of the +1364-1995ext+ and +systemverilogext+ flags. // // This source code contains constructs that are valid in SystemVerilog 2009 // but not in Verilog 1995. So it should fail if we set the language to be // Verilog 1995, but not SystemVerilog 2009. // // Compile only test, so no need for "All Finished" output. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [1:0] res; // Instantiate the test test test_i (/*AUTOINST*/ // Outputs .res (res), // Inputs .clk (clk), .in (1'b1)); endmodule module test (// Outputs res, // Inputs clk, in ); output [1:0] res; input clk; input in; // This is a SystemVerilog 2009 only test generate genvar i; for (i=0; i<2; i=i+1) begin always @(posedge clk) begin unique0 case (i) 0: res[0:0] <= in; 1: res[1:1] <= in; endcase end end endgenerate endmodule verilator-3.874/test_regress/t/t_sys_readmem_h.mem0000664000177100017500000000075512473477707022372 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test data file // // Copyright 2006 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. @4 4004_37654321_27654321_17654321_07654321_abcdef10 @a 400a_37654321_27654321_17654321_07654321_abcdef11 400b_37654321_27654321_17654321_07654321_abcdef12 400c_37654321_27654321_17654321_07654321_abcdef13 verilator-3.874/test_regress/t/t_func_paramed.pl0000775000177100017500000000071712473477707022035 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_mnpipe.pl0000775000177100017500000000072412473477707021734 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_v.v0000664000177100017500000000120212473477707020506 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Chandan Egbert. // See bug569 module t(); `ifdef T_FUNC_V_NOINL // verilator no_inline_module `endif level1 ul1(); initial ul1.doit(4'b0); endmodule module level1(); `ifdef T_FUNC_V_NOINL // verilator no_inline_module `endif level2 ul2(); task doit(input logic [3:0] v); ul2.mem = v; $write("*-* All Finished *-*\n"); $finish; endtask endmodule module level2(); `ifdef T_FUNC_V_NOINL // verilator no_inline_module `endif logic [3:0] mem; endmodule verilator-3.874/test_regress/t/t_func_named.v0000664000177100017500000000153412473477707021335 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t (/*AUTOARG*/); function int f( int j = 1, int s = 0 ); return (j<<16) | s; endfunction `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); initial begin `checkh( f(.j(2), .s(1)) , 32'h2_0001 ); `checkh( f(.s(1)) , 32'h1_0001 ); `checkh( f(, 1) , 32'h1_0001 ); `checkh( f(.j(2)) , 32'h2_0000 ); `checkh( f(.s(1), .j(2)) , 32'h2_0001 ); `checkh( f(.s(), .j()) , 32'h1_0000 ); `checkh( f(2) , 32'h2_0000 ); `checkh( f() , 32'h1_0000 ); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_vlcov_rewrite.pl0000775000177100017500000000146512473477707022304 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); foreach my $basename ("t_vlcov_data_a.dat", "t_vlcov_data_b.dat", "t_vlcov_data_c.dat", "t_vlcov_data_d.dat", ) { $Self->_run(cmd=>["../bin/verilator_coverage", "t/${basename}", "--write", "$Self->{obj_dir}/${basename}" ], tee=>0, ); ok(files_identical("$Self->{obj_dir}/${basename}", "t/${basename}")); } 1; verilator-3.874/test_regress/t/t_param_ceil.v0000664000177100017500000000175412473477707021336 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/); /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] O_out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .O_out (O_out[31:0])); initial begin if (O_out != 32'h4) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module Test ( output [31:0] O_out ); test #( .pFOO(5), .pBAR(2) ) U_test ( .O_out(O_out) ); endmodule module test #(parameter pFOO = 7, parameter pBAR = 3, parameter pBAZ = ceiling(pFOO, pBAR) ) ( output [31:0] O_out ); assign O_out = pBAZ; function integer ceiling; input [31:0] x, y; ceiling = ((x%y == 0) ? x/y : (x/y)+1) + 1; endfunction endmodule verilator-3.874/test_regress/t/t_extend.pl0000775000177100017500000000072112473477707020673 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_assert_synth_parallel.pl0000775000177100017500000000133012473477707024003 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_assert_synth.v"); compile ( v_flags2 => ['+define+FAILING_PARALLEL'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], ); execute ( check_finished=>0, fails => $Self->{v3}, expect=> '%Error: t_assert_synth.v:\d+: Assertion failed in top.v: synthesis parallel_case' ); ok(1); 1; verilator-3.874/test_regress/t/t_wire_types.v0000664000177100017500000000313112473477707021423 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); `define checkr(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got=%g exp=%g\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); // IEEE: integer_atom_type wire byte w_byte; wire shortint w_shortint; wire int w_int; wire longint w_longint; wire integer w_integer; // IEEE: integer_atom_type wire bit w_bit; wire logic w_logic; wire bit [1:0] w_bit2; wire logic [1:0] w_logic2; // IEEE: non_integer_type //UNSUP shortreal w_shortreal; wire real w_real; assign w_byte = 8'h12; assign w_shortint = 16'h1234; assign w_int = -123456; assign w_longint = -1234567; assign w_integer = -123456; assign w_bit = 1'b1; assign w_logic = 1'b1; assign w_bit2 = 2'b10; assign w_logic2 = 2'b10; assign w_real = 3.14; always @ (posedge clk) begin `checkh(w_byte, 8'h12); `checkh(w_shortint, 16'h1234); `checkh(w_int, -123456); `checkh(w_longint, -1234567); `checkh(w_integer, -123456); `checkh(w_bit, 1'b1); `checkh(w_logic, 1'b1); `checkh(w_bit2, 2'b10); `checkh(w_logic2, 2'b10); `checkr(w_real, 3.14); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_mem_slot.pl0000775000177100017500000000116012473477707021221 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_eqcase.v0000664000177100017500000000705012473477707021354 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; wire [3:0] drv_a = crc[3:0]; wire [3:0] drv_b = crc[7:4]; wire [3:0] drv_e = crc[19:16]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [8:0] match1; // From test1 of Test1.v wire [8:0] match2; // From test2 of Test2.v // End of automatics Test1 test1 (/*AUTOINST*/ // Outputs .match1 (match1[8:0]), // Inputs .drv_a (drv_a[3:0]), .drv_e (drv_e[3:0])); Test2 test2 (/*AUTOINST*/ // Outputs .match2 (match2[8:0]), // Inputs .drv_a (drv_a[3:0]), .drv_e (drv_e[3:0])); // Aggregate outputs into a single result vector wire [63:0] result = {39'h0, match2, 7'h0, match1}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x m1=%x m2=%x (%b??%b:%b)\n",$time, cyc, crc, match1, match2, drv_e,drv_a,drv_b); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hc0c4a2b9aea7c4b4 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test1 ( input wire [3:0] drv_a, input wire [3:0] drv_e, output wire [8:0] match1 ); wire [2:1] drv_all; bufif1 bufa [2:1] (drv_all, drv_a[2:1], drv_e[2:1]); `ifdef VERILATOR // At present Verilator only allows comparisons with Zs assign match1[0] = (drv_a[2:1]== 2'b00 && drv_e[2:1]==2'b11); assign match1[1] = (drv_a[2:1]== 2'b01 && drv_e[2:1]==2'b11); assign match1[2] = (drv_a[2:1]== 2'b10 && drv_e[2:1]==2'b11); assign match1[3] = (drv_a[2:1]== 2'b11 && drv_e[2:1]==2'b11); `else assign match1[0] = drv_all === 2'b00; assign match1[1] = drv_all === 2'b01; assign match1[2] = drv_all === 2'b10; assign match1[3] = drv_all === 2'b11; `endif assign match1[4] = drv_all === 2'bz0; assign match1[5] = drv_all === 2'bz1; assign match1[6] = drv_all === 2'bzz; assign match1[7] = drv_all === 2'b0z; assign match1[8] = drv_all === 2'b1z; endmodule module Test2 ( input wire [3:0] drv_a, input wire [3:0] drv_e, output wire [8:0] match2 ); wire [2:1] drv_all; bufif1 bufa [2:1] (drv_all, drv_a[2:1], drv_e[2:1]); `ifdef VERILATOR assign match2[0] = (drv_all !== 2'b00 || drv_e[2:1]!=2'b11); assign match2[1] = (drv_all !== 2'b01 || drv_e[2:1]!=2'b11); assign match2[2] = (drv_all !== 2'b10 || drv_e[2:1]!=2'b11); assign match2[3] = (drv_all !== 2'b11 || drv_e[2:1]!=2'b11); `else assign match2[0] = drv_all !== 2'b00; assign match2[1] = drv_all !== 2'b01; assign match2[2] = drv_all !== 2'b10; assign match2[3] = drv_all !== 2'b11; `endif assign match2[4] = drv_all !== 2'bz0; assign match2[5] = drv_all !== 2'bz1; assign match2[6] = drv_all !== 2'bzz; assign match2[7] = drv_all !== 2'b0z; assign match2[8] = drv_all !== 2'b1z; endmodule verilator-3.874/test_regress/t/t_func_flip.pl0000775000177100017500000000071712473477707021356 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_block_redecl_bad.pl0000775000177100017500000000144212473477707023651 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); $Self->{vlt} and $Self->unsupported("Verilator unsupported, bug485, false begin due to WHILE conversion blocks duplicate name detection"); compile ( v_flags2 => ["--lint-only"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning: duplicate... %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_array.pl0000775000177100017500000000114612473477707021402 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # When fix, update ifdefs in t_sv_cpu files; search for t_tri_array $Self->{vlt} and $Self->unsupported("Verilator unsupported, tristate arrays"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vlcov_rank.out0000664000177100017500000000041412473477707021740 0ustar wsnyderwsnyderTests: Covered, Rank, RankPts, Filename 2, 2, 1, "t/t_vlcov_data_a.dat" 3, 1, 3, "t/t_vlcov_data_b.dat" 1, 3, 1, "t/t_vlcov_data_c.dat" 1, 0, 0, "t/t_vlcov_data_d.dat" verilator-3.874/test_regress/t/t_math_sign_extend.pl0000775000177100017500000000072212525247644022716 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_enum_type_pins.pl0000775000177100017500000000106012525171734022424 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # Not yet working on Verilator $Self->{vlt} and $Self->unsupported("Verilator unsupported"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_gen.v0000664000177100017500000000446212473477707020643 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // verilator lint_off GENCLK reg gendlyclk_r; reg [31:0] gendlydata_r; reg [31:0] dlydata_gr; reg genblkclk; reg [31:0] genblkdata; reg [31:0] blkdata_gr; wire [31:0] constwire = 32'h11; reg [31:0] initwire; integer i; initial begin for (i=0; i<10000; i=i+1) begin initwire = 32'h2200; end end wire [31:0] either = gendlydata_r | dlydata_gr | blkdata_gr | initwire | constwire; wire [31:0] either_unused = gendlydata_r | dlydata_gr | blkdata_gr | initwire | constwire; always @ (posedge clk) begin gendlydata_r <= 32'h0011_0000; gendlyclk_r <= 0; // surefire lint_off SEQASS genblkclk = 0; genblkdata = 0; if (cyc!=0) begin cyc <= cyc + 1; if (cyc==2) begin gendlyclk_r <= 1; gendlydata_r <= 32'h00540000; genblkclk = 1; genblkdata = 32'hace; $write("[%0t] Send pulse\n", $time); end if (cyc==3) begin genblkdata = 32'hdce; gendlydata_r <= 32'h00ff0000; if (either != 32'h87542211) $stop; $write("*-* All Finished *-*\n"); $finish; end end // surefire lint_on SEQASS end always @ (posedge gendlyclk_r) begin if ($time>0) begin // Hack, don't split the block $write("[%0t] Got gendlyclk_r, d=%x b=%x\n", $time, gendlydata_r, genblkdata); dlydata_gr <= 32'h80000000; // Delayed activity list will already be completed for gendlydata // because genclk is from a delayed assignment. // Thus we get the NEW not old value of gendlydata_r if (gendlydata_r != 32'h00540000) $stop; if (genblkdata != 32'hace) $stop; end end always @ (posedge genblkclk) begin if ($time>0) begin // Hack, don't split the block $write("[%0t] Got genblkclk, d=%x b=%x\n", $time, gendlydata_r, genblkdata); blkdata_gr <= 32'h07000000; // Clock from non-delayed assignment, we get old value of gendlydata_r `ifdef verilator `else // V3.2 races... technically legal if (gendlydata_r != 32'h00110000) $stop; `endif if (genblkdata != 32'hace) $stop; end end endmodule verilator-3.874/test_regress/t/t_case_onehot.pl0000775000177100017500000000071712473477707021700 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_multi_ref_bad.pl0000775000177100017500000000227412473477707023043 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( fails=>$Self->{v3}, nc=>0, # Need to get it not to give the prompt expect=> q{%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is (bit|logic) .*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is (bit|logic) .*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is (bit|logic) .*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal \+: or -: select; type already selected, or bad dimension: type is UNPACKARRAYDTYPE .*%Error: t/t_mem_multi_ref_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is logic .*%Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_named.v0000664000177100017500000000213712473477707021502 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); parameter PAR = 3; input clk; `ifdef verilator // Else it becomes a localparam, per IEEE 4.10.1, but we don't check it defparam m3.FROMDEFP = 19; `endif m3 #(.P3(PAR), .P2(2)) m3(.clk(clk)); integer cyc=1; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==1) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module m3 #( parameter UNCH = 99, parameter P1 = 10, parameter P2 = 20, P3 = 30 ) (/*AUTOARG*/ // Inputs clk ); input clk; localparam LOC = 13; parameter FROMDEFP = 11; initial begin $display("%x %x %x",P1,P2,P3); end always @ (posedge clk) begin if (UNCH !== 99) $stop; if (P1 !== 10) $stop; if (P2 !== 2) $stop; if (P3 !== 3) $stop; `ifdef verilator if (FROMDEFP !== 19) $stop; `endif end endmodule verilator-3.874/test_regress/t/t_clk_condflop_nord.pl0000775000177100017500000000101112473477707023054 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2=>["-no-order-clock-delay"], ); execute ( check_finished => 1 ); ok(1); 1; verilator-3.874/test_regress/t/t_math_pow2.v0000664000177100017500000000244012473477707021133 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Aggregate outputs into a single result vector //wire [31:0] pow32b = {24'h0,crc[15:8]}**crc[7:0]; // Overflows wire [3:0] pow4b = crc[7:4]**crc[3:0]; wire [63:0] result = {60'h0, pow4b}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h1fec4b2b71cf8024 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_final.pl0000775000177100017500000000072212473477707020476 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_signed2.pl0000775000177100017500000000071712473477707021755 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_unpacked.v0000664000177100017500000000077412473477707022441 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module x; // verilator lint_off UNPACKED typedef struct { int a; } notpacked_t; // verilator lint_on UNPACKED typedef struct packed { notpacked_t b; } ispacked_t; ispacked_t p; initial begin p.b = 1; if (p.b != 1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_gen_if.v0000664000177100017500000000212712473477707020464 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // simplistic example, should choose 1st conditional generate and assign straight through // the tool also compiles the special case and determines an error (replication value is 0) // // This file ONLY is placed into the Public Domain, for any use, // without warranty. `timescale 1ns / 1ps module t(data_i, data_o, single); parameter op_bits = 32; input [op_bits -1:0] data_i; output [31:0] data_o; input single; //simplistic example, should choose 1st conditional generate and assign straight through //the tool also compiles the special case and determines an error (replication value is 0 generate if (op_bits == 32) begin : general_case assign data_o = data_i; // Test implicit signals /* verilator lint_off IMPLICIT */ assign imp = single; /* verilator lint_on IMPLICIT */ end else begin : special_case assign data_o = {{(32 -op_bits){1'b0}},data_i}; /* verilator lint_off IMPLICIT */ assign imp = single; /* verilator lint_on IMPLICIT */ end endgenerate endmodule verilator-3.874/test_regress/t/t_mem_slice_conc_bad.v0000664000177100017500000000466112473477707023007 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. // // bug354 typedef logic [5:0] data_t; module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire rst; data_t iii_in = crc[5:0]; data_t jjj_in = crc[11:6]; data_t iii_out; data_t jjj_out; logic [1:0] ctl0 = crc[63:62]; aaa aaa (.*); // Aggregate outputs into a single result vector wire [63:0] result = {64'h0}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; rst <= 1'b0; end else if (cyc<10) begin sum <= 64'h0; rst <= 1'b1; end else if (cyc<90) begin rst <= 1'b0; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h4afe43fb79d7b71e if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module bbb ( output data_t ggg_out[1:0], input data_t ggg_in [1:0], input [1:0] [1:0] ctl, input logic clk, input logic rst ); genvar i; generate for (i=0; i<2; i++) begin: PPP always_ff @(posedge clk) begin if (rst) begin ggg_out[i] <= 6'b0; end else begin if (ctl[i][0]) begin if (ctl[i][1]) begin ggg_out[i] <= ~ggg_in[i]; end else begin ggg_out[i] <= ggg_in[i]; end end end end end endgenerate endmodule module aaa ( input data_t iii_in, input data_t jjj_in, input [1:0] ctl0, output data_t iii_out, output data_t jjj_out, input logic clk, input logic rst ); // Below is a bug; {} concat isn't used to make arrays bbb bbb ( .ggg_in ({jjj_in, iii_in}), .ggg_out ({jjj_out, iii_out}), .ctl ({{1'b1,ctl0[1]}, {1'b0,ctl0[0]}}), .*); endmodule verilator-3.874/test_regress/t/t_bitsel_struct3.v0000664000177100017500000000264312525171734022176 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // A test case for struct signal bit selection. // // This test is to check that bit selection of multi-dimensional signal inside // of a packed struct works. Currently +: and -: blow up with packed structs. // // This file ONLY is placed into the Public Domain, for any use, without // warranty, 2013 by Jie Xu. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t(/*AUTOARG*/ // Inputs clk ); input clk; typedef struct packed { logic [15:0] channel; logic [15:0] others; } buss_t; buss_t b; reg [7:0] a; reg [7:0] c; reg [7:0] d; union packed { logic [31:0] [7:0] idx; struct packed { logic [15:0] z, y, x; logic [25:0] [7:0] r; } nam; } gpr; reg [14:0] gpr_a; initial begin b = {16'h8765,16'h4321}; a = b[19:12]; // This works c = b[8+:8]; // This fails d = b[11-:8]; // This fails `checkh(a, 8'h54); `checkh(c, 8'h43); `checkh(d, 8'h32); gpr = 256'h12346789_abcdef12_3456789a_bcdef123_456789ab_cdef1234_56789abc_def12345; `checkh (gpr[255:255-14], 15'h091a); gpr_a = gpr.nam.z[15:1]; `checkh (gpr_a, 15'h091a); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_enum_overlap_bad.v0000664000177100017500000000043212473477707022534 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/); enum { e0, e1, e2, e1b=1 } BAD1; initial begin $stop; end endmodule verilator-3.874/test_regress/t/t_select_negative.v0000664000177100017500000000356112473477707022401 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; wire [15:-16] sel2 = crc[31:0]; wire [80:-10] sel3 = {crc[26:0],crc}; wire [3:0] out21 = sel2[-3 : -6]; wire [3:0] out22 = sel2[{1'b0,crc[3:0]} - 16 +: 4]; wire [3:0] out23 = sel2[{1'b0,crc[3:0]} - 10 -: 4]; wire [3:0] out31 = sel3[-3 : -6]; wire [3:0] out32 = sel3[crc[5:0] - 6 +: 4]; wire [3:0] out33 = sel3[crc[5:0] - 6 -: 4]; // Aggregate outputs into a single result vector wire [63:0] result = {40'h0, out21, out22, out23, out31, out32, out33}; reg [15:-16] sel1; initial begin // Path clearing sel1 = 32'h12345678; if (sel1 != 32'h12345678) $stop; if (sel1[-13 : -16] != 4'h8) $stop; if (sel1[3:0] != 4'h4) $stop; if (sel1[4 +: 4] != 4'h3) $stop; if (sel1[11 -: 4] != 4'h2) $stop; end // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] sels=%x,%x,%x %x,%x,%x\n",$time, out21,out22,out23, out31,out32,out33); $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; `define EXPECTED_SUM 64'hba7fe1e7ac128362 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_enum_type_methods.v0000664000177100017500000000450212525171734022751 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); `define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); module t (/*AUTOARG*/ // Inputs clk ); input clk; typedef enum { E01 = 1, E03 = 3, E04 = 4 } my_t; integer cyc=0; my_t e; int arrayfits [e.num]; // Check can use as constant string all; // Check constification initial begin e = E03; `checkh(e.first, E01); `checkh(e.last, E04); `checkh(e.last(), E04); `checkh(e.next, E04); `checkh(e.next(), E04); `checkh(e.next(1), E04); //Unsup: `checkh(e.next(2), E01); `checkh(e.prev, E01); `checkh(e.prev(1), E01); //Unsup: `checkh(e.prev(2), E04); `checkh(e.num, 3); `checks(e.name, "E03"); // all = ""; for (my_t e = e.first; e != e.last; e = e.next) begin all = {all, e.name}; end e = e.last; all = {all, e.name}; `checks(all, "E01E03E04"); end // Check runtime always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin // Setup e <= E01; end else if (cyc==1) begin `checks(e.name, "E01"); `checkh(e.next, E03); `checkh(e.next(1), E03); //Unsup: `checkh(e.next(2), E04); `checkh(e.prev, E04); `checkh(e.prev(1), E04); //Unsup: `checkh(e.prev(2), E03); e <= E03; end else if (cyc==2) begin `checks(e.name, "E03"); `checkh(e.next, E04); `checkh(e.next(1), E04); //Unsup: `checkh(e.next(2), E01); `checkh(e.prev, E01); `checkh(e.prev(1), E01); //Unsup: `checkh(e.prev(2), E04); e <= E04; end else if (cyc==3) begin `checks(e.name, "E04"); `checkh(e.next, E01); `checkh(e.next(1), E01); //Unsup: `checkh(e.next(2), E03); `checkh(e.prev, E03); `checkh(e.prev(1), E03); //Unsup: `checkh(e.prev(2), E01); e <= E01; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_struct_portsel.pl0000775000177100017500000000072212473477707022501 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_array.pl0000775000177100017500000000072212473477707022127 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_svl2.pl0000775000177100017500000000071412473477707021305 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2006 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param.pl0000775000177100017500000000071712473477707020511 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_huge.v0000664000177100017500000001577012473477707021170 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [9:0] index; wire [7:0] index0 = index[7:0] + 8'h0; wire [7:0] index1 = index[7:0] + 8'h1; wire [7:0] index2 = index[7:0] + 8'h2; wire [7:0] index3 = index[7:0] + 8'h3; wire [7:0] index4 = index[7:0] + 8'h4; wire [7:0] index5 = index[7:0] + 8'h5; wire [7:0] index6 = index[7:0] + 8'h6; wire [7:0] index7 = index[7:0] + 8'h7; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [9:0] outa0; // From s0 of t_case_huge_sub.v wire [9:0] outa1; // From s1 of t_case_huge_sub.v wire [9:0] outa2; // From s2 of t_case_huge_sub.v wire [9:0] outa3; // From s3 of t_case_huge_sub.v wire [9:0] outa4; // From s4 of t_case_huge_sub.v wire [9:0] outa5; // From s5 of t_case_huge_sub.v wire [9:0] outa6; // From s6 of t_case_huge_sub.v wire [9:0] outa7; // From s7 of t_case_huge_sub.v wire [1:0] outb0; // From s0 of t_case_huge_sub.v wire [1:0] outb1; // From s1 of t_case_huge_sub.v wire [1:0] outb2; // From s2 of t_case_huge_sub.v wire [1:0] outb3; // From s3 of t_case_huge_sub.v wire [1:0] outb4; // From s4 of t_case_huge_sub.v wire [1:0] outb5; // From s5 of t_case_huge_sub.v wire [1:0] outb6; // From s6 of t_case_huge_sub.v wire [1:0] outb7; // From s7 of t_case_huge_sub.v wire outc0; // From s0 of t_case_huge_sub.v wire outc1; // From s1 of t_case_huge_sub.v wire outc2; // From s2 of t_case_huge_sub.v wire outc3; // From s3 of t_case_huge_sub.v wire outc4; // From s4 of t_case_huge_sub.v wire outc5; // From s5 of t_case_huge_sub.v wire outc6; // From s6 of t_case_huge_sub.v wire outc7; // From s7 of t_case_huge_sub.v wire [9:0] outq; // From q of t_case_huge_sub4.v wire [3:0] outr; // From sub3 of t_case_huge_sub3.v wire [9:0] outsmall; // From sub2 of t_case_huge_sub2.v // End of automatics t_case_huge_sub2 sub2 ( // Outputs .outa (outsmall[9:0]), /*AUTOINST*/ // Inputs .index (index[9:0])); t_case_huge_sub3 sub3 (/*AUTOINST*/ // Outputs .outr (outr[3:0]), // Inputs .clk (clk), .index (index[9:0])); /* t_case_huge_sub AUTO_TEMPLATE ( .outa (outa@[]), .outb (outb@[]), .outc (outc@[]), .index (index@[])); */ t_case_huge_sub s0 (/*AUTOINST*/ // Outputs .outa (outa0[9:0]), // Templated .outb (outb0[1:0]), // Templated .outc (outc0), // Templated // Inputs .index (index0[7:0])); // Templated t_case_huge_sub s1 (/*AUTOINST*/ // Outputs .outa (outa1[9:0]), // Templated .outb (outb1[1:0]), // Templated .outc (outc1), // Templated // Inputs .index (index1[7:0])); // Templated t_case_huge_sub s2 (/*AUTOINST*/ // Outputs .outa (outa2[9:0]), // Templated .outb (outb2[1:0]), // Templated .outc (outc2), // Templated // Inputs .index (index2[7:0])); // Templated t_case_huge_sub s3 (/*AUTOINST*/ // Outputs .outa (outa3[9:0]), // Templated .outb (outb3[1:0]), // Templated .outc (outc3), // Templated // Inputs .index (index3[7:0])); // Templated t_case_huge_sub s4 (/*AUTOINST*/ // Outputs .outa (outa4[9:0]), // Templated .outb (outb4[1:0]), // Templated .outc (outc4), // Templated // Inputs .index (index4[7:0])); // Templated t_case_huge_sub s5 (/*AUTOINST*/ // Outputs .outa (outa5[9:0]), // Templated .outb (outb5[1:0]), // Templated .outc (outc5), // Templated // Inputs .index (index5[7:0])); // Templated t_case_huge_sub s6 (/*AUTOINST*/ // Outputs .outa (outa6[9:0]), // Templated .outb (outb6[1:0]), // Templated .outc (outc6), // Templated // Inputs .index (index6[7:0])); // Templated t_case_huge_sub s7 (/*AUTOINST*/ // Outputs .outa (outa7[9:0]), // Templated .outb (outb7[1:0]), // Templated .outc (outc7), // Templated // Inputs .index (index7[7:0])); // Templated t_case_huge_sub4 q (/*AUTOINST*/ // Outputs .outq (outq[9:0]), // Inputs .index (index[7:0])); integer cyc; initial cyc=1; initial index = 10'h0; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; //$write("%x: %x\n",cyc,outr); //$write("%x: %x %x %x %x\n", cyc, outa1,outb1,outc1,index1); if (cyc==1) begin index <= 10'h236; end if (cyc==2) begin index <= 10'h022; if (outsmall != 10'h282) $stop; if (outr != 4'b0) $stop; if ({outa0,outb0,outc0}!={10'h282,2'd3,1'b0}) $stop; if ({outa1,outb1,outc1}!={10'h21c,2'd3,1'b1}) $stop; if ({outa2,outb2,outc2}!={10'h148,2'd0,1'b1}) $stop; if ({outa3,outb3,outc3}!={10'h3c0,2'd2,1'b0}) $stop; if ({outa4,outb4,outc4}!={10'h176,2'd1,1'b1}) $stop; if ({outa5,outb5,outc5}!={10'h3fc,2'd2,1'b1}) $stop; if ({outa6,outb6,outc6}!={10'h295,2'd3,1'b1}) $stop; if ({outa7,outb7,outc7}!={10'h113,2'd2,1'b1}) $stop; if (outq != 10'h001) $stop; end if (cyc==3) begin index <= 10'h165; if (outsmall != 10'h191) $stop; if (outr != 4'h5) $stop; if ({outa1,outb1,outc1}!={10'h379,2'd1,1'b0}) $stop; if ({outa2,outb2,outc2}!={10'h073,2'd0,1'b0}) $stop; if ({outa3,outb3,outc3}!={10'h2fd,2'd3,1'b1}) $stop; if ({outa4,outb4,outc4}!={10'h2e0,2'd3,1'b1}) $stop; if ({outa5,outb5,outc5}!={10'h337,2'd1,1'b1}) $stop; if ({outa6,outb6,outc6}!={10'h2c7,2'd3,1'b1}) $stop; if ({outa7,outb7,outc7}!={10'h19e,2'd3,1'b0}) $stop; if (outq != 10'h001) $stop; end if (cyc==4) begin index <= 10'h201; if (outsmall != 10'h268) $stop; if (outr != 4'h2) $stop; if ({outa1,outb1,outc1}!={10'h111,2'd1,1'b0}) $stop; if ({outa2,outb2,outc2}!={10'h1f9,2'd0,1'b0}) $stop; if ({outa3,outb3,outc3}!={10'h232,2'd0,1'b1}) $stop; if ({outa4,outb4,outc4}!={10'h255,2'd3,1'b0}) $stop; if ({outa5,outb5,outc5}!={10'h34c,2'd1,1'b1}) $stop; if ({outa6,outb6,outc6}!={10'h049,2'd1,1'b1}) $stop; if ({outa7,outb7,outc7}!={10'h197,2'd3,1'b0}) $stop; if (outq != 10'h001) $stop; end if (cyc==5) begin index <= 10'h3ff; if (outr != 4'hd) $stop; if (outq != 10'h001) $stop; end if (cyc==6) begin index <= 10'h0; if (outr != 4'hd) $stop; if (outq != 10'h114) $stop; end if (cyc==7) begin if (outr != 4'h4) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_inst_sv.pl0000775000177100017500000000071712473477707021076 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_hierarchy_identifier.v0000664000177100017500000000206212473477707023413 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter SIZE = 8; integer cnt = 0; logic [SIZE-1:0] vld_for; logic vld_if = 1'b0; logic vld_else = 1'b0; genvar i; // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if (cnt==SIZE) begin : \0escaped___name $write("*-* All Finished *-*\n"); $finish; end : \0escaped___name generate for (i=0; i0) begin : generate_if_if always @ (posedge clk) vld_if <= 1'b1; end : generate_if_if else begin : generate_if_else always @ (posedge clk) vld_else <= 1'b1; end : generate_if_else endgenerate endmodule : t verilator-3.874/test_regress/t/t_tri_select.cpp0000664000177100017500000000275012473477707021711 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- #include "Vt_tri_select.h" Vt_tri_select *tb = NULL; double sc_time_stamp() { return 0; } bool check() { bool pass = true; #ifdef TEST_VERBOSE bool verbose = true; #else bool verbose = false; #endif int Y = (tb->OE1 & !tb->OE2) ? tb->A1 : (!tb->OE1 & tb->OE2) ? tb->A2 : (tb->OE1 & tb->OE2) ? (tb->A1 | tb->A2) : 3; // pullup int W = (((tb->OE2) ? (tb->A2 & 0x1) : 0) << tb->A1) | (((tb->OE1) ? (tb->A2 >> 1)&0x1 : 0) << tb->A2); if(tb->Y1 == Y && tb->Y2 == Y && tb->Y3 == Y && tb->W == W) { pass = true; if (verbose) printf("- pass: "); } else { pass = false; verbose = true; printf("%%E-Fail: "); } if (verbose) printf("Read: OE1=%d OE2=%d A1=0x%x A2=0x%x Y1=0x%x Y2=0x%x Y3=0x%x W=0x%x Expected: Y1=Y2=Y3=%d and W=0x%x\n", tb->OE1, tb->OE2, tb->A1, tb->A2, tb->Y1, tb->Y2, tb->Y3, tb->W, Y,W); return pass; } int main() { bool pass = true; Verilated::debug(0); tb = new Vt_tri_select("tb"); // loop through every possibility and check the result for (tb->OE1=0; tb->OE1<2; tb->OE1++) { for (tb->OE2=0; tb->OE2<2; tb->OE2++) { for (tb->A1=0; tb->A1<4; tb->A1++) { for (tb->A2=0; tb->A2<4; tb->A2++) { tb->eval(); if(!check()) { pass = false; } } } } } if(pass) { VL_PRINTF("*-* All Finished *-*\n"); tb->final(); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from t_tri_select\n"); } return 0; } verilator-3.874/test_regress/t/t_mem.pl0000775000177100017500000000071712473477707020167 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_cover_sva_notflat.pl0000775000177100017500000000147712473477707023133 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ['--assert --cc --coverage-user'], ); execute ( check_finished=>1, ); #if ($Self->{nc}) ... # See t_assert_cover.pl for NC version # Allow old Perl format dump, or new binary dump # Check that the hierarchy doesn't include __PVT__ # Otherwise our coverage reports would look really ugly file_grep ($Self->{coverage_filename}, qr/(top\.v\.sub.*.cyc_eq_5)/) if $Self->{vlt}; ok(1); 1; verilator-3.874/test_regress/t/t_for_count.pl0000775000177100017500000000071712473477707021407 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_div0.pl0000775000177100017500000000071712473477707021104 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_topmod2_bad.pl0000775000177100017500000000131512473477707022567 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--top-module a "], fails=>$Self->{v3}, nc=>0, # Need to get it not to give the prompt expect=> '%Error: Specified --top-module \'a\' isn.t at the top level, it.s under another cell \'a_top\' %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/TestSimulator.h0000664000177100017500000000510612473477707021513 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2013-2014 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "vpi_user.h" class TestSimulator { private: struct SimTypes { int verilator; int icarus; int mti; int ncsim; int vcs; }; s_vpi_vlog_info m_info; SimTypes m_simulators; public: TestSimulator() { vpi_get_vlog_info(&m_info); if (0 == strcmp(m_info.product, "Verilator")) { m_simulators.verilator = true; } else if (0 == strcmp(m_info.product, "Verilator")) { m_simulators.icarus = true; } else if (0 == strncmp(m_info.product, "Chronologic Simulation VCS", strlen("Chronologic Simulation VCS"))) { m_simulators.vcs = true; } else { printf("%%Warning: %s:%d: Unknown simulator in TestSimulator.h: %s\n", __FILE__, __LINE__, m_info.product); } } ~TestSimulator() { } // METHORS private: static TestSimulator& singleton() { static TestSimulator s_singleton; return s_singleton; } static const SimTypes& simulators() { return singleton().m_simulators; } public: static const s_vpi_vlog_info& get_info() { return singleton().m_info; } // Simulator names static bool is_icarus() { return simulators().icarus; } static bool is_verilator() { return simulators().verilator; } static bool is_mti() { return simulators().mti; } static bool is_ncsim() { return simulators().ncsim; } static bool is_vcs() { return simulators().vcs; } // Simulator properties static bool is_event_driven() { return !simulators().verilator; } static bool has_get_scalar() { return !simulators().icarus; } // return test level scope static const char* top() { if (simulators().verilator) { return "t"; } else { return "top.t"; } } // return absolute scope of obj static const char* rooted(const char *obj) { static char buf[256]; snprintf(buf, sizeof(buf), "%s.%s", top(), obj); return buf; } }; #define VPI_HANDLE(signal) vpi_handle_by_name((PLI_BYTE8*)TestSimulator::rooted(signal), NULL); verilator-3.874/test_regress/t/t_trace_cat_renew.out0000664000177100017500000001745012473477707022731 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Sat Feb 23 20:18:07 2013 $end $timescale 1ns $end $scope module top $end $var wire 1 $ clk $end $scope module v $end $var wire 1 $ clk $end $var wire 32 # cyc [31:0] $end $upscope $end $upscope $end $enddefinitions $end #0 b00000000000000000000000000000001 # 1$ #1 0$ #2 b00000000000000000000000000000010 # 1$ #3 0$ #4 b00000000000000000000000000000011 # 1$ #5 0$ #6 b00000000000000000000000000000100 # 1$ #7 0$ #8 b00000000000000000000000000000101 # 1$ #9 0$ #10 b00000000000000000000000000000110 # 1$ #11 0$ #12 b00000000000000000000000000000111 # 1$ #13 0$ #14 b00000000000000000000000000001000 # 1$ #15 0$ #16 b00000000000000000000000000001001 # 1$ #17 0$ #18 b00000000000000000000000000001010 # 1$ #19 0$ #20 b00000000000000000000000000001011 # 1$ #21 0$ #22 b00000000000000000000000000001100 # 1$ #23 0$ #24 b00000000000000000000000000001101 # 1$ #25 0$ #26 b00000000000000000000000000001110 # 1$ #27 0$ #28 b00000000000000000000000000001111 # 1$ #29 0$ #30 b00000000000000000000000000010000 # 1$ #31 0$ #32 b00000000000000000000000000010001 # 1$ #33 0$ #34 b00000000000000000000000000010010 # 1$ #35 0$ #36 b00000000000000000000000000010011 # 1$ #37 0$ #38 b00000000000000000000000000010100 # 1$ #39 0$ #40 b00000000000000000000000000010101 # 1$ #41 0$ #42 b00000000000000000000000000010110 # 1$ #43 0$ #44 b00000000000000000000000000010111 # 1$ #45 0$ #46 b00000000000000000000000000011000 # 1$ #47 0$ #48 b00000000000000000000000000011001 # 1$ #49 0$ #50 b00000000000000000000000000011010 # 1$ #51 0$ #52 b00000000000000000000000000011011 # 1$ #53 0$ #54 b00000000000000000000000000011100 # 1$ #55 0$ #56 b00000000000000000000000000011101 # 1$ #57 0$ #58 b00000000000000000000000000011110 # 1$ #59 0$ #60 b00000000000000000000000000011111 # 1$ #61 0$ #62 b00000000000000000000000000100000 # 1$ #63 0$ #64 b00000000000000000000000000100001 # 1$ #65 0$ #66 b00000000000000000000000000100010 # 1$ #67 0$ #68 b00000000000000000000000000100011 # 1$ #69 0$ #70 b00000000000000000000000000100100 # 1$ #71 0$ #72 b00000000000000000000000000100101 # 1$ #73 0$ #74 b00000000000000000000000000100110 # 1$ #75 0$ #76 b00000000000000000000000000100111 # 1$ #77 0$ #78 b00000000000000000000000000101000 # 1$ #79 0$ #80 b00000000000000000000000000101001 # 1$ #81 0$ #82 b00000000000000000000000000101010 # 1$ #83 0$ #84 b00000000000000000000000000101011 # 1$ #85 0$ #86 b00000000000000000000000000101100 # 1$ #87 0$ #88 b00000000000000000000000000101101 # 1$ #89 0$ #90 b00000000000000000000000000101110 # 1$ #91 0$ #92 b00000000000000000000000000101111 # 1$ #93 0$ #94 b00000000000000000000000000110000 # 1$ #95 0$ #96 b00000000000000000000000000110001 # 1$ #97 0$ #98 b00000000000000000000000000110010 # 1$ #99 0$ #100 b00000000000000000000000000110011 # 1$ #101 0$ #102 b00000000000000000000000000110100 # 1$ #103 0$ #104 b00000000000000000000000000110101 # 1$ #105 0$ #106 b00000000000000000000000000110110 # 1$ #107 0$ #108 b00000000000000000000000000110111 # 1$ #109 0$ #110 b00000000000000000000000000111000 # 1$ #111 0$ #112 b00000000000000000000000000111001 # 1$ #113 0$ #114 b00000000000000000000000000111010 # 1$ #115 0$ #116 b00000000000000000000000000111011 # 1$ #117 0$ #118 b00000000000000000000000000111100 # 1$ #119 0$ #120 b00000000000000000000000000111101 # 1$ #121 0$ #122 b00000000000000000000000000111110 # 1$ #123 0$ #124 b00000000000000000000000000111111 # 1$ #125 0$ #126 b00000000000000000000000001000000 # 1$ #127 0$ #128 b00000000000000000000000001000001 # 1$ #129 0$ #130 b00000000000000000000000001000010 # 1$ #131 0$ #132 b00000000000000000000000001000011 # 1$ #133 0$ #134 b00000000000000000000000001000100 # 1$ #135 0$ #136 b00000000000000000000000001000101 # 1$ #137 0$ #138 b00000000000000000000000001000110 # 1$ #139 0$ #140 b00000000000000000000000001000111 # 1$ #141 0$ #142 b00000000000000000000000001001000 # 1$ #143 0$ #144 b00000000000000000000000001001001 # 1$ #145 0$ #146 b00000000000000000000000001001010 # 1$ #147 0$ #148 b00000000000000000000000001001011 # 1$ #149 0$ #150 b00000000000000000000000001001100 # 1$ #151 0$ #152 b00000000000000000000000001001101 # 1$ #153 0$ #154 b00000000000000000000000001001110 # 1$ #155 0$ #156 b00000000000000000000000001001111 # 1$ #157 0$ #158 b00000000000000000000000001010000 # 1$ #159 0$ #160 b00000000000000000000000001010001 # 1$ #161 0$ #162 b00000000000000000000000001010010 # 1$ #163 0$ #164 b00000000000000000000000001010011 # 1$ #165 0$ #166 b00000000000000000000000001010100 # 1$ #167 0$ #168 b00000000000000000000000001010101 # 1$ #169 0$ #170 b00000000000000000000000001010110 # 1$ #171 0$ #172 b00000000000000000000000001010111 # 1$ #173 0$ #174 b00000000000000000000000001011000 # 1$ #175 0$ #176 b00000000000000000000000001011001 # 1$ #177 0$ #178 b00000000000000000000000001011010 # 1$ #179 0$ #180 b00000000000000000000000001011011 # 1$ #181 0$ #182 b00000000000000000000000001011100 # 1$ #183 0$ #184 b00000000000000000000000001011101 # 1$ #185 0$ #186 b00000000000000000000000001011110 # 1$ #187 0$ #188 b00000000000000000000000001011111 # 1$ #189 0$ #190 b00000000000000000000000001100000 # 1$ #191 0$ #192 b00000000000000000000000001100001 # 1$ #193 0$ #194 b00000000000000000000000001100010 # 1$ #195 0$ #196 b00000000000000000000000001100011 # 1$ #197 0$ #198 b00000000000000000000000001100100 # 1$ #199 0$ #200 b00000000000000000000000001100101 # 1$ #201 0$ #202 b00000000000000000000000001100110 # 1$ #203 0$ #204 b00000000000000000000000001100111 # 1$ #205 0$ #206 b00000000000000000000000001101000 # 1$ #207 0$ #208 b00000000000000000000000001101001 # 1$ #209 0$ #210 b00000000000000000000000001101010 # 1$ #211 0$ #212 b00000000000000000000000001101011 # 1$ #213 0$ #214 b00000000000000000000000001101100 # 1$ #215 0$ #216 b00000000000000000000000001101101 # 1$ #217 0$ #218 b00000000000000000000000001101110 # 1$ #219 0$ #220 b00000000000000000000000001101111 # 1$ #221 0$ #222 b00000000000000000000000001110000 # 1$ #223 0$ #224 b00000000000000000000000001110001 # 1$ #225 0$ #226 b00000000000000000000000001110010 # 1$ #227 0$ #228 b00000000000000000000000001110011 # 1$ #229 0$ #230 b00000000000000000000000001110100 # 1$ #231 0$ #232 b00000000000000000000000001110101 # 1$ #233 0$ #234 b00000000000000000000000001110110 # 1$ #235 0$ #236 b00000000000000000000000001110111 # 1$ #237 0$ #238 b00000000000000000000000001111000 # 1$ #239 0$ #240 b00000000000000000000000001111001 # 1$ #241 0$ #242 b00000000000000000000000001111010 # 1$ #243 0$ #244 b00000000000000000000000001111011 # 1$ #245 0$ #246 b00000000000000000000000001111100 # 1$ #247 0$ #248 b00000000000000000000000001111101 # 1$ #249 0$ #250 b00000000000000000000000001111110 # 1$ #251 0$ #252 b00000000000000000000000001111111 # 1$ #253 0$ #254 b00000000000000000000000010000000 # 1$ #255 0$ #256 b00000000000000000000000010000001 # 1$ #257 0$ #258 b00000000000000000000000010000010 # 1$ #259 0$ #260 b00000000000000000000000010000011 # 1$ #261 0$ #262 b00000000000000000000000010000100 # 1$ #263 0$ #264 b00000000000000000000000010000101 # 1$ #265 0$ #266 b00000000000000000000000010000110 # 1$ #267 0$ #268 b00000000000000000000000010000111 # 1$ #269 0$ #270 b00000000000000000000000010001000 # 1$ #271 0$ #272 b00000000000000000000000010001001 # 1$ #273 0$ #274 b00000000000000000000000010001010 # 1$ #275 0$ #276 b00000000000000000000000010001011 # 1$ #277 0$ #278 b00000000000000000000000010001100 # 1$ #279 0$ #280 b00000000000000000000000010001101 # 1$ #281 0$ #282 b00000000000000000000000010001110 # 1$ #283 0$ #284 b00000000000000000000000010001111 # 1$ #285 0$ #286 b00000000000000000000000010010000 # 1$ #287 0$ #288 b00000000000000000000000010010001 # 1$ #289 0$ #290 b00000000000000000000000010010010 # 1$ #291 0$ #292 b00000000000000000000000010010011 # 1$ #293 0$ #294 b00000000000000000000000010010100 # 1$ #295 0$ #296 b00000000000000000000000010010101 # 1$ #297 0$ #298 b00000000000000000000000010010110 # 1$ #299 0$ verilator-3.874/test_regress/t/t_dpi_2exp_bad.pl0000775000177100017500000000114712473477707021727 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Error: t/t_dpi_2exp_bad.v:11: Function was already DPI Exported, duplicate not allowed: dpix_twice %Error: Exiting due to .*' ); ok(1); 1; verilator-3.874/test_regress/t/t_cover_sva_notflat.v0000664000177100017500000000215112473477707022750 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg toggle; integer cyc; initial cyc=1; Test suba (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle), .cyc (cyc[31:0])); Test subb (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle), .cyc (cyc[31:0])); Test subc (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle), .cyc (cyc[31:0])); always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; toggle <= !cyc[0]; if (cyc==9) begin end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module Test ( input clk, input toggle, input [31:0] cyc ); // Don't flatten out these modules please: // verilator no_inline_module // Labeled cover cyc_eq_5: cover property (@(posedge clk) cyc==5) $display("*COVER: Cyc==5"); endmodule verilator-3.874/test_regress/t/t_inst_mism.v0000664000177100017500000000135412473477707021240 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Alex Solomatnikov. //bug595 module t (/*AUTOARG*/ // Inputs clk ); input clk; logic [6-1:0] foo; initial foo = 20; dut #(.W(6)) udut(.clk(clk), .foo(foo-16)); endmodule module dut #(parameter W = 1) (input logic clk, input logic [W-1:0] foo); genvar i; generate for (i = 0; i < W; i++) begin suba ua(.clk(clk), .foo(foo[i])); end endgenerate endmodule module suba (input logic clk, input logic foo); always @(posedge clk) begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_dpi_display_c.cpp0000664000177100017500000000235312473477707022356 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include "svdpi.h" //====================================================================== #if defined(VERILATOR) # include "Vt_dpi_display__Dpi.h" #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef NEED_EXTERNS extern "C" { extern void dpii_display_call (const char* c); } #endif //====================================================================== void dpii_display_call(const char* c) { VL_PRINTF("dpii_display_call: %s\n", c); } verilator-3.874/test_regress/t/t_select_param.pl0000775000177100017500000000072012473477707022042 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mod_dup_ign.v0000664000177100017500000000065412473477707021524 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t; sub sub (); endmodule module sub; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule // verilator lint_off MODDUP module sub; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_struct_anon.v0000664000177100017500000000103112473477707021565 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // Anonymous struct packed { logic [31:0] val1; logic [31:0] val2; } struct1; struct packed { logic [31:0] val3; logic [31:0] val4; } struct2; module t ( output [63:0] s1, output [63:0] s2 ); initial struct1 = 64'h123456789_abcdef0; always_comb s1 = struct1; initial struct2 = 64'h123456789_abcdef0; always_comb s2 = struct2; endmodule verilator-3.874/test_regress/t/t_interface_gen3.pl0000775000177100017500000000072712473477707022266 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_pp_dupdef.pl0000775000177100017500000000101412473477707021346 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( verilator_flags2 => ["-Wno-REDEFMACRO"], ); ok(1); 1; verilator-3.874/test_regress/t/t_math_pow3.pl0000775000177100017500000000071412473477707021307 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_down.pl0000775000177100017500000000072712473477707022401 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_complex.pl0000775000177100017500000000216412473477707022234 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ['--cc --trace'], ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_strp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_strp_strp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp_arrp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp_strp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru\(/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arru\(/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arrp\(/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_strp\(/); vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out"); ok(1); 1; verilator-3.874/test_regress/t/t_debug_sigsegv_bad.pl0000775000177100017500000000134412473477707023031 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); $ENV{VERILATOR_TEST_NO_GDB} and $Self->skip("Skipping due to VERILATOR_TEST_NO_GDB"); compile ( verilator_flags2 => ["--debug-sigsegv"], fails=>$Self->{v3}, expect=> '%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt %Error: Command Failed.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_pick.v0000664000177100017500000000427112473477707021176 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire pick1 = crc[0]; wire [13:0][1:0] data1 = crc[27+1:1]; wire [3:0][2:0][1:0] data2 = crc[23+29:29]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) logic [15:0] [1:0] datao; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .datao (datao/*[15:0][1:0]*/), // Inputs .pick1 (pick1), .data1 (data1/*[13:0][1:0]*/), .data2 (data2/*[2:0][3:0][1:0]*/)); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, datao}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h3ff4bf0e6407b281 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( input logic pick1, input logic [13:0] [1:0] data1, // 14 x 2 = 28 bits input logic [ 3:0] [2:0] [1:0] data2, // 4 x 3 x 2 = 24 bits output logic [15:0] [1:0] datao // 16 x 2 = 32 bits ); // verilator lint_off WIDTH always_comb datao[13: 0] // 28 bits = (pick1) ? {data1} // 28 bits : {'0, data2}; // 25-28 bits, perhaps not legal as '0 is unsized // verilator lint_on WIDTH always_comb datao[15:14] = '0; endmodule verilator-3.874/test_regress/t/t_math_signed4.v0000664000177100017500000001035512473477707021605 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0) `define checkf(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%f exp=%f\n", `__FILE__,`__LINE__, (gotv), (expv)); fail='1; end while(0) module t (/*AUTOARG*/); bit fail; localparam signed [3:0] bug737_p1 = 4'b1000; wire [3:0] bug737_a = 4'b1010; reg [5:0] bug737_y; reg signed [3:0] w4_s; reg signed [4:0] w5_s; reg [3:0] w4_u; reg [4:0] w5_u; reg signed [8:0] w9_s; real r; initial begin // verilator lint_off WIDTH bug737_y = bug737_a + (bug737_p1 + 4'sb0); `checkh(bug737_y, 6'b010010); //bug737 // 6u +[6u] 4s +[6s] 6s bug737_y = 6'b001010 + (4'sb1000 + 6'sb0); `checkh(bug737_y, 6'b010010); //bug737, getx 000010 // 6u +[6u] 4s +[6s] 6s bug737_y = 6'b001010 + (4'b1000 + 6'sb0); `checkh(bug737_y, 6'b010010); //ok bug737_y = 6'b001010 + (6'sb111000 + 6'sb0); `checkh(bug737_y, 6'b000010); //ok // v--- sign extends to 6-bits bug737_y = 6'sb001010 + (4'sb1000 + 6'sb0); `checkh(bug737_y, 6'b000010); //ok // From t_math_signed_3 w4_s = 4'sb1111 - 1'b1; `checkh(w4_s,33'he); w4_s = 4'sb1111 - 5'b00001; `checkh(w4_s,33'he); w4_s = 4'sb1111 - 1'sb1; `checkh(w4_s,4'h0); w5_s = 4'sb1111 - 1'sb1; `checkh(w5_s,4'h0); w4_s = 4'sb1111 - 4'sb1111; `checkh(w4_s,4'h0); w5_s = 4'sb1111 - 4'sb1111; `checkh(w5_s,5'h0); // The assign LHS being signed or unsigned does not matter per IEEE // The upper add being signed DOES matter propagating to lower w4_s = 4'sb1111 - (1'sb1 + 4'b0); //1'sb1 not extended as unsigned add `checkh(w4_s,4'he); w4_s = 4'sb1111 - (1'sb1 + 4'sb0); //1'sb1 does sign extend `checkh(w4_s,4'h0); w4_s = 4'b1111 - (1'sb1 + 4'sb0); //1'sb1 does *NOT* sign extend `checkh(w4_s,4'he); // BUG, Verilator says 'h0 w5_u = 4'b1111 + 4'b0001; // Extends to 5 bits due to LHS `checkh(w5_u, 5'b10000); w4_u = 4'b1111 + 4'b0001; // Normal case `checkh(w4_u, 4'b0000); // Another example of promotion, the add is 4 bits wide w4_u = 3'b111 + 3'b010; `checkh(w4_u, 4'b1001); // w4_u = 3'sb111 * 3'sb001; // Signed output, LHS does not matter `checkh(w4_u, 4'sb1111); w4_s = 3'sb111 * 3'sb001; // Signed output `checkh(w4_s, 4'sb1111); w4_s = 3'b111 * 3'sb001; // Unsigned output `checkh(w4_s, 4'b0111); // Conditionals get width from parent; are assignment-like w4_u = 1'b0 ? 4'b0 : (2'b01+2'b11); `checkh(w4_u, 4'b0100); w4_u = 1'b0 ? 4'b0 : (6'b001000+6'b001000); `checkh(w4_u, 4'b0000); // If RHS is larger, that larger size is used w4_u = 5'b10000 / 5'b00100; `checkh(w4_u, 4'b0100); // bug754 w5_u = 4'sb0010 << -2'sd1; // << 3 `ifdef VCS `checkh(w5_u, 5'b00000); // VCS E-2014.03 bug `else `checkh(w5_u, 5'b10000); // VCS E-2014.03 bug `endif w5_u = 4'sb1000 << 0; // Sign extends `checkh(w5_u, 5'b11000); // Reals do not propagate to children r = 1.0 + ( 1 + (1 / 2)); `checkf(r, 2.0); // Self determined sign extension r = $itor(3'sb111); `checkf(r, -1.0); // If any part of case is real, all is real case (22) 22.0: ; 22.1: $stop; default: $stop; endcase // bug759 w5_u = { -4'sd7 }; `checkh(w5_u, 5'b01001); w5_u = {2{ -2'sd1 }}; `checkh(w5_u, 5'b01111); // Don't break concats.... w5_u = {{0{1'b1}}, -4'sd7 }; `checkh(w5_u, 5'b01001); w9_s = { -4'sd7, -4'sd7 }; `checkh(w9_s, 9'b010011001); {w5_u, {w4_u}} = 9'b10101_1100; `checkh(w5_u, 5'b10101); `checkh(w4_u, 4'b1100); {w4_u} = 4'b1011; `checkh(w4_u, 4'b1011); if (fail) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_gen_for_shuffle.pl0000775000177100017500000000071712473477707022544 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_pull2_bad.v0000664000177100017500000000046312473477707021760 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Lane Brooks. module t (clk); input clk; wire A; pullup p1(A); child child(/*AUTOINST*/ // Inouts .A (A)); endmodule module child(inout A); pulldown p2(A); endmodule verilator-3.874/test_regress/t/t_alw_combdly.pl0000775000177100017500000000071712473477707021705 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_typedef_port.v0000664000177100017500000000437312473477707021746 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. typedef reg [2:0] threeansi_t; module t (/*AUTOARG*/ // Inputs clk ); input clk; typedef reg [2:0] three_t; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [2:0] in = crc[2:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) threeansi_t outa; // From testa of TestAnsi.v three_t outna; // From test of TestNonAnsi.v // End of automatics TestNonAnsi test (// Outputs .out (outna), /*AUTOINST*/ // Inputs .clk (clk), .in (in)); TestAnsi testa (// Outputs .out (outa), /*AUTOINST*/ // Inputs .clk (clk), .in (in)); // Aggregate outputs into a single result vector wire [63:0] result = {57'h0, outna, 1'b0, outa}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h018decfea0a8828a if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module TestNonAnsi (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); typedef reg [2:0] three_t; input clk; input three_t in; output three_t out; always @(posedge clk) begin out <= ~in; end endmodule module TestAnsi ( input clk, input threeansi_t in, output threeansi_t out ); always @(posedge clk) begin out <= ~in; end endmodule // Local Variables: // verilog-typedef-regexp: "_t$" // End: verilator-3.874/test_regress/t/t_tri_gate_bufif0.pl0000775000177100017500000000134312473477707022436 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_tri_gate.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ['+define+T_BUFIF0',], make_flags => 'CPPFLAGS_ADD=-DT_BUFIF0', verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_converge.v0000664000177100017500000000062612473477707022274 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs x, // Inputs clk ); `ifdef ALLOW_UNOPT /*verilator lint_off UNOPTFLAT*/ `endif input clk; output x; // Avoid eliminating x reg x; always @* begin x = ~x; end endmodule verilator-3.874/test_regress/t/t_var_bad_sameas.v0000664000177100017500000000112412473477707022160 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t; integer varfirst; sub varfirst (); // Error: Cell hits var task varfirst; begin end endtask // Error: Task hits var sub cellfirst (); integer cellfirst; // Error: Var hits cell task cellfirst; begin end endtask // Error: Task hits cell task taskfirst; begin end endtask integer taskfirst; // Error: Var hits task sub taskfirst (); // Error: Cell hits task endmodule module sub; endmodule verilator-3.874/test_regress/t/t_inside_wild.pl0000775000177100017500000000072212473477707021677 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_blksync_bad.v0000664000177100017500000000151012473477707022531 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer i; reg sync_blk; reg sync_blk2; reg sync_nblk; reg sync2_ok; reg sync3_ok; reg combo_blk; reg combo_nblk; always @(posedge clk) begin sync_blk = 1'b1; sync_blk2 = 1'b1; // Only warn once per block sync_nblk <= 1'b1; end always @* begin combo_blk = 1'b1; combo_nblk <= 1'b1; end always @(posedge clk) begin for (int i=0; i<20; i++) begin sync2_ok <= 1'b1; end end always @(posedge clk) begin sync3_ok <= f(sync3_ok); end function f (input v); f = ~v; endfunction endmodule verilator-3.874/test_regress/t/t_struct_unpacked_bad.pl0000775000177100017500000000112612473477707023410 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( fails=>$Self->{v3}, expect=> q{%Warning-UNPACKED: t/t_struct_unpacked_bad.v:\d+: Unsupported: Unpacked struct/union %Warning-UNPACKED: Use .* .*%Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_ifbegin.pl0000775000177100017500000000067212473477707021672 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); # No exeecution ok(1); 1; verilator-3.874/test_regress/t/t_var_in_assign_bad.v0000664000177100017500000000065712473477707022673 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs value ); input [3:0] value; assign value = 4'h0; sub sub (.valueSub (value[3:0])); endmodule module sub (/*AUTOARG*/ // Inputs valueSub ); input [3:0] valueSub; assign valueSub = 4'h0; endmodule verilator-3.874/test_regress/t/t_case_inside.pl0000775000177100017500000000072212473477707021653 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_dsp.v0000664000177100017500000000723512473477707020661 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // verilator lint_off GENCLK reg [7:0] cyc; initial cyc=0; reg [7:0] padd; reg dsp_ph1, dsp_ph2, dsp_reset; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [7:0] out; // From dspchip of t_dspchip.v // End of automatics t_dspchip dspchip (/*AUTOINST*/ // Outputs .out (out[7:0]), // Inputs .dsp_ph1 (dsp_ph1), .dsp_ph2 (dsp_ph2), .dsp_reset (dsp_reset), .padd (padd[7:0])); always @ (posedge clk) begin $write("cyc %d\n",cyc); if (cyc == 8'd0) begin cyc <= 8'd1; dsp_reset <= 0; // Need a posedge padd <= 0; end else if (cyc == 8'd20) begin $write("*-* All Finished *-*\n"); $finish; end else begin cyc <= cyc + 8'd1; dsp_ph1 <= ((cyc&8'd3) == 8'd0); dsp_ph2 <= ((cyc&8'd3) == 8'd2); dsp_reset <= (cyc == 8'd1); padd <= cyc; //$write("[%0t] cyc %d %x->%x\n", $time, cyc, padd, out); case (cyc) default: $stop; 8'd01: ; 8'd02: ; 8'd03: ; 8'd04: ; 8'd05: ; 8'd06: ; 8'd07: ; 8'd08: ; 8'd09: if (out!==8'h04) $stop; 8'd10: if (out!==8'h04) $stop; 8'd11: if (out!==8'h08) $stop; 8'd12: if (out!==8'h08) $stop; 8'd13: if (out!==8'h00) $stop; 8'd14: if (out!==8'h00) $stop; 8'd15: if (out!==8'h00) $stop; 8'd16: if (out!==8'h00) $stop; 8'd17: if (out!==8'h0c) $stop; 8'd18: if (out!==8'h0c) $stop; 8'd19: if (out!==8'h10) $stop; endcase end end endmodule module t_dspchip (/*AUTOARG*/ // Outputs out, // Inputs dsp_ph1, dsp_ph2, dsp_reset, padd ); input dsp_ph1, dsp_ph2, dsp_reset; input [7:0] padd; output [7:0] out; wire dsp_ph1, dsp_ph2; wire [7:0] out; wire pla_ph1, pla_ph2; wire out1_r; wire [7:0] out2_r, padd; wire clk_en; t_dspcore t_dspcore (/*AUTOINST*/ // Outputs .out1_r (out1_r), .pla_ph1 (pla_ph1), .pla_ph2 (pla_ph2), // Inputs .dsp_ph1 (dsp_ph1), .dsp_ph2 (dsp_ph2), .dsp_reset (dsp_reset), .clk_en (clk_en)); t_dsppla t_dsppla (/*AUTOINST*/ // Outputs .out2_r (out2_r[7:0]), // Inputs .pla_ph1 (pla_ph1), .pla_ph2 (pla_ph2), .dsp_reset (dsp_reset), .padd (padd[7:0])); assign out = out1_r ? 8'h00 : out2_r; assign clk_en = 1'b1; endmodule module t_dspcore (/*AUTOARG*/ // Outputs out1_r, pla_ph1, pla_ph2, // Inputs dsp_ph1, dsp_ph2, dsp_reset, clk_en ); input dsp_ph1, dsp_ph2, dsp_reset; input clk_en; output out1_r, pla_ph1, pla_ph2; wire dsp_ph1, dsp_ph2, dsp_reset; wire pla_ph1, pla_ph2; reg out1_r; always @(posedge dsp_ph1 or posedge dsp_reset) begin if (dsp_reset) out1_r <= 1'h0; else out1_r <= ~out1_r; end assign pla_ph1 = dsp_ph1; assign pla_ph2 = dsp_ph2 & clk_en; endmodule module t_dsppla (/*AUTOARG*/ // Outputs out2_r, // Inputs pla_ph1, pla_ph2, dsp_reset, padd ); input pla_ph1, pla_ph2, dsp_reset; input [7:0] padd; output [7:0] out2_r; wire pla_ph1, pla_ph2, dsp_reset; wire [7:0] padd; reg [7:0] out2_r; reg [7:0] latched_r; always @(posedge pla_ph1 or posedge dsp_reset) begin if (dsp_reset) latched_r <= 8'h00; else latched_r <= padd; end always @(posedge pla_ph2 or posedge dsp_reset) begin if (dsp_reset) out2_r <= 8'h00; else out2_r <= latched_r; end endmodule verilator-3.874/test_regress/t/t_inst_first.v0000664000177100017500000000674212473477707021430 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk, fastclk ); input clk; input fastclk; genvar unused; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire o_com; // From b of t_inst_first_b.v wire o_seq_d1r; // From b of t_inst_first_b.v // End of automatics integer _mode; // initial _mode=0 reg na,nb,nc,nd,ne; wire ma,mb,mc,md,me; wire da,db,dc,dd,de; reg [7:0] wa,wb,wc,wd,we; wire [7:0] qa,qb,qc,qd,qe; wire [5:0] ra; wire [4:0] rb; wire [29:0] rc; wire [63:0] rd; reg [5:0] sa; reg [4:0] sb; reg [29:0] sc; reg [63:0] sd; reg _guard1; initial _guard1=0; wire [104:0] r_wide = {ra,rb,rc,rd}; reg _guard2; initial _guard2=0; wire [98:0] r_wide0 = {rb,rc,rd}; reg _guard3; initial _guard3=0; wire [93:0] r_wide1 = {rc,rd}; reg _guard4; initial _guard4=0; wire [63:0] r_wide2 = {rd}; reg _guard5; initial _guard5=0; wire [168:0] r_wide3 = {ra,rb,rc,rd,rd}; reg [127:0] _guard6; initial _guard6=0; t_inst_first_a a ( .clk (clk), // Outputs .o_w5 ({ma,mb,mc,md,me}), .o_w5_d1r ({da,db,dc,dd,de}), .o_w40 ({qa,qb,qc,qd,qe}), .o_w104 ({ra,rb,rc,rd}), // Inputs .i_w5 ({na,nb,nc,nd,ne}), .i_w40 ({wa,wb,wc,wd,we}), .i_w104 ({sa,sb,sc,sd}) ); reg i_seq; reg i_com; wire [15:14] o2_comhigh; t_inst_first_b b ( .o2_com (o2_comhigh), .i2_com ({i_com,~i_com}), .wide_for_trace (128'h1234_5678_aaaa_bbbb_cccc_dddd), .wide_for_trace_2 (_guard6 + 128'h1234_5678_aaaa_bbbb_cccc_dddd), /*AUTOINST*/ // Outputs .o_seq_d1r (o_seq_d1r), .o_com (o_com), // Inputs .clk (clk), .i_seq (i_seq), .i_com (i_com)); // surefire lint_off STMINI initial _mode = 0; always @ (posedge fastclk) begin if (_mode==1) begin if (o_com !== ~i_com) $stop; if (o2_comhigh !== {~i_com,i_com}) $stop; end end always @ (posedge clk) begin //$write("[%0t] t_inst: MODE = %0x NA=%x MA=%x DA=%x\n", $time, _mode, // {na,nb,nc,nd,ne}, {ma,mb,mc,md,me}, {da,db,dc,dd,de}); $write("[%0t] t_inst: MODE = %0x IS=%x OS=%x\n", $time, _mode, i_seq, o_seq_d1r); if (_mode==0) begin $write("[%0t] t_inst: Running\n", $time); _mode<=1; {na,nb,nc,nd,ne} <= 5'b10110; {wa,wb,wc,wd,we} <= {8'ha, 8'hb, 8'hc, 8'hd, 8'he}; {sa,sb,sc,sd} <= {6'hf, 5'h3, 30'h12345, 32'h0abc_abcd, 32'h7654_3210}; // i_seq <= 1'b1; i_com <= 1'b1; end else if (_mode==1) begin _mode<=2; if ({ma,mb,mc,md,me} !== 5'b10110) $stop; if ({qa,qb,qc,qd,qe} !== {8'ha,8'hb,8'hc,8'hd,8'he}) $stop; if ({sa,sb,sc,sd} !== {6'hf, 5'h3, 30'h12345, 32'h0abc_abcd, 32'h7654_3210}) $stop; end else if (_mode==2) begin _mode<=3; if ({da,db,dc,dd,de} !== 5'b10110) $stop; if (o_seq_d1r !== ~i_seq) $stop; // $write("*-* All Finished *-*\n"); $finish; end if (|{_guard1,_guard2,_guard3,_guard4,_guard5,_guard6}) begin $write("Guard error %x %x %x %x %x\n",_guard1,_guard2,_guard3,_guard4,_guard5); $stop; end end // surefire lint_off UDDSDN wire _unused_ok = |{1'b1, r_wide0, r_wide1,r_wide2,r_wide3,r_wide}; endmodule verilator-3.874/test_regress/t/t_math_trig.v0000664000177100017500000001244112473477707021213 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2011 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. module t (/*AUTOARG*/ // Inputs clk ); input clk; real r, r2; integer cyc=0; task check(integer line, real got, real ex); if (got != ex) begin if ((got - ex) > 0.000001) begin $display("%%Error: Line %0d: Bad result, got=%0.99g expect=%0.99g",line,got,ex); $stop; end end endtask initial begin // Check constant propagation // Note $abs is not defined in SystemVerilog (as of 2012) check(`__LINE__, $ceil(-1.2), -1); check(`__LINE__, $ceil(1.2), 2); check(`__LINE__, $exp(1.2), 3.3201169227365472380597566370852291584014892578125); check(`__LINE__, $exp(0.0), 1); check(`__LINE__, $exp(-1.2), 0.301194211912202136627314530414878390729427337646484375); check(`__LINE__, $floor(-1.2), -2); check(`__LINE__, $floor(1.2), 1); check(`__LINE__, $ln(1.2), 0.1823215567939545922460098381634452380239963531494140625); //check(`__LINE__, $ln(0), 0); // Bad value //check(`__LINE__, $ln(-1.2), 0); // Bad value check(`__LINE__, $log10(1.2), 0.07918124604762481755226843915806966833770275115966796875); //check(`__LINE__, $log10(0), 0); // Bad value //check(`__LINE__, $log10(-1.2), 0); check(`__LINE__, $pow(2.3,1.2), 2.71689843249914897427288451581262052059173583984375); check(`__LINE__, $pow(2.3,-1.2), 0.368066758785732861536388327294844202697277069091796875); //check(`__LINE__, $pow(-2.3,1.2),0); // Bad value check(`__LINE__, $sqrt(1.2), 1.095445115010332148841598609578795731067657470703125); //check(`__LINE__, $sqrt(-1.2), 0); // Bad value check(`__LINE__, ((1.5)**(1.25)), 1.660023); `ifndef VERILATOR check(`__LINE__, $acos (0.2), 1.369438406); // Arg1 is -1..1 check(`__LINE__, $acosh(1.2), 0.622362503); check(`__LINE__, $asin (0.2), 0.201357920); // Arg1 is -1..1 check(`__LINE__, $asinh(1.2), 1.015973134); check(`__LINE__, $atan (0.2), 0.197395559); check(`__LINE__, $atan2(0.2,2.3), 0.086738338); // Arg1 is -1..1 check(`__LINE__, $atanh(0.2), 0.202732554); // Arg1 is -1..1 check(`__LINE__, $cos (1.2), 0.362357754); check(`__LINE__, $cosh (1.2), 1.810655567); check(`__LINE__, $hypot(1.2,2.3), 2.594224354); check(`__LINE__, $sin (1.2), 0.932039085); check(`__LINE__, $sinh (1.2), 1.509461355); check(`__LINE__, $tan (1.2), 2.572151622); check(`__LINE__, $tanh (1.2), 0.833654607); `endif end real sum_ceil; real sum_exp; real sum_floor; real sum_ln; real sum_log10; real sum_pow1; real sum_pow2; real sum_sqrt; real sum_acos; real sum_acosh; real sum_asin; real sum_asinh; real sum_atan; real sum_atan2; real sum_atanh; real sum_cos ; real sum_cosh; real sum_hypot; real sum_sin; real sum_sinh; real sum_tan; real sum_tanh; // Test loop always @ (posedge clk) begin r = $itor(cyc)/10.0 - 5.0; // Crosses 0 `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d r=%g s_ln=%0.12g\n",$time, cyc, r, sum_ln); `endif cyc <= cyc + 1; if (cyc==0) begin end else if (cyc<90) begin // Setup sum_ceil += 1.0+$ceil(r); sum_exp += 1.0+$exp(r); sum_floor += 1.0+$floor(r); if (r > 0.0) sum_ln += 1.0+$ln(r); if (r > 0.0) sum_log10 += 1.0+$log10(r); // Pow requires if arg1<0 then arg1 integral sum_pow1 += 1.0+$pow(2.3,r); if (r >= 0.0) sum_pow2 += 1.0+$pow(r,2.3); if (r >= 0.0) sum_sqrt += 1.0+$sqrt(r); `ifndef VERILATOR if (r>=-1.0 && r<=1.0) sum_acos += 1.0+$acos (r); if (r>=1.0) sum_acosh += 1.0+$acosh(r); if (r>=-1.0 && r<=1.0) sum_asin += 1.0+$asin (r); sum_asinh += 1.0+$asinh(r); sum_atan += 1.0+$atan (r); if (r>=-1.0 && r<=1.0) sum_atan2 += 1.0+$atan2(r,2.3); if (r>=-1.0 && r<=1.0) sum_atanh += 1.0+$atanh(r); sum_cos += 1.0+$cos (r); sum_cosh += 1.0+$cosh (r); sum_hypot += 1.0+$hypot(r,2.3); sum_sin += 1.0+$sin (r); sum_sinh += 1.0+$sinh (r); sum_tan += 1.0+$tan (r); sum_tanh += 1.0+$tanh (r); `endif end else if (cyc==99) begin check (`__LINE__, sum_ceil, 85); check (`__LINE__, sum_exp, 608.06652950); check (`__LINE__, sum_floor, 4); check (`__LINE__, sum_ln, 55.830941633); check (`__LINE__, sum_log10, 46.309585076); check (`__LINE__, sum_pow1, 410.98798177); check (`__LINE__, sum_pow2, 321.94765689); check (`__LINE__, sum_sqrt, 92.269677253); `ifndef VERILATOR check (`__LINE__, sum_acos, 53.986722862); check (`__LINE__, sum_acosh, 72.685208498); check (`__LINE__, sum_asin, 21); check (`__LINE__, sum_asinh, 67.034973416); check (`__LINE__, sum_atan, 75.511045389); check (`__LINE__, sum_atan2, 21); check (`__LINE__, sum_atanh, 0); check (`__LINE__, sum_cos, 72.042023124); check (`__LINE__, sum_cosh, 1054.0178222); check (`__LINE__, sum_hypot, 388.92858406); check (`__LINE__, sum_sin, 98.264184989); check (`__LINE__, sum_sinh, 0); check (`__LINE__, sum_tan, 1.7007946043); check (`__LINE__, sum_tanh, 79.003199681); `endif $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_preproc.out0000664000177100017500000002572012525172076021242 0ustar wsnyderwsnyder`line 1 "t/t_preproc.v" 1 `line 5 "t/t_preproc.v" 0 `line 7 "t/t_preproc.v" 0 `line 1 "t/t_preproc_inc2.vh" 1 `line 2 "t/t_preproc_inc2.vh" 0 At file "t/t_preproc_inc2.vh" line 4 `line 6 "t/t_preproc_inc2.vh" 0 `line 1 "t/t_preproc_inc3.vh" 1 `line 2 "inc3_a_filename_from_line_directive" 0 `line 6 "inc3_a_filename_from_line_directive" 0 At file "inc3_a_filename_from_line_directive" line 10 `line 12 "inc3_a_filename_from_line_directive" 0 `line 15 "inc3_a_filename_from_line_directive" 0 `line 19 "inc3_a_filename_from_line_directive" 2 `line 6 "t/t_preproc_inc2.vh" 0 `line 8 "t/t_preproc_inc2.vh" 2 `line 7 "t/t_preproc.v" 0 `line 9 "t/t_preproc.v" 0 `line 12 "t/t_preproc.v" 0 /*verilator pass_thru comment*/ `line 14 "t/t_preproc.v" 0 /*verilator pass_thru_comment2*/ `line 16 "t/t_preproc.v" 0 `line 19 "t/t_preproc.v" 0 wire [3:0] q = { 1'b1 , 1'b0 , 1'b1 , 1'b1 }; `line 29 "t/t_preproc.v" 0 text. `line 31 "t/t_preproc.v" 0 foo bar foobar2 `line 36 "t/t_preproc.v" 0 `line 40 "t/t_preproc.v" 0 `line 45 "t/t_preproc.v" 0 first part `line 46 "t/t_preproc.v" 0 second part `line 46 "t/t_preproc.v" 0 third part { `line 47 "t/t_preproc.v" 0 a, `line 47 "t/t_preproc.v" 0 b, `line 47 "t/t_preproc.v" 0 c} Line_Preproc_Check 48 `line 50 "t/t_preproc.v" 0 `line 52 "t/t_preproc.v" 0 `line 54 "t/t_preproc.v" 0 deep deep `line 58 "t/t_preproc.v" 0 "Inside: `nosubst" "`nosubst" `line 63 "t/t_preproc.v" 0 x y LLZZ x y p q LLZZ p q r s LLZZ r s LLZZ p q LLZZ p q r s LLZZ r s `line 69 "t/t_preproc.v" 0 firstline comma","line LLZZ firstline comma","line `line 71 "t/t_preproc.v" 0 x y LLZZ "x" y `line 74 "t/t_preproc.v" 0 (a,b)(a,b) `line 77 "t/t_preproc.v" 0 $display("left side: \"right side\"") `line 80 "t/t_preproc.v" 0 bar_suffix more `line 83 "t/t_preproc.v" 0 `line 85 "t/t_preproc.v" 0 $c("Zap(\"",bug1,"\");");; `line 86 "t/t_preproc.v" 0 $c("Zap(\"","bug2","\");");; `line 88 "t/t_preproc.v" 0 `line 91 "t/t_preproc.v" 0 `line 94 "t/t_preproc.v" 0 initial begin $display("pre thrupre thrumid thrupost post: \"right side\""); $display("left side: \"right side\""); $display("left side: \"right side\""); $display("left_side: \"right_side\""); $display("na: \"right_side\""); $display("prep ( midp1 left_side midp2 ( outp ) ): \"right_side\""); $display("na: \"nana\""); $display("left_side right_side: \"left_side right_side\""); $display(": \"\""); $display("left side: \"right side\""); $display("left side: \"right side\""); $display("standalone"); `line 115 "t/t_preproc.v" 0 $display("twoline: \"first second\""); $write("*-* All Finished *-*\n"); $finish; end endmodule `line 125 "t/t_preproc.v" 0 `line 128 "t/t_preproc.v" 0 `line 133 "t/t_preproc.v" 0 module add1 ( input wire d1, output wire o1); `line 134 "t/t_preproc.v" 0 wire tmp_d1 = d1; `line 134 "t/t_preproc.v" 0 wire tmp_o1 = tmp_d1 + 1; `line 134 "t/t_preproc.v" 0 assign o1 = tmp_o1 ; endmodule module add2 ( input wire d2, output wire o2); `line 137 "t/t_preproc.v" 0 wire tmp_d2 = d2; `line 137 "t/t_preproc.v" 0 wire tmp_o2 = tmp_d2 + 1; `line 137 "t/t_preproc.v" 0 assign o2 = tmp_o2 ; endmodule `line 140 "t/t_preproc.v" 0 `line 146 "t/t_preproc.v" 0 `line 151 "t/t_preproc.v" 0 `line 151 "t/t_preproc.v" 0 generate for (i=0; i<(3); i=i+1) begin `line 151 "t/t_preproc.v" 0 psl cover { m5k.f .ctl._ctl_mvldx_m1.d[i] & ~m5k.f .ctl._ctl_mvldx_m1.q[i] & !m5k.f .ctl._ctl_mvldx_m1.cond & ((m5k.f .ctl.alive & m5k.f .ctl.alive_m1))} report "fondNoRise: m5kc_fcl._ctl_mvldx_m1"; `line 151 "t/t_preproc.v" 0 psl cover { ~m5k.f .ctl._ctl_mvldx_m1.d[i] & m5k.f .ctl._ctl_mvldx_m1.q[i] & !m5k.f .ctl._ctl_mvldx_m1.cond & ((m5k.f .ctl.alive & m5k.f .ctl.alive_m1))} report "fondNoFall: m5kc_fcl._ctl_mvldx_m1"; `line 151 "t/t_preproc.v" 0 end endgenerate `line 153 "t/t_preproc.v" 0 module prot(); `protected I!#r#e6<_Q{{E2+]I3<[3s)1@D|'E''i!O?]jD>Jo_![Cl) #nj1]p,3^1~,="E@QZB\T)eU\pC#C|7=\$J$##A[@-@{Qk] `line 159 "t/t_preproc.v" 0 `endprotected endmodule `line 163 "t/t_preproc.v" 0 `line 173 "t/t_preproc.v" 0 begin addr <= (({regs[6], regs[7]} + 1)); rd <= 1; end and begin addr <= (({regs[6], regs[7]})); wdata <= (rdata); wr <= 1; end begin addr <= ({regs[6], regs[7]} + 1); rd <= 1; end begin addr <= ({regs[6], regs[7]}); wdata <= (rdata); wr <= 1; end more `line 177 "t/t_preproc.v" 0 `line 180 "t/t_preproc.v" 0 `line 1 "t/t_preproc_inc4.vh" 1 `line 2 "t/t_preproc_inc4.vh" 0 `line 5 "t/t_preproc_inc4.vh" 0 `line 7 "t/t_preproc_inc4.vh" 2 `line 180 "t/t_preproc.v" 0 `line 181 "t/t_preproc.v" 0 `line 184 "t/t_preproc.v" 0 `line 186 "t/t_preproc.v" 0 `line 190 "t/t_preproc.v" 0 `line 193 "t/t_preproc.v" 0 $blah("ab,cd","e,f"); $blah(this.logfile,vec); $blah(this.logfile,vec[1,2,3]); $blah(this.logfile,{blah.name(), " is not foo"}); `line 199 "t/t_preproc.v" 0 `line 202 "t/t_preproc.v" 0 `pragma foo = 1 `default_nettype none `default_nettype uwire `line 206 "t/t_preproc.v" 0 `line 209 "t/t_preproc.v" 0 `line 213 "t/t_preproc.v" 0 Line_Preproc_Check 213 `line 215 "t/t_preproc.v" 0 `line 218 "t/t_preproc.v" 0 (p,q) `line 225 "t/t_preproc.v" 0 (x,y) Line_Preproc_Check 226 `line 228 "t/t_preproc.v" 0 `line 231 "t/t_preproc.v" 0 beginend beginend "beginend" `line 239 "t/t_preproc.v" 0 `\esc`def `line 245 "t/t_preproc.v" 0 Not a \`define `line 247 "t/t_preproc.v" 0 x,y)--bee submacro has comma paren `line 255 "t/t_preproc.v" 0 $display("10 %d %d", $bits(foo), 10); `line 260 "t/t_preproc.v" 0 `line 265 "t/t_preproc.v" 0 `line 268 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 `line 282 "t/t_preproc.v" 0 assign a3 = ~b3 ; `line 282 "t/t_preproc.v" 0 `line 284 "t/t_preproc.v" 0 \ `line 293 "t/t_preproc.v" 0 `line 293 "t/t_preproc.v" 0 `line 293 "t/t_preproc.v" 0 def i `line 295 "t/t_preproc.v" 0 `line 297 "t/t_preproc.v" 0 `line 301 "t/t_preproc.v" 0 `line 307 "t/t_preproc.v" 0 1 /*verilator NOT IN DEFINE*/ (nodef) 2 /*verilator PART OF DEFINE*/ (hasdef) 3 `line 309 "t/t_preproc.v" 0 /*verilator NOT PART OF DEFINE*/ (nodef) `line 310 "t/t_preproc.v" 0 4 `line 310 "t/t_preproc.v" 0 /*verilator PART OF DEFINE*/ (nodef) `line 311 "t/t_preproc.v" 0 5 also in `line 311 "t/t_preproc.v" 0 also3 (nodef) HAS a NEW `line 314 "t/t_preproc.v" 0 LINE `line 316 "t/t_preproc.v" 0 `line 318 "t/t_preproc.v" 0 `line 331 "t/t_preproc.v" 0 `line 334 "t/t_preproc.v" 0 EXP: clxx_scen clxx_scen EXP: clxx_scen "clxx_scen" EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", " end"}); end while(0); `line 340 "t/t_preproc.v" 0 do `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 if (start("t/t_preproc.v", 340)) begin `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 message({"Blah-", "clx_scen", " end"}); `line 340 "t/t_preproc.v" 0 end `line 340 "t/t_preproc.v" 0 `line 340 "t/t_preproc.v" 0 while(0); `line 342 "t/t_preproc.v" 0 `line 344 "t/t_preproc.v" 0 `line 348 "t/t_preproc.v" 0 `line 348 "t/t_preproc.v" 0 `line 349 "t/t_preproc.v" 0 EXP: This is fooed This is fooed EXP: This is fooed_2 This is fooed_2 `line 356 "t/t_preproc.v" 0 np np `line 367 "t/t_preproc.v" 0 `line 370 "t/t_preproc.v" 0 `line 378 "t/t_preproc.v" 0 `line 382 "t/t_preproc.v" 0 hello3hello3hello3 hello4hello4hello4hello4 `line 388 "t/t_preproc.v" 0 `line 1 "t/t_preproc_inc4.vh" 1 `line 2 "t/t_preproc_inc4.vh" 0 `line 5 "t/t_preproc_inc4.vh" 0 `line 7 "t/t_preproc_inc4.vh" 2 `line 388 "t/t_preproc.v" 0 `line 389 "t/t_preproc.v" 0 `line 397 "t/t_preproc.v" 0 Line_Preproc_Check 401 Line_Preproc_Check 407 "FOO \ BAR " "arg_line1 \ arg_line2" "FOO \ BAR " `line 410 "t/t_preproc.v" 0 Line_Preproc_Check 410 `line 414 "t/t_preproc.v" 0 abc `line 424 "t/t_preproc.v" 0 EXP: sonet_frame sonet_frame `line 430 "t/t_preproc.v" 0 EXP: sonet_frame sonet_frame EXP: sonet_frame sonet_frame `line 440 "t/t_preproc.v" 0 EXP: module zzz ; endmodule module zzz ; endmodule module zzz ; endmodule `line 447 "t/t_preproc.v" 0 EXP: module a_b ; endmodule module a_b ; endmodule module a_b ; endmodule `line 452 "t/t_preproc.v" 0 integer foo; module t; initial begin : \`LEX_CAT(a[0],_assignment) `line 464 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\`LEX_CAT(a[0],_assignment) "); end initial begin : \a[0]_assignment_a[1] `line 471 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\a[0]_assignment_a[1] "); end initial begin : \`CAT(pp,suffix) $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(pp,suffix) "); end initial begin : \`CAT(ff,bb) `line 485 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\`CAT(ff,bb) "); end initial begin : \`zzz `line 491 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\`zzz "); end initial begin : \`FOO `line 498 "t/t_preproc.v" 0 $write("GOT%%m='%m' OTHER_EXP='%s'\n OUR_EXP='%s'", "t.bar ","t.\\`FOO "); end initial begin : \xx`FOO `line 500 "t/t_preproc.v" 0 $write("GOT%%m='%m' EXP='%s'\n", "t.\\xx`FOO "); end initial begin : \`UNKNOWN $write("GOT%%m='%m' EXP='%s'\n", "t.\\`UNKNOWN "); end initial begin : \`DEF_NO_EXPAND $write("GOT%%m='%m' EXP='%s'\n", "t.\\`DEF_NO_EXPAND "); end initial $write("GOT='%s' EXP='%s'\n", "foo bar baz", "foo bar baz"); initial $write("GOT='%s' EXP='%s'\n", "foo `A(bar) baz", "foo `A(bar) baz"); initial $write("Slashed=`%s'\n", "1//2.3"); initial `line 531 "t/t_preproc.v" 0 $display("%s%s","a1","b2c3\n"); endmodule predef 0 0 predef 1 1 predef 2 2 predef 3 3 predef 10 10 predef 11 11 predef 20 20 predef 21 21 predef 22 22 predef 23 23 predef -2 -2 predef -1 -1 predef 0 0 predef 1 1 predef 2 2 `line 553 "t/t_preproc.v" 2 verilator-3.874/test_regress/t/t_func_check.pl0000775000177100017500000000076212473477707021501 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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->{verilated_randReset} = 1; compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_multidriven_bad.v0000664000177100017500000000130212473477707023425 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs out, out2, // Inputs clk, a0, d0, d1 ); input clk; input [1:0] a0; input [7:0] d0; input [7:0] d1; output reg [31:0] out; output reg [15:0] out2; reg [7:0] mem [4]; always @(posedge clk) begin mem[a0] <= d0; end always @(negedge clk) begin mem[a0] <= d1; end assign out = {mem[3],mem[2],mem[1],mem[0]}; always @(posedge clk) begin out2[7:0] <= d0; end always @(negedge clk) begin out2[15:8] <= d0; end endmodule verilator-3.874/test_regress/t/t_var_nonamebegin.out0000664000177100017500000000240412473477707022727 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Tue Jul 24 18:46:01 2012 $end $timescale 1ns $end $scope module top $end $var wire 1 # clk $end $var wire 1 $ reset_l $end $scope module v $end $var wire 1 # clk $end $var wire 1 % inmod $end $var wire 32 & rawmod [31:0] $end $var wire 1 $ reset_l $end $scope module genblk1 $end $var wire 32 ' ingen [31:0] $end $upscope $end $scope module unnamedblk1 $end $var wire 32 ( upa [31:0] $end $scope module d3nameda $end $var wire 32 ) d3a [31:0] $end $upscope $end $upscope $end $scope module unnamedblk2 $end $var wire 32 * b2 [31:0] $end $scope module b3named $end $var wire 32 + b3n [31:0] $end $upscope $end $scope module unnamedblk3 $end $var wire 32 , b3 [31:0] $end $scope module unnamedblk4 $end $var wire 32 - b4 [31:0] $end $upscope $end $upscope $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 0# 0$ 0% b00000000000000000000000000000000 & b00000000000000000000000000000000 ' b00000000000000000000000000000000 ( b00000000000000000000000000000000 ) b00000000000000000000000000000000 * b00000000000000000000000000000000 + b00000000000000000000000000000000 , b00000000000000000000000000000000 - verilator-3.874/test_regress/t/t_param_bit_sel.v0000664000177100017500000000132312473477707022033 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // We see Verilator assumes a 1-bit parameter is a scalar rather than a 1-bit // long vector. This causes the following code to fail. // // Other event drive simulators accept this. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; // At this point it is ambiguous whether a is scalar or vector parameter a = 1'b0; wire b = a[0]; // Note however b[0] is illegal. always @(posedge clk) begin if (b == 1'b0) begin $write("*-* All Finished *-*\n"); $finish; end else begin $stop; end end endmodule verilator-3.874/test_regress/t/t_extend.v0000664000177100017500000000332412473477707020524 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); /*verilator public_module*/ input clk; // No verilator_public needed, because it's outside the "" in the $c statement reg [7:0] cyc; initial cyc=0; reg c_worked; reg [8:0] c_wider; wire one = 1'b1; always @ (posedge clk) begin cyc <= cyc+8'd1; // coverage testing if (one) begin end if (!one) begin end if (cyc[0]) begin end if (!cyc[0]) begin end // multiple on a line if (cyc == 8'd1) begin c_worked <= 0; end if (cyc == 8'd2) begin `ifdef VERILATOR $c("VL_PRINTF(\"Calling $c, calling $c...\\n\");"); $c("VL_PRINTF(\"Cyc=%d\\n\",",cyc,");"); c_worked <= $c("my_function()"); c_wider <= $c9("0x10"); `else c_worked <= 1'b1; c_wider <= 9'h10; `endif end if (cyc == 8'd3) begin if (c_worked !== 1'b1) $stop; if (c_wider !== 9'h10) $stop; $finish; end end `ifdef verilator `systemc_header #define DID_INT_HEADER 1 `systemc_interface #ifndef DID_INT_HEADER #error "`systemc_header didn't work" #endif bool m_did_ctor; vluint32_t my_function() { if (!m_did_ctor) vl_fatal(__FILE__,__LINE__,__FILE__,"`systemc_ctor didn't work"); return 1; } `systemc_imp_header #define DID_IMP_HEADER 1 `systemc_implementation #ifndef DID_IMP_HEADER #error "`systemc_imp_header didn't work" #endif `systemc_ctor m_did_ctor = 1; `systemc_dtor printf("In systemc_dtor\n"); printf("*-* All Finished *-*\n"); `verilog // Test verilator comment after a endif `endif // verilator endmodule verilator-3.874/test_regress/t/t_mem_twoedge.v0000664000177100017500000000512712473477707021534 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // verilator lint_off MULTIDRIVEN /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v wire [15:0] out2; // From test of Test.v // End of automatics // verilator lint_on MULTIDRIVEN Test test ( .en (crc[21:20]), .a1 (crc[19:18]), .a0 (crc[17:16]), .d1 (crc[15:8]), .d0 (crc[7:0]), /*AUTOINST*/ // Outputs .out (out[31:0]), .out2 (out2[15:0]), // Inputs .clk (clk)); // Aggregate outputs into a single result vector wire [63:0] result = {out2, 16'h0, out}; // Test loop `ifdef TEST_VERBOSE always @ (negedge clk) begin $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); end `endif always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; test.clear(); end else if (cyc<10) begin sum <= 64'h0; test.clear(); end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hc68a94a34ec970aa if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, out2, // Inputs clk, en, a0, a1, d0, d1 ); input clk; input [1:0] en; input [1:0] a0; input [1:0] a1; input [7:0] d0; input [7:0] d1; output reg [31:0] out; output reg [15:0] out2; // verilator lint_off MULTIDRIVEN reg [7:0] mem [4]; // verilator lint_on MULTIDRIVEN task clear(); for (int i=0; i<4; ++i) mem[i] = 0; endtask always @(posedge clk) begin if (en[0]) begin mem[a0] <= d0; out2[7:0] <= d0; end end always @(negedge clk) begin if (en[1]) begin mem[a1] <= d1; out2[15:8] <= d0; end end assign out = {mem[3],mem[2],mem[1],mem[0]}; endmodule verilator-3.874/test_regress/t/t_struct_unpacked_bad.v0000664000177100017500000000067112473477707023243 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module x; typedef struct { int a; } notpacked_t; typedef struct packed { notpacked_t b; } ispacked_t; ispacked_t p; initial begin p.b = 1; if (p.b != 1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_interface_down_inlb.pl0000775000177100017500000000110312473477707023372 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_B'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_real_abs.pl0000775000177100017500000000072212473477707022170 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_cat.cpp0000664000177100017500000000355312473477707021503 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. #include #include #if defined(T_TRACE_CAT) # include "Vt_trace_cat.h" #elif defined(T_TRACE_CAT_REOPEN) # include "Vt_trace_cat_reopen.h" #elif defined(T_TRACE_CAT_RENEW) # include "Vt_trace_cat_renew.h" #else # error "Unknown test" #endif unsigned long long main_time = 0; double sc_time_stamp() { return (double)main_time; } const char* trace_name() { static char name[1000]; #if defined(T_TRACE_CAT) snprintf(name,1000,"obj_dir/t_trace_cat/simpart_%04d.vcd", (int)main_time); #elif defined(T_TRACE_CAT_REOPEN) snprintf(name,1000,"obj_dir/t_trace_cat_reopen/simpart_%04d.vcd", (int)main_time); #elif defined(T_TRACE_CAT_RENEW) snprintf(name,1000,"obj_dir/t_trace_cat_renew/simpart_%04d.vcd", (int)main_time); #else # error "Unknown test" #endif return name; } int main(int argc, char **argv, char **env) { VM_PREFIX* top = new VM_PREFIX("top"); Verilated::debug(0); Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; top->trace(tfp,99); tfp->open(trace_name()); top->clk = 0; while (main_time < 190) { // Creates 2 files top->clk = ~top->clk; top->eval(); if ((main_time % 100) == 0) { #if defined(T_TRACE_CAT) tfp->openNext(true); #elif defined(T_TRACE_CAT_REOPEN) tfp->close(); tfp->open(trace_name()); #elif defined(T_TRACE_CAT_RENEW) tfp->close(); delete tfp; tfp = new VerilatedVcdC; top->trace(tfp,99); tfp->open(trace_name()); #else # error "Unknown test" #endif } tfp->dump((unsigned int)(main_time)); ++main_time; } tfp->close(); top->final(); printf ("*-* All Finished *-*\n"); return 0; } verilator-3.874/test_regress/t/t_dpi_vams.pl0000775000177100017500000000110512473477707021203 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe","$Self->{t_dir}/$Self->{name}.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_package_ddecl.v0000664000177100017500000000140512473477707021761 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. // see bug 474 package functions; localparam LP_PACK = 512; localparam LP_PACK_AND_MOD = 19; task check_param; $display("In %m\n"); // "In functions::check_param" if (LP_PACK_AND_MOD != 19) $stop; endtask endpackage module t (); // synthesis translate off import functions::*; // synthesis translate on localparam LP_PACK_AND_MOD = 20; initial begin // verilator lint_off STMTDLY #10; // verilator lint_on STMTDLY if (LP_PACK_AND_MOD != 20) $stop; check_param(); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_var_dotted_inl1.pl0000775000177100017500000000103612473477707022462 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_var_dotted.v"); compile ( v_flags2 => ['+define+USE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dist_portability.pl0000775000177100017500000000613312534317670022762 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. use IO::File; my $root = ".."; my $Debug; if (!-r "$root/.git") { $Self->skip("Not in a git repository"); } else { uint(); printfll(); cstr(); vsnprintf(); } ok(1); sub uint { ### Must trim output before and after our file list #my $files = "*/*.c* */*.h test_regress/t/*.c* test_regress/t/*.h"; # src isn't clean, and probably doesn't need to be (yet?) my $files = "include/*.c* include/*.h test_c/*.c* test_regress/t/*.c* test_regress/t/*.h"; my $cmd = "cd $root && fgrep -n int $files | sort"; print "C $cmd\n"; my $grep = `$cmd`; my %names; foreach my $line (split /\n/, $grep) { $line =~ s!//.*$!!; next if $line !~ /uint\d+_t\b/; next if $line =~ /vl[su]int\d+_t/; next if $line =~ /typedef/; next if $line =~ m!include/svdpi.h!; # Not ours if ($line =~ /^([^:]+)/) { $names{$1} = 1; print "$line\n"; } } if (keys %names) { $Self->error("Files with uint32*_t instead of vluint32s: ",join(' ',sort keys %names)); } } sub printfll { my $files = "src/*.c* src/*.h include/*.c* include/*.h test_c/*.c* test_regress/t/*.c* test_regress/t/*.h"; my $cmd = "cd $root && fgrep -n ll $files | sort"; print "C $cmd\n"; my $grep = `$cmd`; my %names; foreach my $line (split /\n/, $grep) { next if $line !~ /%[a-z0-9]*ll/; next if $line !~ /\blong\S+long\b/; # Assume a cast print "$line\n"; if ($line =~ /^([^:]+)/) { $names{$1} = 1; } else { $names{UNKNOWN} = 1; } } if (keys %names) { $Self->error("Files with %ll instead of VL_PRI64: ",join(' ',sort keys %names)); } } sub cstr { my $files = "src/*.c* src/*.h include/*.c* include/*.h test_c/*.c* test_regress/t/*.c* test_regress/t/*.h"; my $cmd = "cd $root && grep -n -P 'c_str|begin|end' $files | sort"; print "C $cmd\n"; my $grep = `$cmd`; my %names; foreach my $line (split /\n/, $grep) { if ($line =~ /^([^:]+).*\(\)[a-z0-9_().->]*[.->]+(c_str|r?begin|r?end)\(\)/) { next if $line =~ /lintok-begin-on-ref/; print "$line\n"; $names{$1} = 1; } } if (keys %names) { $Self->error("Files with potential c_str() lifetime issue: ",join(' ',sort keys %names)); } } sub vsnprintf { my $files = "src/*.c* src/*.h include/*.c* include/*.h test_c/*.c* test_regress/t/*.c* test_regress/t/*.h"; my $cmd = "cd $root && grep -n -P 'vsnprintf' $files | sort"; print "C $cmd\n"; my $grep = `$cmd`; my %names; foreach my $line (split /\n/, $grep) { if ($line =~ /\b(vsnprintf)\b/) { next if $line =~ /# *define\s*VL_VSNPRINTF/; print "$line\n"; $names{$1} = 1; } } if (keys %names) { $Self->error("Files with vsnprintf, use VL_VSNPRINTF: ",join(' ',sort keys %names)); } } 1; verilator-3.874/test_regress/t/t_flag_stats.pl0000775000177100017500000000107112525171734021517 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( verilator_flags2 => ["--stats --stats-vars"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_assert_synth_full.pl0000775000177100017500000000132012473477707023150 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_assert_synth.v"); compile ( v_flags2 => ['+define+FAILING_FULL'], verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], ); execute ( check_finished=>0, fails=> $Self->{vlt}, expect=> '%Error: t_assert_synth.v:\d+: Assertion failed in top.v: synthesis full_case' ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_portsel.v0000664000177100017500000000425112473477707022331 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [19:0] in = crc[19:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [19:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[19:0]), // Inputs .in (in[19:0])); // Aggregate outputs into a single result vector wire [63:0] result = {44'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hdb7bc61592f31b99 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule typedef struct packed { logic [7:0] cn; logic vbfval; logic vabval; } rel_t; module Test (/*AUTOARG*/ // Outputs out, // Inputs in ); input [19:0] in; output [19:0] out; rel_t [1:0] i; // From ifb0 of ifb.v, ... rel_t [1:0] o; // From ifb0 of ifb.v, ... assign i = in; assign out = o; sub sub ( .i (i[1:0]), .o (o[1:0])); endmodule module sub (/*AUTOARG*/ // Outputs o, // Inputs i ); input rel_t [1:0] i; output rel_t [1:0] o; assign o = i; endmodule // Local Variables: // verilog-typedef-regexp: "_t$" // End: verilator-3.874/test_regress/t/t_case_write1.v0000664000177100017500000000172712473477707021450 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. `include "verilated.v" module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [63:0] crc; `verilator_file_descriptor fd; t_case_write1_tasks tasks (); integer cyc; initial cyc=0; always @ (posedge clk) begin $fwrite(fd, "[%0d] crc=%x ", cyc, crc); tasks.big_case(fd, crc[31:0]); $fwrite(fd, "\n"); end always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%x\n",$time, cyc, crc); cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==1) begin crc <= 64'h00000000_00000097; $write("Open obj_dir/t_case_write1/t_case_write1_logger.log\n"); fd = $fopen("obj_dir/t_case_write1/t_case_write1_logger.log", "w"); end if (cyc==90) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_sys_rand.v0000664000177100017500000000144312473477707021057 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t; reg [31:0] lastrand; reg [31:0] thisrand; integer same = 0; integer i; `define TRIES 20 initial begin // There's a 1^32 chance of the numbers being the same twice, // so we'll allow one failure lastrand = $random; for (i=0; i<`TRIES; i=i+1) begin thisrand = $random; `ifdef TEST_VERBOSE $write("Random = %x\n", thisrand); `endif if (thisrand == lastrand) same=same+1; lastrand = thisrand; end if (same > 1) begin $write("%%Error: Too many similar numbers: %d\n", same); $stop; end $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_unopt_converge_print_bad.pl0000775000177100017500000000125612473477707024467 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2007 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. top_filename("t/t_unopt_converge.v"); #$Self->{verilated_debug} = 1; compile ( v_flags2 => ['+define+ALLOW_UNOPT'], make_flags => 'CPPFLAGS_ADD=-DVL_DEBUG', ); execute ( fails=>1, expect=> '%Error: \S+:\d+: Verilated model didn\'t converge', ) if $Self->{vlt}; ok(1); 1; verilator-3.874/test_regress/t/t_inst_dff.v0000664000177100017500000000563412473477707021037 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; localparam WIDTH = 31; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [WIDTH-1:0] b; // From test of Test.v wire [WIDTH-1:0] c; // From test of Test.v // End of automatics reg rst_l; Test #(.WIDTH(WIDTH)) test (/*AUTOINST*/ // Outputs .b (b[WIDTH-1:0]), .c (c[WIDTH-1:0]), // Inputs .clk (clk), .rst_l (rst_l), .in (in[WIDTH-1:0])); // Aggregate outputs into a single result vector wire [63:0] result = {1'h0, c, 1'b0, b}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; rst_l <= ~1'b1; end else if (cyc<10) begin sum <= 64'h0; rst_l <= ~1'b1; // Hold reset while summing end else if (cyc<20) begin rst_l <= ~1'b0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hbcfcebdb75ec9d32 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs b, c, // Inputs clk, rst_l, in ); parameter WIDTH = 5; input clk; input rst_l; input [WIDTH-1:0] in; output wire [WIDTH-1:0] b; output wire [WIDTH-1:0] c; dff # ( .WIDTH (WIDTH), .RESET ('0), // Although this is a single bit, the parameter must be the specified type .RESET_WIDTH (1) ) sub1 ( .clk(clk), .rst_l(rst_l), .q(b), .d(in) ); dff # ( .WIDTH (WIDTH), .RESET ({ 1'b1, {(WIDTH-1){1'b0}} }), .RESET_WIDTH (WIDTH)) sub2 ( .clk(clk), .rst_l(rst_l), .q(c), .d(in) ); endmodule module dff (/*AUTOARG*/ // Outputs q, // Inputs clk, rst_l, d ); parameter WIDTH = 1; parameter RESET = {WIDTH{1'b0}}; parameter RESET_WIDTH = WIDTH; input clk; input rst_l; input [WIDTH-1:0] d; output reg [WIDTH-1:0] q; always_ff @(posedge clk or negedge rst_l) begin if ($bits(RESET) != RESET_WIDTH) $stop; // verilator lint_off WIDTH if (~rst_l) q <= RESET; // verilator lint_on WIDTH else q <= d; end endmodule verilator-3.874/test_regress/t/t_interface_down_inlad.pl0000775000177100017500000000112412473477707023540 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_A +define+INLINE_D'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_first.pl0000775000177100017500000000072212473477707021571 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_rsvd.pl0000775000177100017500000000071712473477707021237 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_down_inlcd.pl0000775000177100017500000000112412473477707023542 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_C +define+INLINE_D'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_string.pl0000775000177100017500000000072212525171734020700 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_escape.v0000664000177100017500000000322512473477707021345 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs \escaped_normal , double__underscore, \9num , \bra[ket]slash/dash-colon:9backslash\done , // Inputs clk ); input clk; integer cyc; initial cyc=1; output \escaped_normal ; wire \escaped_normal = cyc[0]; output double__underscore ; wire double__underscore = cyc[0]; // C doesn't allow leading non-alpha, so must escape output \9num ; wire \9num = cyc[0]; output \bra[ket]slash/dash-colon:9backslash\done ; wire \bra[ket]slash/dash-colon:9backslash\done = cyc[0]; wire \wire = cyc[0]; wire \check_alias = cyc[0]; wire \check:alias = cyc[0]; wire \check;alias = !cyc[0]; // These are *different entities*, bug83 wire [31:0] \a0.cyc = ~a0.cyc; wire [31:0] \other.cyc = ~a0.cyc; sub a0 (.cyc(cyc)); sub \mod.with_dot (.cyc(cyc)); always @ (posedge clk) begin cyc <= cyc + 1; if (escaped_normal != cyc[0]) $stop; if (\escaped_normal != cyc[0]) $stop; if (double__underscore != cyc[0]) $stop; if (\9num != cyc[0]) $stop; if (\bra[ket]slash/dash-colon:9backslash\done != cyc[0]) $stop; if (\wire != cyc[0]) $stop; if (\check_alias != cyc[0]) $stop; if (\check:alias != cyc[0]) $stop; if (\check;alias != !cyc[0]) $stop; if (\a0.cyc != ~cyc) $stop; if (\other.cyc != ~cyc) $stop; if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub ( input [31:0] cyc ); endmodule verilator-3.874/test_regress/t/t_var_nonamebegin.pl0000775000177100017500000000145612473477707022544 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ['-trace'], ); execute ( expect=>quotemeta( 'ingen: {mod}.genblk1 top.v.genblk1 d3a: {mod}.d3nameda top.v.d3nameda b2: {mod} top.v b3n: {mod}.b3named: top.v.b3named b3: {mod} top.v b4: {mod} top.v t1 {mod}.tsk top.v t2 {mod}.tsk top.v *-* All Finished *-*'), ); if ($Self->{vlt}) { vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out"); } ok(1); 1; verilator-3.874/test_regress/t/t_mem_multidim.v0000664000177100017500000000564612473477707021730 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // verilator lint_off LITENDIAN // verilator lint_off BLKANDNBLK // 3 3 4 reg [71:0] memw [2:0][1:3][5:2]; reg [7:0] memn [2:0][1:3][5:2]; // verilator lint_on BLKANDNBLK integer cyc; initial cyc=0; reg [63:0] crc; reg [71:0] wide; reg [7:0] narrow; reg [1:0] index0; reg [1:0] index1; reg [2:0] index2; integer i0,i1,i2; integer imem[2:0][1:3]; reg [2:0] cstyle[2]; // verilator lint_on LITENDIAN initial begin for (i0=0; i0<3; i0=i0+1) begin for (i1=1; i1<4; i1=i1+1) begin imem[i0[1:0]] [i1[1:0]] = i1; for (i2=2; i2<6; i2=i2+1) begin memw[i0[1:0]] [i1[1:0]] [i2[2:0]] = {56'hfe_fee0_fee0_fee0_,4'b0,i0[3:0],i1[3:0],i2[3:0]}; memn[i0[1:0]] [i1[1:0]] [i2[2:0]] = 8'b1000_0001; end end end end reg [71:0] wread; reg wreadb; always @ (posedge clk) begin //$write("cyc==%0d crc=%x i[%d][%d][%d] nar=%x wide=%x\n",cyc, crc, index0,index1,index2, narrow, wide); cyc <= cyc + 1; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; narrow <= 8'h0; wide <= 72'h0; index0 <= 2'b0; index1 <= 2'b0; index2 <= 3'b0; end else if (cyc<90) begin index0 <= crc[1:0]; index1 <= crc[3:2]; index2 <= crc[6:4]; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; // We never read past bounds, or get unspecific results // We also never read lowest indexes, as writing outside of range may corrupt them if (index0>=0+1 && index0<=2 && index1>=1+1 /*&& index1<=3 CMPCONST*/ && index2>=2+1 && index2<=5) begin narrow <= ({narrow[6:0], narrow[7]^narrow[0]} ^ {memn[index0][index1][index2]}); wread = memw[index0][index1][index2]; wreadb = memw[index0][index1][index2][2]; wide <= ({wide[70:0], wide[71]^wide[2]^wide[0]} ^ wread); //$write("Get memw[%d][%d][%d] -> %x\n",index0,index1,index2, wread); end // We may write past bounds of memory memn[index0][index1][index2] [crc[10:8]+:3] <= crc[2:0]; memn[index0][index1][index2] <= {~crc[6:0],crc[7]}; memw[index0][index1][index2] <= {~crc[7:0],crc}; //$write("Set memw[%d][%d][%d] <= %x\n",index0,index1,index2, {~crc[7:0],crc}); cstyle[cyc[0]] <= cyc[2:0]; if (cyc>20) if (cstyle[~cyc[0]] != (cyc[2:0]-3'b1)) $stop; end else if (cyc==90) begin memn[0][1][3] <= memn[0][1][3] ^ 8'ha8; end else if (cyc==91) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x nar=%x wide=%x\n",$time, cyc, crc, narrow, wide); if (crc != 64'h65e3bddcd9bc2750) $stop; if (narrow != 8'hca) $stop; if (wide != 72'h4edafed31ba6873f73) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_trace_array.v0000664000177100017500000000110212473477707021521 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (clk); input clk; integer cyc=0; // Trace would overflow at 256KB which is 256 kb dump, 16 kb in a chunk typedef struct packed { logic [1024*1024:0] d; } s1_t; // 128 b s1_t biggie; always @ (posedge clk) begin cyc <= cyc + 1; biggie [ cyc +: 32 ] <= 32'hfeedface; if (cyc == 5) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_pp_circdef_bad.pl0000775000177100017500000000120212473477707022303 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_pp_circdef_bad.v:\d+: Recursive `define or other nested inclusion .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_case_write2.v0000664000177100017500000000172712473477707021451 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. `include "verilated.v" module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [63:0] crc; `verilator_file_descriptor fd; t_case_write2_tasks tasks (); integer cyc; initial cyc=0; always @ (posedge clk) begin $fwrite(fd, "[%0d] crc=%x ", cyc, crc); tasks.big_case(fd, crc[31:0]); $fwrite(fd, "\n"); end always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%x\n",$time, cyc, crc); cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==1) begin crc <= 64'h00000000_00000097; $write("Open obj_dir/t_case_write2/t_case_write2_logger.log\n"); fd = $fopen("obj_dir/t_case_write2/t_case_write2_logger.log", "w"); end if (cyc==90) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_assign_inline.v0000664000177100017500000000210212525171734022035 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Mike Thyer. module t (/*AUTOARG*/ // Inputs clk ); input clk; int cycle=0; // verilator lint_off UNOPTFLAT reg [7:0] a_r; wire [7:0] a_w; reg [7:0] b_r; reg [7:0] c_d_r, c_q_r; assign a_w = a_r; always @(*) begin a_r = 0; b_r = a_w; // Substituting the a_w assignment to get b_r = 0 is wrong, as a_r is not "complete" a_r = c_q_r; c_d_r = c_q_r; end // stimulus + checks always @(posedge clk) begin cycle <= cycle+1; if (cycle==0) begin c_q_r <= 8'b0; end else begin c_q_r <= c_d_r+1; `ifdef TEST_VERBOSE $display("[%0t] a_r=%0d, b_r=%0d", $time, a_r, b_r); // a_r and b_r should always be the same `endif end if (cycle >= 10) begin if (b_r==9) begin $write("*-* All Finished *-*\n"); $finish; end else begin $stop; end end end endmodule verilator-3.874/test_regress/t/t_sys_file_autoflush.pl0000775000177100017500000000114012473477707023307 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_sys_file_basic.v"); compile ( v_flags2 => ['+incdir+../include', '+define+AUTOFLUSH'], verilator_flags2 => ['--autoflush'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_range.pl0000775000177100017500000000071712473477707021520 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_assert_dup_bad.pl0000775000177100017500000000121312473477707022360 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_assert_dup_bad.v:\d+: Duplicate declaration of block: covlabel %Error: t/t_assert_dup_bad.v:\d+: ... Location of original declaration %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_file_basic_input.dat0000664000177100017500000000021612473477707023732 0ustar wsnyderwsnyderhi lquad widestuff *xa=1f xb=237904689_02348923 *ba=10 bb=11010010101001010101 note_the_two *oa=23 ob=12563 *d=-236123 *fredfishblah 12346789 verilator-3.874/test_regress/t/t_lint_implicit_def_bad.v0000664000177100017500000000070712473477707023523 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (a,z); input a; output z; assign imp_warn = 1'b1; // verilator lint_off IMPLICIT assign imp_ok = 1'b1; `default_nettype none assign imp_err = 1'b1; `default_nettype wire assign imp_ok2 = 1'b1; `default_nettype none `resetall assign imp_ok3 = 1'b1; endmodule verilator-3.874/test_regress/t/t_clk_dsp.pl0000775000177100017500000000071712473477707021030 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_down_inlbd.pl0000775000177100017500000000112412473477707023541 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_B +define+INLINE_D'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_bad_hide2.pl0000775000177100017500000000132012473477707022051 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only -Wwarn-VARHIDDEN"], fails=>$Self->{v3}, expect=> '%Warning-VARHIDDEN: t/t_var_bad_hide2.v:\d+: Declaration of signal hides declaration in upper scope: t %Warning-VARHIDDEN: t/t_var_bad_hide2.v:\d+: ... Location of original declaration .* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_for_loop.v0000664000177100017500000000346312473477707021060 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [7:0] cyc; initial cyc=0; reg [31:0] loops; reg [31:0] loops2; integer i; always @ (posedge clk) begin cyc <= cyc+8'd1; if (cyc == 8'd1) begin $write("[%0t] t_loop: Running\n",$time); // Unwind < loops = 0; loops2 = 0; for (i=0; i<16; i=i+1) begin loops = loops + i; // surefire lint_off_line ASWEMB loops2 = loops2 + i; // surefire lint_off_line ASWEMB end if (i !== 16) $stop; if (loops !== 120) $stop; if (loops2 !== 120) $stop; // Unwind <= loops = 0; for (i=0; i<=16; i=i+1) begin loops = loops + 1; end if (i !== 17) $stop; if (loops !== 17) $stop; // Don't unwind breaked loops loops = 0; for (i=0; i<16; i=i+1) begin loops = loops + 1; if (i==7) i=99; // break out of loop end if (loops !== 8) $stop; // Don't unwind large loops! loops = 0; for (i=0; i<100000; i=i+1) begin loops = loops + 1; end if (loops !== 100000) $stop; // Test post-increment loops = 0; for (i=0; i<=16; i++) begin loops = loops + 1; end if (i !== 17) $stop; if (loops !== 17) $stop; // Test pre-increment loops = 0; for (i=0; i<=16; ++i) begin loops = loops + 1; end if (i !== 17) $stop; if (loops !== 17) $stop; // Test post-decrement loops = 0; for (i=16; i>=0; i--) begin loops = loops + 1; end if (i !== -1) $stop; if (loops !== 17) $stop; // Test pre-decrement loops = 0; for (i=16; i>=0; --i) begin loops = loops + 1; end if (i !== -1) $stop; if (loops !== 17) $stop; // $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_tri_unconn.v0000664000177100017500000001051612473477707021414 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; wire one = '1; wire z0 = 'z; wire z1 = 'z; wire z2 = 'z; wire z3 = 'z; wire tog = cyc[0]; // verilator lint_off PINMISSING t_tri0 tri0a (.line(`__LINE__), .expval(1'b0)); // Pin missing t_tri0 tri0b (.line(`__LINE__), .expval(1'b0), .tn()); t_tri0 tri0z (.line(`__LINE__), .expval(1'b0), .tn(z0)); t_tri0 tri0Z (.line(`__LINE__), .expval(1'b0), .tn(1'bz)); t_tri0 tri0c (.line(`__LINE__), .expval(1'b0), .tn(1'b0)); t_tri0 tri0d (.line(`__LINE__), .expval(1'b1), .tn(1'b1)); // Warning would be reasonable given tri0 connect t_tri0 tri0e (.line(`__LINE__), .expval(1'b0), .tn(~one)); t_tri0 tri0f (.line(`__LINE__), .expval(1'b1), .tn(one)); t_tri0 tri0g (.line(`__LINE__), .expval(~cyc[0]), .tn(~tog)); t_tri0 tri0h (.line(`__LINE__), .expval(cyc[0]), .tn(tog)); t_tri1 tri1a (.line(`__LINE__), .expval(1'b1)); // Pin missing t_tri1 tri1b (.line(`__LINE__), .expval(1'b1), .tn()); t_tri1 tri1z (.line(`__LINE__), .expval(1'b1), .tn(z1)); t_tri1 tri1Z (.line(`__LINE__), .expval(1'b1), .tn(1'bz)); t_tri1 tri1c (.line(`__LINE__), .expval(1'b0), .tn(1'b0)); // Warning would be reasonable given tri1 connect t_tri1 tri1d (.line(`__LINE__), .expval(1'b1), .tn(1'b1)); t_tri1 tri1e (.line(`__LINE__), .expval(1'b0), .tn(~one)); t_tri1 tri1f (.line(`__LINE__), .expval(1'b1), .tn(one)); t_tri1 tri1g (.line(`__LINE__), .expval(~cyc[0]), .tn(~tog)); t_tri1 tri1h (.line(`__LINE__), .expval(cyc[0]), .tn(tog)); t_tri2 tri2a (.line(`__LINE__), .expval(1'b0)); // Pin missing t_tri2 tri2b (.line(`__LINE__), .expval(1'b0), .tn()); t_tri2 tri2z (.line(`__LINE__), .expval(1'b0), .tn(z2)); t_tri2 tri2Z (.line(`__LINE__), .expval(1'b0), .tn(1'bz)); t_tri2 tri2c (.line(`__LINE__), .expval(1'b0), .tn(1'b0)); t_tri2 tri2d (.line(`__LINE__), .expval(1'b1), .tn(1'b1)); t_tri2 tri2e (.line(`__LINE__), .expval(1'b0), .tn(~one)); t_tri2 tri2f (.line(`__LINE__), .expval(1'b1), .tn(one)); t_tri2 tri2g (.line(`__LINE__), .expval(~cyc[0]), .tn(~tog)); t_tri2 tri2h (.line(`__LINE__), .expval(cyc[0]), .tn(tog)); t_tri3 tri3a (.line(`__LINE__), .expval(1'b1)); // Pin missing t_tri3 tri3b (.line(`__LINE__), .expval(1'b1), .tn()); t_tri3 tri3z (.line(`__LINE__), .expval(1'b1), .tn(z3)); t_tri3 tri3Z (.line(`__LINE__), .expval(1'b1), .tn(1'bz)); t_tri3 tri3c (.line(`__LINE__), .expval(1'b0), .tn(1'b0)); t_tri3 tri3d (.line(`__LINE__), .expval(1'b1), .tn(1'b1)); t_tri3 tri3e (.line(`__LINE__), .expval(1'b0), .tn(~one)); t_tri3 tri3f (.line(`__LINE__), .expval(1'b1), .tn(one)); t_tri3 tri3g (.line(`__LINE__), .expval(~cyc[0]), .tn(~tog)); t_tri3 tri3h (.line(`__LINE__), .expval(cyc[0]), .tn(tog)); // verilator lint_on PINMISSING // Test loop always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module t_tri0 (line, expval, tn); input integer line; input expval; input tn; // Illegal to be inout; spec requires net connection to any inout tri0 tn; wire clk = t.clk; always @(posedge clk) if (tn !== expval) begin $display("%%Error: from line %0d got=%x exp=%x",line,tn,expval); $stop; end endmodule module t_tri1 (line, expval, tn); input integer line; input expval; input tn; tri1 tn; wire clk = t.clk; always @(posedge clk) if (tn !== expval) begin $display("%%Error: from line %0d got=%x exp=%x",line,tn,expval); $stop; end endmodule module t_tri2 (line, expval, tn); input integer line; input expval; input tn; pulldown(tn); wire clk = t.clk; always @(posedge clk) if (tn !== expval) begin $display("%%Error: from line %0d got=%x exp=%x",line,tn,expval); $stop; end endmodule module t_tri3 (line, expval, tn); input integer line; input expval; input tn; pullup(tn); wire clk = t.clk; always @(negedge clk) if (tn !== expval) begin $display("%%Error: from line %0d got=%x exp=%x",line,tn,expval); $stop; end endmodule verilator-3.874/test_regress/t/t_gen_missing.pl0000775000177100017500000000077412473477707021716 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ['+define+T_GEN_MISSING'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_dtree_inlbc.pl0000775000177100017500000000112012473477707022705 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_dtree.v"); compile ( v_flags2 => ['+define+INLINE_B +define+INLINE_C'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_overwide.pl0000775000177100017500000000102112473477707022257 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( make_top_shell=>0, verilator_flags2 => [qw(-sc -Wno-WIDTH)], verilator_make_gcc=>0, ); #No execute () ok(1); 1; verilator-3.874/test_regress/t/t_select_set.v0000664000177100017500000000216312473477707021367 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (clk); input clk; reg [63:0] inwide; reg [39:0] addr; integer cyc; initial cyc=1; always @ (posedge clk) begin `ifdef TEST_VERBOSE $write ("%x %x\n", cyc, addr); `endif if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin addr <= 40'h12_3456_7890; end if (cyc==2) begin if (addr !== 40'h1234567890) $stop; addr[31:0] <= 32'habcd_efaa; end if (cyc==3) begin if (addr !== 40'h12abcdefaa) $stop; addr[39:32] <= 8'h44; inwide <= 64'hffeeddcc_11334466; end if (cyc==4) begin if (addr !== 40'h44abcdefaa) $stop; addr[31:0] <= inwide[31:0]; end if (cyc==5) begin if (addr !== 40'h4411334466) $stop; $display ("Flip [%x]\n", inwide[3:0]); addr[{2'b0,inwide[3:0]}] <= ! addr[{2'b0,inwide[3:0]}]; end if (cyc==6) begin if (addr !== 40'h4411334426) $stop; end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_math_swap.v0000664000177100017500000001014112473477707021213 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] Operand1 = crc[31:0]; wire [15:0] Operand2 = crc[47:32]; wire Unsigned = crc[48]; reg rst; parameter wl = 16; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [wl-1:0] Quotient; // From test of Test.v wire [wl-1:0] Remainder; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .Quotient (Quotient[wl-1:0]), .Remainder (Remainder[wl-1:0]), // Inputs .Operand1 (Operand1[wl*2-1:0]), .Operand2 (Operand2[wl-1:0]), .clk (clk), .rst (rst), .Unsigned (Unsigned)); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, Quotient, Remainder}; // What checksum will we end up with `define EXPECTED_SUM 64'h98d41f89a8be5693 // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x it=%x\n",$time, cyc, crc, result, test.Iteration); `endif cyc <= cyc + 1; if (cyc < 20 || test.Iteration==4'd15) begin crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; end sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; rst <= 1'b1; end else if (cyc<20) begin sum <= 64'h0; rst <= 1'b0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'h8dd70a44972ad809) $stop; if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test(clk, rst, Operand1, Operand2, Unsigned, Quotient, Remainder); parameter wl = 16; input [wl*2-1:0] Operand1; input [wl-1:0] Operand2; input clk, rst, Unsigned; output [wl-1:0] Quotient, Remainder; reg Cy, Overflow, Sign1, Sign2, Zero, Negative; reg [wl-1:0] ah,al,Quotient, Remainder; reg [3:0] Iteration; reg [wl-1:0] sub_quot,op; reg ah_ext; reg [1:0] a,b,c,d,e; always @(posedge clk) begin if (!rst) begin {a,b,c,d,e} = Operand1[9:0]; {a,b,c,d,e} = {e,d,c,b,a}; if (a != Operand1[1:0]) $stop; if (b != Operand1[3:2]) $stop; if (c != Operand1[5:4]) $stop; if (d != Operand1[7:6]) $stop; if (e != Operand1[9:8]) $stop; end end always @(posedge clk) begin if (rst) begin Iteration <= 0; Quotient <= 0; Remainder <= 0; end else begin if (Iteration == 0) begin {ah,al} = Operand1; op = Operand2; Cy = 0; Overflow = 0; Sign1 = (~Unsigned)&ah[wl-1]; Sign2 = (~Unsigned)&(ah[wl-1]^op[wl-1]); if (Sign1) {ah,al} = -{ah,al}; end `define BUG1 `ifdef BUG1 {ah_ext,ah,al} = {ah,al,Cy}; `else ah_ext = ah[15]; ah[15:1] = ah[14:0]; ah[0] = al[15]; al[15:1] = al[14:0]; al[0] = Cy; `endif `ifdef TEST_VERBOSE $display("%x %x %x %x %x %x %x %x %x", Iteration, ah, al, Quotient, Remainder, Overflow, ah_ext, sub_quot, Cy); `endif {Cy,sub_quot} = (~Unsigned)&op[wl-1]? {ah_ext,ah}+op : {ah_ext,ah} - {1'b1,op}; if (Cy) begin {ah_ext,ah} = {1'b0,sub_quot}; end if (Iteration != 15 ) begin if (ah_ext) Overflow = 1; end else begin if (al[14] && ~Unsigned) Overflow = 1; Quotient <= Sign2 ? -{al[14:0],Cy} : {al[14:0],Cy}; Remainder <= Sign1 ? -ah : ah; if (Overflow) begin Quotient <= Sign2 ? 16'h8001 : {Unsigned,{15{1'b1}}}; Remainder <= Unsigned ? 16'hffff : 16'h8000; Zero = 1; Negative = 1; end end Iteration <= Iteration + 1; // Count number of times this instruction is repeated end end endmodule verilator-3.874/test_regress/t/t_dpi_sys_c.cpp0000664000177100017500000000244512473477707021531 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2009 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include "svdpi.h" //====================================================================== #if defined(VERILATOR) # include "Vt_dpi_sys__Dpi.h" #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef NEED_EXTERNS extern "C" { extern void dpii_sys_task (int i); extern int dpii_sys_func (int i); } #endif //====================================================================== static int hidden = 0; void dpii_sys_task(int i) { hidden = i; } int dpii_sys_func(int i) { return i + hidden; } verilator-3.874/test_regress/t/t_sys_time.pl0000775000177100017500000000071712473477707021245 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_udp.v0000664000177100017500000000726612473477707020036 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v // End of automatics // Async clears must not race with clocks if we want repeatable results reg set_l = in[20]; reg clr_l = in[21]; always @ (negedge clk) begin set_l <= in[20]; clr_l <= in[21]; end //====== Mux wire [1:0] qm; // delay z a b sel udp_mux2 #(0.1) m0 (qm[0], in[0], in[2], in[4]); udp_mux2 #0.1 m1 (qm[1], in[1], in[3], in[4]); `define verilatorxx `ifdef verilatorxx reg [1:0] ql; reg [1:0] qd; // No sequential tables, yet // always @* begin // if (!clk) ql = in[13:12]; // end always @(posedge clk or negedge set_l or negedge clr_l) begin if (!set_l) qd <= ~2'b0; else if (!clr_l) qd <= 2'b0; else qd <= in[17:16]; end `else //====== Latch // wire [1:0] ql; // // q clk d // udp_latch l0 (ql[0], !in[8], in[12]); // udp_latch l1 (ql[1], !in[8], in[13]); //====== DFF wire [1:0] qd; //always @* $display("UL q=%b c=%b d=%b", ql[1:0], in[8], in[13:12]); // q clk d set_l clr_l udp_dff d0 (qd[0], in[8], in[16], set_l, clr_l); udp_dff d2 (qd[1], in[8], in[17], set_l, clr_l); `endif // Aggregate outputs into a single result vector wire [63:0] result = {52'h0, 2'b0,qd, 4'b0, 2'b0,qm}; // wire [63:0] result = {52'h0, 2'b0,qd, 2'b0,ql, 2'b0,qm}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) // Note not all simulators agree about the latch result. Maybe have a race? `define EXPECTED_SUM 64'hb73acf228acaeaa3 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule primitive udp_mux2 (z, a, b, sel); output z; input a, b, sel; table //a b s o ? 1 1 : 1 ; ? 0 1 : 0 ; 1 ? 0 : 1 ; 0 ? 0 : 0 ; 1 1 x : 1 ; 0 0 x : 0 ; endtable endprimitive primitive udp_latch (q, clk, d); output q; reg q; input clk, d; table //clk d q q' 0 1 : ? : 1; 0 0 : ? : 0; 1 ? : ? : -; endtable endprimitive primitive udp_dff (q, clk, d, set_l, clr_l); output q; input clk, d, set_l, clr_l; reg q; table //ck d s c : q : q' r 0 1 ? : ? : 0 ; r 1 ? 1 : ? : 1 ; * 1 ? 1 : 1 : 1 ; * 0 1 ? : 0 : 0 ; f ? ? ? : ? : - ; b * ? ? : ? : - ; ? ? 0 ? : ? : 1 ; b ? * 1 : 1 : 1 ; x 1 * 1 : 1 : 1 ; ? ? 1 0 : ? : 0 ; b ? 1 * : 0 : 0 ; x 0 1 * : 0 : 0 ; endtable endprimitive verilator-3.874/test_regress/t/t_cellarray.pl0000775000177100017500000000113012473477707021355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--stats"], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Gate assign merged\s+(\d+)/i, 28); }; ok(1); 1; verilator-3.874/test_regress/t/t_lint_block_redecl_bad.v0000664000177100017500000000065512473477707023505 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. //bug485, but see t_gen_forif.v for an OK example. module t (/*AUTOARG*/ // Inputs clk ); input clk; always_comb begin integer i; for(i=0; i<10; i++ ) begin: COMB end for(i=0; i<9; i++ ) begin: COMB end end endmodule verilator-3.874/test_regress/t/t_dpi_sys.pl0000775000177100017500000000077012473477707021062 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["t/t_dpi_sys_c.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_comma_inl0.pl0000775000177100017500000000104012525171734022437 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_inst_comma.v"); compile ( v_flags2 => ['+define+NOUSE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_anon.pl0000775000177100017500000000102412473477707021740 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_array.pl0000775000177100017500000000072212473477707021703 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface1_modport_trace.pl0000775000177100017500000000104712473477707024351 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_interface1_modport.v"); compile ( verilator_flags2 => ['--trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_init_concat.pl0000775000177100017500000000071712473477707021703 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_export.pl0000775000177100017500000000127012473477707021561 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # irun -sv top.v t_dpi_export.v -cpost t_dpi_export_c.c -end compile ( # Amazingly VCS, NC and Verilator all just accept the C file here! v_flags2 => ["t/t_dpi_export_c.cpp"], verilator_flags2 => ["-Wall -Wno-DECLFILENAME -no-l2name"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_imm2.cpp0000664000177100017500000000236112473477707021427 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- #include #include "Vt_math_imm2.h" QData MaskVal (int lbit, int hbit) { QData val; for (val = 0; lbit <= hbit; lbit++) val |= (1ULL << lbit); return val; } int main (int argc, char *argv[]) { Verilated::debug(0); Vt_math_imm2 *sim = new Vt_math_imm2; int lbit, hbit; int errs=0; for (lbit = 0; lbit < 32; lbit++) { for (hbit = lbit; hbit < 32; hbit++) { QData expected; sim->LowMaskSel_Bot = lbit; sim->LowMaskSel_Top = lbit; sim->HighMaskSel_Bot = hbit; sim->HighMaskSel_Top = hbit; sim->eval(); expected = (MaskVal (sim->LowMaskSel_Top, sim->HighMaskSel_Top) << 32ULL) | MaskVal (sim->LowMaskSel_Bot, sim->HighMaskSel_Bot); if (sim->LogicImm != expected) { printf ("%%Error: %d.%d,%d.%d -> %016" VL_PRI64 "x/%016" VL_PRI64 "x -> %016" VL_PRI64 "x (expected %016" VL_PRI64 "x)\n", sim->LowMaskSel_Top, sim->HighMaskSel_Top, sim->LowMaskSel_Bot, sim->HighMaskSel_Bot, sim->LowLogicImm, sim->HighLogicImm, sim->LogicImm, expected); errs=1; } } } if (errs) { vl_stop(__FILE__, __LINE__, "TOP-cpp"); exit(10); } else { printf ("*-* All Finished *-*\n"); exit(0); } } verilator-3.874/test_regress/t/t_mem_multi_io.v0000664000177100017500000000222612473477707021714 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic [7:0] arr [7:0]; logic [7:0] arri [7:0]; has_array am1 (.clk(clk), .arri(arr), .arro(arri)); integer cyc; initial cyc = 0; initial begin for (int i = 0; i < 8; i++) begin arr[i] = 0; end end always @(posedge clk) begin cyc <= cyc + 1; if (cyc == 5 && arri[1] != 8) begin $stop; end for (int i = 0; i < 7; ++i) begin arr[i+1] <= arr[i]; end arr[0] <= arr[0] + 1; end endmodule : t module has_array ( input clk, input logic [7:0] arri [7:0], output logic [7:0] arro [7:0] ); integer cyc; initial cyc = 0; always @(posedge clk) begin cyc <= cyc + 1; if (arri[0] == 10 && cyc == 10) begin $write("*-* All Finished *-*\n"); $finish; end end always @(posedge clk) begin for (integer i = 0; i < 7; ++i) begin arro[i+1] <= arro[i]; end arro[0] = arro[0] + 2; end endmodule : has_array verilator-3.874/test_regress/t/t_select_lhs_oob.pl0000775000177100017500000000072212473477707022371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_types.pl0000775000177100017500000000106312473477707021420 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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->{verilated_randReset} = 1; # allow checking if we initialize vars to zero only when needed compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_logic_bad.v0000664000177100017500000000071212473477707021772 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. module t (); // Can't handle logic (yet?) import "DPI-C" dpii_fa_bit = function int oth_f_int1(input logic [2:0] i); initial begin $stop; end endmodule verilator-3.874/test_regress/t/t_math_imm.v0000664000177100017500000000615312473477707021033 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. // // Example module to create problem. // // generate a 64 bit value with bits // [HighMaskSel_Bot : LowMaskSel_Bot ] = 1 // [HighMaskSel_Top+32: LowMaskSel_Top+32] = 1 // all other bits zero. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [7:0] crc; reg [63:0] sum; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [63:0] HighLogicImm; // From example of example.v wire [63:0] LogicImm; // From example of example.v wire [63:0] LowLogicImm; // From example of example.v // End of automatics wire [5:0] LowMaskSel_Top = crc[5:0]; wire [5:0] LowMaskSel_Bot = crc[5:0]; wire [5:0] HighMaskSel_Top = crc[5:0]+{4'b0,crc[7:6]}; wire [5:0] HighMaskSel_Bot = crc[5:0]+{4'b0,crc[7:6]}; example example (/*AUTOINST*/ // Outputs .LogicImm (LogicImm[63:0]), .LowLogicImm (LowLogicImm[63:0]), .HighLogicImm (HighLogicImm[63:0]), // Inputs .LowMaskSel_Top (LowMaskSel_Top[5:0]), .HighMaskSel_Top (HighMaskSel_Top[5:0]), .LowMaskSel_Bot (LowMaskSel_Bot[5:0]), .HighMaskSel_Bot (HighMaskSel_Bot[5:0])); always @ (posedge clk) begin cyc <= cyc + 1; crc <= {crc[6:0], ~^ {crc[7],crc[5],crc[4],crc[3]}}; `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%b %d.%d,%d.%d -> %x.%x -> %x\n",$time, cyc, crc, LowMaskSel_Top, HighMaskSel_Top, LowMaskSel_Bot, HighMaskSel_Bot, LowLogicImm, HighLogicImm, LogicImm); `endif if (cyc==0) begin // Single case crc <= 8'h0; sum <= 64'h0; end else if (cyc==1) begin // Setup crc <= 8'hed; sum <= 64'h0; end else if (cyc<90) begin sum <= {sum[62:0],sum[63]} ^ LogicImm; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%b %x\n",$time, cyc, crc, sum); if (crc !== 8'b00111000) $stop; if (sum !== 64'h58743ffa61e41075) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module example (/*AUTOARG*/ // Outputs LogicImm, LowLogicImm, HighLogicImm, // Inputs LowMaskSel_Top, HighMaskSel_Top, LowMaskSel_Bot, HighMaskSel_Bot ); input [5:0] LowMaskSel_Top, HighMaskSel_Top; input [5:0] LowMaskSel_Bot, HighMaskSel_Bot; output [63:0] LogicImm; output [63:0] LowLogicImm, HighLogicImm; wire [63:0] LowLogicImm, HighLogicImm; /* verilator lint_off UNSIGNED */ /* verilator lint_off CMPCONST */ genvar i; generate for (i=0;i<64;i=i+1) begin : MaskVal if (i >= 32) begin assign LowLogicImm[i] = (LowMaskSel_Top <= i[5:0]); assign HighLogicImm[i] = (HighMaskSel_Top >= i[5:0]); end else begin assign LowLogicImm[i] = (LowMaskSel_Bot <= i[5:0]); assign HighLogicImm[i] = (HighMaskSel_Bot >= i[5:0]); end end endgenerate /* verilator lint_on UNSIGNED */ /* verilator lint_on CMPCONST */ assign LogicImm = LowLogicImm & HighLogicImm; endmodule verilator-3.874/test_regress/t/t_case_genx_bad.v0000664000177100017500000000056412473477707022002 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005-2007 by Wilson Snyder. module t (/*AUTOARG*/); parameter P = 32'b1000; generate case (P) 32'b0: initial begin end 32'b1xxx: initial begin end default: initial begin end endcase endgenerate endmodule verilator-3.874/test_regress/t/t_var_vec_sel.v0000664000177100017500000000117012473477707021522 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. // bug601 module t ( input clk, input [3:0] in3, // worky input [0:0] in2 [3:0], // worky input in1 [3:0], // no worky input [1:0] sel, output reg out1, output reg out2, output reg out3 ); always @(posedge clk) begin out3 <= in3[sel] ? in3[sel] : out3; out2 <= in2[sel] ? in2[sel] : out2; out1 <= in1[sel] ? in1[sel] : out1; // breaks $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_mem_multi_io3_sc.pl0000775000177100017500000000123112525171734022615 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_mem_multi_io3.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io3.cpp --sc -Oi"], verilator_flags3 => [], ); ok(1); 1; verilator-3.874/test_regress/t/t_func_grey.v0000664000177100017500000000273412473477707021222 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); // surefire lint_off _NETNM // surefire lint_off STMINI input clk; integer _mode; initial _mode = 0; wire [2:0] b3; reg [2:0] g3; wire [5:0] b6; reg [5:0] g6; t_func_grey2bin #(3) g2b3 (.b(b3), .g(g3)); t_func_grey2bin #(6) g2b6 (.b(b6), .g(g6)); always @ (posedge clk) begin if (_mode==0) begin _mode <= 1; g3 <= 3'b101; g6 <= 6'b110101; end else if (_mode==1) begin if (b3 !== 3'b110) $stop; if (b6 !== 6'b100110) $stop; _mode <= 2; $write("*-* All Finished *-*\n"); $finish; end end endmodule // Module gray2bin // convert an arbitrary width gray coded number to binary. The conversion // of a 4 bit gray (represented as "g") to binary ("b") would go as follows: // b[3] = ^g[3] = g[3] // b[2] = ^g[3:2] // b[1] = ^g[3:1] // b[0] = ^g[3:[SZ-1:0] cur0] module t_func_grey2bin (/*AUTOARG*/ // Outputs b, // Inputs g ); // surefire lint_off STMFOR parameter SZ = 5; output [SZ-1:0] b; input [SZ-1:0] g; /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [SZ-1:0] b; // End of automatics integer i; always @(/*AUTOSENSE*/g) for (i=0; i> i); // surefire lint_off_line LATASS endmodule verilator-3.874/test_regress/t/t_array_pattern_packed.v0000664000177100017500000001523712473477707023425 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic [1:0] [3:0] [3:0] array_simp; // big endian array logic [3:0] array_oned; initial begin array_oned = '{2:1'b1, 0:1'b1, default:1'b0}; if (array_oned != 4'b0101) $stop; array_simp[0] = '{ 4'd3, 4'd2, 4'd1, 4'd0}; if (array_simp[0] !== 16'h3210) $stop; // verilator lint_off WIDTH array_simp[0] = '{ 3 ,2 ,1, 0 }; // verilator lint_on WIDTH if (array_simp[0] !== 16'h3210) $stop; // Doesn't seem to work for unpacked arrays in other simulators //if (array_simp[0] !== 16'h3210) $stop; //array_simp[0] = '{ 1:4'd3, default:13}; //if (array_simp[0] !== 16'hDD3D) $stop; array_simp = '{ '{ 4'd3, 4'd2, 4'd1, 4'd0 }, '{ 4'd1, 4'd2, 4'd3, 4'd4 }}; if (array_simp !== 32'h3210_1234) $stop; // IEEE says '{} allowed only on assignments, not !=, ==. // Doesn't seem to work for unpacked arrays in other simulators array_simp = '{2{ '{4'd3, 4'd2, 4'd1, 4'd0 } }}; if (array_simp !== 32'h3210_3210) $stop; array_simp = '{2{ '{4{ 4'd3 }} }}; if (array_simp !== 32'h3333_3333) $stop; // Not legal in other simulators - replication doesn't match // However IEEE suggests this is legal. //array_simp = '{2{ '{2{ 4'd3, 4'd2 }} }}; // Note it's not '{3,2} $write("*-* All Finished *-*\n"); $finish; end //==================== // parameters for array sizes localparam WA = 4; // address dimension size localparam WB = 4; // bit dimension size localparam NO = 11; // number of access events // 2D packed arrays logic [WA-1:0] [WB-1:0] array_bg; // big endian array /* verilator lint_off LITENDIAN */ logic [0:WA-1] [0:WB-1] array_lt; // little endian array /* verilator lint_on LITENDIAN */ integer cnt = 0; // event counter always @ (posedge clk) begin cnt <= cnt + 1; end // finish report always @ (posedge clk) if ((cnt[30:2]==(NO-1)) && (cnt[1:0]==2'd3)) begin $write("*-* All Finished *-*\n"); $finish; end // big endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaults (all bits 1'b0) if (cnt[30:2]== 0) array_bg <= '0; else if (cnt[30:2]== 1) array_bg <= '0; else if (cnt[30:2]== 2) array_bg <= '0; else if (cnt[30:2]== 3) array_bg <= '0; else if (cnt[30:2]== 4) array_bg <= '0; else if (cnt[30:2]== 5) array_bg <= '0; else if (cnt[30:2]== 6) array_bg <= '0; else if (cnt[30:2]== 7) array_bg <= '0; else if (cnt[30:2]== 8) array_bg <= '0; else if (cnt[30:2]== 9) array_bg <= '0; else if (cnt[30:2]==10) array_bg <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]== 0) begin end else if (cnt[30:2]== 1) array_bg <= '{ 3 ,2 ,1, 0 }; else if (cnt[30:2]== 2) array_bg <= '{default:13}; else if (cnt[30:2]== 3) array_bg <= '{0:4, 1:5, 2:6, 3:7}; else if (cnt[30:2]== 4) array_bg <= '{2:15, default:13}; else if (cnt[30:2]== 5) array_bg <= '{WA { {WB/2 {2'b10}} }}; else if (cnt[30:2]== 6) array_bg <= '{cnt[3:0]+0, cnt[3:0]+1, cnt[3:0]+2, cnt[3:0]+3}; end else if (cnt[1:0]==2'd2) begin // chack array agains expected value if (cnt[30:2]== 0) begin if (array_bg !== 16'b0000000000000000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 1) begin if (array_bg !== 16'b0011001000010000) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 2) begin if (array_bg !== 16'b1101110111011101) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 3) begin if (array_bg !== 16'b0111011001010100) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 4) begin if (array_bg !== 16'b1101111111011101) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 5) begin if (array_bg !== 16'b1010101010101010) begin $display("%b", array_bg); $stop(); end end else if (cnt[30:2]== 6) begin if (array_bg !== 16'b1001101010111100) begin $display("%b", array_bg); $stop(); end end end // little endian always @ (posedge clk) if (cnt[1:0]==2'd0) begin // initialize to defaults (all bits 1'b0) if (cnt[30:2]== 0) array_lt <= '0; else if (cnt[30:2]== 1) array_lt <= '0; else if (cnt[30:2]== 2) array_lt <= '0; else if (cnt[30:2]== 3) array_lt <= '0; else if (cnt[30:2]== 4) array_lt <= '0; else if (cnt[30:2]== 5) array_lt <= '0; else if (cnt[30:2]== 6) array_lt <= '0; else if (cnt[30:2]== 7) array_lt <= '0; else if (cnt[30:2]== 8) array_lt <= '0; else if (cnt[30:2]== 9) array_lt <= '0; else if (cnt[30:2]==10) array_lt <= '0; end else if (cnt[1:0]==2'd1) begin // write data into whole or part of the array using literals if (cnt[30:2]== 0) begin end else if (cnt[30:2]== 1) array_lt <= '{ 3 ,2 ,1, 0 }; else if (cnt[30:2]== 2) array_lt <= '{default:13}; else if (cnt[30:2]== 3) array_lt <= '{3:4, 2:5, 1:6, 0:7}; else if (cnt[30:2]== 4) array_lt <= '{1:15, default:13}; else if (cnt[30:2]== 5) array_lt <= '{WA { {WB/2 {2'b10}} }}; else if (cnt[30:2]==10) array_lt <= '{cnt[3:0]+0, cnt[3:0]+1, cnt[3:0]+2, cnt[3:0]+3}; end else if (cnt[1:0]==2'd2) begin // chack array agains expected value if (cnt[30:2]== 0) begin if (array_lt !== 16'b0000000000000000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 1) begin if (array_lt !== 16'b0011001000010000) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 2) begin if (array_lt !== 16'b1101110111011101) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 3) begin if (array_lt !== 16'b0111011001010100) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 4) begin if (array_lt !== 16'b1101111111011101) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]== 5) begin if (array_lt !== 16'b1010101010101010) begin $display("%b", array_lt); $stop(); end end else if (cnt[30:2]==10) begin if (array_lt !== 16'b1001101010111100) begin $display("%b", array_lt); $stop(); end end end endmodule verilator-3.874/test_regress/t/t_lint_declfilename.v0000664000177100017500000000037212473477707022673 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t; t_lint_declfilename sub (); endmodule module t_lint_declfilename; endmodule verilator-3.874/test_regress/t/t_array_packed_sysfunct.pl0000775000177100017500000000071712473477707023774 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_public_sig.cpp0000664000177100017500000000204212473477707023044 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. #include #include #include "Vt_trace_public_sig.h" #include "Vt_trace_public_sig_t.h" #include "Vt_trace_public_sig_glbl.h" unsigned long long main_time = 0; double sc_time_stamp() { return (double)main_time; } const unsigned long long dt_2 = 3; int main(int argc, char **argv, char **env) { Vt_trace_public_sig *top = new Vt_trace_public_sig("top"); Verilated::debug(0); Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; top->trace(tfp,99); tfp->open("obj_dir/t_trace_public_sig/simx.vcd"); while (main_time <= 20) { top->CLK = (main_time/dt_2)%2; top->eval(); top->v->glbl->GSR = (main_time < 7); tfp->dump((unsigned int)(main_time)); ++main_time; } tfp->close(); top->final(); printf ("*-* All Finished *-*\n"); return 0; } verilator-3.874/test_regress/t/t_lint_incabspath.pl0000775000177100017500000000112212473477707022542 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( verilator_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_hierarchy_unnamed.pl0000775000177100017500000000102412473477707023066 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], make_top_shell => 0, make_main => 0, verilator_make_gcc => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_display_signed.pl0000775000177100017500000000237712473477707022413 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, expect=> quotemeta( '[0] lp %x=0bbccc %x=0bbccc %o=2736314 %b=010111011110011001100 %0d=769228 %d= 769228 [0] ln %x=1bbccc %x=1bbccc %o=6736314 %b=110111011110011001100 %0d=-279348 %d= -279348 [0] qp %x=001bbbbcccc %x=001bbbbcccc %o=00067356746314 %b=00000000110111011101110111100110011001100 %0d=7444614348 %d= 7444614348 [0] qn %x=101bbbbcccc %x=101bbbbcccc %o=20067356746314 %b=10000000110111011101110111100110011001100 %0d=-1092067013428 %d=-1092067013428 [0] wp %x=000bc1234567812345678 %x=000bc1234567812345678 %o=000570110642547402215053170 %b=000000000101111000001001000110100010101100111100000010010001101000101011001111000 [0] wn %x=000bc1234577812345678 %x=000bc1234577812345678 %o=000570110642567402215053170 %b=000000000101111000001001000110100010101110111100000010010001101000101011001111000 '), ); ok(1); 1; verilator-3.874/test_regress/t/t_unoptflat_simple_bad.pl0000775000177100017500000000076012473477707023602 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_unoptflat_simple.v"); # Compile only compile ( fails => 1 ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_modport_inl.pl0000775000177100017500000000115212473477707023751 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_interface_modport.v"); compile ( # Avoid inlining so we find bugs in the non-inliner connection code verilator_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_f.pl0000775000177100017500000000076012473477707020625 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. compile ( v_flags2 => ["-f t/t_flag_f.vc"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_preproc_inc3.vh0000664000177100017500000000070312473477707021771 0ustar wsnyderwsnyder`line 2 "inc3_a_filename_from_line_directive" 0 // DESCRIPTION: Verilog::Preproc: Example source code // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2000-2007 by Wilson Snyder. `ifndef _EXAMPLE_INC2_V_ `define _EXAMPLE_INC2_V_ 1 `define _EMPTY // FOO At file `__FILE__ line `__LINE__ `else `error "INC2 File already included once" `endif // guard `ifdef not_defined `include "NotToBeInced.vh" `endif verilator-3.874/test_regress/t/t_assign_inline.pl0000775000177100017500000000076712525171734022225 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["-O0 -OG"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_orig.v0000664000177100017500000001010712473477707021165 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg _ranit; reg rnd; reg [2:0] a; reg [2:0] b; reg [31:0] wide; // surefire lint_off STMINI initial _ranit = 0; wire sigone1 = 1'b1; wire sigone2 = 1'b1; reg ok; parameter [1:0] twounkn = 2'b?; // This gets extended to 2'b?? // Large case statements should be well optimizable. reg [2:0] anot; always @ (/*AS*/a) begin casez (a) default: anot = 3'b001; 3'd0: anot = 3'b111; 3'd1: anot = 3'b110; 3'd2: anot = 3'b101; 3'd3: anot = 3'b101; 3'd4: anot = 3'b011; 3'd5: anot = 3'b010; 3'd6: anot = 3'b001; // Same so folds with 7 endcase end always @ (posedge clk) begin if (!_ranit) begin _ranit <= 1; rnd <= 1; $write("[%0t] t_case: Running\n", $time); // a = 3'b101; b = 3'b111; // verilator lint_off CASEX casex (a) default: $stop; 3'bx1x: $stop; 3'b100: $stop; 3'bx01: ; endcase casez (a) default: $stop; 3'b?1?: $stop; 3'b100: $stop; 3'b?01: ; endcase casez (a) default: $stop; {1'b0, twounkn}: $stop; {1'b1, twounkn}: ; endcase casez (b) default: $stop; {1'b0, twounkn}: $stop; {1'b1, twounkn}: ; // {1'b0, 2'b??}: $stop; // {1'b1, 2'b??}: ; endcase case(a[0]) default: ; endcase casex(a) default: ; 3'b?0?: ; endcase // verilator lint_off CASEX //This is illegal, the default occurs before the statements. //case(a[0]) // default: $stop; // 1'b1: ; //endcase // wide = 32'h12345678; casez (wide) default: $stop; 32'h12345677, 32'h12345678, 32'h12345679: ; endcase // ok = 0; casez ({sigone1,sigone2}) //2'b10, 2'b01, 2'bXX: ; // verilator bails at this since in 2 state it can be true... 2'b10, 2'b01: ; 2'b00: ; default: ok=1'b1; endcase if (ok !== 1'b1) $stop; // if (rnd) begin $write(""); end // $write("*-* All Finished *-*\n"); $finish; end end // Check parameters in case statements parameter ALU_DO_REGISTER = 3'h1; // input selected by reg addr. parameter DSP_REGISTER_V = 6'h03; reg [2:0] alu_ctl_2s; // Delayed version of alu_ctl reg [5:0] reg_addr_2s; // Delayed version of reg_addr reg [7:0] ir_slave_2s; // Instruction Register delayed 2 phases reg [15:10] f_tmp_2s; // Delayed copy of F reg p00_2s; initial begin alu_ctl_2s = 3'h1; reg_addr_2s = 6'h3; ir_slave_2s= 0; f_tmp_2s= 0; casex ({alu_ctl_2s,reg_addr_2s, ir_slave_2s[7],ir_slave_2s[5:4],ir_slave_2s[1:0], f_tmp_2s[11:10]}) default: p00_2s = 1'b0; {ALU_DO_REGISTER,DSP_REGISTER_V,1'bx,2'bx,2'bx,2'bx}: p00_2s = 1'b1; endcase if (1'b0) $display ("%x %x %x %x", alu_ctl_2s, ir_slave_2s, f_tmp_2s, p00_2s); //Prevent unused // case ({1'b1, 1'b1}) default: $stop; {1'b1, p00_2s}: ; endcase end // Check wide overlapping cases // surefire lint_off CSEOVR parameter ANY_STATE = 7'h??; reg [19:0] foo; initial begin foo = {1'b0,1'b0,1'b0,1'b0,1'b0,7'h04,8'b0}; casez (foo) default: $stop; {1'b1,1'b?,1'b?,1'b?,1'b?,ANY_STATE,8'b?}: $stop; {1'b?,1'b1,1'b?,1'b?,1'b?,7'h00,8'b?}: $stop; {1'b?,1'b?,1'b1,1'b?,1'b?,7'h00,8'b?}: $stop; {1'b?,1'b?,1'b?,1'b1,1'b?,7'h00,8'b?}: $stop; {1'b?,1'b?,1'b?,1'b?,1'b?,7'h04,8'b?}: ; {1'b?,1'b?,1'b?,1'b?,1'b?,7'h06,8'hdf}: $stop; {1'b?,1'b?,1'b?,1'b?,1'b?,7'h06,8'h00}: $stop; endcase end initial begin foo = 20'b1010; casex (foo[3:0]) default: $stop; 4'b0xxx, 4'b100x, 4'b11xx: $stop; 4'b1010: ; endcase end initial begin foo = 20'b1010; ok = 1'b0; // Test of RANGE(CONCAT reductions... casex ({foo[3:2],foo[1:0],foo[3]}) 5'bxx10x: begin ok=1'b0; foo=20'd1; ok=1'b1; end // Check multiple expressions 5'bxx00x: $stop; 5'bxx01x: $stop; 5'bxx11x: $stop; endcase if (!ok) $stop; end endmodule verilator-3.874/test_regress/t/t_initial_edge.v0000664000177100017500000000434412473477707021655 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: initial edge issue // // The module initial_edge drives the output "res" high when the reset signal, // rst, goes high. // // The module initial_edge_n drives the output "res_n" high when the reset // signal, rst_n, goes low. // // For 4-state simulators, that edge occurs when the initial value of rst_n, // X, goes to zero. However, by default for Verilator, being 2-state, the // initial value is zero, so no edge is seen. // // This is not a bug in verilator (it is bad design to rely on an edge // transition from an unitialized signal), but the problem is that there are // quite a few instances of code out there that seems to be dependent on this // behaviour to get out of reset. // // The Verilator --x-initial-edge flag causes these initial edges to trigger, // thus matching the behaviour of a 4-state simulator. This is reportedly also // the behaviour of commercial cycle accurate modelling tools as well. // // This file ONLY is placed into the Public Domain, for any use, without // warranty, 2012 by Wilson Snyder. `timescale 1ns/1ns module t (/*AUTOARG*/ // Inputs clk ); input clk; wire res; wire res_n; reg rst; reg rst_n; integer count = 0; initial_edge i_edge (.res (res), .rst (rst)); initial_edge_n i_edge_n (.res_n (res_n), .rst_n (rst_n)); // run for 3 cycles, with one cycle of reset. always @(posedge clk) begin rst <= (count == 0) ? 1 : 0; rst_n <= (count == 0) ? 0 : 1; if (count == 3) begin if ((res == 1) && (res_n == 1)) begin $write ("*-* All Finished *-*\n"); $finish; end else begin `ifdef TEST_VERBOSE $write ("FAILED: res = %b, res_n = %b\n", res, res_n); `endif $stop; end end count = count + 1; end endmodule module initial_edge_n (res_n, rst_n); output res_n; input rst_n; reg res_n = 1'b0; always @(negedge rst_n) begin if (rst_n == 1'b0) begin res_n <= 1'b1; end end endmodule // initial_edge_n module initial_edge (res, rst); output res; input rst; reg res = 1'b0; always @(posedge rst) begin if (rst == 1'b1) begin res <= 1'b1; end end endmodule // initial_edge verilator-3.874/test_regress/t/t_enum_type_methods.pl0000775000177100017500000000072212473477707023135 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_2exp_bad.v0000664000177100017500000000076212473477707021560 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. module t; export "DPI-C" task dpix_twice; export "DPI-C" dpix_t_int_renamed = task dpix_twice; task dpix_twice(input int i, output int o); o = ~i; endtask initial begin $stop; end endmodule verilator-3.874/test_regress/t/t_embed1.pl0000775000177100017500000000276412473477707020552 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. use File::Spec; my $self = $Self; my $child_dir = "$Self->{obj_dir}_child"; mkdir $child_dir; # Compile the child { my @cmdargs = $Self->compile_vlt_flags (VM_PREFIX => "$Self->{VM_PREFIX}_child", top_filename => "$Self->{name}_child.v", verilator_flags => ["-cc", "-Mdir", "${child_dir}", "--debug-check"], ); $Self->_run(logfile=>"${child_dir}/vlt_compile.log", cmd=>\@cmdargs); $Self->_run(logfile=>"${child_dir}/vlt_gcc.log", cmd=>["cd ${child_dir} && ", "make", "-f".getcwd()."/Makefile_obj", "CPPFLAGS_DRIVER=-D".uc($self->{name}), ($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""), "MAKE_MAIN=0", "VM_PREFIX=$self->{VM_PREFIX}_child", "V$self->{name}_child__ALL.a", # bypass default rule, make archive ($param{make_flags}||""), ]); } # Compile the parent (might be with other than verilator) compile ( v_flags2 => [File::Spec->rel2abs("${child_dir}/V$self->{name}_child__ALL.a"), # TODO would be nice to have this in embedded archive "t/t_embed1_c.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_cast.pl0000775000177100017500000000071712473477707020343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_set_link.pl0000775000177100017500000000071712473477707022071 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_detectarray_2.pl0000775000177100017500000000077312525171734022130 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["-Wno-CLKDATA"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_display_signed.v0000664000177100017500000000270012473477707022230 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; reg signed [20:0] longp; initial longp = 21'shbbccc; reg signed [20:0] longn; initial longn = 21'shbbccc; initial longn[20]=1'b1; reg signed [40:0] quadp; initial quadp = 41'sh1_bbbb_cccc; reg signed [40:0] quadn; initial quadn = 41'sh1_bbbb_cccc; initial quadn[40]=1'b1; reg signed [80:0] widep; initial widep = 81'shbc_1234_5678_1234_5678; reg signed [80:0] widen; initial widen = 81'shbc_1234_5678_1234_5678; initial widen[40]=1'b1; initial begin // Display formatting $display("[%0t] lp %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time, longp, longp, longp, longp, longp, longp); $display("[%0t] ln %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time, longn, longn, longn, longn, longn, longn); $display("[%0t] qp %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time, quadp, quadp, quadp, quadp, quadp, quadp); $display("[%0t] qn %%x=%x %%x=%x %%o=%o %%b=%b %%0d=%0d %%d=%d", $time, quadn, quadn, quadn, quadn, quadn, quadn); $display("[%0t] wp %%x=%x %%x=%x %%o=%o %%b=%b", $time, widep, widep, widep, widep); $display("[%0t] wn %%x=%x %%x=%x %%o=%o %%b=%b", $time, widen, widen, widen, widen); $display; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_inst_missing.pl0000775000177100017500000000106212473477707022111 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( v_flags2 => ["--lint-only --Wall -Wno-DECLFILENAME"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_dist_untracked.pl0000775000177100017500000000210412473477707022404 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. my $root = ".."; my $Debug; if (!-r "$root/.git") { $Self->skip("Not in a git repository"); } else { ### Must trim output before and after our file list my $status = `cd $root && git ls-files -o --exclude-standard`; print "ST $status\n" if $Debug; my %warns; foreach my $file (sort split /\n/, $status) { next if $file =~ /nodist/; $warns{$file} = "File not in git or .gitignore: $file"; } if (keys %warns) { # First warning lists everything as that's shown in the driver summary $Self->error("Files untracked in git or .gitignore: ",join(' ',sort keys %warns)); foreach my $file (sort keys %warns) { $Self->error($warns{$file}); } } } ok(1); 1; verilator-3.874/test_regress/t/t_trace_public.out0000664000177100017500000000507012473477707022233 0ustar wsnyderwsnyder$version Generated by SpTraceVcd $end $date Tue Nov 3 09:34:23 2009 $end $timescale 1ns $end $scope module top $end $var wire 1 6 CLK $end $var wire 1 7 RESET $end $scope module v $end $var wire 1 6 CLK $end $var wire 1 # RESET $end $var wire 32 $ val [31:0] $end $var wire 2 3 vec(3) [2:1] $end $var wire 2 4 vec(4) [2:1] $end $scope module glbl $end $var wire 1 5 GSR $end $upscope $end $scope module little $end $var wire 1 6 clk $end $var wire 128 / i128 [63:190] $end $var wire 49 - i48 [1:49] $end $var wire 8 , i8 [0:7] $end $upscope $end $scope module neg $end $var wire 1 6 clk $end $var wire 128 ( i128 [63:-64] $end $var wire 48 & i48 [-1:-48] $end $var wire 8 % i8 [0:-7] $end $upscope $end $upscope $end $upscope $end $enddefinitions $end #0 1# b00000000000000000000000000000000 $ b00000000 % b000000000000000000000000000000000000000000000000 & b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ( b00000000 , b0000000000000000000000000000000000000000000000000 - b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 / b00 3 b00 4 15 17 06 #1 #2 #3 b11111111 % b111111111111111111111111111111111111111111111111 & b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ( b11111111 , b1111111111111111111111111111111111111111111111111 - b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 / 16 #4 #5 #6 06 #7 05 #8 #9 0# b00000000 % b000000000000000000000000000000000000000000000000 & b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ( b00000000 , b0000000000000000000000000000000000000000000000000 - b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 / 07 16 #10 #11 #12 06 #13 #14 #15 b00000000000000000000000000000001 $ b11111111 % b111111111111111111111111111111111111111111111111 & b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ( b11111111 , b1111111111111111111111111111111111111111111111111 - b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 / 16 #16 #17 #18 06 #19 #20 verilator-3.874/test_regress/t/t_inst_aport.pl0000775000177100017500000000103112473477707021561 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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->unsupported("Verilator/commercial slice unsupported, bug711"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_dotted.v0000664000177100017500000000762412473477707021542 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); // verilator lint_off MULTIDRIVEN ma ma0 (); global_mod #(32'hf00d) global_cell (); global_mod #(32'hf22d) global_cell2 (); input clk; integer cyc=1; function [31:0] getName; input fake; getName = "t "; endfunction always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==2) begin if (global_cell. getGlob(1'b0) !== 32'hf00d) $stop; if (global_cell2.getGlob(1'b0) !== 32'hf22d) $stop; end if (cyc==3) begin if (ma0. getName(1'b0) !== "ma ") $stop; if (ma0.mb0. getName(1'b0) !== "mb ") $stop; if (ma0.mb0.mc0.getName(1'b0) !== "mc ") $stop; end if (cyc==4) begin if (ma0.mb0. getP2(1'b0) !== 32'h0) $stop; if (ma0.mb0.mc0.getP3(1'b0) !== 32'h0) $stop; if (ma0.mb0.mc1.getP3(1'b0) !== 32'h1) $stop; end if (cyc==5) begin ma0. checkName(ma0. getName(1'b0)); ma0.mb0. checkName(ma0.mb0. getName(1'b0)); ma0.mb0.mc0.checkName(ma0.mb0.mc0.getName(1'b0)); end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule `ifdef USE_INLINE_MID `define INLINE_MODULE /*verilator inline_module*/ `define INLINE_MID_MODULE /*verilator no_inline_module*/ `else `ifdef USE_INLINE `define INLINE_MODULE /*verilator inline_module*/ `define INLINE_MID_MODULE /*verilator inline_module*/ `else `define INLINE_MODULE /*verilator public_module*/ `define INLINE_MID_MODULE /*verilator public_module*/ `endif `endif module global_mod; `INLINE_MODULE parameter INITVAL = 0; integer globali; initial globali = INITVAL; function [31:0] getName; input fake; getName = "gmod"; endfunction function [31:0] getGlob; input fake; getGlob = globali; endfunction endmodule module ma (); `INLINE_MODULE mb #(0) mb0 (); reg [31:0] gName; initial gName = "ma "; function [31:0] getName; input fake; getName = "ma "; endfunction task checkName; input [31:0] name; if (name !== "ma ") $stop; endtask initial begin if (ma.getName(1'b0) !== "ma ") $stop; if (mb0.getName(1'b0) !== "mb ") $stop; if (mb0.mc0.getName(1'b0) !== "mc ") $stop; end endmodule module mb (); `INLINE_MID_MODULE parameter P2 = 0; mc #(P2,0) mc0 (); mc #(P2,1) mc1 (); global_mod #(32'hf33d) global_cell2 (); reg [31:0] gName; initial gName = "mb "; function [31:0] getName; input fake; getName = "mb "; endfunction function [31:0] getP2 ; input fake; getP2 = P2; endfunction task checkName; input [31:0] name; if (name !== "mb ") $stop; endtask initial begin `ifndef verilator #1; `endif if (ma. getName(1'b0) !== "ma ") $stop; if ( getName(1'b0) !== "mb ") $stop; if (mc1.getName(1'b0) !== "mc ") $stop; ma. checkName (ma. gName); /**/checkName ( gName); mc1.checkName (mc1.gName); ma. checkName (ma. getName(1'b0)); /**/checkName ( getName(1'b0)); mc1.checkName (mc1.getName(1'b0)); end endmodule module mc (); `INLINE_MODULE parameter P2 = 0; parameter P3 = 0; reg [31:0] gName; initial gName = "mc "; function [31:0] getName; input fake; getName = "mc "; endfunction function [31:0] getP3 ; input fake; getP3 = P3; endfunction task checkName; input [31:0] name; if (name !== "mc ") $stop; endtask initial begin `ifndef verilator #1; `endif if (ma.getName(1'b0) !== "ma ") $stop; if (mb.getName(1'b0) !== "mb ") $stop; if (mc.getName(1'b0) !== "mc ") $stop; ma.checkName (ma.gName); mb.checkName (mb.gName); mc.checkName (mc.gName); ma.checkName (ma.getName(1'b0)); mb.checkName (mb.getName(1'b0)); mc.checkName (mc.getName(1'b0)); end endmodule verilator-3.874/test_regress/t/t_var_rsvd.v0000664000177100017500000000121112473477707021054 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. // verilator lint_off SYMRSVDWORD module t (/*AUTOARG*/ // Inputs bool ); input bool; // BAD reg vector; // OK, as not public reg switch /*verilator public*/; // Bad typedef struct packed { logic [31:0] vector; // OK, as not public } test; test t; // global is a 1800-2009 reserved word, but we allow it when possible. reg global; initial begin t.vector = 1; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_dpi_export_c.cpp0000664000177100017500000001123512473477707022231 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2009 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include "svdpi.h" #ifdef _WIN32 # define T_PRI64 "I64" #else // Linux or compliant Unix flavors # define T_PRI64 "ll" #endif //====================================================================== #if defined(VERILATOR) # include "Vt_dpi_export__Dpi.h" #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef NEED_EXTERNS extern "C" { extern int dpix_run_tests(); extern int dpix_t_int(int i, int* o); extern int dpix_t_renamed(int i, int* o); extern int dpix_int123(); extern unsigned char dpix_f_bit(unsigned char i); extern int dpix_f_int(int i); extern char dpix_f_byte(char i); extern short int dpix_f_shortint(short int i); extern long long dpix_f_longint(long long i); extern void* dpix_f_chandle(void* i); extern int dpix_sub_inst (int i); } #endif //====================================================================== #define CHECK_RESULT(type, got, exp) \ if ((got) != (exp)) { \ printf("%%Error: %s:%d:", __FILE__,__LINE__); \ union { type a; long long l; } u; \ u.l = 0; u.a = got; \ printf(" GOT = %" T_PRI64 "x", u.l); \ u.l = 0; u.a = exp; \ printf(" EXP = %" T_PRI64 "x\n", u.l); \ return __LINE__; \ } #define CHECK_RESULT_NNULL(got) \ if (!(got)) { \ printf("%%Error: %s:%d: GOT = %p EXP = !NULL\n", __FILE__,__LINE__, (got)); \ return __LINE__; \ } static int check_sub(const char* name, int i) { svScope scope = svGetScopeFromName(name); #ifdef TEST_VERBOSE printf("svGetScopeFromName(\"%s\") -> %p\n", name, scope); #endif CHECK_RESULT_NNULL (scope); svScope prev = svGetScope(); svScope sout = svSetScope(scope); CHECK_RESULT(svScope, sout, prev); CHECK_RESULT(svScope, svGetScope(), scope); int out = dpix_sub_inst(100*i); CHECK_RESULT(int, out, 100*i + i); return 0; // OK } // Called from our Verilog code to run the tests int dpix_run_tests() { printf("dpix_run_tests:\n"); #ifdef VERILATOR static int didDump = 0; if (didDump++ == 0) { # ifdef TEST_VERBOSE Verilated::internalsDump(); # endif } #endif #ifndef CADENCE // Unimplemented; how hard is it? printf ("svDpiVersion: %s\n",svDpiVersion()); CHECK_RESULT (bool, strcmp(svDpiVersion(), "1800-2005")==0 || strcmp(svDpiVersion(), "P1800-2005")==0 , 1); #endif CHECK_RESULT (int, dpix_int123(), 0x123 ); #ifndef CADENCE // No export calls from an import int o; dpix_t_int(0x456, &o); CHECK_RESULT (unsigned long, o, ~0x456UL); dpix_t_renamed(0x456, &o); CHECK_RESULT (int, o, 0x458UL); #endif svBitVecVal vec10[1] = {0x10}; CHECK_RESULT (int, dpix_f_bit(1), 0x0); CHECK_RESULT (int, dpix_f_bit(0), 0x1); CHECK_RESULT (int, dpix_f_bit15(vec10) & 0x7fUL, 0x6f); // Simulators disagree over the next three's sign extension unless we mask the upper bits CHECK_RESULT (int, dpix_f_int(1) & 0xffffffffUL, 0xfffffffeUL); CHECK_RESULT (int, dpix_f_byte(1) & 0xffUL, 0xfe); CHECK_RESULT (int, dpix_f_shortint(1) & 0xffffUL, 0xfffeUL); CHECK_RESULT (unsigned long long, dpix_f_longint(1), 0xfffffffffffffffeULL); CHECK_RESULT (void*, dpix_f_chandle((void*)(12345)), (void*)(12345)); { svBitVecVal i_vec95[3] = {0x72912312,0xab782a12,0x8a413bd9}; svBitVecVal o_vec95[3] = {0,0,0}; dpix_t_bit95(i_vec95, o_vec95); CHECK_RESULT(int, o_vec95[0], ~i_vec95[0]); CHECK_RESULT(int, o_vec95[1], ~i_vec95[1]); CHECK_RESULT(int, o_vec95[2], (~i_vec95[2])&0x7fffffffUL); } { svBitVecVal i_vec96[3] = {0xf2912312,0xab782a12,0x8a413bd9}; svBitVecVal o_vec96[3] = {0,0,0}; dpix_t_bit96(i_vec96, o_vec96); CHECK_RESULT(int, o_vec96[0], ~i_vec96[0]); CHECK_RESULT(int, o_vec96[1], ~i_vec96[1]); CHECK_RESULT(int, o_vec96[2], ~i_vec96[2]); } if (int bad=check_sub("top.t.a",1)) return bad; if (int bad=check_sub("top.t.b",2)) return bad; return -1; // OK status } verilator-3.874/test_regress/t/t_clk_dpulse.v0000664000177100017500000000205212473477707021357 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // verilator lint_off GENCLK reg [7:0] cyc; initial cyc=0; reg genclk; // verilator lint_off MULTIDRIVEN reg [7:0] set_both; // verilator lint_on MULTIDRIVEN wire genthiscyc = ( (cyc % 2) == 1 ); always @ (posedge clk) begin cyc <= cyc + 8'h1; genclk <= genthiscyc; set_both <= cyc; $write ("SB set_both %x <= cyc %x\n", set_both, cyc); if (genthiscyc) begin if (cyc>1 && set_both != (cyc - 8'h1)) $stop; end else begin if (cyc>1 && set_both != ~(cyc - 8'h1)) $stop; end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end always @ (posedge genclk) begin set_both <= ~ set_both; $write ("SB set_both %x <= cyc %x\n", set_both, ~cyc); if (cyc>1 && set_both != (cyc - 8'h1)) $stop; end endmodule verilator-3.874/test_regress/t/t_enum_func.v0000664000177100017500000000235212473477707021214 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. typedef enum { EN_ZERO, EN_ONE } En_t; module t (/*AUTOARG*/ // Inputs clk ); input clk; // Insure that we can declare a type with a function declaration function enum integer { EF_TRUE = 1, EF_FALSE = 0 } f_enum_inv ( input a); f_enum_inv = a ? EF_FALSE : EF_TRUE; endfunction initial begin if (f_enum_inv(1) != 0) $stop; if (f_enum_inv(0) != 1) $stop; end En_t a, z; sub sub (/*AUTOINST*/ // Outputs .z (z), // Inputs .a (a)); integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin a <= EN_ZERO; end if (cyc==2) begin a <= EN_ONE; if (z != EN_ONE) $stop; end if (cyc==3) begin if (z != EN_ZERO) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module sub (input En_t a, output En_t z); always @* z = (a==EN_ONE) ? EN_ZERO : EN_ONE; endmodule // Local Variables: // verilog-typedef-regexp: "_t$" // End: verilator-3.874/test_regress/t/t_flag_f__2.vc0000664000177100017500000000012512473477707021172 0ustar wsnyderwsnyder +define+GOT_DEF1 // -DNON_DEF /* +define+NON_DEF */ +define+GOT_DEF2=1 verilator-3.874/test_regress/t/t_unroll_genf.v0000664000177100017500000000075612473477707021555 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. //bug830 module sub(); endmodule function integer cdiv(input integer x); begin cdiv = 10; end endfunction module t (/*AUTOARG*/); genvar j; generate for (j = 0; j < cdiv(10); j=j+1) sub sub(); endgenerate initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_xml_first.pl0000775000177100017500000000121712473477707021414 0ustar wsnyderwsnyder#!/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, ); file_grep ($out_filename, qr//); ok(1); 1; verilator-3.874/test_regress/t/t_math_mul.v0000664000177100017500000000277312473477707021052 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; reg [63:0] sum; wire [31:0] out1; wire [31:0] out2; sub sub (.in1(crc[15:0]), .in2(crc[31:16]), .out1(out1), .out2); always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x sum=%x out=%x %x\n",$time, cyc, crc, sum, out1, out2); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= {sum[62:0], sum[63]^sum[2]^sum[0]} ^ {out2,out1}; if (cyc==1) begin // Setup crc <= 64'h00000000_00000097; sum <= 64'h0; end else if (cyc==90) begin if (sum !== 64'he396068aba3898a2) $stop; end else if (cyc==91) begin end else if (cyc==92) begin end else if (cyc==93) begin end else if (cyc==94) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub (/*AUTOARG*/ // Outputs out1, out2, // Inputs in1, in2 ); input [15:0] in1; input [15:0] in2; output reg signed [31:0] out1; output reg unsigned [31:0] out2; always @* begin // verilator lint_off WIDTH out1 = $signed(in1) * $signed(in2); out2 = $unsigned(in1) * $unsigned(in2); // verilator lint_on WIDTH end endmodule verilator-3.874/test_regress/t/t_initial_edge_bad.pl0000775000177100017500000000125412473477707022631 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_initial_edge.v"); # This works with other simulators, we we don't run it for them. It should # fail with Verilator if --x-initial-edge is not specified. $Self->{vlt} or $Self->skip("Verilator only test"); compile ( ); execute ( fails => 1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_width_bad.pl0000775000177100017500000000261612473477707022364 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{.*%Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator VAR 'XS' expects 4 bits on the Initial value, but Initial value's CONST '\?32\?bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' generates 32 bits. %Warning-WIDTH: Use .* %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator ASSIGNW expects 5 bits on the Assign RHS, but Assign RHS's VARREF 'in' generates 4 bits. %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator SHIFTL expects 5 bits on the LHS, but LHS's CONST '1'h1' generates 1 bits. %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator ASSIGNW expects 6 bits on the Assign RHS, but Assign RHS's SHIFTL generates 7 bits. %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator ADD expects 3 bits on the LHS, but LHS's VARREF 'one' generates 1 bits. %Warning-WIDTH: t/t_lint_width_bad.v:\d+: Operator ADD expects 3 bits on the RHS, but RHS's VARREF 'one' generates 1 bits. %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_eq.pl0000775000177100017500000000071712473477707021027 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_package.pl0000775000177100017500000000071712473477707021004 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_bitsel_const_bad.v0000664000177100017500000000073112473477707022532 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Test of select from constant // // This tests issue 508, bit select of constant fails // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; // Note that if we declare "wire [0:0] b", this works just fine. wire a; wire b; assign b = 1'b0; assign a = b[0]; // IEEE illegal can't extract scalar endmodule verilator-3.874/test_regress/t/t_pipe_filter.pl0000775000177100017500000000143212473477707021706 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010-2011 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->skip("Verilator only test") if !$Self->{vlt}; $Self->{golden_out} ||= "t/$Self->{name}.out"; my $stdout_filename = "$Self->{obj_dir}/$Self->{name}__test.vpp"; compile ( verilator_flags2 => ['-E --pipe-filter \'perl t/t_pipe_filter.pf\' '], verilator_make_gcc=>0, stdout_filename => $stdout_filename, ); ok(files_identical($stdout_filename, $Self->{golden_out})); 1; verilator-3.874/test_regress/t/t_mem_slot.v0000664000177100017500000000111612473477707021051 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. `define RegDel 1 module t_mem_slot (Clk, SlotIdx, BitToChange, BitVal, SlotToReturn, OutputVal); input Clk; input [1:0] SlotIdx; input BitToChange; input BitVal; input [1:0] SlotToReturn; output [1:0] OutputVal; reg [1:0] Array[2:0]; always @(posedge Clk) begin Array[SlotIdx][BitToChange] <= #`RegDel BitVal; OutputVal = Array[SlotToReturn]; end endmodule verilator-3.874/test_regress/t/t_math_imm2.v0000664000177100017500000000231512473477707021111 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. // // Example module to create problem. // // generate a 64 bit value with bits // [HighMaskSel_Bot : LowMaskSel_Bot ] = 1 // [HighMaskSel_Top+32: LowMaskSel_Top+32] = 1 // all other bits zero. module t_math_imm2 (/*AUTOARG*/ // Outputs LogicImm, LowLogicImm, HighLogicImm, // Inputs LowMaskSel_Top, HighMaskSel_Top, LowMaskSel_Bot, HighMaskSel_Bot ); input [4:0] LowMaskSel_Top, HighMaskSel_Top; input [4:0] LowMaskSel_Bot, HighMaskSel_Bot; output [63:0] LogicImm; output [63:0] LowLogicImm, HighLogicImm; /* verilator lint_off UNSIGNED */ /* verilator lint_off CMPCONST */ genvar i; generate for (i=0;i<64;i=i+1) begin : MaskVal if (i >= 32) begin assign LowLogicImm[i] = (LowMaskSel_Top <= i[4:0]); assign HighLogicImm[i] = (HighMaskSel_Top >= i[4:0]); end else begin assign LowLogicImm[i] = (LowMaskSel_Bot <= i[4:0]); assign HighLogicImm[i] = (HighMaskSel_Bot >= i[4:0]); end end endgenerate assign LogicImm = LowLogicImm & HighLogicImm; endmodule verilator-3.874/test_regress/t/t_unopt_combo_isolate.pl0000775000177100017500000000117112473477707023450 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_unopt_combo.v"); compile ( verilator_flags2 => ['+define+ISOLATE --stats'], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, isolate_assignments blocks\s+5/i); } execute ( ); ok(1); 1; verilator-3.874/test_regress/t/t_sv_cpu.pl0000775000177100017500000000266612473477707020715 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # 22-Mar-2012: Modifications for this test contributed by Jeremy Bennett, # Embecosm. compile ( # Taken from the original VCS command line. v_flags2 => ["t/t_sv_cpu_code/timescale.sv", "t/t_sv_cpu_code/program_h.sv", "t/t_sv_cpu_code/pads_h.sv", "t/t_sv_cpu_code/ports_h.sv", "t/t_sv_cpu_code/pinout_h.sv", "t/t_sv_cpu_code/genbus_if.sv", "t/t_sv_cpu_code/pads_if.sv", "t/t_sv_cpu_code/adrdec.sv", "t/t_sv_cpu_code/pad_gpio.sv", "t/t_sv_cpu_code/pad_vdd.sv", "t/t_sv_cpu_code/pad_gnd.sv", "t/t_sv_cpu_code/pads.sv", "t/t_sv_cpu_code/ports.sv", "t/t_sv_cpu_code/ac_dig.sv", "t/t_sv_cpu_code/ac_ana.sv", "t/t_sv_cpu_code/ac.sv", "t/t_sv_cpu_code/cpu.sv", "t/t_sv_cpu_code/chip.sv"], vcs_flags2 => ["-R -sverilog +memcbk -y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code"], verilator_flags2 => ["-y t/t_sv_cpu_code +libext+.sv+ +incdir+t/t_sv_cpu_code --top-module t"], iv_flags2 => ["-yt/t_sv_cpu_code -It/t_sv_cpu_code -Y.sv"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_display_real_noopt.pl0000775000177100017500000000262612473477707023301 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_display_real.v"); compile ( verilator_flags2 => ["-O0"], ); execute ( check_finished=>1, expect=> quotemeta( '[0] e=0.000000e+00 e1=0.000000e+00 e30=0e+00 e32=0.00e+00 [0] f=0.000000 f1=0.000000e+00 f30=0e+00 f32=0.00e+00 [0] g=0 g1=0.000000e+00 g30=0e+00 g32=0.00e+00 [0] e=1.000000e+00 e1=1.000000e+00 e30=1e+00 e32=1.00e+00 [0] f=1.000000 f1=1.000000e+00 f30=1e+00 f32=1.00e+00 [0] g=1 g1=1.000000e+00 g30=1e+00 g32=1.00e+00 [0] e=1.000000e-01 e1=1.000000e-01 e30=1e-01 e32=1.00e-01 [0] f=0.100000 f1=1.000000e-01 f30=1e-01 f32=1.00e-01 [0] g=0.1 g1=1.000000e-01 g30=1e-01 g32=1.00e-01 [0] e=1.234500e-15 e1=1.234500e-15 e30=1e-15 e32=1.23e-15 [0] f=0.000000 f1=1.234500e-15 f30=1e-15 f32=1.23e-15 [0] g=1.2345e-15 g1=1.234500e-15 g30=1e-15 g32=1.23e-15 [0] e=2.579000e+15 e1=2.579000e+15 e30=3e+15 e32=2.58e+15 [0] f=2579000000000000.000000 f1=2.579000e+15 f30=3e+15 f32=2.58e+15 [0] g=2.579e+15 g1=2.579000e+15 g30=3e+15 g32=2.58e+15 r8= 3 n1=1 n2=0.1 n1=1 n2=0.1 r8= 3 '), ); ok(1); 1; verilator-3.874/test_regress/t/t_package_export_bad.pl0000775000177100017500000000132212473477707023204 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_package_export.v"); compile ( v_flags2 => ['+define+T_PACKAGE_EXPORT_BAD',], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Error: t/t_package_export.v:\d+: Can\'t find definition of variable: PARAM2 %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_package_dimport.v0000664000177100017500000000303312473477707022363 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. package defs; function automatic integer max; input integer a; input integer b; max = (a > b) ? a : b; endfunction function automatic integer log2; input integer value; value = value >> 1; for (log2 = 0; value > 0; log2 = log2 + 1) value = value >> 1; endfunction function automatic integer ceil_log2; input integer value; value = value - 1; for (ceil_log2 = 0; value > 0; ceil_log2 = ceil_log2 + 1) value = value >> 1; endfunction endpackage module sub(); import defs::*; parameter RAND_NUM_MAX = ""; localparam DATA_RANGE = RAND_NUM_MAX + 1; localparam DATA_WIDTH = ceil_log2(DATA_RANGE); localparam WIDTH = max(4, ceil_log2(DATA_RANGE + 1)); endmodule module t(/*AUTOARG*/ // Inputs clk ); import defs::*; parameter WHICH = 0; parameter MAX_COUNT = 10; localparam MAX_EXPONENT = log2(MAX_COUNT); localparam EXPONENT_WIDTH = ceil_log2(MAX_EXPONENT + 1); input clk; generate if (WHICH == 1) begin : which_true sub sub_true(); defparam sub_true.RAND_NUM_MAX = MAX_EXPONENT; end else begin : which_false sub sub_false(); defparam sub_false.RAND_NUM_MAX = MAX_COUNT; end endgenerate endmodule verilator-3.874/test_regress/t/t_savable.pl0000775000177100017500000000132412473477707021021 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--savable"], save_time => 500, ); execute ( check_finished=>0, all_run_flags => ['+save_time=500'], ); -r "$Self->{obj_dir}/saved.vltsv" or $Self->error("Saved.vltsv not created\n"); execute ( all_run_flags => ['+save_restore=1'], check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_const.v0000664000177100017500000000105512473477707021232 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; const logic [2:0] five = 3'd5; const logic unsigned [31:0] var_const = 22; logic [7:0] res_const; assign res_const = var_const[7:0]; // bug693 always @ (posedge clk) begin if (five !== 3'd5) $stop; if (res_const !== 8'd22) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_func_public.v0000664000177100017500000001262612473477707021533 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (clk); input clk; tpub p1 (.clk(clk), .i(32'd1)); tpub p2 (.clk(clk), .i(32'd2)); integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin `ifdef verilator $c("publicTop();"); `endif end if (cyc==20) begin $write("*-* All Finished *-*\n"); $finish; end end end task publicTop; // verilator public // We have different optimizations if only one of something, so try it out. $write("Hello in publicTop\n"); endtask endmodule module tpub ( input clk, input [31:0] i); reg [23:0] var_long; reg [59:0] var_quad; reg [71:0] var_wide; reg var_bool; // verilator lint_off BLKANDNBLK reg [11:0] var_flop; // verilator lint_on BLKANDNBLK reg [23:0] got_long /*verilator public*/; reg [59:0] got_quad /*verilator public*/; reg [71:0] got_wide /*verilator public*/; reg got_bool /*verilator public*/; integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; // cyc==1 is in top level if (cyc==2) begin publicNoArgs; publicSetBool(1'b1); publicSetLong(24'habca); publicSetQuad(60'h4444_3333_2222); publicSetWide(72'h12_5678_9123_1245_2352); var_flop <= 12'habe; end if (cyc==3) begin if (1'b1 != publicGetSetBool(1'b0)) $stop; if (24'habca != publicGetSetLong(24'h1234)) $stop; if (60'h4444_3333_2222 != publicGetSetQuad(60'h123_4567_89ab)) $stop; if (72'h12_5678_9123_1245_2352 != publicGetSetWide(72'hac_abca_aaaa_bbbb_1234)) $stop; end if (cyc==4) begin publicGetBool(got_bool); if (1'b0 != got_bool) $stop; publicGetLong(got_long); if (24'h1234 != got_long) $stop; publicGetQuad(got_quad); if (60'h123_4567_89ab != got_quad) $stop; publicGetWide(got_wide); if (72'hac_abca_aaaa_bbbb_1234 != got_wide) $stop; end // `ifdef VERILATOR_PUBLIC_TASKS if (cyc==11) begin $c("publicNoArgs();"); $c("publicSetBool(true);"); $c("publicSetLong(0x11bca);"); $c("publicSetQuad(VL_ULL(0x66655554444));"); $c("publicSetFlop(0x321);"); //Unsupported: $c("WData w[3] = {0x12, 0x5678_9123, 0x1245_2352}; publicSetWide(w);"); end if (cyc==12) begin $c("got_bool = publicGetSetBool(true);"); $c("got_long = publicGetSetLong(0x11bca);"); $c("got_quad = publicGetSetQuad(VL_ULL(0xaaaabbbbcccc));"); end if (cyc==13) begin $c("{ bool gb; publicGetBool(gb); got_bool=gb; }"); if (1'b1 != got_bool) $stop; $c("publicGetLong(got_long);"); if (24'h11bca != got_long) $stop; $c("{ vluint64_t qq; publicGetQuad(qq); got_quad=qq; }"); if (60'haaaa_bbbb_cccc != got_quad) $stop; $c("{ WData gw[3]; publicGetWide(gw); VL_ASSIGN_W(72,got_wide,gw); }"); if (72'hac_abca_aaaa_bbbb_1234 != got_wide) $stop; //Below doesn't work, because we're calling it inside the loop that sets var_flop // if (12'h321 != var_flop) $stop; end if (cyc==14) begin if ($c32("publicInstNum()") != i) $stop; end `endif end end task publicEmpty; // verilator public begin end endtask task publicNoArgs; // verilator public $write("Hello in publicNoArgs\n"); endtask task publicSetBool; // verilator public input in_bool; var_bool = in_bool; endtask task publicSetLong; // verilator public input [23:0] in_long; reg [23:0] not_long; begin not_long = ~in_long; // Test that we can have local variables var_long = ~not_long; end endtask task publicSetQuad; // verilator public input [59:0] in_quad; var_quad = in_quad; endtask task publicSetFlop; // verilator public input [11:0] in_flop; var_flop = in_flop; endtask task publicSetWide; // verilator public input [71:0] in_wide; var_wide = in_wide; endtask task publicGetBool; // verilator public output out_bool; out_bool = var_bool; endtask task publicGetLong; // verilator public output [23:0] out_long; out_long = var_long; endtask task publicGetQuad; // verilator public output [59:0] out_quad; out_quad = var_quad; endtask task publicGetWide; // verilator public output [71:0] out_wide; out_wide = var_wide; endtask function publicGetSetBool; // verilator public input in_bool; begin publicGetSetBool = var_bool; var_bool = in_bool; end endfunction function [23:0] publicGetSetLong; // verilator public input [23:0] in_long; begin publicGetSetLong = var_long; var_long = in_long; end endfunction function [59:0] publicGetSetQuad; // verilator public input [59:0] in_quad; begin publicGetSetQuad = var_quad; var_quad = in_quad; end endfunction function [71:0] publicGetSetWide; // Can't be public, as no wide return types in C++ input [71:0] in_wide; begin publicGetSetWide = var_wide; var_wide = in_wide; end endfunction `ifdef VERILATOR_PUBLIC_TASKS function [31:0] publicInstNum; // verilator public publicInstNum = i; endfunction `endif endmodule verilator-3.874/test_regress/t/t_clk_powerdn.v0000664000177100017500000000611512473477707021545 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg reset_l; // verilator lint_off GENCLK /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) // End of automatics reg clkgate_e2r; reg clkgate_e1r_l; always @(posedge clk or negedge reset_l) begin if (!reset_l) begin clkgate_e1r_l <= ~1'b1; end else begin clkgate_e1r_l <= ~clkgate_e2r; end end reg clkgate_e1f; always @(negedge clk) begin // Yes, it's really a = clkgate_e1f = ~clkgate_e1r_l | ~reset_l; end wire clkgated = clk & clkgate_e1f; reg [31:0] countgated; always @(posedge clkgated or negedge reset_l) begin if (!reset_l) begin countgated <= 32'h1000; end else begin countgated <= countgated + 32'd1; end end reg [31:0] count; always @(posedge clk or negedge reset_l) begin if (!reset_l) begin count <= 32'h1000; end else begin count <= count + 32'd1; end end reg [7:0] cyc; initial cyc=0; always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] rs %x cyc %d cg1f %x cnt %x cg %x\n",$time,reset_l,cyc,clkgate_e1f,count,countgated); `endif cyc <= cyc + 8'd1; case (cyc) 8'd00: begin reset_l <= ~1'b0; clkgate_e2r <= 1'b1; end 8'd01: begin reset_l <= ~1'b0; end 8'd02: begin end 8'd03: begin reset_l <= ~1'b1; // Need a posedge end 8'd04: begin end 8'd05: begin reset_l <= ~1'b0; end 8'd09: begin clkgate_e2r <= 1'b0; end 8'd11: begin clkgate_e2r <= 1'b1; end 8'd20: begin $write("*-* All Finished *-*\n"); $finish; end default: ; endcase case (cyc) 8'd00: ; 8'd01: ; 8'd02: ; 8'd03: ; 8'd04: if (count!=32'h00001000 || countgated!=32'h 00001000) $stop; 8'd05: if (count!=32'h00001000 || countgated!=32'h 00001000) $stop; 8'd06: if (count!=32'h00001000 || countgated!=32'h 00001000) $stop; 8'd07: if (count!=32'h00001001 || countgated!=32'h 00001001) $stop; 8'd08: if (count!=32'h00001002 || countgated!=32'h 00001002) $stop; 8'd09: if (count!=32'h00001003 || countgated!=32'h 00001003) $stop; 8'd10: if (count!=32'h00001004 || countgated!=32'h 00001004) $stop; 8'd11: if (count!=32'h00001005 || countgated!=32'h 00001005) $stop; 8'd12: if (count!=32'h00001006 || countgated!=32'h 00001005) $stop; 8'd13: if (count!=32'h00001007 || countgated!=32'h 00001005) $stop; 8'd14: if (count!=32'h00001008 || countgated!=32'h 00001006) $stop; 8'd15: if (count!=32'h00001009 || countgated!=32'h 00001007) $stop; 8'd16: if (count!=32'h0000100a || countgated!=32'h 00001008) $stop; 8'd17: if (count!=32'h0000100b || countgated!=32'h 00001009) $stop; 8'd18: if (count!=32'h0000100c || countgated!=32'h 0000100a) $stop; 8'd19: if (count!=32'h0000100d || countgated!=32'h 0000100b) $stop; 8'd20: if (count!=32'h0000100e || countgated!=32'h 0000100c) $stop; default: $stop; endcase end endmodule verilator-3.874/test_regress/t/t_dpi_import_c.cpp0000664000177100017500000001325512473477707022226 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2009 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include "svdpi.h" //====================================================================== #if defined(VERILATOR) # include "Vt_dpi_import__Dpi.h" #elif defined(VCS) # include "../vc_hdrs.h" #elif defined(CADENCE) # define NEED_EXTERNS #else # error "Unknown simulator for DPI test" #endif #ifdef NEED_EXTERNS extern "C" { extern unsigned char dpii_f_bit (unsigned char i); extern svBitVecVal dpii_f_bit8 (const svBitVecVal* i); extern svBitVecVal dpii_f_bit9 (const svBitVecVal* i); extern svBitVecVal dpii_f_bit16 (const svBitVecVal* i); extern svBitVecVal dpii_f_bit17 (const svBitVecVal* i); extern svBitVecVal dpii_f_bit32 (const svBitVecVal* i); extern long long dpii_f_bit33 (const svBitVecVal* i); extern long long dpii_f_bit64 (const svBitVecVal* i); extern long long dpii_f_bit95 (const svBitVecVal* i, svBitVecVal* o); extern int dpii_f_int (int i); extern char dpii_f_byte (char i); extern short int dpii_f_shortint(short int i); extern long long dpii_f_longint (long long i); extern void* dpii_f_chandle (void* i); extern const char* dpii_f_string (const char* i); extern double dpii_f_real (double i); extern float dpii_f_shortreal(float i); extern void dpii_v_bit (unsigned char i, unsigned char* o); extern void dpii_v_int (int i, int *o); extern void dpii_v_uint (unsigned int i, unsigned int *o); extern void dpii_v_byte (char i, char *o); extern void dpii_v_shortint (short int i, short int *o); extern void dpii_v_ushort (unsigned short i, unsigned short *o); extern void dpii_v_longint (long long i, long long *o); extern void dpii_v_ulong (unsigned long long i, unsigned long long *o); extern void dpii_v_chandle (void* i, void* *o); extern void dpii_v_string (const char* i, const char** o); extern void dpii_v_real (double i, double* o); extern void dpii_v_shortreal(float i, float* o); extern void dpii_f_void (); extern int dpii_t_void (); extern int dpii_t_void_context (); extern int dpii_t_int (int i, int *o); extern int dpii_f_strlen (const char* i); extern int dpii_fa_bit(int i); } #endif //====================================================================== unsigned char dpii_f_bit (unsigned char i) { return SV_MASK(1) & ~i; } svBitVecVal dpii_f_bit8 (const svBitVecVal *i) { return SV_MASK(8) & ~*i; } svBitVecVal dpii_f_bit9 (const svBitVecVal *i) { return SV_MASK(9) & ~*i; } svBitVecVal dpii_f_bit16(const svBitVecVal *i) { return SV_MASK(16) & ~*i; } svBitVecVal dpii_f_bit17(const svBitVecVal *i) { return SV_MASK(17) & ~*i; } svBitVecVal dpii_f_bit32(const svBitVecVal *i) { return ~*i; } long long dpii_f_bit33(const svBitVecVal *i) { return ((1ULL<<33)-1) & ~((long long)(i[1])<<32ULL | i[0]); } long long dpii_f_bit64(const svBitVecVal *i) { return ~((long long)(i[1])<<32ULL | i[0]); } int dpii_f_int (int i) { return ~i; } char dpii_f_byte (char i) { return ~i; } short int dpii_f_shortint(short int i) { return ~i; } long long dpii_f_longint (long long i) { return ~i; } void* dpii_f_chandle (void* i) { return i; } const char* dpii_f_string (const char* i) { return i; } double dpii_f_real (double i) { return i+1.5; } float dpii_f_shortreal(float i) { return i+1.5; } void dpii_v_bit (unsigned char i, unsigned char *o) { *o = SV_MASK(1) & ~i; } void dpii_v_int (int i, int *o) { *o = ~i; } void dpii_v_uint (unsigned int i, unsigned int *o) { *o = ~i; } void dpii_v_byte (char i, char *o) { *o = ~i; } void dpii_v_shortint (short int i, short int *o) { *o = ~i; } void dpii_v_ushort (unsigned short i, unsigned short *o) { *o = ~i; } void dpii_v_longint (long long i, long long *o) { *o = ~i; } void dpii_v_ulong (unsigned long long i, unsigned long long *o) { *o = ~i; } void dpii_v_chandle (void* i, void* *o) { *o = i; } void dpii_v_string (const char* i, const char** o) { *o = i; } void dpii_v_real (double i, double* o) { *o = i + 1.5; } void dpii_v_shortreal(float i, float* o) { *o = i + 1.5; } void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o) { o[0] = ~i[0]; o[1] = ~i[1]; } void dpii_v_bit95(const svBitVecVal* i, svBitVecVal* o) { o[0] = ~i[0]; o[1] = ~i[1]; o[2] = SV_MASK(95-64) & ~i[2]; } void dpii_v_bit96(const svBitVecVal* i, svBitVecVal* o) { o[0] = ~i[0]; o[1] = ~i[1]; o[2] = ~i[2]; } int dpii_f_strlen (const char* i) { return strlen(i); } //====================================================================== void dpii_f_void () {} #ifdef VCS void dpii_t_void () {} void dpii_t_void_context () {} void dpii_t_int (int i, int *o) { *o = i; } #else int dpii_t_void () { return svIsDisabledState(); } int dpii_t_void_context () { return svIsDisabledState(); } int dpii_t_int (int i, int *o) { *o = i; return svIsDisabledState(); // Tasks generally need this } #endif int dpii_fa_bit (int i) { return ~i; } verilator-3.874/test_regress/t/t_select_bound1.v0000664000177100017500000000420112473477707021757 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. // bug823 module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [2:0] in = crc[2:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [3:0] mask; // From test of Test.v wire [3:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[3:0]), .mask (mask[3:0]), // Inputs .clk (clk), .in (in[2:0])); // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, out & mask}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x out=%b mask=%b\n",$time, cyc, crc, out, mask); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= '0; end else if (cyc<10) begin sum <= '0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'ha9d3a7a69d2bea75 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, mask, // Inputs clk, in ); input clk; input [2:0] in; output reg [3:0] out; output reg [3:0] mask; localparam [15:5] p = 11'h1ac; always @(posedge clk) begin // verilator lint_off WIDTH out <= p[15 + in -: 5]; // verilator lint_on WIDTH mask[3] <= ((15 + in - 5) < 12); mask[2] <= ((15 + in - 5) < 13); mask[1] <= ((15 + in - 5) < 14); mask[0] <= ((15 + in - 5) < 15); end endmodule verilator-3.874/test_regress/t/t_concat_opt.v0000664000177100017500000000341312473477707021365 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Jie Xu. // // The test was added together with the concat optimization. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [31:0] in_a; reg [31:0] in_b; reg [31:0] in_c; reg [31:0] in_d; reg [31:0] in_e; reg [15:0] in_f; wire [31:0] in_g; assign in_g = in_a << 4; reg [31:0] out_x; reg [31:0] out_y; reg [31:0] out_z; reg [31:0] out_o; reg [31:0] out_p; reg [31:0] out_q; assign out_x = {in_a[31:16] & in_f, in_a[15:0] & in_f}; assign out_y = {in_a[31:18] & in_b[31:18], in_a[17:0] & in_b[17:0]}; assign out_z = {in_c[31:14] & in_d[31:14] & in_e[31:14], in_c[13:0] & in_d[13:0] & in_e[13:0]}; assign out_o = out_z | out_y; assign out_p = {in_a[31:16] & in_f | in_e[31:16], in_a[15:0] & in_f | in_e[15:0]}; assign out_q = {{in_a[31:25] ^ in_g[31:25], in_a[24:16] ^ in_g[24:16]}, {in_a[15:5] ^ in_g[15:5], in_a[4:0] ^ in_g[4:0]}}; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; in_a <= cyc; in_b <= cyc + 1; in_c <= cyc + 3; in_d <= cyc + 8; in_e <= cyc; in_f <= cyc[15:0]; if (out_x != (in_a & {2{in_f}})) $stop; if (out_y != (in_a&in_b)) $stop; if (out_z != (in_e&in_d&in_c)) $stop; if (out_o != (((in_a&in_b)|(in_c&in_e&in_d)))) $stop; if (out_p != (in_a & {2{in_f}} | in_e)) $stop; if (out_q != (in_a ^ in_g)) $stop; if (cyc==100) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_interface_param1.v0000664000177100017500000000165112473477707022437 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jie Xu. //bug692 module t (/*AUTOARG*/ // Inputs clk ); input wire clk; wire [31:0] result; test_if #(.id(3)) s(); sub_test U_SUB_TEST(s.a.b, result); // the line causing error endmodule : t // --------------------------------------------------------------------------- module sub_test ( input [31:0] b, output [31:0] c ); assign c = b; endmodule // --------------------------------------------------------------------------- interface test_if #(parameter id = 0) (); typedef struct packed { logic a; logic [31:0] b; } aType; aType a; typedef struct packed { logic c; logic [31:0] d; } bType; bType b; modport master (input a, output b); endinterface verilator-3.874/test_regress/t/t_math_signed_wire.v0000664000177100017500000000200212473477707022535 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. // bug511 module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [7:0] au; wire [7:0] as; Test1 test1 (.au); Test2 test2 (.as); // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] result=%x %x\n",$time, au, as); `endif if (au != 'h12) $stop; if (as != 'h02) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module Test1 (output [7:0] au); wire [7:0] b; wire signed [3:0] c; // verilator lint_off WIDTH assign c=-1; // 'hf assign b=3; // 'h3 assign au=b+c; // 'h12 // verilator lint_on WIDTH endmodule module Test2 (output [7:0] as); wire signed [7:0] b; wire signed [3:0] c; // verilator lint_off WIDTH assign c=-1; // 'hf assign b=3; // 'h3 assign as=b+c; // 'h12 // verilator lint_on WIDTH endmodule verilator-3.874/test_regress/t/t_gen_forif.v0000664000177100017500000000442312473477707021174 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; wire [3:0] Value = crc[3:0]; wire [3:0] Result; wire [3:0] Result2; Testit testit (/*AUTOINST*/ // Outputs .Result (Result[3:0]), .Result2 (Result2[3:0]), // Inputs .clk (clk), .Value (Value[3:0])); always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x %x %x %x\n",$time, cyc, crc, Result, Result2); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= {56'h0, Result, Result2} ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $write("[%0t] cyc==%0d crc=%x %x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== 64'h4af37965592f64f9) $stop; $finish; end end endmodule module Test (clk, Value, Result); input clk; input Value; output Result; reg Internal; assign Result = Internal ^ clk; always @(posedge clk) Internal <= #1 Value; endmodule module Test_wrap1 (clk, Value, Result); input clk; input Value; output Result; Test t (clk, Value, Result); endmodule module Test_wrap2 (clk, Value, Result); input clk; input Value; output Result; Test t (clk, Value, Result); endmodule module Testit (clk, Value, Result, Result2); input clk; input [3:0] Value; output [3:0] Result; output [3:0] Result2; genvar i; generate for (i = 0; i < 4; i = i + 1) begin : a if ((i == 0) || (i == 2)) begin : gblk Test_wrap1 test (clk, Value[i] , Result[i]); end else begin : gblk Test_wrap2 test (clk, Value[i], Result[i]); end end endgenerate assign Result2[0] = a[0].gblk.test.t.Internal; assign Result2[1] = a[1].gblk.test.t.Internal; assign Result2[2] = a[2].gblk.test.t.Internal; assign Result2[3] = a[3].gblk.test.t.Internal; endmodule verilator-3.874/test_regress/t/t_sv_cpu_code/0000775000177100017500000000000012534632371021321 5ustar wsnyderwsnyderverilator-3.874/test_regress/t/t_sv_cpu_code/program_h.sv0000664000177100017500000000201412473477707023662 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. `ifndef _PROGRAM_H_V_ `define _PROGRAM_H_V_ // ***************************************************************************** // Assembly Mnemonic Defines // ***************************************************************************** typedef enum reg [3:0] { R0,R1,R2,R3,R4,R5,R6,R7, R8,R9,R10,R11,R12,R13,R14,R15 } cpu_registers; `define NOP 16'h0000, `define JMP( k8 ) {4'h1, 4'h0, 8'h k8}, `define LDI( rd, k8 ) {4'h4, rd, 8'h k8}, `define STS( k8, rs ) {4'h8, rs, 8'h k8}, `define LDS( rd, k8 ) {4'h9, rd, 8'h k8}, `define EOP 16'h0000 // ***************************************************************************** // Include ROM // ***************************************************************************** `include "rom.sv" `endif // !`ifdef _PROGRAM_H_V_ verilator-3.874/test_regress/t/t_sv_cpu_code/timescale.sv0000664000177100017500000000041112473477707023651 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. // **** Set simulation time scale **** `timescale 1ns/1ps verilator-3.874/test_regress/t/t_sv_cpu_code/ports_h.sv0000664000177100017500000000172712473477707023374 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. `ifndef _PORTS_H_SV_ `define _PORTS_H_SV_ // ***************************************************************************** // // ***************************************************************************** // !!!! Incomplete! localparam int str_pinid [0:15] = '{ "DEF", "ERR", "ERR", "ERR", "ERR", "ERR", "ERR", "ERR", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7" }; // **** Port Identifiers **** typedef enum int { PORTID_A = 32'd0, // MUST BE ZERO! PORTID_B, PORTID_C, PORTID_D, PORTID_E, PORTID_F, PORTID_G, PORTID_H, // PORTID_I, -> DO NOT USE! PORTID_J, PORTID_K, PORTID_L, PORTID_M, PORTID_N, // PORTID_O, -> DO NOT USE! PORTID_P, PORTID_Q, PORTID_R } t_portid; `endif // !`ifdef _PORTS_H_SV_ // **** End of File **** verilator-3.874/test_regress/t/t_sv_cpu_code/pad_gnd.sv0000664000177100017500000000102112473477707023275 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. //***************************************************************************** // PAD_GND - Ground Supply Pad (Dummy!!!!) //***************************************************************************** module pad_gnd #( parameter ID = 0 ) ( inout wire pad ); assign pad = 1'b0; endmodule // pad_gnd verilator-3.874/test_regress/t/t_sv_cpu_code/adrdec.sv0000664000177100017500000000215312473477707023132 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. module adrdec #( parameter NSLAVES = 2 ) ( // *************************************************************************** // Module Interface (interfaces, outputs, and inputs) // *************************************************************************** // **** Interfaces **** genbus_if.adrdec dbus ); // *************************************************************************** // Address Decode // *************************************************************************** // const logic [15:0] adrmap[1:2] = '{} always_comb begin logic sel [1:NSLAVES]; sel[1] = (dbus.s_adr[1][7:4] == 4'h0); sel[2] = (dbus.s_adr[2][7:4] == 4'h1); // sel[3] = (dbus.s_adr[3][7:4] == 4'h2); dbus.s_sel = sel; // for ( i = 1; i <= dbus.aNumSlaves; i++ ) // begin // dbus.s_sel[i] = (dbus.s_adr[i] == adrmap[i]); // end end endmodule // adrdec verilator-3.874/test_regress/t/t_sv_cpu_code/ports.sv0000664000177100017500000001020712473477707023056 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. `ifdef VERILATOR //TODO `define PACKED packed `else `define packed `endif module ports #( parameter ID = 1 ) ( // *************************************************************************** // Module Interface (interfaces, outputs, and inputs) // *************************************************************************** genbus_if.slave dbus, pads_if.mp_dig padsif, // - System - input logic clk, input logic rst ); // *************************************************************************** // Regs and Wires // *************************************************************************** // **** Internal Data Bus **** logic [15:0] sdata; logic ws; logic [15:0] mdata; logic [15:0] adr; logic [1:0] we; logic [1:0] re; // **** Interal Registers **** struct `PACKED { logic [7:0][1:0] in; logic [7:0] dir; logic [7:0] out; struct `PACKED { logic [7:2] reserved; logic pullupen; logic slewlim; } cfg; } port [PORTID_A:PORTID_D]; // *************************************************************************** // "dbus" Connection // *************************************************************************** always_comb begin: dbus_Connect dbus.sConnect( .id(ID), .rst(rst), .sdata(sdata), .ws(ws), .mdata(mdata), .adr(adr), .we(we), .re(re) ); end // *************************************************************************** // Register Access // For PORTA...PORTD (Excluding I and O) // +0x00 DIR // +0x01 OUT // +0x02 IN // +0x03 CFG // *************************************************************************** always_comb begin padsif.Init(); end // **** Register Write **** always_ff @( posedge clk ) begin // - Local Variables - integer i, j; // **** Setup Port Registers **** for ( j = PORTID_A; j <= PORTID_D; j++ ) begin if ( padsif.IsPort( j ) ) begin if ( ((adr[3:2] == j[1:0]) && (adr[1] == 1'b0)) | rst ) begin if ( we[0] ) port[j].dir <= mdata[7:0]; if ( we[1] ) port[j].out <= mdata[15:8]; end end else begin port[j].dir <= 8'h00; port[j].out <= 8'h00; end end end // **** Regiser Read **** always_comb begin: RegisterRead // - Local Variables - integer i, j; logic [7:0] data [PORTID_D:PORTID_A][3:0]; // **** Output to "dbus" **** // - Setup read multiplexer - for ( j = PORTID_A; j <= PORTID_D; j++ ) begin if ( padsif.IsPort( j ) ) data[j] = '{ port[j].dir, port[j].out, 8'h00, 8'h00 }; else data[j] = '{ 8'h00, 8'h00, 8'h00, 8'h00 }; end // - Connect "genbusif" - sdata = { 8'h00, data[ adr[3:2] ][ adr[1:0] ] }; ws = 1'b0; end // *************************************************************************** // Output // *************************************************************************** always_comb begin // - Local Variables - integer i, j; // **** Defaults **** for ( i = 1; i <= $size( pinout ); i++ ) begin padsif.pullup_en [i] = 1'b0; padsif.pulldown_en [i] = 1'b0; padsif.output_en [i] = 1'b0; padsif.output_val [i] = 1'b0; padsif.slew_limit_en[i] = 1'b0; padsif.input_en [i] = 1'b0; end // **** Connect to Pads **** for ( i = 1; i <= $size( pinout ); i++ ) begin j = pinout[i].id; if ( PINID_D7 >= j ) begin padsif.output_en [i] = port[j[4:3]].dir[j[2:0]]; padsif.output_val[i] = port[j[4:3]].out[j[2:0]]; end end end endmodule // ports verilator-3.874/test_regress/t/t_sv_cpu_code/ac_dig.sv0000664000177100017500000000645312473477707023125 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. module ac_dig #( parameter ID = 1 ) ( // *************************************************************************** // Module Interface (interfaces, outputs, and inputs) // *************************************************************************** // **** Interfaces **** genbus_if.slave dbus, // **** Outputs **** output logic acenable, // **** Inputs **** input logic acout, // - System - input logic clk, input logic rst ); // *************************************************************************** // Regs and Wires // *************************************************************************** // **** Internal Data Bus **** logic [15:0] sdata; logic ws; logic [15:0] mdata; logic [15:0] adr; logic [1:0] we; logic [1:0] re; // **** User Registers **** struct packed { logic [7:1] reserved; logic enable; } control; struct packed { logic [7:1] reserved; logic acout; } status; // **** Internals **** logic [1:0] sync; // *************************************************************************** // Assignments // *************************************************************************** assign acenable = control.enable; // *************************************************************************** // "dbus" Connection // *************************************************************************** always_comb begin `ifdef VERILATOR //TODO dbus.sConnect( .id(ID), .rst(rst), .sdata(sdata), .ws(ws), .mdata(mdata), .adr(adr ), .we(we), .re(re) ); `else dbus.sConnect( .id(ID), .rst(rst), .sdata(sdata), .ws(ws), .mdata(mdata), .adr(adr[1:0]), .we(we), .re(re) ); `endif // dbus.sConnect( ID, rst, sdata, ws, mdata, adr, we, re ); end // *************************************************************************** // Register Access // *************************************************************************** // **** Register Write **** always_ff @( posedge clk ) begin if ( rst ) control <= 8'h00; else if ( (adr[1:0] == 2'b00) & we[0] ) control <= mdata[7:0]; end // **** Regiser Read **** always_comb begin: RegisterRead // - Local Variables - logic [7:0] data[0:3]; // Read access concatination. // - Setup read multiplexer - data = '{ control, status, 8'h00, 8'h00 }; // - Connect "genbusif" - sdata = { 8'h00, data[ adr[1:0] ] }; ws = 1'b0; end // *************************************************************************** // Status // *************************************************************************** // **** Synchronization **** always_ff @( posedge clk ) begin if ( rst ) sync <= 2'b00; else if ( control.enable ) sync <= {sync[0], acout}; end always_comb begin // - Defaults - status = {$size(status){1'b0}}; // - Set register values - status.acout = sync[1]; end endmodule // ac_dig verilator-3.874/test_regress/t/t_sv_cpu_code/rom.sv0000664000177100017500000000147212473477707022510 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. // ***************************************************************************** // Code ROM // // IMPORTANT! // Array size must be uppdated according to program size. // ***************************************************************************** const logic [15:0] rom[0:13] = '{ `LDI( R0, 11 ) `LDI( R1, 22 ) `LDI( R2, 33 ) `LDI( R3, 44 ) `STS( 0, R0 ) `STS( 1, R1 ) `STS( 2, R2 ) `STS( 3, R3 ) `LDS( R4, 0 ) `LDS( R5, 1 ) `LDS( R6, 0 ) `LDS( R7, 0 ) `JMP( 00 ) `EOP // End of Program (NOP) }; verilator-3.874/test_regress/t/t_sv_cpu_code/ac.sv0000664000177100017500000000350512473477707022275 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. module ac #( parameter ID = 1 ) ( // *************************************************************************** // Module Interface (interfaces, outputs, and inputs) // *************************************************************************** // **** Interfaces **** genbus_if.slave dbus, pads_if.mp_ana padsif, // - System - input logic clk, input logic rst ); // *************************************************************************** // Regs and Wires, Automatics // *************************************************************************** /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) logic acenable; // From i_ac_dig of ac_dig.v logic acout; // From i_ac_ana of ac_ana.v // End of automatics // *************************************************************************** // Digital Control // *************************************************************************** ac_dig #( .ID(ID) ) i_ac_dig ( .dbus (dbus), /*AUTOINST*/ // Outputs .acenable (acenable), // Inputs .acout (acout), .clk (clk), .rst (rst)); // *************************************************************************** // Analog Model // *************************************************************************** ac_ana i_ac_ana ( .padsif (padsif), /*AUTOINST*/ // Outputs .acout (acout), // Inputs .acenable (acenable), .clk (clk), .rst (rst)); endmodule // ac verilator-3.874/test_regress/t/t_sv_cpu_code/pinout_h.sv0000664000177100017500000000322612473477707023537 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. `ifndef _PINOUT_H_SV_ `define _PINOUT_H_SV_ // ***************************************************************************** // Structs/Unions // ***************************************************************************** // **** Pin Descriptor **** // - Pin Descriptor - typedef struct packed { t_pinid id; t_padtype padtype; int aux; } t_pin_descriptor; // ***************************************************************************** // Pinout // ***************************************************************************** // **** Preferred Solution !!!! **** localparam t_pin_descriptor pinout[ 1: 6] = '{ '{default:0, id:PINID_A0, padtype:PADTYPE_GPIO, aux:1}, '{default:0, id:PINID_A1, padtype:PADTYPE_GPIO}, '{default:0, id:PINID_A2, padtype:PADTYPE_GPIO}, '{default:0, id:PINID_D0, padtype:PADTYPE_GPIO}, '{default:0, id:PINID_VDD0, padtype:PADTYPE_VDD}, '{default:0, id:PINID_GND0, padtype:PADTYPE_GND} }; // **** Workaround !!!! **** typedef enum int { pinout_wa_id = 1, pinout_wa_padtype, pinout_wa_aux } t_pinout_wa; localparam int pinout_size = 6; localparam int pinout_wa[1:pinout_size][pinout_wa_id:pinout_wa_aux] = '{ '{PINID_A0, PADTYPE_GPIO, 0}, '{PINID_A1, PADTYPE_GPIO, 0}, '{PINID_A2, PADTYPE_GPIO, 0}, '{PINID_D0, PADTYPE_GPIO, 0}, '{PINID_VDD0, PADTYPE_VDD, 0}, '{PINID_GND0, PADTYPE_GND , 0} }; `endif // `ifndef _PINOUT_H_SV_ // **** End of File **** verilator-3.874/test_regress/t/t_sv_cpu_code/pads_h.sv0000664000177100017500000000535312473477707023153 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. `ifndef _PADS_H_SV_ `define _PADS_H_SV_ // ***************************************************************************** // // ***************************************************************************** // **** Pin Identifiers **** typedef enum int { PINID_A0 = 32'd0, // MUST BE ZERO! // - Standard Ports - PINID_A1, PINID_A2, PINID_A3, PINID_A4, PINID_A5, PINID_A6, PINID_A7, PINID_B0, PINID_B1, PINID_B2, PINID_B3, PINID_B4, PINID_B5, PINID_B6, PINID_B7, PINID_C0, PINID_C1, PINID_C2, PINID_C3, PINID_C4, PINID_C5, PINID_C6, PINID_C7, PINID_D0, PINID_D1, PINID_D2, PINID_D3, PINID_D4, PINID_D5, PINID_D6, PINID_D7, PINID_E0, PINID_E1, PINID_E2, PINID_E3, PINID_E4, PINID_E5, PINID_E6, PINID_E7, PINID_F0, PINID_F1, PINID_F2, PINID_F3, PINID_F4, PINID_F5, PINID_F6, PINID_F7, PINID_G0, PINID_G1, PINID_G2, PINID_G3, PINID_G4, PINID_G5, PINID_G6, PINID_G7, PINID_H0, PINID_H1, PINID_H2, PINID_H3, PINID_H4, PINID_H5, PINID_H6, PINID_H7, // PINID_I0, PINID_I1, PINID_I2, PINID_I3, PINID_I4, PINID_I5, PINID_I6, PINID_I7,-> DO NOT USE!!!! I == 1 PINID_J0, PINID_J1, PINID_J2, PINID_J3, PINID_J4, PINID_J5, PINID_J6, PINID_J7, PINID_K0, PINID_K1, PINID_K2, PINID_K3, PINID_K4, PINID_K5, PINID_K6, PINID_K7, PINID_L0, PINID_L1, PINID_L2, PINID_L3, PINID_L4, PINID_L5, PINID_L6, PINID_L7, PINID_M0, PINID_M1, PINID_M2, PINID_M3, PINID_M4, PINID_M5, PINID_M6, PINID_M7, PINID_N0, PINID_N1, PINID_N2, PINID_N3, PINID_N4, PINID_N5, PINID_N6, PINID_N7, // PINID_O0, PINID_O1, PINID_O2, PINID_O3, PINID_O4, PINID_O5, PINID_O6, PINID_O7,-> DO NOT USE!!!! O == 0 PINID_P0, PINID_P1, PINID_P2, PINID_P3, PINID_P4, PINID_P5, PINID_P6, PINID_P7, PINID_Q0, PINID_Q1, PINID_Q2, PINID_Q3, PINID_Q4, PINID_Q5, PINID_Q6, PINID_Q7, PINID_R0, PINID_R1, PINID_R2, PINID_R3, PINID_R4, PINID_R5, PINID_R6, PINID_R7, // - AUX Port (Custom) - PINID_X0, PINID_X1, PINID_X2, PINID_X3, PINID_X4, PINID_X5, PINID_X6, PINID_X7, // - PDI Port - PINID_D2W_DAT, PINID_D2W_CLK, // - Power Pins - PINID_VDD0, PINID_VDD1, PINID_VDD2, PINID_VDD3, PINID_GND0, PINID_GND1, PINID_GND2, PINID_GND3, // - Maximum number of pins - PINID_MAX } t_pinid; // **** Pad types **** typedef enum int { PADTYPE_DEFAULT = 32'd0, PADTYPE_GPIO, // General Purpose I/O Pad (GPIO). PADTYPE_GPIO_ANA, // GPIO with Analog connection. Low noise GPIO. PADTYPE_GPIO_HDS, // GPIO with High Drive Strength. PADTYPE_VDD, // VDD Supply Pad PADTYPE_GND // Ground Pad } t_padtype; `endif // !`ifdef _PADS_H_SV_ verilator-3.874/test_regress/t/t_sv_cpu_code/pad_gpio.sv0000664000177100017500000000211112473477707023464 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. //***************************************************************************** // PAD_GPIO - General Purpose I/O Pad (Dummy!!!!) //***************************************************************************** module pad_gpio #( parameter ID = 0 ) ( input logic pullup_en, input logic pulldown_en, input logic output_en, input logic output_val, input logic slew_limit_en, input logic input_en, output logic input_val, inout wire ana, inout wire pad ); // **** Analog <-> pad connection **** `ifndef VERILATOR //TODO alias alias ana = pad; `endif // **** Digital driver <-> pad connection **** assign pad = (output_en) ? output_val : 1'bz; // **** Digital pull-up/pull-down <-> pad connection **** // TO BE ADDED!!!! // **** Digital input <-> pad connection **** assign input_val = (input_en) ? pad : 1'b0; endmodule // pad_gpio verilator-3.874/test_regress/t/t_sv_cpu_code/cpu.sv0000664000177100017500000001331012473477707022474 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. module cpu #( parameter // ... ID = 1 ) // Not used! ( // *************************************************************************** // Module Interface (interfaces, outputs, and inputs) // *************************************************************************** // **** Interfaces **** genbus_if.master dbus, // **** Outputs **** // N/A // **** Inputs **** input logic clk, input logic rst ); // *************************************************************************** // Regs and Wires // *************************************************************************** // **** Program Memory **** logic [15:0] rom_out; // **** Register File (RF) **** logic [7:0] rf[0:15]; // **** Fetch Stage **** logic [7:0] pc; // PC -> Program counter. logic [15:0] ir; // IR -> Instruction Register. // **** Decode **** logic [3:0] idec_rd; logic idec_rd_we; logic [7:0] idec_rd_data; logic [3:0] idec_rs; logic [7:0] idec_nextpc; // New PC if change of program flow. logic idec_coff; // Indicates a change of program flow. logic [7:0] idec_mem_adr; logic idec_mem_re; logic idec_mem_we; // **** Memory **** logic [7:0] mem_data; // Data from peripheral. logic mem_ws; // Waitstate. // *************************************************************************** // Program Memory (ROM) Interface // *************************************************************************** always_comb begin: ROM // - Local Variables - integer i; reg [15:0] irom [0:255]; // - Set default - for ( i = 0; i < 256; i++ ) begin if ( i < $size(rom) ) irom[i] = rom[i]; else irom[i] = 16'h0000; end rom_out = irom[pc[7:0]]; end // *************************************************************************** // Register File (RF) // *************************************************************************** always_ff @( posedge clk ) begin: RegFile // - Local Variables - integer i; // - Register File - for ( i = 0; i < 16; i++ ) begin if ( rst ) rf[i][7:0] <= 8'h00; else if ( idec_rd_we & (idec_rd == i[3:0]) ) rf[i] <= idec_rd_data; end end // *************************************************************************** // Fetch Stage // *************************************************************************** // **** Program Counter (PC) / Instruction Register (IR) **** always_ff @( posedge clk ) begin if ( rst ) begin pc <= 8'h00; ir <= 16'h0000; end else //if ( ~mem_ws ) begin if ( ~idec_coff ) begin pc <= pc + 1; ir <= rom_out; // Fetch Instruction. end else begin pc <= idec_nextpc; ir <= 16'h0000; // Insert no operation (NOP). end end end // *************************************************************************** // Decode/Execute Stage // *************************************************************************** always_comb begin // - Defaults - idec_rd = 4'h0; idec_rd_we = 1'b0; idec_rd_data = 8'h00; idec_rs = 4'h0; idec_nextpc = 8'h00; idec_coff = 1'b0; idec_mem_adr = 8'h00; idec_mem_re = 1'b0; idec_mem_we = 1'b0; casez ( ir ) 16'h0000:; // NOP (<=> Default) 16'h1???: // JMP imm begin idec_nextpc = ir[7:0]; idec_coff = 1'b1; end 16'h4???: // LDI rd, imm begin idec_rd = ir[8+:4]; idec_rd_we = 1'b1; idec_rd_data = ir[0+:8]; end 16'h8???: begin // STS imm, rs idec_mem_adr = ir[0+:8]; idec_mem_we = 1'b1; idec_rs = ir[8+:4]; end 16'h9???: begin // LDS rd, imm idec_mem_adr = ir[0+:8]; idec_mem_we = 1'b1; idec_rd = ir[8+:4]; idec_rd_we = 1'b1; idec_rd_data = mem_data[0+:8]; end endcase end // *************************************************************************** // Memory Access ("Stage") // *************************************************************************** // **** Connect to "dbus" **** always_comb begin: Conntect reg [15:0] sdata16; dbus.mConnect ( ID, // ID sdata16, // sdata mem_ws, // ws {2{rf[idec_rs]}}, // mdata // adr {8'h00, idec_mem_adr[7:1], 1'b0}, // we {idec_mem_adr[0],~idec_mem_adr[0]} & {2{idec_mem_we}}, // re {idec_mem_adr[0],~idec_mem_adr[0]} & {2{idec_mem_re}} ); // - Connect 16-bit databus to 8-bit CPU - mem_data = ( idec_mem_adr[0] ) ? sdata16[15:8] : sdata16[7:0]; end mPreAdrDecode_resp busproperty; always_comb begin: PreAdrDecode // verilator lint_off WIDTH busproperty = dbus.mPreAdrDecode( 0, idec_mem_adr ); // verilator lint_on WIDTH end endmodule // cpu verilator-3.874/test_regress/t/t_sv_cpu_code/chip.sv0000664000177100017500000000654212473477707022641 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. // ***************************************************************************** // Top level of System Verilog evalution (Full chip level) // ***************************************************************************** module chip #( parameter NUMPADS = $size( pinout ) ) ( // **** Pinout **** `ifdef VERILATOR // see t_tri_array inout wire [NUMPADS:1] pad, `else inout wire pad [1:NUMPADS], `endif // **** Inputs !!!! **** input logic clk, input logic rst ); // *************************************************************************** // Local Parameters // *************************************************************************** localparam NSLAVES = 2; // *************************************************************************** // PADS // *************************************************************************** // **** Interface **** pads_if padsif(); // **** Pad Instansiations **** pads // #( ) i_pads ( /*AUTOINST*/ // Interfaces .padsif (padsif.mp_pads), // Inouts .pad (pad), // Inputs .clk (clk), .rst (rst)); // *************************************************************************** // "dbus" Interface // *************************************************************************** genbus_if #( .NSLAVES(NSLAVES) ) dbus( .clk(clk), .rst(rst), .test_mode(1'b0) ); adrdec // #( ) i_adrdec ( /*AUTOINST*/ // Interfaces .dbus (dbus.adrdec)); // *************************************************************************** // CPU ("dbus" Master) // *************************************************************************** cpu #( .ID(1) ) i_cpu ( /*AUTOINST*/ // Interfaces .dbus (dbus.master), // Inputs .clk (clk), .rst (rst)); // *************************************************************************** // PORTS ("dbus" Slave #1) // *************************************************************************** ports #( .ID(1) ) i_ports ( /*AUTOINST*/ // Interfaces .dbus (dbus.slave), .padsif (padsif.mp_dig), // Inputs .clk (clk), .rst (rst)); // *************************************************************************** // Analog Comparator ("dbus" Slave #2) // *************************************************************************** ac #( .ID(2) ) i_ac ( /*AUTOINST*/ // Interfaces .dbus (dbus.slave), .padsif (padsif.mp_ana), // Inputs .clk (clk), .rst (rst)); endmodule // chip verilator-3.874/test_regress/t/t_sv_cpu_code/pad_vdd.sv0000664000177100017500000000101612473477707023306 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. //***************************************************************************** // PAD_VDD - VDD Supply Pad (Dummy!!!!) //***************************************************************************** module pad_vdd #( parameter ID = 0 ) ( inout wire pad ); assign pad = 1'b1; endmodule // pad_vdd verilator-3.874/test_regress/t/t_sv_cpu_code/pads_if.sv0000664000177100017500000000570312473477707023321 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. interface pads_if(); // *************************************************************************** // Local Parameters // *************************************************************************** localparam NUMPADS = $size( pinout ); // *************************************************************************** // Interface Variables // *************************************************************************** // - PADS Digital Interface - logic pullup_en [1:NUMPADS];// Pull-up/down/bus-keeper enable. logic pulldown_en [1:NUMPADS];// Pull direction (0:Pull-up; 1:Pull-down). logic output_en [1:NUMPADS];// Digital output buffer enable. logic output_val [1:NUMPADS];// Digital output value. logic input_en [1:NUMPADS];// Digital input buffer enable. logic slew_limit_en [1:NUMPADS];// Slew rate limiter enable. logic input_val [1:NUMPADS];// Digital input value. // - PADS Analog Interface - logic ana_override [1:NUMPADS];// Disables digital output when driving analog output. wire ana [1:NUMPADS]; // *************************************************************************** // Modports // *************************************************************************** modport mp_pads( input pullup_en, input pulldown_en, input output_en, input output_val, input slew_limit_en, input input_en, output input_val, input ana_override, inout ana ); modport mp_dig( import IsPad, import IsPort, import Init, output pullup_en, output pulldown_en, output output_en, output output_val, output slew_limit_en, output input_en, input input_val ); modport mp_ana( import IsPad, output ana_override, inout ana ); // *************************************************************************** // Check for which pins exists // *************************************************************************** bit [PINID_D7:PINID_A0] exists; function automatic void Init( ); exists = {(PINID_D7+1){1'b0}}; for ( int i = 1; i <= $size( pinout ); i++ ) if ( PINID_D7 >= pinout[i].id ) exists[pinout[i].id] = 1'b1; endfunction // *************************************************************************** // Functions and Tasks // *************************************************************************** function automatic bit IsPad( integer i ); IsPad = exists[i]; endfunction function automatic bit IsPort( integer i ); IsPort = |exists[8*i+:8]; endfunction endinterface // pads_if verilator-3.874/test_regress/t/t_sv_cpu_code/ac_ana.sv0000664000177100017500000000202612473477707023111 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. module ac_ana // #( parameter // ID = 1 ) ( // *************************************************************************** // Module Interface (interfaces, outputs, and inputs) // *************************************************************************** // **** Interfaces **** pads_if.mp_ana padsif, // **** Outputs **** output logic acout, // **** Inputs **** input logic acenable, // - System - input logic clk, input logic rst ); // *************************************************************************** // Analog Model // *************************************************************************** assign acout = (padsif.ana[1] - padsif.ana[2]) & acenable; assign padsif.ana_override[1] = 1'b0; assign padsif.ana_override[2] = 1'b0; endmodule // ac_ana verilator-3.874/test_regress/t/t_sv_cpu_code/pads.sv0000664000177100017500000000523312473477707022641 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. module pads #( parameter NUMPADS = $size( pinout ) ) ( // *************************************************************************** // Module Interface // *************************************************************************** // **** Interfaces **** pads_if.mp_pads padsif, // **** Pinout **** `ifdef VERILATOR // see t_tri_array inout wire [NUMPADS:1] pad, `else inout wire pad [1:NUMPADS], `endif // **** Inputs **** input logic clk, input logic rst ); // *************************************************************************** // Code Section // *************************************************************************** `ifdef VERILATOR // see t_tri_array tri [NUMPADS:1] _anahack; `endif genvar i; for ( i = 1; i <= NUMPADS; i++ ) begin `ifdef VCS localparam t_padtype p_type = t_padtype'(pinout_wa[i][pinout_wa_padtype]); localparam t_pinid p_id = t_pinid'(pinout_wa[i][pinout_wa_id]); `else localparam t_padtype p_type = pinout[i].padtype; localparam t_pinid p_id = pinout[i].id; `endif case ( p_type ) PADTYPE_GPIO: pad_gpio #( .ID( i ) ) i_pad_gpio( .pad (pad [i]), // Outputs .input_val (padsif.input_val [i]), // Inouts `ifdef VERILATOR // see t_tri_array .ana (_anahack [i]), `else .ana (padsif.ana [i]), `endif // Inputs .pullup_en (padsif.pullup_en [i]), .pulldown_en (padsif.pulldown_en [i]), .output_en (padsif.output_en [i]), .output_val (padsif.output_val [i]), .slew_limit_en (padsif.slew_limit_en[i]), .input_en (padsif.input_en [i]) /*AUTOINST*/); PADTYPE_VDD: begin pad_vdd #( .ID( i ) ) i_pad_vdd( .pad (pad[i]) /*AUTOINST*/); // Not SV standard, yet... assign padsif.input_val[i] = (); end PADTYPE_GND: begin pad_gnd #( .ID( i ) ) i_pad_gnd(.pad (pad[i]) /*AUTOINST*/); end endcase end endmodule // pads verilator-3.874/test_regress/t/t_sv_cpu_code/genbus_if.sv0000664000177100017500000001505012473477707023651 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Large test for SystemVerilog // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012. // Contributed by M W Lund, Atmel Corporation. typedef struct packed { bit [1:0] size; } mPreAdrDecode_resp; interface genbus_if #( parameter DSIZE = 2, SSIZE = DSIZE, ASIZE = 16, NMASTERS = 1, NSLAVES = 1, DMSB = (DSIZE<<3) - 1, SMSB = SSIZE - 1, AMSB = ASIZE - 1 ) ( // **** Inputs **** // - System - input logic clk, // Device Clock. input logic rst, // Device Reset. input logic test_mode // Test mode. ); // *************************************************************************** // Interface Variables // *************************************************************************** // **** Master **** logic [DMSB:0] m_sdata[1:NMASTERS]; // Slave data. logic m_ws [1:NMASTERS]; // Slave wait state. logic [DMSB:0] m_mdata[1:NMASTERS]; // Master data. logic [AMSB:0] m_adr [1:NMASTERS]; // Address. logic [SMSB:0] m_we [1:NMASTERS]; // Write enable. logic [SMSB:0] m_re [1:NMASTERS]; // Read enable. // **** Slave **** logic [DMSB:0] s_sdata[1:NSLAVES]; // Slave data (from slave). logic s_ws [1:NSLAVES]; // Slave wait state (from slave). logic [DMSB:0] s_mdata[1:NSLAVES]; // Master data (to slave). logic [AMSB:0] s_adr [1:NSLAVES]; // Address (to slave). logic [SMSB:0] s_we [1:NSLAVES]; // Write enable (to slave). logic [SMSB:0] s_re [1:NSLAVES]; // Read enable (to slave). // **** Address Decoder **** logic s_sel [1:NSLAVES]; // Slave select (to slave). // *************************************************************************** // Modports // *************************************************************************** modport master( import mConnect, import mPreAdrDecode, input m_sdata, input m_ws, output m_mdata, output m_adr, output m_we, output m_re ); // - Slaves - modport slave( import sConnect, output s_sdata, output s_ws, input s_mdata, input s_adr, input s_we, input s_re, input s_sel ); // UNSUPPORTED // for (genvar i = 1; i <= NSLAVES; i++ ) // begin: mps // modport slave( // import sConnect, // output .s_sdata( s_sdata[i] ), // output .s_ws ( s_ws [i] ), // input .s_mdata( s_mdata[i] ), // input .s_adr ( s_adr [i] ), // input .s_we ( s_we [i] ), // input .s_re ( s_re [i] ), // input .s_sel ( s_sel [i] ) // ); // end // blocks modport adrdec( import aNumSlaves, input s_adr, output s_sel ); // *************************************************************************** // Bus Multiplexers // *************************************************************************** always_comb begin: busmux // - Local Variables - integer i; // - Defautls - m_sdata[1] = {(DSIZE<<3){1'b0}}; m_ws [1] = 1'b0; for ( i = 1; i <= NSLAVES; i++ ) begin m_sdata[1] |= s_sdata[i]; m_ws [1] |= s_ws [i]; s_mdata[i] = m_mdata[1]; s_adr [i] = m_adr [1]; s_we [i] = m_we [1]; s_re [i] = m_re [1]; end end // *************************************************************************** // Master Functions and Tasks // *************************************************************************** function automatic void mConnect( input integer id, output logic [DMSB:0] sdata, output logic ws, input logic [DMSB:0] mdata, input logic [AMSB:0] adr, input logic [SMSB:0] we, input logic [SMSB:0] re ); begin m_mdata[id] = mdata; m_adr [id] = adr; m_we [id] = we; m_re [id] = re; sdata = m_sdata[id]; ws = m_ws [id]; end endfunction function automatic mPreAdrDecode_resp mPreAdrDecode( input integer id, input logic [AMSB:0] adr ); begin // ToDo: Add parameterized address decoding!!!! // Example code: if ( adr[0] ) mPreAdrDecode.size = 2'b01; // Word (16-bit) memory. else mPreAdrDecode.size = 2'b10; // Double Word (32-bit) memory. end endfunction // *************************************************************************** // Slave Functions and Tasks // *************************************************************************** function automatic void sConnect( input integer id, input logic rst, input logic [DMSB:0] sdata, input logic ws, output logic [DMSB:0] mdata, output logic [AMSB:0] adr, output logic [SMSB:0] we, output logic [SMSB:0] re ); begin s_sdata[id] = sdata & {(DSIZE<<3){s_sel[id]}}; // verilator lint_off WIDTH s_ws [id] = ws & {SSIZE{s_sel[id]}}; // verilator lint_on WIDTH mdata = s_mdata[id] & {16{~rst}}; adr = s_adr [id]; we = (s_we [id] & {SSIZE{s_sel[id]}}) | {SSIZE{rst}}; re = s_re [id] & {SSIZE{s_sel[id]}}; end endfunction // *************************************************************************** // Address Decoder Functions and Tasks // *************************************************************************** function automatic integer aNumSlaves; aNumSlaves = NSLAVES; endfunction endinterface // genbus_if verilator-3.874/test_regress/t/t_order_2d.pl0000775000177100017500000000072212525171734021072 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_modport.pl0000775000177100017500000000072712473477707023116 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_init_concat.v0000664000177100017500000000341712473477707021532 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [31:0] wr_data; reg wr_en; wire [31:0] rd_data; wire [1:0] rd_guards; wire [1:0] rd_guardsok; regfile regfile (/*AUTOINST*/ // Outputs .rd_data (rd_data[31:0]), .rd_guards (rd_guards[1:0]), .rd_guardsok (rd_guardsok[1:0]), // Inputs .wr_data (wr_data[31:0]), .wr_en (wr_en), .clk (clk)); initial wr_en = 0; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin if (!rd_guards[0]) $stop; if (!rd_guardsok[0]) $stop; wr_en <= 1'b1; wr_data <= 32'hfeedf; end if (cyc==2) begin wr_en <= 0; end if (cyc==3) begin wr_en <= 0; if (rd_data != 32'hfeedf) $stop; if (rd_guards != 2'b11) $stop; if (rd_guardsok != 2'b11) $stop; end if (cyc==4) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module regfile ( input [31:0] wr_data, input wr_en, output reg [31:0] rd_data, output [1:0] rd_guards /*verilator public*/, output [1:0] rd_guardsok /*verilator public*/, input clk ); always @(posedge clk) begin if (wr_en) begin rd_data <= wr_data; end end // this initial statement will induce correct initialize behavior // initial rd_guards= { 2'b11 }; assign rd_guards= { rd_data[0], 1'b1 }; assign rd_guardsok[0] = 1'b1; assign rd_guardsok[1] = rd_data[0]; endmodule // regfile verilator-3.874/test_regress/t/t_assert_basic.v0000664000177100017500000000232012473477707021672 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg toggle; integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; always @ (negedge clk) begin AssertionFalse1: assert (cyc<100); assert (!(cyc==5) || toggle); // FIX cover {cyc==3 || cyc==4}; // FIX cover {cyc==9} report "DefaultClock,expect=1"; // FIX cover {(cyc==5)->toggle} report "ToggleLogIf,expect=1"; end always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; toggle <= !cyc[0]; if (cyc==7) assert (cyc[0] == cyc[1]); // bug743 if (cyc==9) begin `ifdef FAILING_ASSERTIONS assert (0) else $info; assert (0) else $info("Info message"); assert (0) else $info("Info message, cyc=%d", cyc); InWarningBlock: assert (0) else $warning("Warning.... 1.0=%f 2.0=%f", 1.0, 2.0); InErrorBlock: assert (0) else $error("Error...."); assert (0) else $fatal(1,"Fatal...."); `endif end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_func_dotted_inl0.pl0000775000177100017500000000104112473477707022620 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_func_dotted.v"); compile ( v_flags2 => ['+define+NOUSE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_name_bad.pl0000775000177100017500000000115112473477707021764 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Error: t/t_dpi_name_bad.v:\d+: DPI function has illegal characters in C identifier name: badly.named %Error: Exiting due to .*' ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_gate_notif0.pl0000775000177100017500000000134312473477707022462 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_tri_gate.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ['+define+T_NOTIF0',], make_flags => 'CPPFLAGS_ADD=-DT_NOTIF0', verilator_flags2 => ["--exe $Self->{t_dir}/t_tri_gate.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_lib.v0000664000177100017500000000032612473477707020773 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/); liblib_a a (); endmodule verilator-3.874/test_regress/t/t_unoptflat_simple_2_bad.pl0000775000177100017500000000137312525171734024011 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_unoptflat_simple_2.v"); # Compile only compile ( verilator_flags3 => [], verilator_flags2 => ["--report-unoptflat"], fails => 1, expect=> '.*%Warning-UNOPTFLAT: Widest candidate vars to split: %Warning-UNOPTFLAT: t/t_unoptflat_simple_2.v:\d+: v.x, width 3, fanout \d+ .*%Error: Exiting due to ', ); ok(1); 1; verilator-3.874/test_regress/t/t_param_long.pl0000775000177100017500000000071712473477707021530 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_unoptflat_simple_2.v0000664000177100017500000000120712473477707023041 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Simple test of unoptflat // // Simple demonstration of an UNOPTFLAT combinatorial loop, using 3 bits. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [2:0] x; initial begin x = 3'b000; end assign x[1:0] = { x[0], clk }; assign x[2:1] = { clk, x[1] }; always @(posedge clk or negedge clk) begin `ifdef TEST_VERBOSE $write("x = %x\n", x); `endif if (x[1] != 0) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule // t verilator-3.874/test_regress/t/t_func_sum.v0000664000177100017500000000362212473477707021055 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008-2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; wire [9:0] I1 = crc[9:0]; wire [9:0] I2 = crc[19:10]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [9:0] S; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .S (S[9:0]), // Inputs .I1 (I1[9:0]), .I2 (I2[9:0])); wire [63:0] result = {32'h0, 22'h0, S}; `define EXPECTED_SUM 64'h24c38b77b0fcc2e7 // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs S, // Inputs I1, I2 ); input [9:0] I1/*verilator public*/; input [9:0] I2/*verilator public*/; output reg [9:0] S/*verilator public*/; always @(I1 or I2) t2(I1,I2,S); task t1; input In1,In2; output Sum; Sum = In1 ^ In2; endtask task t2; input[9:0] In1,In2; output [9:0] Sum; integer I; begin for (I=0;I<10;I=I+1) t1(In1[I],In2[I],Sum[I]); end endtask endmodule verilator-3.874/test_regress/t/t_func_bad_width.v0000664000177100017500000000065412473477707022200 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; reg [3:0] out; reg [38:0] in; initial begin in = 39'h0; out = MUX (in); $write("bad widths %x", out); end function [31:0] MUX; input [39:0] XX ; begin MUX = XX[39:8]; end endfunction endmodule verilator-3.874/test_regress/t/t_math_strwidth.v0000664000177100017500000000066212473477707022120 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008-2008 by Wilson Snyder. module t (/*AUTOARG*/); reg [4*8:1] strg; initial begin strg = "CHK"; if (strg != "CHK") $stop; if (strg == "JOE") $stop; $write("String = %s = %x\n", strg, strg); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_dist_install.pl0000775000177100017500000000275512473477707022106 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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. use Cwd; my $root = ".."; my $Debug; if (!-r "$root/.git") { $Self->skip("Not in a git repository"); } else { my $cwd = getcwd(); my $destdir = "$cwd/".$Self->{obj_dir}; # Start clean $Self->_run(cmd=>["rm -rf $destdir && mkdir -p $destdir"], check_finished=>0); # Install into temp area print "Install...\n"; $Self->_run (cmd=>["cd $root && make DESTDIR=$destdir install-all"], check_finished=>0); # Check we can run a test # Unfortunately the prefix was hardcoded in the exec at a different place, # so we can't do much here. #print "Check install...\n"; # Uninstall print "Uninstall...\n"; $Self->_run (cmd=>["cd $root && make DESTDIR=$destdir uninstall"], check_finished=>0); # Check empty my @files; $finds = `find $destdir -type f -print`; foreach my $file (split /\n/, $finds) { next if $file =~ /\.status/; # Made by driver.pl, not Verilator print "\tLEFT: $file\n"; $file =~ s!^$cwd!.!; push @files, $file; } if ($#files >= 0) { $Self->error("Uninstall missed files: ",join(' ',@files)); } } ok(1); 1; verilator-3.874/test_regress/t/t_interface_modport_import.pl0000775000177100017500000000072212473477707024503 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_nest.pl0000775000177100017500000000071712473477707021355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_vams.v0000664000177100017500000000077212473477707021043 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. //`begin_keywords "VAMS-2.3" `begin_keywords "1800+VAMS" module t (/*AUTOARG*/ // Outputs out, // Inputs in ); input in; wreal in; output out; wreal out; import "DPI-C" context function void dpii_call(input real in, output real out); initial begin dpii_call(in,out); $finish; end endmodule verilator-3.874/test_regress/t/t_trace_cat_renew_0100.out0000664000177100017500000000510212473477707023360 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Sat Feb 23 20:40:11 2013 $end $timescale 1ns $end $scope module top $end $var wire 1 $ clk $end $scope module v $end $var wire 1 $ clk $end $var wire 32 # cyc [31:0] $end $upscope $end $upscope $end $enddefinitions $end #100 b00000000000000000000000000110011 # 1$ #101 0$ #102 b00000000000000000000000000110100 # 1$ #103 0$ #104 b00000000000000000000000000110101 # 1$ #105 0$ #106 b00000000000000000000000000110110 # 1$ #107 0$ #108 b00000000000000000000000000110111 # 1$ #109 0$ #110 b00000000000000000000000000111000 # 1$ #111 0$ #112 b00000000000000000000000000111001 # 1$ #113 0$ #114 b00000000000000000000000000111010 # 1$ #115 0$ #116 b00000000000000000000000000111011 # 1$ #117 0$ #118 b00000000000000000000000000111100 # 1$ #119 0$ #120 b00000000000000000000000000111101 # 1$ #121 0$ #122 b00000000000000000000000000111110 # 1$ #123 0$ #124 b00000000000000000000000000111111 # 1$ #125 0$ #126 b00000000000000000000000001000000 # 1$ #127 0$ #128 b00000000000000000000000001000001 # 1$ #129 0$ #130 b00000000000000000000000001000010 # 1$ #131 0$ #132 b00000000000000000000000001000011 # 1$ #133 0$ #134 b00000000000000000000000001000100 # 1$ #135 0$ #136 b00000000000000000000000001000101 # 1$ #137 0$ #138 b00000000000000000000000001000110 # 1$ #139 0$ #140 b00000000000000000000000001000111 # 1$ #141 0$ #142 b00000000000000000000000001001000 # 1$ #143 0$ #144 b00000000000000000000000001001001 # 1$ #145 0$ #146 b00000000000000000000000001001010 # 1$ #147 0$ #148 b00000000000000000000000001001011 # 1$ #149 0$ #150 b00000000000000000000000001001100 # 1$ #151 0$ #152 b00000000000000000000000001001101 # 1$ #153 0$ #154 b00000000000000000000000001001110 # 1$ #155 0$ #156 b00000000000000000000000001001111 # 1$ #157 0$ #158 b00000000000000000000000001010000 # 1$ #159 0$ #160 b00000000000000000000000001010001 # 1$ #161 0$ #162 b00000000000000000000000001010010 # 1$ #163 0$ #164 b00000000000000000000000001010011 # 1$ #165 0$ #166 b00000000000000000000000001010100 # 1$ #167 0$ #168 b00000000000000000000000001010101 # 1$ #169 0$ #170 b00000000000000000000000001010110 # 1$ #171 0$ #172 b00000000000000000000000001010111 # 1$ #173 0$ #174 b00000000000000000000000001011000 # 1$ #175 0$ #176 b00000000000000000000000001011001 # 1$ #177 0$ #178 b00000000000000000000000001011010 # 1$ #179 0$ #180 b00000000000000000000000001011011 # 1$ #181 0$ #182 b00000000000000000000000001011100 # 1$ #183 0$ #184 b00000000000000000000000001011101 # 1$ #185 0$ #186 b00000000000000000000000001011110 # 1$ #187 0$ #188 b00000000000000000000000001011111 # 1$ #189 0$ verilator-3.874/test_regress/t/t_case_deep.pl0000775000177100017500000000104612473477707021315 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--compiler msvc"], # We have deep expressions we want to test ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_pow4.pl0000775000177100017500000000072212473477707021307 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_initial_dlyass_bad.pl0000775000177100017500000000115112473477707023220 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t_initial_dlyass.v"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> qr{%Warning-INITIALDLY: t/t_initial_dlyass.v:\d+: Delayed assignments .* %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_trig.pl0000775000177100017500000000071712473477707021367 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_table_fsm.pl0000775000177100017500000000071712473477707021345 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_inc.pl0000775000177100017500000000071712473477707021013 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_woff.v0000664000177100017500000000073012473477707021165 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t; // width warnings off due to command line wire A = 15'd1234; // width warnings off due to command line + manual switch // verilator lint_off WIDTH wire B = 15'd1234; // this turnon does nothing as off on command line // verilator lint_on WIDTH wire C = 15'd1234; endmodule verilator-3.874/test_regress/t/t_interface_twod.v0000664000177100017500000000154212473477707022232 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. interface ifc; integer value; modport i (output value); modport o (input value); endinterface module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc itop1a(), itop1b(); wrapper c1 (.isuba(itop1a), .isubb(itop1b), .i_valuea(14), .i_valueb(15)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==20) begin if (itop1a.value != 14) $stop; if (itop1b.value != 15) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module wrapper ( ifc.i isuba, isubb, input integer i_valuea, i_valueb ); always @* begin isuba.value = i_valuea; isubb.value = i_valueb; end endmodule verilator-3.874/test_regress/t/t_math_shiftrs.v0000664000177100017500000000226412473477707021732 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg signed [64+15:0] data; integer i; integer b; reg signed [64+15:0] srs; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==2) begin data <= 80'h0; data[75] <= 1'b1; data[10] <= 1'b1; end if (cyc==3) begin for (i=0; i<85; i=i+1) begin srs = data>>>i; //$write (" %x >>> %d == %x\n",data,i,srs); for (b=0; b<80; b=b+1) begin if (srs[b] != (b==(75-i) || b==(10-i))) $stop; end end end if (cyc==10) begin data <= 80'h0; data[79] <= 1'b1; data[10] <= 1'b1; end if (cyc==12) begin for (i=0; i<85; i=i+1) begin srs = data>>>i; //$write (" %x >>> %d == %x\n",data,i,srs); for (b=0; b<80; b=b+1) begin if (srs[b] != (b>=(79-i) || b==(10-i))) $stop; end end end if (cyc==20) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_vpi_get.pl0000775000177100017500000000134112473477707021040 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --no-l2name $Self->{t_dir}/t_vpi_get.cpp"], make_pli => 1, iv_flags2 => ["-g2005-sv -D USE_VPI_NOT_DPI"], v_flags2 => ["+define+USE_VPI_NOT_DPI"], ); execute ( iv_pli => 1, check_finished=>1 ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_unpacked.pl0000775000177100017500000000072212473477707022603 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_array_pattern_packed.pl0000775000177100017500000000072212473477707023567 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_missing_bad.pl0000775000177100017500000000150412473477707022720 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( v_flags2 => ["--lint-only --Wall -Wno-DECLFILENAME"], fails=>1, expect=> q{%Warning-PINNOCONNECT: t/t_inst_missing_bad.v:8: Cell pin is not connected: __pinNumber2 %Warning-PINNOCONNECT: Use .* %Warning-PINCONNECTEMPTY: t/t_inst_missing_bad.v:8: Cell pin connected by name with empty reference: nc %Warning-PINMISSING: t/t_inst_missing_bad.v:8: Cell has missing pin: missing %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_preproc_inc_bad.pl0000775000177100017500000000126012473477707022514 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( verilator_flags2 => ["--lint-only"], fails=>1, # The .vh file has the error, not the .v file expect=> '%Error: t/t_preproc_inc_inc_bad.vh:10: syntax error, unexpected endmodule, expecting IDENTIFIER' ); ok(1); 1; verilator-3.874/test_regress/t/t_param_first_b.v0000664000177100017500000000067112473477707022047 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_param_first_b (/*AUTOARG*/ // Outputs par, varwidth ); parameter X = 1; parameter FIVE = 0; // Overridden parameter TWO = 2; output [4:0] par; output [X:0] varwidth; wire [4:0] par = X; wire [X:0] varwidth = (FIVE==5)?TWO:0; endmodule verilator-3.874/test_regress/t/t_trace_complex.v0000664000177100017500000000420412473477707022060 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. bit global_bit; module t (clk); input clk; integer cyc=0; typedef struct packed { bit b1; bit b0; } strp_t; typedef struct packed { strp_t x1; strp_t x0; } strp_strp_t; typedef union packed { strp_t x1; strp_t x0; } unip_strp_t; typedef bit [2:1] arrp_t; typedef arrp_t [4:3] arrp_arrp_t; typedef strp_t [4:3] arrp_strp_t; typedef bit arru_t [2:1]; typedef arru_t arru_arru_t [4:3]; typedef arrp_t arru_arrp_t [4:3]; typedef strp_t arru_strp_t [4:3]; strp_t v_strp; strp_strp_t v_strp_strp; unip_strp_t v_unip_strp; arrp_t v_arrp; arrp_arrp_t v_arrp_arrp; arrp_strp_t v_arrp_strp; arru_t v_arru; arru_arru_t v_arru_arru; arru_arrp_t v_arru_arrp; arru_strp_t v_arru_strp; real v_real; real v_arr_real [2]; string v_string; typedef struct packed { logic [31:0] data; } str32_t; str32_t [1:0] v_str32x2; // If no --trace-struct, this packed array is traced as 63:0 initial v_str32x2[0] = 32'hff; initial v_str32x2[1] = 0; p #(.PARAM(2)) p2 (); p #(.PARAM(3)) p3 (); always @ (posedge clk) begin cyc <= cyc + 1; v_strp <= ~v_strp; v_strp_strp <= ~v_strp_strp; v_unip_strp <= ~v_unip_strp; v_arrp_strp <= ~v_arrp_strp; v_arrp <= ~v_arrp; v_arrp_arrp <= ~v_arrp_arrp; v_real <= v_real + 0.1; v_string <= "foo"; v_arr_real[0] <= v_arr_real[0] + 0.2; v_arr_real[1] <= v_arr_real[1] + 0.3; for (integer b=3; b<=4; b++) begin v_arru[b] <= ~v_arru[b]; v_arru_strp[b] <= ~v_arru_strp[b]; v_arru_arrp[b] <= ~v_arru_arrp[b]; for (integer a=3; a<=4; a++) begin v_arru_arru[a][b] = ~v_arru_arru[a][b]; end end v_str32x2[0] <= v_str32x2[0] - 1; v_str32x2[1] <= v_str32x2[1] + 1; if (cyc == 5) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module p; parameter PARAM = 1; initial global_bit = 1; endmodule verilator-3.874/test_regress/t/t_struct_init_trace.pl0000775000177100017500000000103512473477707023130 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_struct_init.v"); compile ( verilator_flags2 => ['--cc --trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_pipe_filter_inc.vh0000664000177100017500000000041412473477707022535 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. inc line 6; inc line 7; // example_lint_off_line FOO inc line 8; // example_lint_off_line BAR inc line 9; verilator-3.874/test_regress/t/t_sys_system.pl0000775000177100017500000000071712473477707021633 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_wide.v0000664000177100017500000000153112473477707021176 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (clk); input clk; reg [43:0] mi; wire [31:0] mo; muxtop um ( mi, mo); integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin mi <= 44'h1234567890; end if (cyc==3) begin if (mo !== 32'h12345678) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule module muxtop ( input [ 43:0 ] i, output reg [ 31:0 ] o ); always @ ( i[43:0] ) // Verify we ignore ranges on always statement sense lists o = MUX( i[39:0] ); function [31:0] MUX; input [39:0] XX ; begin MUX = XX[39:8]; end endfunction endmodule verilator-3.874/test_regress/t/t_var_dotted_inl0.pl0000775000177100017500000000104012473477707022454 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_var_dotted.v"); compile ( v_flags2 => ['+define+NOUSE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_eq.v0000664000177100017500000000347212473477707020657 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [3:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[3:0]), // Inputs .clk (clk), .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, out}; // What checksum will we end up with `define EXPECTED_SUM 64'h1a0d07009b6a30d2 // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); input clk; input [31:0] in; output [3:0] out; assign out[0] = in[3:0] ==? 4'b1001; assign out[1] = in[3:0] !=? 4'b1001; assign out[2] = in[3:0] ==? 4'bx01x; assign out[3] = in[3:0] !=? 4'bx01x; endmodule verilator-3.874/test_regress/t/t_func_endian.pl0000775000177100017500000000071712473477707021662 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_overwide_bad.pl0000775000177100017500000000251712473477707023100 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. top_filename("t/t_inst_overwide.v"); compile ( v_flags2 => ["--lint-only"], make_top_shell=>0, verilator_flags=> [qw(-cc)], verilator_make_gcc=>0, fails=>$Self->{v3}, expect=> q{%Warning-WIDTH: t/t_inst_overwide.v:\d+: Output port connection 'outy_w92' expects 92 bits on the pin connection, but pin connection's VARREF 'outc_w30' generates 30 bits. %Warning-WIDTH: Use .* to disable this message. %Warning-WIDTH: t/t_inst_overwide.v:\d+: Output port connection 'outz_w22' expects 22 bits on the pin connection, but pin connection's VARREF 'outd_w73' generates 73 bits. %Warning-WIDTH: t/t_inst_overwide.v:\d+: Input port connection 'inw_w31' expects 31 bits on the pin connection, but pin connection's VARREF 'ina_w1' generates 1 bits. %Warning-WIDTH: t/t_inst_overwide.v:\d+: Input port connection 'inx_w11' expects 11 bits on the pin connection, but pin connection's VARREF 'inb_w61' generates 61 bits. %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_latch.v0000664000177100017500000000617312473477707021166 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs fastclk, clk ); `ifdef EDGE_DETECT_STYLE // Two 'common' forms of latching, with full combo, and with pos/negedge `define posstyle posedge `define negstyle negedge `else `define posstyle `define negstyle `endif input fastclk; input clk; reg [7:0] data; reg [7:0] data_a; reg [7:0] data_a_a; reg [7:0] data_a_b; reg [7:0] data_b; reg [7:0] data_b_a; reg [7:0] data_b_b; reg [8*6-1:0] check [100:0]; wire [8*6-1:0] compare = {data_a,data_a_a,data_b_a,data_b,data_a_b,data_b_b}; initial begin check[7'd19] = {8'h0d, 8'h0e, 8'h0e, 8'h0d, 8'h0e, 8'h0e}; check[7'd20] = {8'h0d, 8'h0e, 8'h0e, 8'h0d, 8'h0e, 8'h0e}; check[7'd21] = {8'h15, 8'h16, 8'h0e, 8'h0d, 8'h0e, 8'h0e}; check[7'd22] = {8'h15, 8'h16, 8'h0e, 8'h0d, 8'h0e, 8'h0e}; check[7'd23] = {8'h15, 8'h16, 8'h0e, 8'h15, 8'h16, 8'h0e}; check[7'd24] = {8'h15, 8'h16, 8'h0e, 8'h15, 8'h16, 8'h0e}; check[7'd25] = {8'h15, 8'h16, 8'h0e, 8'h15, 8'h16, 8'h0e}; check[7'd26] = {8'h15, 8'h16, 8'h16, 8'h15, 8'h16, 8'h0e}; check[7'd27] = {8'h15, 8'h16, 8'h16, 8'h15, 8'h16, 8'h0e}; check[7'd28] = {8'h15, 8'h16, 8'h16, 8'h15, 8'h16, 8'h16}; check[7'd29] = {8'h15, 8'h16, 8'h16, 8'h15, 8'h16, 8'h16}; check[7'd30] = {8'h15, 8'h16, 8'h16, 8'h15, 8'h16, 8'h16}; check[7'd31] = {8'h1f, 8'h20, 8'h16, 8'h15, 8'h16, 8'h16}; check[7'd32] = {8'h1f, 8'h20, 8'h16, 8'h15, 8'h16, 8'h16}; check[7'd33] = {8'h1f, 8'h20, 8'h16, 8'h1f, 8'h20, 8'h16}; check[7'd34] = {8'h1f, 8'h20, 8'h16, 8'h1f, 8'h20, 8'h16}; check[7'd35] = {8'h1f, 8'h20, 8'h16, 8'h1f, 8'h20, 8'h16}; check[7'd36] = {8'h1f, 8'h20, 8'h20, 8'h1f, 8'h20, 8'h16}; check[7'd37] = {8'h1f, 8'h20, 8'h20, 8'h1f, 8'h20, 8'h16}; end // verilator lint_off COMBDLY always @ (`posstyle clk /*AS*/ or data) begin if (clk) begin data_a <= data + 8'd1; end end always @ (`posstyle clk /*AS*/ or data_a) begin if (clk) begin data_a_a <= data_a + 8'd1; end end always @ (`posstyle clk /*AS*/ or data_b) begin if (clk) begin data_b_a <= data_b + 8'd1; end end always @ (`negstyle clk /*AS*/ or data or data_a) begin if (~clk) begin data_b <= data + 8'd1; data_a_b <= data_a + 8'd1; data_b_b <= data_b + 8'd1; end end integer cyc; initial cyc=0; always @ (posedge fastclk) begin cyc <= cyc+1; `ifdef TEST_VERBOSE $write("%d %x %x %x %x %x %x\n",cyc,data_a,data_a_a,data_b_a,data_b,data_a_b,data_b_b); `endif if (cyc>=19 && cyc<36) begin if (compare !== check[cyc]) begin $write("[%0t] Mismatch, got=%x, exp=%x\n", $time, compare, check[cyc]); $stop; end end if (cyc == 10) begin data <= 8'd12; end if (cyc == 20) begin data <= 8'd20; end if (cyc == 30) begin data <= 8'd30; end if (cyc == 40) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_typedef_signed.v0000664000177100017500000000371112473477707022226 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. //bug456 typedef logic signed [34:0] rc_t; module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [34:0] rc = crc[34:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) logic o; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .o (o), // Inputs .rc (rc), .clk (clk)); // Aggregate outputs into a single result vector wire [63:0] result = {63'h0, o}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h7211d24a17b25ec9 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test( output logic o, input rc_t rc, input logic clk); localparam RATIO = 2; rc_t rc_d[RATIO:1]; always_ff @(posedge clk) begin integer k; rc_d[1] <= rc; for( k=2; k$Self->{v3}, expect=> '%Error: t/t_sys_readmem_bad_addr.mem:\d+: \$readmem file address beyond bounds of array', ); ok(1); 1; verilator-3.874/test_regress/t/t_unpacked_array_order.v0000664000177100017500000000153712525171734023411 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Duraid Madina. module t (/*AUTOARG*/ // Inputs clk ); input clk; parameter logic [1:0] t0 [ 2][ 2] = '{'{2'd0, 2'd1}, '{2'd2, 2'd3}}; parameter logic [1:0] t1 [0:1][0:1] = '{'{2'd0, 2'd1}, '{2'd2, 2'd3}}; parameter logic [1:0] t2 [1:0][1:0] = '{'{2'd3, 2'd2}, '{2'd1, 2'd0}}; always @ (posedge clk) begin if (t0[0][0] != t1[0][0]) $stop; if (t0[0][1] != t1[0][1]) $stop; if (t0[1][0] != t1[1][0]) $stop; if (t0[1][1] != t1[1][1]) $stop; if (t0[0][0] != t2[0][0]) $stop; if (t0[0][1] != t2[0][1]) $stop; if (t0[1][0] != t2[1][0]) $stop; if (t0[1][1] != t2[1][1]) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_concat_opt.pl0000775000177100017500000000071712473477707021542 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_csplit.v0000664000177100017500000000172512473477707021527 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; parameter CNT = 10; wire [31:0] w [CNT:0]; generate for (genvar g=0; g$Self->{v3}, expect=> '%Error: t/t_tri_pull_bad.v:\d+: Unsupported: Conflicting pull directions. %Error: t/t_tri_pull_bad.v:\d+: ... Location of conflicting pull. %Error: Exiting due to', ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_gen.v0000664000177100017500000000345112473477707022027 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. // Very simple test for interface pathclearing `ifdef VCS `define UNSUPPORTED_MOD_IN_GENS `endif `ifdef VERILATOR `define UNSUPPORTED_MOD_IN_GENS `endif module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; ifc #(1) itopa(); ifc #(2) itopb(); sub #(1) ca (.isub(itopa), .i_value(4)); sub #(2) cb (.isub(itopb), .i_value(5)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==1) begin if (itopa.MODE != 1) $stop; if (itopb.MODE != 2) $stop; end if (cyc==20) begin if (itopa.get_value() != 4) $stop; if (itopb.get_value() != 5) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub #(parameter MODE = 0) ( ifc.out_modport isub, input integer i_value ); `ifdef UNSUPPORTED_MOD_IN_GENS always @* isub.value = i_value; `else generate if (MODE == 1) begin always @* isub.valuea = i_value; end else if (MODE == 2) begin always @* isub.valueb = i_value; end endgenerate `endif endmodule interface ifc; parameter MODE = 0; // Modports under generates not supported by all commercial simulators `ifdef UNSUPPORTED_MOD_IN_GENS integer value; modport out_modport (output value); function integer get_value(); return value; endfunction `else generate if (MODE == 0) begin integer valuea; modport out_modport (output valuea); function integer get_valuea(); return valuea; endfunction end else begin integer valueb; modport out_modport (output valueb); function integer get_valueb(); return valueb; endfunction end endgenerate `endif endinterface verilator-3.874/test_regress/t/t_math_div.pl0000775000177100017500000000071712473477707021204 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_initial_dlyass.pl0000775000177100017500000000077712473477707022427 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ['-Wno-INITIALDLY'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_nest.pl0000775000177100017500000000102412473477707021756 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_huge_sub2.v0000664000177100017500000002254112473477707022115 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t_case_huge_sub2 (/*AUTOARG*/ // Outputs outa, // Inputs index ); input [9:0] index; output [9:0] outa; // ============================= /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [9:0] outa; // End of automatics // ============================= // Created from perl // for $i (0..1023) { printf "\t10'h%03x: begin outa = 10'h%03x; outb = 2'b%02b; outc = 1'b%d; end\n", $i, rand(1024),rand(4),rand(2); }; always @(/*AS*/index) begin case (index[7:0]) `ifdef VERILATOR // Harder test 8'h00: begin outa = $c("0"); end // Makes whole table non-optimizable `else 8'h00: begin outa = 10'h0; end `endif 8'h01: begin outa = 10'h318; end 8'h02: begin outa = 10'h29f; end 8'h03: begin outa = 10'h392; end 8'h04: begin outa = 10'h1ef; end 8'h05: begin outa = 10'h06c; end 8'h06: begin outa = 10'h29f; end 8'h07: begin outa = 10'h29a; end 8'h08: begin outa = 10'h3ce; end 8'h09: begin outa = 10'h37c; end 8'h0a: begin outa = 10'h058; end 8'h0b: begin outa = 10'h3b2; end 8'h0c: begin outa = 10'h36f; end 8'h0d: begin outa = 10'h2c5; end 8'h0e: begin outa = 10'h23a; end 8'h0f: begin outa = 10'h222; end 8'h10: begin outa = 10'h328; end 8'h11: begin outa = 10'h3c3; end 8'h12: begin outa = 10'h12c; end 8'h13: begin outa = 10'h1d0; end 8'h14: begin outa = 10'h3ff; end 8'h15: begin outa = 10'h115; end 8'h16: begin outa = 10'h3ba; end 8'h17: begin outa = 10'h3ba; end 8'h18: begin outa = 10'h10d; end 8'h19: begin outa = 10'h13b; end 8'h1a: begin outa = 10'h0a0; end 8'h1b: begin outa = 10'h264; end 8'h1c: begin outa = 10'h3a2; end 8'h1d: begin outa = 10'h07c; end 8'h1e: begin outa = 10'h291; end 8'h1f: begin outa = 10'h1d1; end 8'h20: begin outa = 10'h354; end 8'h21: begin outa = 10'h0c0; end 8'h22: begin outa = 10'h191; end 8'h23: begin outa = 10'h379; end 8'h24: begin outa = 10'h073; end 8'h25: begin outa = 10'h2fd; end 8'h26: begin outa = 10'h2e0; end 8'h27: begin outa = 10'h337; end 8'h28: begin outa = 10'h2c7; end 8'h29: begin outa = 10'h19e; end 8'h2a: begin outa = 10'h107; end 8'h2b: begin outa = 10'h06a; end 8'h2c: begin outa = 10'h1c7; end 8'h2d: begin outa = 10'h107; end 8'h2e: begin outa = 10'h0cf; end 8'h2f: begin outa = 10'h009; end 8'h30: begin outa = 10'h09d; end 8'h31: begin outa = 10'h28e; end 8'h32: begin outa = 10'h010; end 8'h33: begin outa = 10'h1e0; end 8'h34: begin outa = 10'h079; end 8'h35: begin outa = 10'h13e; end 8'h36: begin outa = 10'h282; end 8'h37: begin outa = 10'h21c; end 8'h38: begin outa = 10'h148; end 8'h39: begin outa = 10'h3c0; end 8'h3a: begin outa = 10'h176; end 8'h3b: begin outa = 10'h3fc; end 8'h3c: begin outa = 10'h295; end 8'h3d: begin outa = 10'h113; end 8'h3e: begin outa = 10'h354; end 8'h3f: begin outa = 10'h0db; end 8'h40: begin outa = 10'h238; end 8'h41: begin outa = 10'h12b; end 8'h42: begin outa = 10'h1dc; end 8'h43: begin outa = 10'h137; end 8'h44: begin outa = 10'h1e2; end 8'h45: begin outa = 10'h3d5; end 8'h46: begin outa = 10'h30c; end 8'h47: begin outa = 10'h298; end 8'h48: begin outa = 10'h080; end 8'h49: begin outa = 10'h35a; end 8'h4a: begin outa = 10'h01b; end 8'h4b: begin outa = 10'h0a3; end 8'h4c: begin outa = 10'h0b3; end 8'h4d: begin outa = 10'h17a; end 8'h4e: begin outa = 10'h3ae; end 8'h4f: begin outa = 10'h078; end 8'h50: begin outa = 10'h322; end 8'h51: begin outa = 10'h213; end 8'h52: begin outa = 10'h11a; end 8'h53: begin outa = 10'h1a7; end 8'h54: begin outa = 10'h35a; end 8'h55: begin outa = 10'h233; end 8'h56: begin outa = 10'h01d; end 8'h57: begin outa = 10'h2d5; end 8'h58: begin outa = 10'h1a0; end 8'h59: begin outa = 10'h3d0; end 8'h5a: begin outa = 10'h181; end 8'h5b: begin outa = 10'h219; end 8'h5c: begin outa = 10'h26a; end 8'h5d: begin outa = 10'h050; end 8'h5e: begin outa = 10'h189; end 8'h5f: begin outa = 10'h1eb; end 8'h60: begin outa = 10'h224; end 8'h61: begin outa = 10'h2fe; end 8'h62: begin outa = 10'h0ae; end 8'h63: begin outa = 10'h1cd; end 8'h64: begin outa = 10'h273; end 8'h65: begin outa = 10'h268; end 8'h66: begin outa = 10'h111; end 8'h67: begin outa = 10'h1f9; end 8'h68: begin outa = 10'h232; end 8'h69: begin outa = 10'h255; end 8'h6a: begin outa = 10'h34c; end 8'h6b: begin outa = 10'h049; end 8'h6c: begin outa = 10'h197; end 8'h6d: begin outa = 10'h0fe; end 8'h6e: begin outa = 10'h253; end 8'h6f: begin outa = 10'h2de; end 8'h70: begin outa = 10'h13b; end 8'h71: begin outa = 10'h040; end 8'h72: begin outa = 10'h0b4; end 8'h73: begin outa = 10'h233; end 8'h74: begin outa = 10'h198; end 8'h75: begin outa = 10'h018; end 8'h76: begin outa = 10'h2f7; end 8'h77: begin outa = 10'h134; end 8'h78: begin outa = 10'h1ca; end 8'h79: begin outa = 10'h286; end 8'h7a: begin outa = 10'h0e6; end 8'h7b: begin outa = 10'h064; end 8'h7c: begin outa = 10'h257; end 8'h7d: begin outa = 10'h31a; end 8'h7e: begin outa = 10'h247; end 8'h7f: begin outa = 10'h299; end 8'h80: begin outa = 10'h02c; end 8'h81: begin outa = 10'h2bb; end 8'h82: begin outa = 10'h180; end 8'h83: begin outa = 10'h245; end 8'h84: begin outa = 10'h0da; end 8'h85: begin outa = 10'h367; end 8'h86: begin outa = 10'h304; end 8'h87: begin outa = 10'h38b; end 8'h88: begin outa = 10'h09f; end 8'h89: begin outa = 10'h1f0; end 8'h8a: begin outa = 10'h281; end 8'h8b: begin outa = 10'h019; end 8'h8c: begin outa = 10'h1f2; end 8'h8d: begin outa = 10'h0b1; end 8'h8e: begin outa = 10'h058; end 8'h8f: begin outa = 10'h39b; end 8'h90: begin outa = 10'h2ec; end 8'h91: begin outa = 10'h250; end 8'h92: begin outa = 10'h3f4; end 8'h93: begin outa = 10'h057; end 8'h94: begin outa = 10'h18f; end 8'h95: begin outa = 10'h105; end 8'h96: begin outa = 10'h1ae; end 8'h97: begin outa = 10'h04e; end 8'h98: begin outa = 10'h240; end 8'h99: begin outa = 10'h3e4; end 8'h9a: begin outa = 10'h3c6; end 8'h9b: begin outa = 10'h109; end 8'h9c: begin outa = 10'h073; end 8'h9d: begin outa = 10'h19f; end 8'h9e: begin outa = 10'h3b8; end 8'h9f: begin outa = 10'h00e; end 8'ha0: begin outa = 10'h1b3; end 8'ha1: begin outa = 10'h2bd; end 8'ha2: begin outa = 10'h324; end 8'ha3: begin outa = 10'h343; end 8'ha4: begin outa = 10'h1c9; end 8'ha5: begin outa = 10'h185; end 8'ha6: begin outa = 10'h37a; end 8'ha7: begin outa = 10'h0e0; end 8'ha8: begin outa = 10'h0a3; end 8'ha9: begin outa = 10'h019; end 8'haa: begin outa = 10'h099; end 8'hab: begin outa = 10'h376; end 8'hac: begin outa = 10'h077; end 8'had: begin outa = 10'h2b1; end 8'hae: begin outa = 10'h27f; end 8'haf: begin outa = 10'h265; end 8'hb0: begin outa = 10'h156; end 8'hb1: begin outa = 10'h1ce; end 8'hb2: begin outa = 10'h008; end 8'hb3: begin outa = 10'h12e; end 8'hb4: begin outa = 10'h199; end 8'hb5: begin outa = 10'h330; end 8'hb6: begin outa = 10'h1ab; end 8'hb7: begin outa = 10'h3bd; end 8'hb8: begin outa = 10'h0ca; end 8'hb9: begin outa = 10'h367; end 8'hba: begin outa = 10'h334; end 8'hbb: begin outa = 10'h040; end 8'hbc: begin outa = 10'h1a7; end 8'hbd: begin outa = 10'h036; end 8'hbe: begin outa = 10'h223; end 8'hbf: begin outa = 10'h075; end 8'hc0: begin outa = 10'h3c4; end 8'hc1: begin outa = 10'h2cc; end 8'hc2: begin outa = 10'h123; end 8'hc3: begin outa = 10'h3fd; end 8'hc4: begin outa = 10'h11e; end 8'hc5: begin outa = 10'h27c; end 8'hc6: begin outa = 10'h1e2; end 8'hc7: begin outa = 10'h377; end 8'hc8: begin outa = 10'h33a; end 8'hc9: begin outa = 10'h32d; end 8'hca: begin outa = 10'h014; end 8'hcb: begin outa = 10'h332; end 8'hcc: begin outa = 10'h359; end 8'hcd: begin outa = 10'h0a4; end 8'hce: begin outa = 10'h348; end 8'hcf: begin outa = 10'h04b; end 8'hd0: begin outa = 10'h147; end 8'hd1: begin outa = 10'h026; end 8'hd2: begin outa = 10'h103; end 8'hd3: begin outa = 10'h106; end 8'hd4: begin outa = 10'h35a; end 8'hd5: begin outa = 10'h254; end 8'hd6: begin outa = 10'h0cd; end 8'hd7: begin outa = 10'h17c; end 8'hd8: begin outa = 10'h37e; end 8'hd9: begin outa = 10'h0a9; end 8'hda: begin outa = 10'h0fe; end 8'hdb: begin outa = 10'h3c0; end 8'hdc: begin outa = 10'h1d9; end 8'hdd: begin outa = 10'h10e; end 8'hde: begin outa = 10'h394; end 8'hdf: begin outa = 10'h316; end 8'he0: begin outa = 10'h05b; end 8'he1: begin outa = 10'h126; end 8'he2: begin outa = 10'h369; end 8'he3: begin outa = 10'h291; end 8'he4: begin outa = 10'h2ca; end 8'he5: begin outa = 10'h25b; end 8'he6: begin outa = 10'h106; end 8'he7: begin outa = 10'h172; end 8'he8: begin outa = 10'h2f7; end 8'he9: begin outa = 10'h2d3; end 8'hea: begin outa = 10'h182; end 8'heb: begin outa = 10'h327; end 8'hec: begin outa = 10'h1d0; end 8'hed: begin outa = 10'h204; end 8'hee: begin outa = 10'h11f; end 8'hef: begin outa = 10'h365; end 8'hf0: begin outa = 10'h2c2; end 8'hf1: begin outa = 10'h2b5; end 8'hf2: begin outa = 10'h1f8; end 8'hf3: begin outa = 10'h2a7; end 8'hf4: begin outa = 10'h1be; end 8'hf5: begin outa = 10'h25e; end 8'hf6: begin outa = 10'h032; end 8'hf7: begin outa = 10'h2ef; end 8'hf8: begin outa = 10'h02f; end 8'hf9: begin outa = 10'h201; end 8'hfa: begin outa = 10'h054; end 8'hfb: begin outa = 10'h013; end 8'hfc: begin outa = 10'h249; end 8'hfd: begin outa = 10'h09a; end 8'hfe: begin outa = 10'h012; end 8'hff: begin outa = 10'h114; end endcase end endmodule verilator-3.874/test_regress/t/t_func_mlog2.pl0000775000177100017500000000071712473477707021444 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_outoforder.v0000664000177100017500000000237312473477707022300 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [125:0] a; wire q; sub sub ( .q (q), .a (a), .clk (clk)); always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin a <= 126'b1000; end if (cyc==2) begin a <= 126'h1001; end if (cyc==3) begin a <= 126'h1010; end if (cyc==4) begin a <= 126'h1111; if (q !== 1'b0) $stop; end if (cyc==5) begin if (q !== 1'b1) $stop; end if (cyc==6) begin if (q !== 1'b0) $stop; end if (cyc==7) begin if (q !== 1'b0) $stop; end if (cyc==8) begin if (q !== 1'b0) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule module sub ( input clk, input [125:0] a, output reg q ); // verilator public_module reg [125:0] g_r; wire [127:0] g_extend = { g_r, 1'b1, 1'b0 }; reg [6:0] sel; wire g_sel = g_extend[sel]; always @ (posedge clk) begin g_r <= a; sel <= a[6:0]; q <= g_sel; end endmodule verilator-3.874/test_regress/t/t_struct_init.v0000664000177100017500000000606512473477707021611 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; //Several simulators don't support this. //typedef struct pack2; // Forward declaration typedef struct packed { // [3:0] bit b3; bit b2; bit b1; bit b0; } b4_t; typedef struct packed { // [3:0] b4_t x1; b4_t x0; } b4x2_t; typedef union packed { // [3:0] bit [3:0] quad0; b4_t quad1; } q4_t; typedef struct packed { // [5:0] bit msb; q4_t four; bit lsb; } pack2_t; typedef union packed { // [5:0] pack2_t pack2; bit [6:1] pvec; // Vector not allowed in packed structure, per spec: // bit vec[6]; // bit vec2d[2][3]; } pack3_t; const b4_t b4_const_a = '{1'b1, 1'b0, 1'b0, 1'b1}; // Cast to a pattern - note bits are tagged out of order const b4_t b4_const_b = b4_t'{ b1 : 1'b0, b0 : 1'b1, b3 : 1'b1, b2 : 1'b0 }; wire b4_t b4_wire; assign b4_wire = '{1'b1, 1'b0, 1'b1, 1'b0}; pack2_t arr[2]; initial begin pack3_t tsu; tsu = 6'b110110; // 543210 if (tsu!=6'b110110) $stop; if (tsu[5:4]!=2'b11) $stop; if (tsu[5:4] == tsu[1:0]) $stop; // Not a good extraction test if LSB subtraction doesn't matter if (tsu.pvec!=6'b110110) $stop; if (tsu.pvec[6:5]!=2'b11) $stop; if (tsu.pack2[5:1] != 5'b11011) $stop; if (tsu.pack2.msb != 1'b1) $stop; if (tsu.pack2.lsb != 1'b0) $stop; if (tsu.pack2.four.quad0 != 4'b1011) $stop; if (tsu.pack2.four.quad1.b0 != 1'b1) $stop; if (tsu.pack2.four.quad1.b1 != 1'b1) $stop; if (tsu.pack2.four.quad1.b2 != 1'b0) $stop; if (tsu.pack2.four.quad1.b3 != 1'b1) $stop; // tsu = 1'b0 ? '0 : '{pvec: 6'b101011}; if (tsu!=6'b101011) $stop; // arr[0] = 6'b101010; arr[1] = 6'b010101; if (arr[0].four !== 4'b0101) $stop; if (arr[1].four !== 4'b1010) $stop; // // Initialization begin b4_t q = '{1'b1, 1'b1, 1'b0, 1'b0}; if (q != 4'b1100) $stop; end begin b4_t q = '{3{1'b1}, 1'b0}; if (q != 4'b1110) $stop; end begin b4_t q = '{4{1'b1}}; // Repeats the {} if (q != 4'b1111) $stop; end begin b4x2_t m = '{4'b1001, '{1'b1, 1'b0, 1'b1, 1'b1}}; if (m != 8'b10011011) $stop; end begin b4_t q = '{default:1'b1}; if (q != 4'b1111) $stop; end begin b4_t q = '{b0:1'b1, b2:1'b1, b3:1'b1, b1:1'b0}; if (q != 4'b1101) $stop; end begin b4_t q = '{b2:1'b0, default:1'b1}; if (q != 4'b1011) $stop; end if (b4_const_a != 4'b1001) $stop; if (b4_const_b != 4'b1001) $stop; if (b4_wire != 4'b1010) $stop; if (pat(4'b1100, 4'b1100)) $stop; if (pat('{1'b1, 1'b0, 1'b1, 1'b1}, 4'b1011)) $stop; $write("*-* All Finished *-*\n"); $finish; end function pat(b4_t in, logic [3:0] cmp); if (in !== cmp) $stop; pat = 1'b0; endfunction endmodule verilator-3.874/test_regress/t/t_inst_aport.v0000664000177100017500000000474012473477707021422 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [15:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[15:0]), // Inputs .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {48'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h4afe43fb79d7b71e if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module callee (input [7:0] port [7:0], output [7:0] o); assign o = ^{port[0], port[1], port[2], port[3], port[4], port[5], port[6], port[7]}; endmodule // callee module Test (/*AUTOARG*/ // Outputs out, // Inputs in ); input [31:0] in; output reg [15:0] out; wire [7:0] port [15:0]; wire [7:0] goodport [7:0]; always_comb begin port[0][7:0] = in[7:0]; port[1][7:0] = in[16:8]; port[2] = '0; port[3] = '0; port[4] = '0; port[5] = '0; port[6] = '0; port[7] = '0; end always_comb begin goodport[0][7:0] = in[7:0]; goodport[1][7:0] = in[16:8]; goodport[2] = '0; goodport[3] = '0; goodport[4] = '0; goodport[5] = '0; goodport[6] = '0; goodport[7] = '0; end callee good (.port(goodport), .o(out[7:0])); // This is a slice, unsupported by other tools, bug711 callee bad (.port(port[7:0]), .o(out[15:8])); endmodule verilator-3.874/test_regress/t/t_rnd.v0000664000177100017500000000170412473477707020020 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg _ranit; reg [2:0] a; reg [33:0] wide; reg unused_r; initial _ranit = 0; always @ (posedge clk) begin : blockName begin // Verify begin/begin is legal unused_r <= 1'b1; end begin end // Verify empty is legal end wire one = 1'b1; wire [7:0] rand_bits = 8'b01xx_xx10; always @ (posedge clk) begin if (!_ranit) begin _ranit <= 1; // a = 3'b1xx; wide <= 34'bx1_00000000_xxxxxxxx_00000000_xxxx0000; if (one !== 1'b1) $stop; if ((rand_bits & 8'b1100_0011) !== 8'b0100_0010) $stop; // $write("*-* All Finished *-*\n"); $finish; end end // verilator lint_off UNUSED wire _unused_ok = |{1'b1, wide}; // verilator lint_on UNUSED endmodule verilator-3.874/test_regress/t/t_gen_lsb.pl0000775000177100017500000000072212473477707021016 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_default_bad.pl0000775000177100017500000000111412473477707022626 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_case_default_bad.v:\d+: Multiple default statements in case statement. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_dist_manifest.pl0000775000177100017500000000412012473477707022232 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. my $root = ".."; my $Debug; ### Must trim output before and after our file list `cd $root && make dist-file-list`; my $manifest_files = `cd $root && make dist-file-list`; $manifest_files =~ s!.*begin-dist-file-list:!!sg; $manifest_files =~ s!end-dist-file-list:.*$!!sg; print "MF $manifest_files\n"; my %files; foreach my $file (split /\s+/,$manifest_files) { next if $file eq ''; $files{$file} |= 1; } my $all_files = `cd $root && find . -type f -print`; foreach my $file (split /\s+/,$all_files) { next if $file eq ''; $file =~ s!^\./!!; $files{$file} |= 2; } my %file_regexps; my $skip = file_contents("$root/MANIFEST.SKIP"); foreach my $file (sort keys %files) { foreach my $skip (split /\s+/,$skip) { if ($file =~ /$skip/) { $files{$file} |= 4; $file_regexps{$file} = $skip; } } } my %warns; foreach my $file (sort keys %files) { my $tar = $files{$file}&1; my $dir = $files{$file}&2; my $skip = $files{$file}&4; print +(($tar ? "TAR ":" ") .($dir ? "DIR ":" ") .($skip ? "SKIP ":" ") ." $file\n") if $Debug; if ($dir && !$tar && !$skip) { $warns{$file} = "File not in manifest or MANIFEST.SKIP: $file"; } elsif (!$dir && $tar && !$skip) { $warns{$file} = "File in manifest, but not directory: $file"; } elsif ($dir && $tar && $skip) { $warns{$file} = "File in manifest and also MANIFEST.SKIP, too general skip regexp '$file_regexps{$file}'?: $file"; } } if (keys %warns) { # First warning lists everything as that's shown in the driver summary $Self->error("Files mismatch with manifest: ",join(' ',sort keys %warns)); foreach my $file (sort keys %warns) { $Self->error($warns{$file}); } } ok(1); 1; verilator-3.874/test_regress/t/t_initial_inc.vh0000664000177100017500000000044312473477707021666 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. `define foo bar `ifdef foo `ifdef baz `else // Test file to make sure includes work; integer user_loaded_value; `endif `endif verilator-3.874/test_regress/t/t_assert_basic_off.pl0000775000177100017500000000101012473477707022670 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_assert_basic.v"); compile ( v_flags2 => [], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_array_partial.pl0000775000177100017500000000071712473477707023300 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_port_bad.v0000664000177100017500000000051112473477707021672 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t; subok subok (.a(1'b1), .b(1'b0)); sub sub (.a(1'b1), .b(1'b0)); endmodule module subok (input a,b); endmodule module sub (a); input a, b; endmodule verilator-3.874/test_regress/t/t_sys_sformat_noopt.pl0000775000177100017500000000114412473477707023174 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_sys_sformat.v"); compile ( # Avoid inlining our simple example, to make sure verilated.h works right verilator_flags2 => ["-O0"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface.v0000664000177100017500000000617712473477707021206 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: SystemVerilog interface test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic rst = 1'b1; // reset integer rst_cnt = 0; // reset is removed after a delay always @ (posedge clk) begin rst_cnt <= rst_cnt + 1; rst <= rst_cnt <= 3; end // counters int cnt; int cnt_src; int cnt_drn; // add all counters assign cnt = cnt_src + cnt_drn + inf.cnt; // finish report always @ (posedge clk) if (cnt == 3*16) begin $write("*-* All Finished *-*\n"); $finish; end // interface instance handshake inf ( .clk (clk), .rst (rst) ); // source instance source #( .RW (8), .RP (8'b11100001) ) source ( .clk (clk), .rst (rst), .inf (inf), .cnt (cnt_src) ); // drain instance drain #( .RW (8), .RP (8'b11010100) ) drain ( .clk (clk), .rst (rst), .inf (inf), .cnt (cnt_drn) ); endmodule : t // interface definition interface handshake #( parameter int unsigned WC = 32 )( input logic clk, input logic rst ); // modport signals logic req; // request logic grt; // grant logic inc; // increment // local signals integer cnt; // counter // source modport src ( output req, input grt ); // drain modport drn ( input req, output grt ); // incremet condition assign inc = req & grt; // local logic (counter) always @ (posedge clk, posedge rst) if (rst) cnt <= '0; else cnt <= cnt + {31'h0, inc}; endinterface : handshake // source module module source #( // random generator parameters parameter int unsigned RW=1, // LFSR width parameter bit [RW-1:0] RP='0, // LFSR polinom parameter bit [RW-1:0] RR='1 // LFSR reset state )( input logic clk, input logic rst, handshake.src inf, output integer cnt ); // LFSR logic [RW-1:0] rnd; // LFSR in Galois form always @ (posedge clk, posedge rst) if (rst) rnd <= RR; else rnd <= {rnd[0], rnd[RW-1:1]} ^ ({RW{rnd[0]}} & RP); // counter always @ (posedge clk, posedge rst) if (rst) cnt <= 32'd0; else cnt <= cnt + {31'd0, (inf.req & inf.grt)}; // request signal assign inf.req = rnd[0]; endmodule : source // drain module module drain #( // random generator parameters parameter int unsigned RW=1, // LFSR width parameter bit [RW-1:0] RP='0, // LFSR polinom parameter bit [RW-1:0] RR='1 // LFSR reset state )( input logic clk, input logic rst, handshake.drn inf, output integer cnt ); // LFSR logic [RW-1:0] rnd; // LFSR in Galois form always @ (posedge clk, posedge rst) if (rst) rnd <= RR; else rnd <= {rnd[0], rnd[RW-1:1]} ^ ({RW{rnd[0]}} & RP); // counter always @ (posedge clk, posedge rst) if (rst) cnt <= 32'd0; else cnt <= cnt + {31'd0, (inf.req & inf.grt)}; // grant signal assign inf.grt = rnd[0]; endmodule : drain verilator-3.874/test_regress/t/t_mem_multi_io2.v0000664000177100017500000000140712473477707021776 0ustar wsnyderwsnyder// This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks module t (/*AUTOARG*/ // Outputs o3, o34, o345, // Inputs i3, i34, i345 ); input [15:0] i3; output wire [15:0] o3; input [15:0] i34 [3:0]; output wire [15:0] o34 [3:0]; input [15:0] i345 [3:0][4:0]; output wire [15:0] o345 [3:0][4:0]; sub sub (.*); endmodule module sub (/*AUTOARG*/ // Outputs o3, o34, o345, // Inputs i3, i34, i345 ); input [15:0] i3; output wire [15:0] o3; input [15:0] i34 [3:0]; output wire [15:0] o34 [3:0]; input [15:0] i345 [3:0][4:0]; output wire [15:0] o345 [3:0][4:0]; assign o3 = i3; assign o34 = i34; assign o345 = i345; endmodule verilator-3.874/test_regress/t/t_pipe_filter.v0000664000177100017500000000065012473477707021536 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. //=========================================================================== // Includes example line 10; example line 11; `include "t_pipe_filter_inc.vh" // Twice to check caching of includes `include "t_pipe_filter_inc.vh" example line 15; example line 16; verilator-3.874/test_regress/t/t_param_sel.v0000664000177100017500000000376612473477707021212 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v // End of automatics Test #(16,2) test (/*AUTOINST*/ // Outputs .out (out[31:0]), // Inputs .clk (clk), .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hf9b3a5000165ed38 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); input clk; input [31:0] in; output [31:0] out; parameter N = 0; parameter PASSDOWN = 1; add #(PASSDOWN) add (.in (in[(2*N)-1:(0*N)]), .out (out)); endmodule module add (/*AUTOARG*/ // Outputs out, // Inputs in ); parameter PASSDOWN = 9999; input [31:0] in; output [31:0] out; wire out = in + PASSDOWN; endmodule verilator-3.874/test_regress/t/t_interface_down.v0000664000177100017500000000261112473477707022222 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Wilson Snyder. interface ifc; integer value; endinterface module t (/*AUTOARG*/ // Inputs clk ); `ifdef INLINE_A //verilator inline_module `else //verilator no_inline_module `endif input clk; integer cyc=1; ifc itop1a(); ifc itop1b(); ifc itop2a(); ifc itop2b(); wrapper c1 (.isuba(itop1a), .isubb(itop1b), .i_valuea(14), .i_valueb(15)); wrapper c2 (.isuba(itop2a), .isubb(itop2b), .i_valuea(24), .i_valueb(25)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==20) begin if (itop1a.value != 14) $stop; if (itop1b.value != 15) $stop; if (itop2a.value != 24) $stop; if (itop2b.value != 25) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module wrapper ( ifc isuba, ifc isubb, input integer i_valuea, input integer i_valueb ); `ifdef INLINE_B //verilator inline_module `else //verilator no_inline_module `endif lower subsuba (.isub(isuba), .i_value(i_valuea)); lower subsubb (.isub(isubb), .i_value(i_valueb)); endmodule module lower ( ifc isub, input integer i_value ); `ifdef INLINE_C //verilator inline_module `else //verilator no_inline_module `endif always @* begin isub.value = i_value; end endmodule verilator-3.874/test_regress/t/t_struct_packed_write_read.pl0000775000177100017500000000071712473477707024451 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_range.v0000664000177100017500000000260312473477707021343 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (clk); input clk; // verilator lint_off WIDTH `define INT_RANGE 31:0 `define INT_RANGE_MAX 31 `define VECTOR_RANGE 63:0 reg [`INT_RANGE] stashb, stasha, stashn, stashm; function [`VECTOR_RANGE] copy_range; input [`VECTOR_RANGE] y; input [`INT_RANGE] b; input [`INT_RANGE] a; input [`VECTOR_RANGE] x; input [`INT_RANGE] n; input [`INT_RANGE] m; begin copy_range = y; stashb = b; stasha = a; stashn = n; stashm = m; end endfunction parameter DATA_SIZE = 16; parameter NUM_OF_REGS = 32; reg [NUM_OF_REGS*DATA_SIZE-1 : 0] memread_rf; reg [DATA_SIZE-1:0] memread_rf_reg; always @(memread_rf) begin : memread_convert memread_rf_reg = copy_range('d0, DATA_SIZE-'d1, DATA_SIZE-'d1, memread_rf, DATA_SIZE-'d1, DATA_SIZE-'d1); end integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin memread_rf = 512'haa; end if (cyc==3) begin if (stashb != 'd15) $stop; if (stasha != 'd15) $stop; if (stashn != 'd15) $stop; if (stashm != 'd15) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_preproc_inc2.vh0000664000177100017500000000040012473477707021762 0ustar wsnyderwsnyder// DESCRIPTION: Verilog::Preproc: Example source code // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2000-2007 by Wilson Snyder. At file `__FILE__ line `__LINE__ `define INCFILE `include `INCFILE verilator-3.874/test_regress/t/t_inst_recurse_bad.pl0000775000177100017500000000106612473477707022722 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2004 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. compile ( fails=>1, expect=> '.*%Error: t/t_inst_recurse_bad.v:\d+: Recursive module .module instantiates itself.: looped %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_typedef_port.pl0000775000177100017500000000071712473477707022115 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_tri.v0000664000177100017500000000103412473477707021040 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/); reg [3:0] a; reg [99:0] x; initial begin a = 4'b010x; if (a[3:2] !== 2'b01) $stop; if (|a !== 1'b1) $stop; if (&a !== 1'b0) $stop; x = 100'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_initial_edge.pl0000775000177100017500000000077712473477707022034 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--x-initial-edge"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_display_noopt.pl0000775000177100017500000000263012473477707022271 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_display.v"); compile ( verilator_flags2 => ["-O0"], ); execute ( check_finished=>1, expect=>quotemeta(dequote( '[0] In top.v: Hi [0] In top.v.sub [0] In top.v.sub.subblock [0] In top.v.sub2 [0] In top.v.sub2.subblock2 [0] Back \ Quote " [0] %X=00c %0X=c %0O=14 %B=000001100 [0] %x=00c %0x=c %0o=14 %b=000001100 [0] %D= 12 %d= 12 %01d=12 %06d=000012 %6d= 12 [0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100 [0] %x=00abc1234567812345678 %0x=abc1234567812345678 %o=012570110642547402215053170 %b=000001010101111000001001000110100010101100111100000010010001101000101011001111000 [0] %t= 0 %03t= 0 %0t=0 [0] %s=! %s= what! %s= hmmm!1234 [0] hello, from a very long string. Percent %s are literally substituted in. [0] Embedded <#013> return [0] Embedded multiline *-* All Finished *-* ')), ); ok(1); # Don't put control chars into our source repository, pre-compress instead sub dequote { my $s = shift; $s =~ s/<#013>/\r/g; $s; } 1; verilator-3.874/test_regress/t/t_mem_multi_io2_cc.pl0000775000177100017500000000127312525171734022602 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_mem_multi_io2.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io2.cpp -Oi"], verilator_flags3 => [], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vlt_warn.v0000664000177100017500000000122412473477707021066 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. // Try inline config `ifdef verilator `verilator_config lint_off -msg CASEX -file "t/t_vlt_warn.v" `verilog `endif module t; reg width_warn_var_line18 = 2'b11; // Width warning - must be line 18 reg width_warn2_var_line19 = 2'b11; // Width warning - must be line 19 reg width_warn3_var_line20 = 2'b11; // Width warning - must be line 20 initial begin casex (1'b1) 1'b0: $stop; endcase $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_lint_restore_bad.pl0000775000177100017500000000133712473477707022727 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{.*%Warning-WIDTH: t/t_lint_restore_bad.v:\d+: Operator ASSIGN expects 5 bits on the Assign RHS, but Assign RHS's CONST '64'h1' generates 64 bits. %Warning-WIDTH: Use .* %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_implicit_bad.pl0000775000177100017500000000204412473477707023052 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. top_filename("t/t_lint_implicit.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only -Wwarn-IMPLICIT"], fails=>1, expect=> '%Warning-IMPLICIT: t/t_lint_implicit.v:\d+: Signal definition not found, creating implicitly: b %Warning-IMPLICIT: Use .* to disable this message. %Warning-IMPLICIT: t/t_lint_implicit.v:\d+: Signal definition not found, creating implicitly: nt0 %Warning-IMPLICIT: t/t_lint_implicit.v:\d+: Signal definition not found, creating implicitly: dummy1 %Warning-IMPLICIT: t/t_lint_implicit.v:\d+: Signal definition not found, creating implicitly: dummy2 %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_for0.v0000664000177100017500000000146512473477707020740 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; Testit testit (/*AUTOINST*/ // Inputs .clk (clk)); always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==0) begin end else if (cyc<10) begin end else if (cyc<90) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module Testit (clk); input clk; genvar igen; generate for (igen=0; igen<0; igen=igen+1) begin : test_gen always @ (posedge clk) begin $display("igen1 = %d", igen); $stop; end end endgenerate endmodule verilator-3.874/test_regress/t/t_debug_fatalsrc_bad.pl0000775000177100017500000000132512473477707023160 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( verilator_flags2 => ["--debug-fatalsrc"], fails=>$Self->{v3}, expect=> '%Error: Internal Error: .*: --debug-fatal-src %Error: Internal Error: See the manual and http://www.veripool.org/verilator for more assistance. %Error: Command Failed.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_array.v0000664000177100017500000000370212473477707021600 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[31:0]), // Inputs .clk (clk), .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h458c2de282e30f8b if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); input clk; input [31:0] in; output wire [31:0] out; reg [31:0] stage [3:0]; genvar g; generate for (g=0; g<4; g++) begin always_comb begin if (g==0) stage[g] = in; else stage[g] = {stage[g-1][30:0],1'b1}; end end endgenerate assign out = stage[3]; endmodule verilator-3.874/test_regress/t/t_lint_once_bad.v0000664000177100017500000000072712473477707022021 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. // Check that we report warnings only once on parameterized modules // Also check that we don't suppress warnings on the same line module t (); sub #(.A(1)) sub1(); sub #(.A(2)) sub2(); sub #(.A(3)) sub3(); endmodule module sub; parameter A = 0; reg [A:0] unus1; reg [A:0] unus2; endmodule verilator-3.874/test_regress/t/t_inst_prepost.v0000664000177100017500000000102312473477707021760 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t; sub #(10,11,12,13) sub (); endmodule module sub (); parameter A = 0; parameter B = 1; ip ip(); parameter C = 2; parameter D = 3; initial begin if (A!=10) $stop; if (B!=11) $stop; if (C!=12) $stop; if (D!=13) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module ip; endmodule verilator-3.874/test_regress/t/t_var_types_bad.pl0000775000177100017500000000227212473477707022231 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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->{verilated_randReset} = 1; # allow checking if we initialize vars to zero only when needed compile ( fails=>1, expect=> '%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is bit .*%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is logic .*%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is logic .*%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is real .*%Error: t/t_var_types_bad.v:\d+: Illegal bit or array select; type does not have a bit range, or bad dimension: type is real .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_case_auto1.pl0000775000177100017500000000071712473477707021435 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_latch_edgestyle.pl0000775000177100017500000000120212473477707023370 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_clk_latch.v"); my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/); compile ( v_flags2 => ['+define+EDGE_DETECT_STYLE'], fails => $fail, ); execute ( check_finished => !$fail, ) if !$fail; ok(1); 1; verilator-3.874/test_regress/t/t_math_cond_huge.pl0000775000177100017500000000071712473477707022355 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_latch.pl0000775000177100017500000000105112473477707021325 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/); compile ( ); execute ( check_finished => !$fail, fails => $fail, ); ok(1); 1; verilator-3.874/test_regress/t/t_display_wide.v0000664000177100017500000000561212473477707021714 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [4095:0] crc; // Test loop always @ (posedge clk) begin cyc <= cyc + 1; crc <= {crc[4094:0], crc[63]^crc[2]^crc[0]}; // not a good crc :) if (cyc==0) begin // Setup crc <= 4096'h9f51804b5275c7b6ab9907144a58649bb778f9718062fa5c336fcc9edcad7cf17aad0a656244017bb21d9f97f7c0c147b6fa7488bb9d5bb8d3635b20fba1deab597121c502b21f49b18da998852d29a6b2b649315a3323a31e7e5f41e9bbb7e44046467438f37694857b963250bdb137a922cfce2af1defd1f93db5aa167f316d751bb274bda96fdee5e2c6eb21886633246b165341f0594c27697b06b62b1ad05ebe3c08909a54272de651296dcdd3d1774fc432d22210d8f6afa50b02cf23336f8cc3a0a2ebfd1a3a60366a1b66ef346e0379116d68caa01279ac2772d1f3cd76d2cbbc68ada6f83ec2441b2679b405486df8aa734ea1729b40c3f82210e8e42823eb3fd6ca77ee19f285741c4e8bac1ab7855c3138e84b6da1d897bbe37faf2d0256ad2f7ff9e704a63d824c1e97bddce990cae1578f9537ae2328d0afd69ffb317cbcf859696736e45e5c628b44727557c535a7d02c07907f2dccd6a21ca9ae9e1dbb1a135a8ebc2e0aa8c7329b898d02896273defe21beaa348e11165b71c48cf1c09714942a5a2ddc2adcb6e42c0f630117ee21205677d5128e8efc18c9a6f82a8475541fd722cca2dd829b7e78fef89dbeab63ab7b849910eb4fe675656c4b42b9452c81a4ca6296190a81dc63e6adfaa31995d7dfe3438ee9df66488d6cf569380569ffe6e5ea313d23af6ff08d979af29374ee9aff1fa143df238a1; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x%x%x%x\n",$time, cyc, crc[4095:3072], crc[2071:2048], crc[2047:1024], crc[1023:0]); $write("[%0t] cyc==%0d crc=%b%b%b%b\n",$time, cyc, crc[4095:3072], crc[2071:2048], crc[2047:1024], crc[1023:0]); //Unsupported: $write("[%0t] cyc==%0d crc=%x\n",$time, cyc, crc); if (crc != 4096'h2961926edde3e5c6018be970cdbf327b72b5f3c5eab42995891005eec8767e5fdf03051edbe9d222ee756ee34d8d6c83ee877aad65c487140ac87d26c636a66214b4a69acad924c568cc8e8c79f97d07a6eedf91011919d0e3cdda5215ee58c942f6c4dea48b3f38abc77bf47e4f6d6a859fcc5b5d46ec9d2f6a5bf7b978b1bac862198cc91ac594d07c165309da5ec1ad8ac6b417af8f0224269509cb79944a5b7374f45dd3f10cb48884363dabe942c0b3c8ccdbe330e828baff468e980d9a86d9bbcd1b80de445b5a32a8049e6b09dcb47cf35db4b2ef1a2b69be0fb09106c99e6d01521b7e2a9cd3a85ca6d030fe08843a390a08facff5b29dfb867ca15d0713a2eb06ade1570c4e3a12db687625eef8dfebcb4095ab4bdffe79c1298f609307a5ef773a6432b855e3e54deb88ca342bf5a7fecc5f2f3e165a59cdb9179718a2d11c9d55f14d69f40b01e41fcb7335a8872a6ba7876ec684d6a3af0b82aa31cca6e26340a2589cf7bf886faa8d23844596dc71233c7025c5250a968b770ab72db90b03d8c045fb8848159df544a3a3bf063269be0aa11d5507f5c8b328b760a6df9e3fbe276faad8eadee126443ad3f99d595b12d0ae514b20693298a58642a07718f9ab7ea8c66575f7f8d0e3ba77d992235b3d5a4e015a7ff9b97a8c4f48ebdbfc2365e6bca4dd3ba6bfc7e850f7c8e2842c717a1d85a977a033f564fc ) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_case_write2.out0000664000177100017500000001155712473477707022015 0ustar wsnyderwsnyder[2] crc=0000000000000097 1009 1410 [3] crc=000000000000012e 1009 1410 [4] crc=000000000000025d 1009 1410 [5] crc=00000000000004ba 1009 1410 [6] crc=0000000000000974 1009 1410 [7] crc=00000000000012e9 1009 1410 [8] crc=00000000000025d3 1009 1410 [9] crc=0000000000004ba7 1009 1410 [10] crc=000000000000974e 1009 1410 [11] crc=0000000000012e9d 1009 1410 [12] crc=0000000000025d3a 1009 1410 [13] crc=000000000004ba74 1009 1410 [14] crc=00000000000974e9 1009 1410 [15] crc=000000000012e9d3 1009 1410 [16] crc=000000000025d3a7 1009 1410 [17] crc=00000000004ba74e 1009 1410 [18] crc=0000000000974e9d 1009 1410 [19] crc=00000000012e9d3a 1009 1410 [20] crc=00000000025d3a74 1009 1410 [21] crc=0000000004ba74e9 1009 1410 [22] crc=000000000974e9d3 1009 23 1303 138 dude 1304 [23] crc=0000000012e9d3a7 1009 46 1309 1311 143 1312 dude 1313 [24] crc=0000000025d3a74e 1009 172 407 175 408 409 410 1106 dude 1129 [25] crc=000000004ba74e9d 1009 223 1014 880 885 1015 1016:0 1007 dude 1017 [26] crc=00000000974e9d3a 1009 1229 967 1230 718 dude 1231 [27] crc=000000012e9d3a74 1009 1410 [28] crc=000000025d3a74e9 1009 58 1369 19 dude 1370 [29] crc=00000004ba74e9d3 1009 194 1033 1034 1008 1035 880 dude 1036 [30] crc=0000000974e9d3a7 1009 1409:69 [31] crc=00000012e9d3a74e 1009 29 1320 137 144 141 138 148 dude 1321 [32] crc=00000025d3a74e9d 1009 1383:3a7 [33] crc=0000004ba74e9d3a 1009 216 1018 882 884 1019 1020 1007 dude 1021 [34] crc=000000974e9d3a74 1009 197 1014 882 883 1015 1016:1 1008 dude 1017 [35] crc=0000012e9d3a74e9 1009 1228 979 1230 713 dude 1231 [36] crc=0000025d3a74e9d3 1009 194 1011 1006 1008 1012 880 dude 1013 [37] crc=000004ba74e9d3a7 1009 1409:69 [38] crc=00000974e9d3a74e 1009 29 1320 137 144 141 138 148 dude 1321 [39] crc=000012e9d3a74e9d 1009 1383:3a7 [40] crc=000025d3a74e9d3a 1009 216 1018 882 884 1019 1020 1007 dude 1021 [41] crc=00004ba74e9d3a74 1009 197 1014 882 883 1015 1016:1 1008 dude 1017 [42] crc=0000974e9d3a74e9 1009 1228 979 1230 713 dude 1231 [43] crc=00012e9d3a74e9d3 1009 194 1011 1006 1008 1012 880 dude 1013 [44] crc=00025d3a74e9d3a7 1009 1409:69 [45] crc=0004ba74e9d3a74e 1009 29 1320 137 144 141 138 148 dude 1321 [46] crc=000974e9d3a74e9d 1009 1383:3a7 [47] crc=0012e9d3a74e9d3a 1009 216 1018 882 884 1019 1020 1007 dude 1021 [48] crc=0025d3a74e9d3a74 1009 197 1014 882 883 1015 1016:1 1008 dude 1017 [49] crc=004ba74e9d3a74e9 1009 1228 979 1230 713 dude 1231 [50] crc=00974e9d3a74e9d3 1009 194 1011 1006 1008 1012 880 dude 1013 [51] crc=012e9d3a74e9d3a7 1009 1409:69 [52] crc=025d3a74e9d3a74e 1009 29 1320 137 144 141 138 148 dude 1321 [53] crc=04ba74e9d3a74e9d 1009 1383:3a7 [54] crc=0974e9d3a74e9d3a 1009 216 1018 882 884 1019 1020 1007 dude 1021 [55] crc=12e9d3a74e9d3a74 1009 197 1014 882 883 1015 1016:1 1008 dude 1017 [56] crc=25d3a74e9d3a74e9 1009 1228 979 1230 713 dude 1231 [57] crc=4ba74e9d3a74e9d3 1009 194 1011 1006 1008 1012 880 dude 1013 [58] crc=974e9d3a74e9d3a7 1009 1409:69 [59] crc=2e9d3a74e9d3a74f 1009 29 1320 137 144 141 138 149 dude 1321 [60] crc=5d3a74e9d3a74e9e 1009 1383:3a7 [61] crc=ba74e9d3a74e9d3d 1009 216 1018 882 884 1019 1020 1007 dude 1021 [62] crc=74e9d3a74e9d3a7b 1009 197 1014 882 883 1015 1016:1 1008 dude 1017 [63] crc=e9d3a74e9d3a74f7 1009 1228 979 1230 713 dude 1231 [64] crc=d3a74e9d3a74e9ef 1009 194 1011 1006 1008 1012 880 dude 1013 [65] crc=a74e9d3a74e9d3df 1009 1409:69 [66] crc=4e9d3a74e9d3a7bf 1009 29 1320 137 144 141 145 149 dude 1321 [67] crc=9d3a74e9d3a74f7e 1009 1383:3a7 [68] crc=3a74e9d3a74e9efc 1009 216 1018 882 884 1019 1020 1007 dude 1021 [69] crc=74e9d3a74e9d3df9 1009 197 1014 882 883 1015 1016:1 1008 dude 1017 [70] crc=e9d3a74e9d3a7bf3 1009 1228 979 1230 713 dude 1231 [71] crc=d3a74e9d3a74f7e6 1009 194 1011 1006 1008 1012 880 dude 1013 [72] crc=a74e9d3a74e9efcc 1009 1409:69 [73] crc=4e9d3a74e9d3df98 1009 29 1320 137 147 149 143 142 dude 1321 [74] crc=9d3a74e9d3a7bf30 1009 1383:3a7 [75] crc=3a74e9d3a74f7e61 1009 216 1018 882 885 1019 1020 1007 dude 1021 [76] crc=74e9d3a74e9efcc3 1009 197 1014 882 884 1015 1016:1 1008 dude 1017 [77] crc=e9d3a74e9d3df987 1009 1228 982 1230 713 dude 1231 [78] crc=d3a74e9d3a7bf30f 1009 194 1011 1006 1008 1012 881 885 dude 1013 [79] crc=a74e9d3a74f7e61f 1009 1409:77 [80] crc=4e9d3a74e9efcc3f 1009 30 1320 149 146 146 137 149 dude 1321 [81] crc=9d3a74e9d3df987e 1009 1383:3df [82] crc=3a74e9d3a7bf30fc 1009 225 1018 882 885 1019 1020 1008 dude 1021 [83] crc=74e9d3a74f7e61f9 1009 218 1014 882 884 1015 1016:1 1008 dude 1017 [84] crc=e9d3a74e9efcc3f3 1009 1228 981 1230 708 dude 1231 [85] crc=d3a74e9d3df987e6 1009 232 1011 1005 1008 1012 881 883 dude 1013 [86] crc=a74e9d3a7bf30fcc 1009 1409:73 [87] crc=4e9d3a74f7e61f98 1009 1006 1258 846 1259 1006 1260 833 1261 dude 1262 [88] crc=9d3a74e9efcc3f30 1009 124 1320 146 137 149 137 134 dude 1321 [89] crc=3a74e9d3df987e61 1009 1383:f98 [90] crc=74e9d3a7bf30fcc3 1009 215 1033 1034 1008 1035 879 dude 1036 verilator-3.874/test_regress/t/t_lint_ifdepth_bad.v0000664000177100017500000000202712473477707022513 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t; integer v = 19; initial begin if (v==1) begin end else if (v==2) begin end else if (v==3) begin end else if (v==4) begin end else if (v==5) begin end else if (v==6) begin end else if (v==7) begin end else if (v==8) begin end else if (v==9) begin end else if (v==10) begin end else if (v==11) begin end // Warn about this one else if (v==12) begin end end initial begin unique0 if (v==1) begin end else if (v==2) begin end else if (v==3) begin end else if (v==4) begin end else if (v==5) begin end else if (v==6) begin end else if (v==7) begin end else if (v==8) begin end else if (v==9) begin end else if (v==10) begin end else if (v==11) begin end // Warn about this one else if (v==12) begin end end endmodule verilator-3.874/test_regress/t/t_param_no_parentheses.pl0000775000177100017500000000071712473477707023606 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_ddeep_width.v0000664000177100017500000000116312473477707022674 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use. // bug541 module t(clk,odata); input clk; output [7:0] odata; paramtest_DFFRE #(1) dffre0(clk,odata[7]); paramtest_WRAP #(7) dffe0(clk,odata[6:0]); endmodule module paramtest_WRAP(clk,q); parameter W=1; input clk; output [W-1:0] q; paramtest_DFFRE #(W) dffre0(clk,q); endmodule module paramtest_DFFRE(clk,q); parameter W=1; parameter [W-1:0] INIT={W{1'b0}}; input clk; output [W-1:0] q; reg [W-1:0] q; always @(posedge clk) begin q <= INIT; end endmodule verilator-3.874/test_regress/t/t_case_nest.v0000664000177100017500000000713312473477707021203 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; reg [63:0] sum; reg out1; sub sub (.in(crc[23:0]), .out1(out1)); always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x sum=%x out=%x\n",$time, cyc, crc, sum, out1); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= {sum[62:0], sum[63]^sum[2]^sum[0]} ^ {63'h0,out1}; if (cyc==1) begin // Setup crc <= 64'h00000000_00000097; sum <= 64'h0; end else if (cyc==90) begin if (sum !== 64'h2e5cb972eb02b8a0) $stop; end else if (cyc==91) begin end else if (cyc==92) begin end else if (cyc==93) begin end else if (cyc==94) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module sub (/*AUTOARG*/ // Outputs out1, // Inputs in ); input [23:0] in; output reg [0:0] out1; // Note this tests a vector of 1 bit, which is different from a non-arrayed signal parameter [1023:0] RANDOM = 1024'b101011010100011011100111101001000000101000001111111111100110000110011011010110011101000100110000110101111101000111100100010111001001110001010101000111000100010000010011100001100011110110110000101100011111000110111110010110011000011111111010101110001101010010001111110111100000110111101100110101110001110110000010000110101110111001111001100001101110001011100111001001110101001010000110101010100101111000010000010110100101110100110000110110101000100011101111100011000110011001100010010011001101100100101110010100110101001110011111110010000111001111000010001101100101101110111110001000010110010011100101001011111110011010110111110000110010011110001110110011010011010110011011111001110100010110100011100001011000101111000010011111010111001110110011101110101011111001100011000101000001000100111110010100111011101010101011001101000100000101111110010011010011010001111010001110000110010100011110110011001010000011001010010110111101010010011111111010001000101100010100100010011001100110000111111000001000000001001111101110000100101; always @* begin casez (in[17:16]) 2'b00: casez (in[2:0]) 3'h0: out1[0] = in[0]^RANDOM[0]; 3'h1: out1[0] = in[0]^RANDOM[1]; 3'h2: out1[0] = in[0]^RANDOM[2]; 3'h3: out1[0] = in[0]^RANDOM[3]; 3'h4: out1[0] = in[0]^RANDOM[4]; 3'h5: out1[0] = in[0]^RANDOM[5]; 3'h6: out1[0] = in[0]^RANDOM[6]; 3'h7: out1[0] = in[0]^RANDOM[7]; endcase 2'b01: casez (in[2:0]) 3'h0: out1[0] = RANDOM[10]; 3'h1: out1[0] = RANDOM[11]; 3'h2: out1[0] = RANDOM[12]; 3'h3: out1[0] = RANDOM[13]; 3'h4: out1[0] = RANDOM[14]; 3'h5: out1[0] = RANDOM[15]; 3'h6: out1[0] = RANDOM[16]; 3'h7: out1[0] = RANDOM[17]; endcase 2'b1?: casez (in[4]) 1'b1: casez (in[2:0]) 3'h0: out1[0] = RANDOM[20]; 3'h1: out1[0] = RANDOM[21]; 3'h2: out1[0] = RANDOM[22]; 3'h3: out1[0] = RANDOM[23]; 3'h4: out1[0] = RANDOM[24]; 3'h5: out1[0] = RANDOM[25]; 3'h6: out1[0] = RANDOM[26]; 3'h7: out1[0] = RANDOM[27]; endcase 1'b0: casez (in[2:0]) 3'h0: out1[0] = RANDOM[30]; 3'h1: out1[0] = RANDOM[31]; 3'h2: out1[0] = RANDOM[32]; 3'h3: out1[0] = RANDOM[33]; 3'h4: out1[0] = RANDOM[34]; 3'h5: out1[0] = RANDOM[35]; 3'h6: out1[0] = RANDOM[36]; 3'h7: out1[0] = RANDOM[37]; endcase endcase endcase end endmodule verilator-3.874/test_regress/t/t_hierarchy_identifier.pl0000775000177100017500000000071712473477707023571 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/.gitattributes0000664000177100017500000000002012473477707021404 0ustar wsnyderwsnydert_dos*.pl -crlf verilator-3.874/test_regress/t/t_flag_future.pl0000775000177100017500000000110012473477707021677 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => [qw(--lint-only -Wfuture-FUTURE1 -Wfuture-FUTURE2)], verilator_make_gcc => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_slice_bad.v0000664000177100017500000000311212473477707021773 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; logic use_AnB; logic [1:0] active_command [8:0]; logic [1:0] command_A [8:0]; logic [1:0] command_B [8:0]; logic [1:0] active_command2 [8:0]; logic [1:0] command_A2 [7:0]; logic [1:0] command_B2 [8:0]; logic [1:0] active_command3 [1:0][2:0][3:0]; logic [1:0] command_A3 [1:0][2:0][3:0]; logic [1:0] command_B3 [1:0][2:0][3:0]; logic [1:0] active_command4 [8:0]; logic [1:0] command_A4 [7:0]; logic [1:0] active_command5 [8:0]; logic [1:0] command_A5 [7:0]; // Single dimension assign assign active_command[3:0] = (use_AnB) ? command_A[7:0] : command_B[7:0]; // Assignment of entire arrays assign active_command2 = (use_AnB) ? command_A2 : command_B2; // Multi-dimension assign assign active_command3[1:0][2:0][3:0] = (use_AnB) ? command_A3[1:0][2:0][3:0] : command_B3[1:0][1:0][3:0]; // Supported: Delayed assigment with RHS Var == LHS Var logic [7:0] arrd [7:0]; always_ff @(posedge clk) arrd[7:4] <= arrd[3:0]; // Unsupported: Non-delayed assigment with RHS Var == LHS Var logic [7:0] arr [7:0]; assign arr[7:4] = arr[3:0]; // Delayed assign always @(posedge clk) begin active_command4[7:0] <= command_A4[8:0]; end // Combinational assign always_comb begin active_command5[8:0] = command_A5[7:0]; end endmodule : t verilator-3.874/test_regress/t/t_func_types.v0000664000177100017500000000401412473477707021411 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t; function int int123(); int123 = 32'h123; endfunction function bit f_bit ; input bit i; f_bit = ~i; endfunction function int f_int ; input int i; f_int = ~i; endfunction function byte f_byte ; input byte i; f_byte = ~i; endfunction function shortint f_shortint; input shortint i; f_shortint = ~i; endfunction function longint f_longint ; input longint i; f_longint = ~i; endfunction function chandle f_chandle ; input chandle i; f_chandle = i; endfunction // Note there's no "input" here vvvv, it's the default function bit g_bit (bit i); g_bit = ~i; endfunction function int g_int (int i); g_int = ~i; endfunction function byte g_byte (byte i); g_byte = ~i; endfunction function shortint g_shortint(shortint i); g_shortint = ~i; endfunction function longint g_longint (longint i); g_longint = ~i; endfunction function chandle g_chandle (chandle i); g_chandle = i; endfunction chandle c; initial begin if (int123() !== 32'h123) $stop; if (f_bit(1'h1) !== 1'h0) $stop; if (f_bit(1'h0) !== 1'h1) $stop; if (f_int(32'h1) !== 32'hfffffffe) $stop; if (f_byte(8'h1) !== 8'hfe) $stop; if (f_shortint(16'h1) !== 16'hfffe) $stop; if (f_longint(64'h1) !== 64'hfffffffffffffffe) $stop; if (f_chandle(c) !== c) $stop; if (g_bit(1'h1) !== 1'h0) $stop; if (g_bit(1'h0) !== 1'h1) $stop; if (g_int(32'h1) !== 32'hfffffffe) $stop; if (g_byte(8'h1) !== 8'hfe) $stop; if (g_shortint(16'h1) !== 16'hfffe) $stop; if (g_longint(64'h1) !== 64'hfffffffffffffffe) $stop; if (g_chandle(c) !== c) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_mem_slice_conc_bad.pl0000775000177100017500000000101112473477707023142 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_detectarray_3.pl0000775000177100017500000000101012473477707022125 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["-Wno-UNOPTFLAT -Wno-WIDTH"] ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_for1.pl0000775000177100017500000000071712473477707021111 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_setout_bad.pl0000775000177100017500000000131212473477707022560 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Error: t/t_lint_setout_bad.v:\d+: Output port is connected to a constant pin, electrical short .*', ); ok(1); 1; verilator-3.874/test_regress/t/t_select_bad_tri.pl0000775000177100017500000000117012473477707022346 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> q{%Error: t/t_select_bad_tri.v:\d+: Selection index is constantly unknown or tristated: lsb=7'bxxxxxxx width=32'sh47 %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_intdot2.pl0000775000177100017500000000071712473477707021625 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_dtree_inlbd.pl0000775000177100017500000000112012473477707022706 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_dtree.v"); compile ( v_flags2 => ['+define+INLINE_B +define+INLINE_D'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_preproc_kwd.pl0000775000177100017500000000071712473477707021730 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_pp_pragmas.pl0000775000177100017500000000071712473477707021542 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_tri_pullup.cpp0000664000177100017500000000240412473477707021747 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Lane Brooks #include "Vt_tri_pullup.h" Vt_tri_pullup *tb = NULL; double sc_time_stamp() { return 0; } bool check() { bool pass; int Z, Y, X; if (tb->OE) { Z = tb->A; Y = tb->A; X = tb->A; } else { Z = 1; Y = 0; X = 1; } #ifdef TEST_VERBOSE bool verbose = true; #else bool verbose = false; #endif if (tb->Z == Z && tb->Y == Y && tb->X == X) { if (verbose) printf("PASS: "); pass = true; } else { printf("%%E-FAIL: "); verbose = true; pass = false; } if (verbose) printf("OE=%d A=%d X=%d xexp=%d Y=%d yexp=%d Z=%d zexp=%d\n", tb->OE, tb->A, tb->X,X, tb->Y,Y, tb->Z,Z); return pass; } int main() { bool pass = true; Verilated::debug(0); tb = new Vt_tri_pullup("tb"); // loop through every possibility and check the result for (tb->OE=0; tb->OE<2; tb->OE++) { for (tb->A=0; tb->A<2; tb->A++) { tb->eval(); if (!check()) { pass = false; } } } if (pass) { VL_PRINTF("*-* All Finished *-*\n"); tb->final(); } else { vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from pullup test\n"); } return 0; } verilator-3.874/test_regress/t/t_var_rsvd_bad.pl0000775000177100017500000000130212473477707022034 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_var_rsvd_port.v"); compile ( fails=>$Self->{v3}, expect=> q{%Warning-SYMRSVDWORD: t/t_var_rsvd_port.v:\d+: Symbol matches C\+\+ common word: 'bool' .* %Warning-SYMRSVDWORD: t/t_var_rsvd_port.v:\d+: Symbol matches C\+\+ reserved word: 'switch' %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_upscope.pl0000775000177100017500000000156612473477707021723 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, expect=>quotemeta( q{created tag with scope = top.v.b.gen[0].tag created tag with scope = top.v.b.gen[1].tag created tag with scope = top.v.tag mod a has scope = top.v mod a has tag = top.v.tag mod b has scope = top.v.b mod b has tag = top.v.tag mod c has scope = top.v.b.gen[0].c mod c has tag = top.v.b.gen[0].tag mod c has scope = top.v.b.gen[1].c mod c has tag = top.v.b.gen[1].tag *-* All Finished *-*}), ); ok(1); 1; verilator-3.874/test_regress/t/t_param_sel_range.pl0000775000177100017500000000114512473477707022524 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( v_flags2 => ["--lint-only -Wno-SELRANGE"], fails=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_gen4.pl0000775000177100017500000000072712525171734022254 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dist_cinclude.pl0000775000177100017500000000332212473477707022215 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. use IO::File; my $root = ".."; my $Debug; if (!-r "$root/.git") { $Self->skip("Not in a git repository"); } else { ### Must trim output before and after our file list my $files = `cd $root && git ls-files --exclude-standard`; print "ST $files\n" if $Debug; $files =~ s/\s+/ /g; my $cmd = "cd $root && fgrep -n include $files | sort"; my $grep = `$cmd`; foreach my $line (split /\n/, $grep) { next if $line =~ /vpi_user.h/; # IEEE Standard file - can't change it my $hit; $hit = 1 if $line =~ /\bassert\.h/; $hit = 1 if $line =~ /\bctype\.h/; $hit = 1 if $line =~ /\berrno\.h/; $hit = 1 if $line =~ /\bfloat\.h/; $hit = 1 if $line =~ /\blimits\.h/; $hit = 1 if $line =~ /\blocale\.h/; $hit = 1 if $line =~ /\bmath\.h/; $hit = 1 if $line =~ /\bsetjmp\.h/; $hit = 1 if $line =~ /\bsignal\.h/; $hit = 1 if $line =~ /\bstdarg\.h/; $hit = 1 if $line =~ /\bstdbool\.h/; $hit = 1 if $line =~ /\bstddef\.h/; #Not yet: $hit = 1 if $line =~ /\bstdint\.h/; $hit = 1 if $line =~ /\bstdio\.h/; $hit = 1 if $line =~ /\bstdlib\.h/; $hit = 1 if $line =~ /\bstring\.h/; $hit = 1 if $line =~ /\btime\.h/; next if !$hit; print "$line\n"; $names{$1} = 1 if $line =~ /^([^:]+)/; } if (keys %names) { $Self->error("Files like stdint.h instead of cstdint: ",join(' ',sort keys %names)); } } ok(1); 1; verilator-3.874/test_regress/t/t_inst_mnpipe.v0000664000177100017500000000266712473477707021573 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [7:0] crc; reg [2:0] sum; wire [2:0] in = crc[2:0]; wire [2:0] out; MxN_pipeline pipe (in, out, clk); always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%b sum=%x\n",$time, cyc, crc, sum); cyc <= cyc + 1; crc <= {crc[6:0], ~^ {crc[7],crc[5],crc[4],crc[3]}}; if (cyc==0) begin // Setup crc <= 8'hed; sum <= 3'h0; end else if (cyc>10 && cyc<90) begin sum <= {sum[1:0],sum[2]} ^ out; end else if (cyc==99) begin if (crc !== 8'b01110000) $stop; if (sum !== 3'h3) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module dffn (q,d,clk); parameter BITS = 1; input [BITS-1:0] d; output reg [BITS-1:0] q; input clk; always @ (posedge clk) begin q <= d; end endmodule module MxN_pipeline (in, out, clk); parameter M=3, N=4; input [M-1:0] in; output [M-1:0] out; input clk; // Unsupported: Per-bit array instantiations with output connections to non-wires. //wire [M*(N-1):1] t; //dffn #(M) p[N:1] ({out,t},{t,in},clk); wire [M*(N-1):1] w; wire [M*N:1] q; dffn #(M) p[N:1] (q,{w,in},clk); assign {out,w} = q; endmodule verilator-3.874/test_regress/t/t_trace_cat.pl0000775000177100017500000000142612473477707021334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2013 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"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_cat.cpp"], ); execute ( check_finished=>1, ); system("cat $Self->{obj_dir}/simpart*.vcd > $Self->{obj_dir}/simall.vcd"); vcd_identical ("$Self->{obj_dir}/simall.vcd", "t/$Self->{name}.out"); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_combo.v0000664000177100017500000000547512473477707021572 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; reg [63:0] sum; `ifdef ALLOW_UNOPT /*verilator lint_off UNOPTFLAT*/ `endif /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] b; // From file of file.v wire [31:0] c; // From file of file.v wire [31:0] d; // From file of file.v // End of automatics file file (/*AUTOINST*/ // Outputs .b (b[31:0]), .c (c[31:0]), .d (d[31:0]), // Inputs .crc (crc[31:0])); always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc=%0d crc=%x sum=%x b=%x d=%x\n",$time,cyc,crc,sum, b, d); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= {b, d} ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $write("[%0t] cyc==%0d crc=%x %x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== 64'h649ee1713d624dd9) $stop; $finish; end end endmodule module file (/*AUTOARG*/ // Outputs b, c, d, // Inputs crc ); input [31:0] crc; `ifdef ISOLATE output reg [31:0] b /* verilator isolate_assignments*/; `else output reg [31:0] b; `endif output reg [31:0] c; output reg [31:0] d; always @* begin // Note that while c and b depend on crc, b doesn't depend on c. casez (crc[3:0]) 4'b??01: begin b = {crc[15:0],get_31_16(crc)}; d = c; end 4'b??00: begin b = {crc[15:0],~crc[31:16]}; d = {crc[15:0],~c[31:16]}; end default: begin set_b_d(crc, c); end endcase end function [31:16] get_31_16 /* verilator isolate_assignments*/; input [31:0] t_crc /* verilator isolate_assignments*/; get_31_16 = t_crc[31:16]; endfunction task set_b_d; `ifdef ISOLATE input [31:0] t_crc /* verilator isolate_assignments*/; input [31:0] t_c /* verilator isolate_assignments*/; `else input [31:0] t_crc; input [31:0] t_c; `endif begin b = {t_crc[31:16],~t_crc[23:8]}; d = {t_crc[31:16], ~t_c[23:8]}; end endtask always @* begin // Any complicated equation we can't optimize casez (crc[3:0]) 4'b00??: begin c = {b[29:0],2'b11}; end 4'b01??: begin c = {b[30:1],2'b01}; end 4'b10??: begin c = {b[31:2],2'b10}; end 4'b11??: begin c = {b[31:2],2'b00}; end endcase end endmodule verilator-3.874/test_regress/t/t_flag_future.v0000664000177100017500000000036712473477707021544 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module module t; initial begin // verilator lint_off FUTURE1 $write("*-* All Finished *-*\n"); $finish; // verilator FUTURE2 // verilator FUTURE2 blah blah end endmodule verilator-3.874/test_regress/t/t_vams_basic.v0000664000177100017500000000177012473477707021347 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. `begin_keywords "VAMS-2.3" module t (/*AUTOARG*/ // Inputs clk ); input clk; task check (integer line, real got, real expec); real delta; delta = got-expec; if (delta > 0.001) begin $display("Line%d: Got %g Exp %g\n", line, got, expec); $stop; end endtask wreal wr; assign wr = 1.1; sub sub (.*); initial begin check(`__LINE__, sqrt(2.0) , 1.414); check(`__LINE__, pow(2.0,2.0) , 4.0); check(`__LINE__, ln(2.0) , 0.693147); check(`__LINE__, log(2.0) , 0.30103); check(`__LINE__, floor(2.5) , 2.0); check(`__LINE__, exp(2.0) , 7.38906); check(`__LINE__, ceil(2.5) , 3.0); $write("*-* All Finished *-*\n"); $finish; end endmodule module sub ( input wreal wr ); initial begin if (wr != 1.1) $stop; end endmodule verilator-3.874/test_regress/t/t_struct_array.v0000664000177100017500000000151512473477707021757 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. package TEST_TYPES; typedef struct packed { logic stuff; } a_struct_t; endpackage // TEST_TYPES module t(clk); input clk; TEST_TYPES::a_struct_t [3:0] a_out; sub sub (.a_out); always @ (posedge clk) begin if (a_out[0] != 1'b0) $stop; if (a_out[1] != 1'b1) $stop; if (a_out[2] != 1'b0) $stop; if (a_out[3] != 1'b1) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module sub(a_out); parameter n = 4; output TEST_TYPES::a_struct_t [n-1:0] a_out; always_comb begin for (int i=0;i 196; my $len = int($pat / (6 + $pat/50)) + 4; $len=20 if $len>20; my ($try, $val, $mask); try: for ($try=0; ; $try++) { next pat if $try>50; $val = 0; for (my $bit=23; $bit>(23-$len); $bit--) { my $b = int(rand()*2); $val |= (1<<$bit) if $b; } $mask = (1<<(23-$len+1))-1; for (my $testval = $val; $testval <= ($val + $mask); $testval ++) { next try if $used[$testval]; } last; } my $bits = ""; my $val2 = 0; for (my $bit=23; $bit>(23-$len); $bit--) { my $b = ($val & (1<<$bit)); $bits .= $b?'1':'0'; } for (my $testval = $val; $testval <= ($val + $mask); $testval++) { $used[$testval]= 1; #printf "U%08x\n", $testval; } if ($try<90) { printf +(" 24'b%s: {next, len, code} = {in[%02d], 5'd%02d, 32'd%03d};\n" ,$bits.("?"x(24-$len)), 31-$len, $len, $pat); $pat++; } } */ always @* begin next = 1'b0; code = 32'd0; len = 5'b11111; casez (in[31:8]) 24'b1010????????????????????: {next, len, code} = {in[27], 5'd04, 32'd000}; 24'b1100????????????????????: {next, len, code} = {in[27], 5'd04, 32'd001}; 24'b0110????????????????????: {next, len, code} = {in[27], 5'd04, 32'd002}; 24'b1001????????????????????: {next, len, code} = {in[27], 5'd04, 32'd003}; 24'b1101????????????????????: {next, len, code} = {in[27], 5'd04, 32'd004}; 24'b0011????????????????????: {next, len, code} = {in[27], 5'd04, 32'd005}; 24'b0001????????????????????: {next, len, code} = {in[27], 5'd04, 32'd006}; 24'b10001???????????????????: {next, len, code} = {in[26], 5'd05, 32'd007}; 24'b01110???????????????????: {next, len, code} = {in[26], 5'd05, 32'd008}; 24'b01000???????????????????: {next, len, code} = {in[26], 5'd05, 32'd009}; 24'b00001???????????????????: {next, len, code} = {in[26], 5'd05, 32'd010}; 24'b11100???????????????????: {next, len, code} = {in[26], 5'd05, 32'd011}; 24'b01011???????????????????: {next, len, code} = {in[26], 5'd05, 32'd012}; 24'b100001??????????????????: {next, len, code} = {in[25], 5'd06, 32'd013}; 24'b111110??????????????????: {next, len, code} = {in[25], 5'd06, 32'd014}; 24'b010010??????????????????: {next, len, code} = {in[25], 5'd06, 32'd015}; 24'b001011??????????????????: {next, len, code} = {in[25], 5'd06, 32'd016}; 24'b101110??????????????????: {next, len, code} = {in[25], 5'd06, 32'd017}; 24'b111011??????????????????: {next, len, code} = {in[25], 5'd06, 32'd018}; 24'b0111101?????????????????: {next, len, code} = {in[24], 5'd07, 32'd020}; 24'b0010100?????????????????: {next, len, code} = {in[24], 5'd07, 32'd021}; 24'b0111111?????????????????: {next, len, code} = {in[24], 5'd07, 32'd022}; 24'b1011010?????????????????: {next, len, code} = {in[24], 5'd07, 32'd023}; 24'b1000000?????????????????: {next, len, code} = {in[24], 5'd07, 32'd024}; 24'b1011111?????????????????: {next, len, code} = {in[24], 5'd07, 32'd025}; 24'b1110100?????????????????: {next, len, code} = {in[24], 5'd07, 32'd026}; 24'b01111100????????????????: {next, len, code} = {in[23], 5'd08, 32'd027}; 24'b00000110????????????????: {next, len, code} = {in[23], 5'd08, 32'd028}; 24'b00000101????????????????: {next, len, code} = {in[23], 5'd08, 32'd029}; 24'b01001100????????????????: {next, len, code} = {in[23], 5'd08, 32'd030}; 24'b10110110????????????????: {next, len, code} = {in[23], 5'd08, 32'd031}; 24'b00100110????????????????: {next, len, code} = {in[23], 5'd08, 32'd032}; 24'b11110010????????????????: {next, len, code} = {in[23], 5'd08, 32'd033}; 24'b010011101???????????????: {next, len, code} = {in[22], 5'd09, 32'd034}; 24'b001000000???????????????: {next, len, code} = {in[22], 5'd09, 32'd035}; 24'b010101111???????????????: {next, len, code} = {in[22], 5'd09, 32'd036}; 24'b010101010???????????????: {next, len, code} = {in[22], 5'd09, 32'd037}; 24'b010011011???????????????: {next, len, code} = {in[22], 5'd09, 32'd038}; 24'b010100011???????????????: {next, len, code} = {in[22], 5'd09, 32'd039}; 24'b010101000???????????????: {next, len, code} = {in[22], 5'd09, 32'd040}; 24'b1111010101??????????????: {next, len, code} = {in[21], 5'd10, 32'd041}; 24'b0010001000??????????????: {next, len, code} = {in[21], 5'd10, 32'd042}; 24'b0101001101??????????????: {next, len, code} = {in[21], 5'd10, 32'd043}; 24'b0010010100??????????????: {next, len, code} = {in[21], 5'd10, 32'd044}; 24'b1011001110??????????????: {next, len, code} = {in[21], 5'd10, 32'd045}; 24'b1111000011??????????????: {next, len, code} = {in[21], 5'd10, 32'd046}; 24'b0101000000??????????????: {next, len, code} = {in[21], 5'd10, 32'd047}; 24'b1111110000??????????????: {next, len, code} = {in[21], 5'd10, 32'd048}; 24'b10110111010?????????????: {next, len, code} = {in[20], 5'd11, 32'd049}; 24'b11110000011?????????????: {next, len, code} = {in[20], 5'd11, 32'd050}; 24'b01001111011?????????????: {next, len, code} = {in[20], 5'd11, 32'd051}; 24'b00101011011?????????????: {next, len, code} = {in[20], 5'd11, 32'd052}; 24'b01010010100?????????????: {next, len, code} = {in[20], 5'd11, 32'd053}; 24'b11110111100?????????????: {next, len, code} = {in[20], 5'd11, 32'd054}; 24'b00100111001?????????????: {next, len, code} = {in[20], 5'd11, 32'd055}; 24'b10110001010?????????????: {next, len, code} = {in[20], 5'd11, 32'd056}; 24'b10000010000?????????????: {next, len, code} = {in[20], 5'd11, 32'd057}; 24'b111111101100????????????: {next, len, code} = {in[19], 5'd12, 32'd058}; 24'b100000111110????????????: {next, len, code} = {in[19], 5'd12, 32'd059}; 24'b100000110010????????????: {next, len, code} = {in[19], 5'd12, 32'd060}; 24'b100000111001????????????: {next, len, code} = {in[19], 5'd12, 32'd061}; 24'b010100101111????????????: {next, len, code} = {in[19], 5'd12, 32'd062}; 24'b001000001100????????????: {next, len, code} = {in[19], 5'd12, 32'd063}; 24'b000001111111????????????: {next, len, code} = {in[19], 5'd12, 32'd064}; 24'b011111010100????????????: {next, len, code} = {in[19], 5'd12, 32'd065}; 24'b1110101111101???????????: {next, len, code} = {in[18], 5'd13, 32'd066}; 24'b0100110101110???????????: {next, len, code} = {in[18], 5'd13, 32'd067}; 24'b1111111011011???????????: {next, len, code} = {in[18], 5'd13, 32'd068}; 24'b0101011011001???????????: {next, len, code} = {in[18], 5'd13, 32'd069}; 24'b0010000101100???????????: {next, len, code} = {in[18], 5'd13, 32'd070}; 24'b1111111101101???????????: {next, len, code} = {in[18], 5'd13, 32'd071}; 24'b1011110010110???????????: {next, len, code} = {in[18], 5'd13, 32'd072}; 24'b0101010111010???????????: {next, len, code} = {in[18], 5'd13, 32'd073}; 24'b1111011010010???????????: {next, len, code} = {in[18], 5'd13, 32'd074}; 24'b01010100100011??????????: {next, len, code} = {in[17], 5'd14, 32'd075}; 24'b10110000110010??????????: {next, len, code} = {in[17], 5'd14, 32'd076}; 24'b10111101001111??????????: {next, len, code} = {in[17], 5'd14, 32'd077}; 24'b10110000010101??????????: {next, len, code} = {in[17], 5'd14, 32'd078}; 24'b00101011001111??????????: {next, len, code} = {in[17], 5'd14, 32'd079}; 24'b00100000101100??????????: {next, len, code} = {in[17], 5'd14, 32'd080}; 24'b11111110010111??????????: {next, len, code} = {in[17], 5'd14, 32'd081}; 24'b10110010100000??????????: {next, len, code} = {in[17], 5'd14, 32'd082}; 24'b11101011101000??????????: {next, len, code} = {in[17], 5'd14, 32'd083}; 24'b01010000011111??????????: {next, len, code} = {in[17], 5'd14, 32'd084}; 24'b101111011001011?????????: {next, len, code} = {in[16], 5'd15, 32'd085}; 24'b101111010001100?????????: {next, len, code} = {in[16], 5'd15, 32'd086}; 24'b100000111100111?????????: {next, len, code} = {in[16], 5'd15, 32'd087}; 24'b001010101011000?????????: {next, len, code} = {in[16], 5'd15, 32'd088}; 24'b111111100100001?????????: {next, len, code} = {in[16], 5'd15, 32'd089}; 24'b001001011000010?????????: {next, len, code} = {in[16], 5'd15, 32'd090}; 24'b011110011001011?????????: {next, len, code} = {in[16], 5'd15, 32'd091}; 24'b111111111111010?????????: {next, len, code} = {in[16], 5'd15, 32'd092}; 24'b101111001010011?????????: {next, len, code} = {in[16], 5'd15, 32'd093}; 24'b100000110000111?????????: {next, len, code} = {in[16], 5'd15, 32'd094}; 24'b0010010000000101????????: {next, len, code} = {in[15], 5'd16, 32'd095}; 24'b0010010010101001????????: {next, len, code} = {in[15], 5'd16, 32'd096}; 24'b1111011010110010????????: {next, len, code} = {in[15], 5'd16, 32'd097}; 24'b0010010001100100????????: {next, len, code} = {in[15], 5'd16, 32'd098}; 24'b0101011101110100????????: {next, len, code} = {in[15], 5'd16, 32'd099}; 24'b0101011010001111????????: {next, len, code} = {in[15], 5'd16, 32'd100}; 24'b0010000110011111????????: {next, len, code} = {in[15], 5'd16, 32'd101}; 24'b0101010010000101????????: {next, len, code} = {in[15], 5'd16, 32'd102}; 24'b1110101011000000????????: {next, len, code} = {in[15], 5'd16, 32'd103}; 24'b1111000000110010????????: {next, len, code} = {in[15], 5'd16, 32'd104}; 24'b0111100010001101????????: {next, len, code} = {in[15], 5'd16, 32'd105}; 24'b00100010110001100???????: {next, len, code} = {in[14], 5'd17, 32'd106}; 24'b00100010101101010???????: {next, len, code} = {in[14], 5'd17, 32'd107}; 24'b11111110111100000???????: {next, len, code} = {in[14], 5'd17, 32'd108}; 24'b00100000111010000???????: {next, len, code} = {in[14], 5'd17, 32'd109}; 24'b00100111011101001???????: {next, len, code} = {in[14], 5'd17, 32'd110}; 24'b11111110111000011???????: {next, len, code} = {in[14], 5'd17, 32'd111}; 24'b11110001101000100???????: {next, len, code} = {in[14], 5'd17, 32'd112}; 24'b11101011101011101???????: {next, len, code} = {in[14], 5'd17, 32'd113}; 24'b01010000100101011???????: {next, len, code} = {in[14], 5'd17, 32'd114}; 24'b00100100110011001???????: {next, len, code} = {in[14], 5'd17, 32'd115}; 24'b01001110010101000???????: {next, len, code} = {in[14], 5'd17, 32'd116}; 24'b010011110101001000??????: {next, len, code} = {in[13], 5'd18, 32'd117}; 24'b111010101110010010??????: {next, len, code} = {in[13], 5'd18, 32'd118}; 24'b001001001001111000??????: {next, len, code} = {in[13], 5'd18, 32'd119}; 24'b101111000110111101??????: {next, len, code} = {in[13], 5'd18, 32'd120}; 24'b101101111010101001??????: {next, len, code} = {in[13], 5'd18, 32'd121}; 24'b111101110010111110??????: {next, len, code} = {in[13], 5'd18, 32'd122}; 24'b010100100011010000??????: {next, len, code} = {in[13], 5'd18, 32'd123}; 24'b001001001111011001??????: {next, len, code} = {in[13], 5'd18, 32'd124}; 24'b010100110010001001??????: {next, len, code} = {in[13], 5'd18, 32'd125}; 24'b111010110000111000??????: {next, len, code} = {in[13], 5'd18, 32'd126}; 24'b111010110011000101??????: {next, len, code} = {in[13], 5'd18, 32'd127}; 24'b010100001000111001??????: {next, len, code} = {in[13], 5'd18, 32'd128}; 24'b1000001011000110100?????: {next, len, code} = {in[12], 5'd19, 32'd129}; 24'b0010010111001110110?????: {next, len, code} = {in[12], 5'd19, 32'd130}; 24'b0101011001000001101?????: {next, len, code} = {in[12], 5'd19, 32'd131}; 24'b0101000010010101011?????: {next, len, code} = {in[12], 5'd19, 32'd132}; 24'b1111011111101001101?????: {next, len, code} = {in[12], 5'd19, 32'd133}; 24'b1011001000101010110?????: {next, len, code} = {in[12], 5'd19, 32'd134}; 24'b1011000001000100001?????: {next, len, code} = {in[12], 5'd19, 32'd135}; 24'b1110101100010011001?????: {next, len, code} = {in[12], 5'd19, 32'd136}; 24'b0010010111010111110?????: {next, len, code} = {in[12], 5'd19, 32'd137}; 24'b0010010001100111100?????: {next, len, code} = {in[12], 5'd19, 32'd138}; 24'b1011001011100000101?????: {next, len, code} = {in[12], 5'd19, 32'd139}; 24'b1011000100010100101?????: {next, len, code} = {in[12], 5'd19, 32'd140}; 24'b1111111001000111011?????: {next, len, code} = {in[12], 5'd19, 32'd141}; 24'b00100010111101101101????: {next, len, code} = {in[11], 5'd20, 32'd142}; 24'b10000010101010101101????: {next, len, code} = {in[11], 5'd20, 32'd143}; 24'b10110010100101001101????: {next, len, code} = {in[11], 5'd20, 32'd144}; 24'b01010110111100010000????: {next, len, code} = {in[11], 5'd20, 32'd145}; 24'b10110111110011001001????: {next, len, code} = {in[11], 5'd20, 32'd146}; 24'b11111101101100100101????: {next, len, code} = {in[11], 5'd20, 32'd147}; 24'b10110000010100100001????: {next, len, code} = {in[11], 5'd20, 32'd148}; 24'b10110010011010110110????: {next, len, code} = {in[11], 5'd20, 32'd149}; 24'b01111001010000011000????: {next, len, code} = {in[11], 5'd20, 32'd150}; 24'b11110110001011011011????: {next, len, code} = {in[11], 5'd20, 32'd151}; 24'b01010000100100001011????: {next, len, code} = {in[11], 5'd20, 32'd152}; 24'b10110001100101110111????: {next, len, code} = {in[11], 5'd20, 32'd153}; 24'b10111100110111101000????: {next, len, code} = {in[11], 5'd20, 32'd154}; 24'b01010001010111010000????: {next, len, code} = {in[11], 5'd20, 32'd155}; 24'b01010100111110001110????: {next, len, code} = {in[11], 5'd20, 32'd156}; 24'b11111110011001100111????: {next, len, code} = {in[11], 5'd20, 32'd157}; 24'b11110111111101010001????: {next, len, code} = {in[11], 5'd20, 32'd158}; 24'b10110000010111100000????: {next, len, code} = {in[11], 5'd20, 32'd159}; 24'b01001111100001000101????: {next, len, code} = {in[11], 5'd20, 32'd160}; 24'b01010010000111010110????: {next, len, code} = {in[11], 5'd20, 32'd161}; 24'b11101010101011101111????: {next, len, code} = {in[11], 5'd20, 32'd162}; 24'b11111110010011100011????: {next, len, code} = {in[11], 5'd20, 32'd163}; 24'b01010111001111101111????: {next, len, code} = {in[11], 5'd20, 32'd164}; 24'b10110001111111111101????: {next, len, code} = {in[11], 5'd20, 32'd165}; 24'b10110001001100110000????: {next, len, code} = {in[11], 5'd20, 32'd166}; 24'b11110100011000111101????: {next, len, code} = {in[11], 5'd20, 32'd167}; 24'b00101011101110100011????: {next, len, code} = {in[11], 5'd20, 32'd168}; 24'b01010000011011111110????: {next, len, code} = {in[11], 5'd20, 32'd169}; 24'b00000111000010000010????: {next, len, code} = {in[11], 5'd20, 32'd170}; 24'b00101010000011001000????: {next, len, code} = {in[11], 5'd20, 32'd171}; 24'b01001110010100101110????: {next, len, code} = {in[11], 5'd20, 32'd172}; 24'b11110000000010000000????: {next, len, code} = {in[11], 5'd20, 32'd173}; 24'b01001101011001111001????: {next, len, code} = {in[11], 5'd20, 32'd174}; 24'b11110111000111010101????: {next, len, code} = {in[11], 5'd20, 32'd175}; 24'b01111001101001110110????: {next, len, code} = {in[11], 5'd20, 32'd176}; 24'b11110000101011101111????: {next, len, code} = {in[11], 5'd20, 32'd177}; 24'b00100100100110101010????: {next, len, code} = {in[11], 5'd20, 32'd178}; 24'b11110001011011000011????: {next, len, code} = {in[11], 5'd20, 32'd179}; 24'b01010111001000110011????: {next, len, code} = {in[11], 5'd20, 32'd180}; 24'b01111000000100010101????: {next, len, code} = {in[11], 5'd20, 32'd181}; 24'b00100101101011001101????: {next, len, code} = {in[11], 5'd20, 32'd182}; 24'b10110010110000111001????: {next, len, code} = {in[11], 5'd20, 32'd183}; 24'b10110000101010000011????: {next, len, code} = {in[11], 5'd20, 32'd184}; 24'b00100100111110001101????: {next, len, code} = {in[11], 5'd20, 32'd185}; 24'b01111001101001101011????: {next, len, code} = {in[11], 5'd20, 32'd186}; 24'b01010001000000010001????: {next, len, code} = {in[11], 5'd20, 32'd187}; 24'b11110101111111101110????: {next, len, code} = {in[11], 5'd20, 32'd188}; 24'b10000010111110110011????: {next, len, code} = {in[11], 5'd20, 32'd189}; 24'b00000100011110100111????: {next, len, code} = {in[11], 5'd20, 32'd190}; 24'b11111101001111101100????: {next, len, code} = {in[11], 5'd20, 32'd191}; 24'b00101011100011110000????: {next, len, code} = {in[11], 5'd20, 32'd192}; 24'b00100100111001011001????: {next, len, code} = {in[11], 5'd20, 32'd193}; 24'b10000010101000000100????: {next, len, code} = {in[11], 5'd20, 32'd194}; 24'b11110001001000111100????: {next, len, code} = {in[11], 5'd20, 32'd195}; 24'b10111100011010011001????: {next, len, code} = {in[11], 5'd20, 32'd196}; 24'b000000??????????????????: begin casez (in[33:32]) 2'b1?: {next, len, code} = {1'b0, 5'd18, 32'd197}; 2'b01: {next, len, code} = {1'b0, 5'd19, 32'd198}; 2'b00: {next, len, code} = {1'b0, 5'd19, 32'd199}; default: ; endcase end default: ; endcase end endmodule verilator-3.874/test_regress/t/t_math_vliw.v0000664000177100017500000000551412473477707021232 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [7:0] crc; reg [223:0] sum; wire [255:0] mglehy = {32{~crc}}; wire [215:0] drricx = {27{crc}}; wire [15:0] apqrli = {2{~crc}}; wire [2:0] szlfpf = crc[2:0]; wire [15:0] dzosui = {2{crc}}; wire [31:0] zndrba = {16{crc[1:0]}}; wire [223:0] bxiouf; vliw vliw ( // Outputs .bxiouf (bxiouf), // Inputs .mglehy (mglehy[255:0]), .drricx (drricx[215:0]), .apqrli (apqrli[15:0]), .szlfpf (szlfpf[2:0]), .dzosui (dzosui[15:0]), .zndrba (zndrba[31:0])); always @ (posedge clk) begin cyc <= cyc + 1; crc <= {crc[6:0], ~^ {crc[7],crc[5],crc[4],crc[3]}}; if (cyc==0) begin // Setup crc <= 8'hed; sum <= 224'h0; end else if (cyc<90) begin //$write("[%0t] cyc==%0d BXI=%x\n",$time, cyc, bxiouf); sum <= {sum[222:0],sum[223]} ^ bxiouf; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%b %x\n",$time, cyc, crc, sum); if (crc !== 8'b01110000) $stop; if (sum !== 224'h1fdff998855c3c38d467e28124847831f9ad6d4a09f2801098f032a8) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module vliw ( input[255:0] mglehy, input[215:0] drricx, input[15:0] apqrli, input[2:0] szlfpf, input[15:0] dzosui, input[31:0] zndrba, output [223:0] bxiouf ); wire [463:0] zhknfc = ({29{~apqrli}} & {mglehy, drricx[215:8]}) | ({29{apqrli}} & {mglehy[247:0], drricx}); wire [335:0] umntwz = ({21{~dzosui}} & zhknfc[463:128]) | ({21{dzosui}} & zhknfc[335:0]); wire [335:0] viuvoc = umntwz << {szlfpf, 4'b0000}; wire [223:0] rzyeut = viuvoc[335:112]; wire [223:0] bxiouf = {rzyeut[7:0], rzyeut[15:8], rzyeut[23:16], rzyeut[31:24], rzyeut[39:32], rzyeut[47:40], rzyeut[55:48], rzyeut[63:56], rzyeut[71:64], rzyeut[79:72], rzyeut[87:80], rzyeut[95:88], rzyeut[103:96], rzyeut[111:104], rzyeut[119:112], rzyeut[127:120], rzyeut[135:128], rzyeut[143:136], rzyeut[151:144], rzyeut[159:152], rzyeut[167:160], rzyeut[175:168], rzyeut[183:176], rzyeut[191:184], rzyeut[199:192], rzyeut[207:200], rzyeut[215:208], rzyeut[223:216]}; endmodule verilator-3.874/test_regress/t/t_gen_missing_bad.pl0000775000177100017500000000161612473477707022520 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_gen_missing.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ['+define+T_GEN_MISSING_BAD'], fails => 1, expect=> '%Error: t/t_gen_missing.v:\d+: Cannot find file containing module: foo_not_needed %Error: t/t_gen_missing.v:\d+: Looked in: %Error: t/t_gen_missing.v:\d+: t/foo_not_needed %Error: t/t_gen_missing.v:\d+: t/foo_not_needed.v %Error: t/t_gen_missing.v:\d+: t/foo_not_needed.sv .*%Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_genvar_misuse_bad.pl0000775000177100017500000000123212473477707023057 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug408"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '.*%Error: t/t_genvar_misuse_bad.v:\d+: Use of genvar where not convertible to constant: i %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_order_first.v0000664000177100017500000000253112473477707021556 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs fastclk ); input fastclk; t_netlist tnetlist (.also_fastclk (fastclk), /*AUTOINST*/ // Inputs .fastclk (fastclk)); endmodule module t_netlist (/*AUTOARG*/ // Inputs fastclk, also_fastclk ); // surefire lint_off ASWEMB input fastclk; input also_fastclk; integer _mode; initial _mode = 0; // This entire module should optimize to nearly nothing... // verilator lint_off UNOPTFLAT reg [4:0] a,a2,b,c,d,e; // verilator lint_on UNOPTFLAT initial a=5'd1; always @ (posedge fastclk) begin b <= a+5'd1; c <= b+5'd1; // Better for ordering if this moves before previous statement end // verilator lint_off UNOPT always @ (d or /*AS*/a or c) begin e = d+5'd1; a2 = a+5'd1; // This can be pulled out of the middle of the always d = c+5'd1; // Better for ordering if this moves before previous statement end // verilator lint_on UNOPT always @ (posedge also_fastclk) begin if (_mode==5) begin if (a2 != 5'd2) $stop; if (e != 5'd5) $stop; $write("*-* All Finished *-*\n"); $finish; end _mode <= _mode + 1; end endmodule verilator-3.874/test_regress/t/t_case_write1.pl0000775000177100017500000000121312473477707021607 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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->{golden_out} ||= "t/$Self->{name}.out"; compile ( verilator_flags2 => ["--stats --O3 -x-assign fast"], ); execute ( check_finished=>1, ); ok(files_identical("$Self->{obj_dir}/$Self->{name}_logger.log", $Self->{golden_out})); 1; verilator-3.874/test_regress/t/t_case_itemwidth.pl0000775000177100017500000000071712473477707022402 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_setout_bad_noinl.pl0000775000177100017500000000136612473477707023770 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. top_filename("t/t_lint_setout_bad.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only -Oi"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Error: t/t_lint_setout_bad.v:\d+: Output port is connected to a constant pin, electrical short .*', ); ok(1); 1; verilator-3.874/test_regress/t/t_stream3.pl0000775000177100017500000000072212473477707020763 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_primitive.v0000664000177100017500000000120712473477707022421 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Jie Xu. module t ( clk ); input clk; integer cyc; initial cyc = 0; reg a; reg b; reg z; sub_t sub_t_i (z, a, b); always @ (posedge clk) begin cyc <= cyc + 1; a <= cyc[0]; b <= cyc[1]; if (cyc > 10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule primitive CINV (a, b); output b; input a; assign b = ~a; endprimitive module sub_t (z, x, y); input x, y; output z; assign z = x & y; endmodule verilator-3.874/test_regress/t/t_package_abs.pl0000775000177100017500000000071712473477707021631 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_first.v0000664000177100017500000001114412473477707021214 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk, fastclk ); input clk /*verilator sc_clock*/; input fastclk /*verilator sc_clock*/; reg reset_l; int cyc; initial reset_l = 0; always @ (posedge clk) begin if (cyc==0) reset_l <= 1'b1; else if (cyc==1) reset_l <= 1'b0; else if (cyc==10) reset_l <= 1'b1; end t_clk t (/*AUTOINST*/ // Inputs .clk (clk), .fastclk (fastclk), .reset_l (reset_l)); endmodule module t_clk (/*AUTOARG*/ // Inputs clk, fastclk, reset_l ); input clk /*verilator sc_clock*/; input fastclk /*verilator sc_clock*/; input reset_l; // surefire lint_off STMINI // surefire lint_off CWECSB // surefire lint_off NBAJAM reg _ranit; initial _ranit=0; // surefire lint_off UDDSMX reg [7:0] clk_clocks; initial clk_clocks = 0; // surefire lint_off_line WRTWRT wire [7:0] clk_clocks_d1r; wire [7:0] clk_clocks_d1sr; wire [7:0] clk_clocks_cp2_d1r; wire [7:0] clk_clocks_cp2_d1sr; // verilator lint_off MULTIDRIVEN reg [7:0] int_clocks; initial int_clocks = 0; // verilator lint_on MULTIDRIVEN reg [7:0] int_clocks_copy; // verilator lint_off GENCLK reg internal_clk; initial internal_clk = 0; reg reset_int_; // verilator lint_on GENCLK always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] CLK1 %x\n", $time, reset_l); `endif if (!reset_l) begin clk_clocks <= 0; int_clocks <= 0; internal_clk <= 1'b1; reset_int_ <= 0; end else begin internal_clk <= ~internal_clk; if (!_ranit) begin _ranit <= 1; `ifdef TEST_VERBOSE $write("[%0t] t_clk: Running\n",$time); `endif reset_int_ <= 1; end end end reg [7:0] sig_rst; always @ (posedge clk or negedge reset_l) begin `ifdef TEST_VERBOSE $write("[%0t] CLK2 %x sr=%x\n", $time, reset_l, sig_rst); `endif if (!reset_l) begin sig_rst <= 0; end else begin sig_rst <= sig_rst + 1; // surefire lint_off_line ASWIBB end end always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] CLK3 %x cc=%x sr=%x\n", $time, reset_l, clk_clocks, sig_rst); `endif if (!reset_l) begin clk_clocks <= 0; end else begin clk_clocks <= clk_clocks + 8'd1; if (clk_clocks == 4) begin if (sig_rst !== 4) $stop; if (clk_clocks_d1r !== 3) $stop; if (int_clocks !== 2) $stop; if (int_clocks_copy !== 2) $stop; if (clk_clocks_d1r !== clk_clocks_cp2_d1r) $stop; if (clk_clocks_d1sr !== clk_clocks_cp2_d1sr) $stop; $write("*-* All Finished *-*\n"); $finish; end end end reg [7:0] resetted; always @ (posedge clk or negedge reset_int_) begin `ifdef TEST_VERBOSE $write("[%0t] CLK4 %x\n", $time, reset_l); `endif if (!reset_int_) begin resetted <= 0; end else begin resetted <= resetted + 8'd1; end end always @ (int_clocks) begin int_clocks_copy = int_clocks; end always @ (negedge internal_clk) begin int_clocks <= int_clocks + 8'd1; end t_clk_flop flopa (.clk(clk), .clk2(fastclk), .a(clk_clocks), .q(clk_clocks_d1r), .q2(clk_clocks_d1sr)); t_clk_flop flopb (.clk(clk), .clk2(fastclk), .a(clk_clocks), .q(clk_clocks_cp2_d1r), .q2(clk_clocks_cp2_d1sr)); t_clk_two two (/*AUTOINST*/ // Inputs .fastclk (fastclk), .reset_l (reset_l)); endmodule module t_clk_flop (/*AUTOARG*/ // Outputs q, q2, // Inputs clk, clk2, a ); parameter WIDTH=8; input clk; input clk2; input [(WIDTH-1):0] a; output [(WIDTH-1):0] q; output [(WIDTH-1):0] q2; reg [(WIDTH-1):0] q; reg [(WIDTH-1):0] q2; always @ (posedge clk) q<=a; always @ (posedge clk2) q2<=a; endmodule module t_clk_two (/*AUTOARG*/ // Inputs fastclk, reset_l ); input fastclk; input reset_l; // verilator lint_off GENCLK reg clk2; // verilator lint_on GENCLK reg [31:0] count; t_clk_twob tb (.*); wire reset_h = ~reset_l; always @ (posedge fastclk) begin if (reset_h) clk2 <= 0; else clk2 <= ~clk2; end always @ (posedge clk2) begin if (reset_h) count <= 0; else count <= count + 1; end endmodule module t_clk_twob (/*AUTOARG*/ // Inputs fastclk, reset_l ); input fastclk; input reset_l; always @ (posedge fastclk) begin // Extra line coverage point, just to make sure coverage // hierarchy under inlining lands properly if (reset_l) ; end endmodule verilator-3.874/test_regress/t/t_func_outfirst.pl0000775000177100017500000000071712473477707022303 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_shift_rep.v0000664000177100017500000000344412473477707022234 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; //bug765; disappears if add this wire //wire [7:0] a = (crc[7] ? {7'b0,crc[0]} : crc[7:0]); // favor low values wire [7:0] a = crc[7:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [15:0] y; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .y (y[15:0]), // Inputs .a (a[7:0])); // Aggregate outputs into a single result vector wire [63:0] result = {48'h0, y}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h0 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs y, // Inputs a ); input signed [7:0] a; output [15:0] y; // verilator lint_off WIDTH assign y = ~66'd0 <<< {4{a}}; // verilator lint_on WIDTH endmodule verilator-3.874/test_regress/t/t_math_div.v0000664000177100017500000000542512473477707021034 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [255:0] a; reg [60:0] divisor; reg [60:0] qq; reg [60:0] rq; reg signed [60:0] qqs; reg signed [60:0] rqs; always @* begin qq = a[60:0] / divisor; rq = a[60:0] % divisor; qqs = $signed(a[60:0]) / $signed(divisor); rqs = $signed(a[60:0]) % $signed(divisor); end integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; //$write("%d: %x %x %x %x\n", cyc, qq, rq, qqs, rqs); if (cyc==1) begin a <= 256'hed388e646c843d35de489bab2413d77045e0eb7642b148537491f3da147e7f26; divisor <= 61'h12371; a[60] <= 1'b0; divisor[60] <= 1'b0; // Unsigned end if (cyc==2) begin a <= 256'h0e17c88f3d5fe51a982646c8e2bd68c3e236ddfddddbdad20a48e039c9f395b8; divisor <= 61'h1238123771; a[60] <= 1'b0; divisor[60] <= 1'b0; // Unsigned if (qq!==61'h00000403ad81c0da) $stop; if (rq!==61'h00000000000090ec) $stop; if (qqs!==61'h00000403ad81c0da) $stop; if (rqs!==61'h00000000000090ec) $stop; end if (cyc==3) begin a <= 256'h0e17c88f00d5fe51a982646c8002bd68c3e236ddfd00ddbdad20a48e00f395b8; divisor <= 61'hf1b; a[60] <= 1'b1; divisor[60] <= 1'b0; // Signed if (qq!==61'h000000000090832e) $stop; if (rq!==61'h0000000334becc6a) $stop; if (qqs!==61'h000000000090832e) $stop; if (rqs!==61'h0000000334becc6a) $stop; end if (cyc==4) begin a[60] <= 1'b0; divisor[60] <= 1'b1; // Signed if (qq!==61'h0001eda37cca1be8) $stop; if (rq!==61'h0000000000000c40) $stop; if (qqs!==61'h1fffcf5187c76510) $stop; if (rqs!==61'h1ffffffffffffd08) $stop; end if (cyc==5) begin a[60] <= 1'b1; divisor[60] <= 1'b1; // Signed if (qq!==61'h0000000000000000) $stop; if (rq!==61'h0d20a48e00f395b8) $stop; if (qqs!==61'h0000000000000000) $stop; if (rqs!==61'h0d20a48e00f395b8) $stop; end if (cyc==6) begin if (qq!==61'h0000000000000001) $stop; if (rq!==61'h0d20a48e00f3869d) $stop; if (qqs!==61'h0000000000000000) $stop; if (rqs!==61'h1d20a48e00f395b8) $stop; end // Div by zero if (cyc==9) begin divisor <= 61'd0; end if (cyc==10) begin `ifdef verilator if (qq !== {61{1'b0}}) $stop; if (rq !== {61{1'b0}}) $stop; `else if (qq !== {61{1'bx}}) $stop; if (rq !== {61{1'bx}}) $stop; `endif if ({16{1'bx}} !== 16'd1/16'd0) $stop; // No div by zero errors if ({16{1'bx}} !== 16'd1%16'd0) $stop; // No div by zero errors end if (cyc==19) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_metacmt_onoff.pl0000775000177100017500000000161212473477707022225 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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. compile ( verilator_flags2 => [qw(--lint-only)], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, fails=>$Self->{vlt}, expect=> '%Warning-LITENDIAN: t/t_metacmt_onoff.v:\d+: Little bit endian vector: MSB < LSB of bit range: 0:1 %Warning-LITENDIAN: Use "/\* verilator lint_off LITENDIAN \*/" and lint_on around source to disable this message. %Warning-LITENDIAN: t/t_metacmt_onoff.v:\d+: Little bit endian vector: MSB < LSB of bit range: 0:3 %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_down_inlbc.pl0000775000177100017500000000112412473477707023540 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_B +define+INLINE_C'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_sys.v0000664000177100017500000000140112473477707020701 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. // Global is the most likely usage scenario import "DPI-C" dpii_sys_task = function void \$dpii_sys (integer i); import "DPI-C" dpii_sys_func = function int \$dpii_func (integer i); module t (); `ifndef verilator `error "Only Verilator supports PLI-ish DPI calls." `endif initial begin $dpii_sys(1); if ($dpii_func(2) != 3) $stop; $dpii_sys(10); if ($dpii_func(2) != 12) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_gen_local.pl0000775000177100017500000000071712473477707021334 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_circ_bad.pl0000775000177100017500000000131312473477707022310 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Error: t/t_param_circ_bad.v:\d+: Variable\'s initial value is circular: X %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_var_in_assign_bad.pl0000775000177100017500000000150612473477707023036 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2005 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"); compile ( v_flags2 => ["--lint-only --Mdir obj_lint_only"], fails=>1, expect=> '%Error-ASSIGNIN: t/t_var_in_assign_bad.v:\d+: Assigning to input variable: value %Error-ASSIGNIN: t/t_var_in_assign_bad.v:\d+: Assigning to input variable: valueSub %Error: Exiting due to.*', ); (!-d "obj_lint_only") or $Self->error("%Error: lint-only shouldn't make output directory"); ok(1); 1; verilator-3.874/test_regress/t/t_bitsel_wire_array_bad.pl0000775000177100017500000000117612525171734023712 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # Comple time only test compile ( verilator_flags2 => ["--lint-only"], fails=>1, expect=> '.*%Error: t/t_bitsel_wire_array_bad.v:\d+: Illegal assignment of constant to unpacked array %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_multiwire.pl0000775000177100017500000000071712473477707022270 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_nomod_bad.v0000664000177100017500000000026012473477707022144 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. `define EMPTY 1 verilator-3.874/test_regress/t/t_sys_file_basic.pl0000775000177100017500000000146612473477707022371 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. unlink("$Self->{obj_dir}/t_sys_file_basic_test.log"); compile ( v_flags2 => ['+incdir+../include'], # Build without cached objects, see bug363 verilator_flags2 => ["--exe ../$Self->{main_filename}"], make_flags=>'MAKE_MAIN=0 VM_PARALLEL_BUILDS=0', ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/t_sys_file_basic_test.log", qr/\[0\] hello v=12345667 \[0\] Hello2 /); ok(1); 1; verilator-3.874/test_regress/t/t_sys_plusargs_bad.pl0000775000177100017500000000140212473477707022745 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( fails=>$Self->{v3}, expect=> q{%Error: t/t_sys_plusargs_bad.v:\d+: Missing or extra \$value\$plusargs format qualifier: 'NOTTHERE' %Error: t/t_sys_plusargs_bad.v:\d+: Illegal \$value\$plusargs format qualifier: 'z' %Error: t/t_sys_plusargs_bad.v:\d+: Missing or extra \$value\$plusargs format qualifier: 'INT=%x%x' %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_types.pl0000775000177100017500000000071712473477707021570 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_defparam.pl0000775000177100017500000000111212473477707022204 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( v_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_order_doubleloop.pl0000775000177100017500000000105112473477707022740 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/); compile ( ); execute ( check_finished => !$fail, fails => $fail, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_task_bad.pl0000775000177100017500000000111612473477707022166 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2011 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. compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> q{%Error: t/t_func_task_bad.v:\d+: Illegal call of a task as a function: task_as_func %Error: Exiting due to.*}, ); ok(1); 1; verilator-3.874/test_regress/t/t_detectarray_2.v0000664000177100017500000000153212473477707021764 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Simple test of unoptflat // // This should trigger the DETECTARRAY error like t_detectarray_1.v, but in // fact it casuses a broken link error. The only difference is that the struct // is defined using a constant rather than a localparam. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jeremy Bennett. localparam ID_MSB = 1; module t (/*AUTOARG*/ // Inputs clk ); input clk; typedef struct packed { logic [1:0] id; } context_t; context_t tsb; assign tsb.id = {tsb.id[0], clk}; initial begin tsb.id = 0; end always @(posedge clk or negedge clk) begin `ifdef TEST_VERBOSE $write("tsb.id = %x\n", tsb.id); `endif if (tsb.id[1] != 0) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_func_under.v0000664000177100017500000000130112473477707021356 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [3:0] counter = 0; integer l2; function log2 (input [3:0] x); integer log2 = (x < 2) ? 1 : (x < 4) ? 2 : (x < 8) ? 3 : 4; endfunction always @(posedge clk) begin counter <= counter + 1; l2 <= log2(counter); // bug589: This failed with (%Error: Internal Error: Function not underneath a statement): $display("log2(%d) == %d", counter, log2(counter)); // $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_assert_dup_bad.v0000664000177100017500000000063112473477707022212 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc = 0; covlabel: cover property (@(posedge clk) cyc==5); covlabel: // Error: Duplicate block_identifier cover property (@(posedge clk) cyc==5); endmodule verilator-3.874/test_regress/t/t_sys_readmem_bad_digit.mem0000664000177100017500000000044312473477707024043 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test data file // // Copyright 2006 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. a0 verilator-3.874/test_regress/t/t_dpi_qw.pl0000775000177100017500000000106112473477707020665 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2011 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. compile ( v_flags2 => ["t/t_dpi_qw_c.cpp"], verilator_flags2 => ["-Wall -Wno-DECLFILENAME -no-l2name"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_pow3.v0000664000177100017500000001001412473477707021130 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); fail=1; end while(0) module t (/*AUTOARG*/); bit fail; // IEEE says for ** the size is L(i). Thus Icarus Verilog is wrong in sizing some of the below. initial begin // NC=67b6cfc1b29a21 VCS=c1b29a20(wrong) IV=67b6cfc1b29a21 Verilator=67b6cfc1b29a21 $display("15 ** 14 = %0x expect 67b6cfc1b29a21", 64'b1111 ** 64'b1110); // NC=1 VCS=0 IV=0 Verilator=1 (wrong,fixed) $display("15 **-4'sd2 = %0x expect 0 (per IEEE negative power)", ((-4'd1 ** -4'sd2))); // NC=1 VCS=0 IV=67b6cfc1b29a21(wrong) Verilator=1 $display("15 ** 14 = %0x expect 1 (LSB 4-bits of 67b6cfc1b29a21)", ((-4'd1 ** -4'd2))); // NC=1 VCS=0 IV=67b6cfc1b29a21(wrong) Verilator=1 $display("15 ** 14 = %0x expect 1 (LSB 4-bits of 67b6cfc1b29a21)", ((4'd15 ** 4'd14))); // NC=8765432187654321 VCS=8765432187654000(wrong) IV=8765432187654321 Verilator=8765432187654321 $display("64'big ** 1 = %0x expect %0x", 64'h8765432187654321 ** 1, 64'h8765432187654321); $display("\n"); `checkh( (64'b1111 ** 64'b1110), 64'h67b6cfc1b29a21); `checkh( (-4'd1 ** -4'sd2), 4'h0); //bug730 `checkh( (-4'd1 ** -4'd2), 4'h1); `checkh( (4'd15 ** 4'd14), 4'h1); `checkh( (64'h8765432187654321 ** 4'h1), 64'h8765432187654321); `checkh((-8'sh3 ** 8'h3) , 8'he5 ); // a**b (-27) `checkh((-8'sh1 ** 8'h2) , 8'h1 ); // -1^odd=-1, -1^even=1 `checkh((-8'sh1 ** 8'h3) , 8'hff ); // -1^odd=-1, -1^even=1 `checkh(( 8'h0 ** 8'h3) , 8'h0 ); // 0 `checkh(( 8'h1 ** 8'h3) , 8'h1 ); // 1 `checkh(( 8'h3 ** 8'h3) , 8'h1b ); // a**b (27) `checkh(( 8'sh3 ** 8'h3) , 8'h1b ); // a**b (27) `checkh(( 8'h6 ** 8'h3) , 8'hd8 ); // a**b (216) `checkh(( 8'sh6 ** 8'h3) , 8'hd8 ); // a**b (216) `checkh((-8'sh3 ** 8'sh3), 8'he5 ); // a**b `checkh((-8'sh1 ** 8'sh2), 8'h1 ); // -1^odd=-1, -1^even=1 `checkh((-8'sh1 ** 8'sh3), 8'hff ); // -1^odd=-1, -1^even=1 `checkh(( 8'h0 ** 8'sh3), 8'h0 ); // 0 `checkh(( 8'h1 ** 8'sh3), 8'h1 ); // 1 `checkh(( 8'h3 ** 8'sh3), 8'h1b ); // a**b (27) `checkh(( 8'sh3 ** 8'sh3), 8'h1b ); // a**b (27) `checkh(( 8'h6 ** 8'sh3), 8'hd8 ); // a**b (216) `checkh(( 8'sh6 ** 8'sh3), 8'hd8 ); // a**b (216) `checkh((-8'sh3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h0 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'sh3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h0 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h1 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'h3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh(( 8'sh3 ** -8'sh0), 8'h1 ); // a**0 always 1 `checkh((-8'sh3 ** -8'sh3), 8'h0 ); // 0 (a<-1) // NCVERILOG bug `checkh((-8'sh1 ** -8'sh2), 8'h1 ); // -1^odd=-1, -1^even=1 `checkh((-8'sh1 ** -8'sh3), 8'hff); // -1^odd=-1, -1^even=1 // `checkh(( 8'h0 ** -8'sh3), 8'hx ); // x // NCVERILOG bug `checkh(( 8'h1 ** -8'sh3), 8'h1 ); // 1**b always 1 `checkh(( 8'h3 ** -8'sh3), 8'h0 ); // 0 // NCVERILOG bug `checkh(( 8'sh3 ** -8'sh3), 8'h0 ); // 0 // NCVERILOG bug if (fail) $stop; else $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_stream2.v0000664000177100017500000000373512473477707020620 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [67:0] left; // From test of Test.v wire [67:0] right; // From test of Test.v // End of automatics wire [6:0] amt = crc[6:0]; wire [67:0] in = {crc[3:0], crc[63:0]}; Test test (/*AUTOINST*/ // Outputs .left (left[67:0]), .right (right[67:0]), // Inputs .amt (amt[6:0]), .in (in[67:0])); wire [63:0] result = (left[63:0] ^ {60'h0, left[67:64]} ^ right[63:0] ^ {60'h0, right[67:64]}); // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x amt=%x left=%x right=%x\n", $time, cyc, crc, result, amt, left, right); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h0da01049b480c38a if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs left, right, // Inputs amt, in ); input [6:0] amt; input [67:0] in; // amt must be constant output wire [67:0] left; output wire [67:0] right; assign right = { << 33 {in}}; assign left = { >> 33 {in}}; endmodule verilator-3.874/test_regress/t/t_var_pinsizes.cpp0000664000177100017500000000177412473477707022275 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- #ifdef T_VAR_PINS_CC # include "Vt_var_pins_cc.h" #elif defined(T_VAR_PINS_SC1) # include "Vt_var_pins_sc1.h" #elif defined(T_VAR_PINS_SC2) # include "Vt_var_pins_sc2.h" #elif defined(T_VAR_PINS_SC32) # include "Vt_var_pins_sc32.h" #elif defined(T_VAR_PINS_SC64) # include "Vt_var_pins_sc64.h" #elif defined(T_VAR_PINS_SCUI) # include "Vt_var_pins_scui.h" #elif defined(T_VAR_PINS_SC_UINT) # include "Vt_var_pins_sc_uint.h" #elif defined(T_VAR_PINS_SC_BIGUINT) # include "Vt_var_pins_sc_biguint.h" #elif defined(T_VAR_PINS_SC_UINT_BIGUINT) # include "Vt_var_pins_sc_uint_biguint.h" #else # error "Unknown test" #endif VM_PREFIX* tb = NULL; double sc_time_stamp() { return 0; } int main() { Verilated::debug(0); tb = new VM_PREFIX("tb"); VL_PRINTF("*-* All Finished *-*\n"); tb->final(); return 0; } int sc_main(int argc, char *argv[]) { tb = new VM_PREFIX("tb"); VL_PRINTF("*-* All Finished *-*\n"); tb->final(); return 0; } verilator-3.874/test_regress/t/t_select_loop.v0000664000177100017500000000241412473477707021544 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [255:0] a; reg [255:0] q; reg [63:0] qq; integer i; always @* begin for (i=0; i<256; i=i+1) begin q[255-i] = a[i]; end q[27:16] = 12'hfed; for (i=0; i<64; i=i+1) begin qq[63-i] = a[i]; end qq[27:16] = 12'hfed; end always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("%x/%x %x\n", q, qq, a); `endif if (cyc==1) begin a = 256'hed388e646c843d35de489bab2413d77045e0eb7642b148537491f3da147e7f26; end if (cyc==2) begin a = 256'h0e17c88f3d5fe51a982646c8e2bd68c3e236ddfddddbdad20a48e039c9f395b8; if (q != 256'h64fe7e285bcf892eca128d426ed707a20eebc824d5d9127bacbc21362fed1cb7) $stop; if (qq != 64'h64fe7e285fed892e) $stop; end if (cyc==3) begin if (q != 256'h1da9cf939c0712504b5bdbbbbfbb6c47c316bd471362641958a7fabcffede870) $stop; if (qq != 64'h1da9cf939fed1250) $stop; end if (cyc==4) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_rnd.pl0000775000177100017500000000071712473477707020174 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_delay.v0000664000177100017500000000135012473477707020330 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); parameter PAR = 3; input clk; integer cyc=1; reg [31:0] dly0; wire [31:0] dly1; wire [31:0] dly2 = dly1 + 32'h1; assign #(1.2000000000000000) dly1 = dly0 + 32'h1; always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==1) begin dly0 <= #0 32'h11; end else if (cyc==2) begin dly0 <= #0.12 dly0 + 32'h12; end else if (cyc==3) begin if (dly0 !== 32'h23) $stop; if (dly2 !== 32'h25) $stop; $write("*-* All Finished *-*\n"); #100 $finish; end end endmodule verilator-3.874/test_regress/t/t_flag_lib.pl0000775000177100017500000000032312473477707021141 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } compile ( v_flags2 => ['-v', 't/t_flag_libinc.v'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_case_huge.pl0000775000177100017500000000125612473477707021333 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--stats"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10); file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 9); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_ena_sc.pl0000775000177100017500000000123112473477707022007 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_trace_ena.v"); compile ( verilator_flags2 => ['-trace -sc'], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { # Note more checks in _cc.pl file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x); } ok(1); 1; verilator-3.874/test_regress/t/t_lint_ifdepth_bad.pl0000775000177100017500000000151212473477707022662 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME --if-depth 10"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning-IFDEPTH: t/t_lint_ifdepth_bad.v:\d+: Deep \'if\' statement; suggest unique/priority to avoid slow logic %Warning-IFDEPTH: Use .* to disable this message. %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_var_life.pl0000775000177100017500000000127212473477707021175 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--stats"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Lifetime assign deletions\s+(\d+)/i, 4); file_grep ($Self->{stats}, qr/Optimizations, Lifetime constant prop\s+(\d+)/i, 2); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_return.v0000664000177100017500000000314012473477707021563 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. // bug420 typedef logic [7-1:0] wb_ind_t; typedef logic [7-1:0] id_t; module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ wire [6:0] out = line_wb_ind( in[6:0] ); // Aggregate outputs into a single result vector wire [63:0] result = {57'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'hc918fa0aa882a206 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end function wb_ind_t line_wb_ind( id_t id ); if( id[$bits(id_t)-1] == 0 ) return {2'b00, id[$bits(wb_ind_t)-3:0]}; else return {2'b01, id[$bits(wb_ind_t)-3:0]}; endfunction // line_wb_ind endmodule verilator-3.874/test_regress/t/t_param_package.pl0000775000177100017500000000072212473477707022160 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_notfound_bad.pl0000775000177100017500000000172512473477707022723 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( fails=>1, expect=> '%Error: t/t_var_notfound_bad.v:\d+: Can\'t find definition of variable: nf %Error: t/t_var_notfound_bad.v:\d+: Can\'t find definition of \'subsubz\' in dotted scope/variable: sub.subsubz %Error: Known scopes under \'sub\': subsub %Error: t/t_var_notfound_bad.v:\d+: Can\'t find definition of task/function: nofunc %Error: t/t_var_notfound_bad.v:\d+: Can\'t find definition of task/function: notask %Error: t/t_var_notfound_bad.v:\d+: Found definition of \'a_var\' as a VAR but expected a task/function %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_func_dotted_inl1.pl0000775000177100017500000000103712473477707022626 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_func_dotted.v"); compile ( v_flags2 => ['+define+USE_INLINE',], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_udp_lint.pl0000775000177100017500000000114312473477707021221 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_udp.v"); compile ( # Unsupported: UDP Tables make_top_shell => 0, make_main => 0, verilator_flags2 => ["--lint-only --bbox-unsup"], verilator_make_gcc => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_udp_noname.v0000664000177100017500000000136612473477707021366 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg a; wire o; udp (o, a); integer cyc; initial cyc=0; // Test loop always @ (posedge clk) begin cyc <= cyc + 1; a <= cyc[0]; if (cyc==0) begin end else if (cyc<90) begin if (a != !cyc[0]) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule primitive udp(o,a); output o; input a; `ifdef verilator wire o = ~a; `else table //o a 0 : 1; 1 : 0; endtable `endif endprimitive verilator-3.874/test_regress/t/t_var_escape.pl0000775000177100017500000000173012473477707021515 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( # Access is so we can dump waves v_flags2 => [$Self->{v3}?'-trace':' +access+rwc'], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x); my $sig = quotemeta("bra[ket]slash/dash-colon:9"); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ $sig/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ other\.cyc /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ module mod\.with_dot /); vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out"); } ok(1); 1; verilator-3.874/test_regress/t/t_math_cmp.v0000664000177100017500000001043612473477707021027 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [2:0] index_a; reg [2:0] index_b; prover #(4) p4 (/*AUTOINST*/ // Inputs .clk (clk), .index_a (index_a), .index_b (index_b)); prover #(32) p32 (/*AUTOINST*/ // Inputs .clk (clk), .index_a (index_a), .index_b (index_b)); prover #(63) p63 (/*AUTOINST*/ // Inputs .clk (clk), .index_a (index_a), .index_b (index_b)); prover #(64) p64 (/*AUTOINST*/ // Inputs .clk (clk), .index_a (index_a), .index_b (index_b)); prover #(72) p72 (/*AUTOINST*/ // Inputs .clk (clk), .index_a (index_a), .index_b (index_b)); prover #(126) p126 (/*AUTOINST*/ // Inputs .clk (clk), .index_a (index_a), .index_b (index_b)); prover #(128) p128 (/*AUTOINST*/ // Inputs .clk (clk), .index_a (index_a), .index_b (index_b)); integer cyc; initial cyc=0; initial index_a = 3'b0; initial index_b = 3'b0; always @* begin index_a = cyc[2:0]; if (index_a>3'd4) index_a=3'd4; index_b = cyc[5:3]; if (index_b>3'd4) index_b=3'd4; end always @ (posedge clk) begin cyc <= cyc + 1; if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module prover ( input clk, input [2:0] index_a, input [2:0] index_b ); parameter WIDTH = 4; reg signed [WIDTH-1:0] as; reg signed [WIDTH-1:0] bs; wire [WIDTH-1:0] b = bs; always @* begin casez (index_a) 3'd0: as = {(WIDTH){1'd0}}; // 0 3'd1: as = {{(WIDTH-1){1'd0}}, 1'b1}; // 1 3'd2: as = {1'b0, {(WIDTH-1){1'd0}}}; // 127 or equiv 3'd3: as = {(WIDTH){1'd1}}; // -1 3'd4: as = {1'b1, {(WIDTH-1){1'd0}}}; // -128 or equiv default: $stop; endcase casez (index_b) 3'd0: bs = {(WIDTH){1'd0}}; // 0 3'd1: bs = {{(WIDTH-1){1'd0}}, 1'b1}; // 1 3'd2: bs = {1'b0, {(WIDTH-1){1'd0}}}; // 127 or equiv 3'd3: bs = {(WIDTH){1'd1}}; // -1 3'd4: bs = {1'b1, {(WIDTH-1){1'd0}}}; // -128 or equiv default: $stop; endcase end reg [7:0] results[4:0][4:0]; wire gt = as>b; wire gts = as>bs; wire gte = as>=b; wire gtes = as>=bs; wire lt = as2) begin `ifdef TEST_VERBOSE $write("results[%d][%d] = 8'b%b_%b_%b_%b_%b_%b_%b_%b;\n", index_a, index_b, gt, gts, gte, gtes, lt, lts, lte, ltes); `endif exp = results[index_a][index_b]; got = {gt, gts, gte, gtes, lt, lts, lte, ltes}; if (exp !== got) begin $display("%%Error: bad comparison width=%0d: %d/%d got=%b exp=%b", WIDTH, index_a,index_b,got, exp); $stop; end end end // Result table initial begin // Indexes: 0, 1, -1, 127, -128 // Gt Gts Gte Gtes Lt Lts Lte Ltes results[0][0] = 8'b0_0_1_1_0_0_1_1; results[0][1] = 8'b0_0_0_0_1_1_1_1; results[0][2] = 8'b0_0_1_1_0_0_1_1; results[0][3] = 8'b0_1_0_1_1_0_1_0; results[0][4] = 8'b0_1_0_1_1_0_1_0; results[1][0] = 8'b1_1_1_1_0_0_0_0; results[1][1] = 8'b0_0_1_1_0_0_1_1; results[1][2] = 8'b1_1_1_1_0_0_0_0; results[1][3] = 8'b0_1_0_1_1_0_1_0; results[1][4] = 8'b0_1_0_1_1_0_1_0; results[2][0] = 8'b0_0_1_1_0_0_1_1; results[2][1] = 8'b0_0_0_0_1_1_1_1; results[2][2] = 8'b0_0_1_1_0_0_1_1; results[2][3] = 8'b0_1_0_1_1_0_1_0; results[2][4] = 8'b0_1_0_1_1_0_1_0; results[3][0] = 8'b1_0_1_0_0_1_0_1; results[3][1] = 8'b1_0_1_0_0_1_0_1; results[3][2] = 8'b1_0_1_0_0_1_0_1; results[3][3] = 8'b0_0_1_1_0_0_1_1; results[3][4] = 8'b1_1_1_1_0_0_0_0; results[4][0] = 8'b1_0_1_0_0_1_0_1; results[4][1] = 8'b1_0_1_0_0_1_0_1; results[4][2] = 8'b1_0_1_0_0_1_0_1; results[4][3] = 8'b0_0_0_0_1_1_1_1; results[4][4] = 8'b0_0_1_1_0_0_1_1; end endmodule verilator-3.874/test_regress/t/t_math_arith.v0000664000177100017500000001101712473477707021353 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg _ranit; reg [2:0] xor3; reg [1:0] xor2; reg [0:0] xor1; reg [2:0] ma, mb; reg [9:0] mc; reg [4:0] mr1; reg [30:0] mr2; reg [67:0] sh1; reg [67:0] shq; wire foo, bar; assign {foo,bar} = 2'b1_0; // surefire lint_off STMINI initial _ranit = 0; wire [4:0] cond_check = (( xor2 == 2'b11) ? 5'h1 : (xor2 == 2'b00) ? 5'h2 : (xor2 == 2'b01) ? 5'h3 : 5'h4); wire ctrue = 1'b1 ? cond_check[1] : cond_check[0]; wire cfalse = 1'b0 ? cond_check[1] : cond_check[0]; wire cif = cond_check[2] ? cond_check[1] : cond_check[0]; wire cifn = (!cond_check[2]) ? cond_check[1] : cond_check[0]; wire [4:0] doubleconc = {1'b0, 1'b1, 1'b0, cond_check[0], 1'b1}; wire zero = 1'b0; wire one = 1'b1; wire [5:0] rep6 = {6{one}}; // verilator lint_off WIDTH localparam [3:0] bug764_p11 = 1'bx; // verilator lint_on WIDTH always @ (posedge clk) begin if (!_ranit) begin _ranit <= 1; if (rep6 != 6'b111111) $stop; if (!one) $stop; if (~one) $stop; if (( 1'b0 ? 3'h3 : 1'b0 ? 3'h2 : 1'b1 ? 3'h1 : 3'h0) !== 3'h1) $stop; // verilator lint_off WIDTH if (( 8'h10 + 1'b0 ? 8'he : 8'hf) !== 8'he) $stop; // + is higher than ? // verilator lint_on WIDTH // surefire lint_off SEQASS xor1 = 1'b1; xor2 = 2'b11; xor3 = 3'b111; // verilator lint_off WIDTH if (1'b1 & | (!xor3)) $stop; // verilator lint_on WIDTH if ({1{xor1}} != 1'b1) $stop; if ({4{xor1}} != 4'b1111) $stop; if (!(~xor1) !== ~(!xor1)) $stop; if ((^xor1) !== 1'b1) $stop; if ((^xor2) !== 1'b0) $stop; if ((^xor3) !== 1'b1) $stop; if (~(^xor2) !== 1'b1) $stop; if (~(^xor3) !== 1'b0) $stop; if ((^~xor1) !== 1'b0) $stop; if ((^~xor2) !== 1'b1) $stop; if ((^~xor3) !== 1'b0) $stop; if ((~^xor1) !== 1'b0) $stop; if ((~^xor2) !== 1'b1) $stop; if ((~^xor3) !== 1'b0) $stop; xor1 = 1'b0; xor2 = 2'b10; xor3 = 3'b101; if ((^xor1) !== 1'b0) $stop; if ((^xor2) !== 1'b1) $stop; if ((^xor3) !== 1'b0) $stop; if (~(^xor2) !== 1'b0) $stop; if (~(^xor3) !== 1'b1) $stop; if ((^~xor1) !== 1'b1) $stop; if ((^~xor2) !== 1'b0) $stop; if ((^~xor3) !== 1'b1) $stop; if ((~^xor1) !== 1'b1) $stop; if ((~^xor2) !== 1'b0) $stop; if ((~^xor3) !== 1'b1) $stop; ma = 3'h3; mb = 3'h4; mc = 10'h5; mr1 = ma * mb; // Lint ASWESB: Assignment width mismatch mr2 = 30'h5 * mc; // Lint ASWESB: Assignment width mismatch if (mr1 !== 5'd12) $stop; if (mr2 !== 31'd25) $stop; // Lint CWECBB: Comparison width mismatch sh1 = 68'hf_def1_9abc_5678_1234; shq = sh1 >> 16; if (shq !== 68'hf_def1_9abc_5678) $stop; shq = sh1 << 16; // Lint ASWESB: Assignment width mismatch if (shq !== 68'h1_9abc_5678_1234_0000) $stop; // surefire lint_on SEQASS // Test display extraction widthing $display("[%0t] %x %x %x(%d)", $time, shq[2:0], shq[2:0]<<2, xor3[2:0], xor3[2:0]); // bug736 //verilator lint_off WIDTH if ((~| 4'b0000) != 4'b0001) $stop; if ((~| 4'b0010) != 4'b0000) $stop; if ((~& 4'b1111) != 4'b0000) $stop; if ((~& 4'b1101) != 4'b0001) $stop; //verilator lint_on WIDTH // bug764 //verilator lint_off WIDTH // X does not sign extend if (bug764_p11 !== 4'b000x) $stop; if (~& bug764_p11 !== 1'b1) $stop; //verilator lint_on WIDTH // However IEEE says for constants in 2012 5.7.1 that smaller-sizes do extend if (4'bx !== 4'bxxxx) $stop; if (4'bz !== 4'bzzzz) $stop; if (4'b1 !== 4'b0001) $stop; $write("*-* All Finished *-*\n"); $finish; end end reg [63:0] m_data_pipe2_r; reg [31:0] m_corr_data_w0, m_corr_data_w1; reg [7:0] m_corr_data_b8; initial begin m_data_pipe2_r = 64'h1234_5678_9abc_def0; {m_corr_data_b8, m_corr_data_w1, m_corr_data_w0} = { m_data_pipe2_r[63:57], 1'b0, //m_corr_data_b8 [7:0] m_data_pipe2_r[56:26], 1'b0, //m_corr_data_w1 [31:0] m_data_pipe2_r[25:11], 1'b0, //m_corr_data_w0 [31:16] m_data_pipe2_r[10:04], 1'b0, //m_corr_data_w0 [15:8] m_data_pipe2_r[03:01], 1'b0, //m_corr_data_w0 [7:4] m_data_pipe2_r[0], 3'b000 //m_corr_data_w0 [3:0] }; if (m_corr_data_w0 != 32'haf36de00) $stop; if (m_corr_data_w1 != 32'h1a2b3c4c) $stop; if (m_corr_data_b8 != 8'h12) $stop; end endmodule verilator-3.874/test_regress/t/t_langext_1_bad.pl0000775000177100017500000000104012473477707022067 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_langext_1.v"); # This is a compile only test. compile ( v_flags2 => ["+verilog1995ext+v"], fails => 1 ); ok(1); 1; verilator-3.874/test_regress/t/t_enumeration.pl0000775000177100017500000000102612473477707021731 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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} and $Self->unsupported("Verilator unsupported, bug460"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vpi_get.cpp0000664000177100017500000001756012525171734021203 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2011 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifdef IS_VPI #include "vpi_user.h" #include #else #include "Vt_vpi_get.h" #include "verilated.h" #include "svdpi.h" #include "Vt_vpi_get__Dpi.h" #include "verilated_vpi.h" #include "verilated_vpi.cpp" #include "verilated_vcd_c.h" #endif #include #include #include using namespace std; #include "TestSimulator.h" #include "TestVpi.h" // __FILE__ is too long #define FILENM "t_vpi_get.cpp" #define TEST_MSG if (0) printf unsigned int main_time = false; //====================================================================== #define CHECK_RESULT_VH(got, exp) \ if ((got) != (exp)) { \ printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \ FILENM,__LINE__, (got), (exp)); \ return __LINE__; \ } #define CHECK_RESULT_NZ(got) \ if (!(got)) { \ printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \ return __LINE__; \ } // Use cout to avoid issues with %d/%lx etc #define CHECK_RESULT(got, exp) \ if ((got) != (exp)) { \ cout<", (exp)?(exp):""); \ return __LINE__; \ } #define CHECK_RESULT_CSTR_STRIP(got, exp) \ CHECK_RESULT_CSTR(got+strspn(got, " "), exp) static int _mon_check_props(TestVpiHandle& handle, int size, int direction, int scalar, int type) { s_vpi_value value = { vpiIntVal }; // check size of object int vpisize = vpi_get(vpiSize, handle); CHECK_RESULT(vpisize, size); // icarus verilog does not support vpiScalar, vpiVector or vpi*Range if (TestSimulator::has_get_scalar()) { int vpiscalar = vpi_get(vpiScalar, handle); CHECK_RESULT((bool)vpiscalar, (bool)scalar); int vpivector = vpi_get(vpiVector, handle); CHECK_RESULT((bool)vpivector, (bool)!scalar); } // Icarus only supports ranges on memories if (!scalar && !(TestSimulator::is_icarus() && type != vpiMemory)) { TestVpiHandle left_h, right_h; // check coherency for vectors // get left hand side of range left_h = vpi_handle(vpiLeftRange, handle); CHECK_RESULT_NZ(left_h); vpi_get_value(left_h, &value); int coherency = value.value.integer; // get right hand side of range right_h = vpi_handle(vpiRightRange, handle); CHECK_RESULT_NZ(right_h); vpi_get_value(right_h, &value); TEST_MSG("%d:%d\n", coherency, value.value.integer); coherency -= value.value.integer; // calculate size & check coherency = abs(coherency) + 1; CHECK_RESULT(coherency, size); } // Only check direction on ports if (type == vpiPort) { // check direction of object int vpidir = vpi_get(vpiDirection, handle); // Don't check port directions in verilator // see #681 if (!TestSimulator::is_verilator()) { CHECK_RESULT(vpidir, direction); } } // check type of object int vpitype = vpi_get(vpiType, handle); if (!(TestSimulator::is_verilator() && type == vpiPort)) { // Don't check for ports in verilator // see #681 CHECK_RESULT(vpitype, type); } return 0; // Ok } struct params { const char* signal; struct { unsigned int size; unsigned int direction; unsigned int scalar; int type; } attributes, children; } values[] = { {"onebit", {1, vpiNoDirection, 1, vpiReg}, {0, 0, 0, 0}}, {"twoone", {2, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}}, {"onetwo", {2, vpiNoDirection, 0, TestSimulator::is_verilator() ? vpiReg : vpiMemory}, {0, 0, 0, 0}}, {"fourthreetwoone", {2, vpiNoDirection, 0, vpiMemory}, {2, vpiNoDirection, 0, vpiMemoryWord}}, {"clk", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, {"testin", {16, vpiInput, 0, vpiPort}, {0, 0, 0, 0}}, {"testout", {24, vpiOutput, 0, vpiPort}, {0, 0, 0, 0}}, {"sub.subin", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, {"sub.subout", {1, vpiOutput, 1, vpiPort}, {0, 0, 0, 0}}, {NULL, {0, 0, 0, 0}, {0, 0, 0, 0}} }; int mon_check_props() { struct params* value = values; while (value->signal) { TestVpiHandle h = VPI_HANDLE(value->signal); CHECK_RESULT_NZ(h); TEST_MSG("%s\n", value->signal); if (int status = _mon_check_props(h, value->attributes.size, value->attributes.direction, value->attributes.scalar, value->attributes.type)) return status; if (value->children.size) { int size = 0; TestVpiHandle iter_h = vpi_iterate(vpiMemoryWord, h); while (TestVpiHandle word_h = vpi_scan(iter_h.nofree())) { // check size and range if (int status = _mon_check_props(word_h, value->children.size, value->children.direction, value->children.scalar, value->children.type)) return status; size++; } CHECK_RESULT(size, value->attributes.size); } value++; } return 0; } int mon_check() { // Callback from initial block in monitor if (int status = mon_check_props()) return status; return 0; // Ok } //====================================================================== #ifdef IS_VPI static int mon_check_vpi() { vpiHandle href = vpi_handle(vpiSysTfCall, 0); s_vpi_value vpi_value; vpi_value.format = vpiIntVal; vpi_value.value.integer = mon_check(); vpi_put_value(href, &vpi_value, NULL, vpiNoDelay); return 0; } static s_vpi_systf_data vpi_systf_data[] = { {vpiSysFunc, vpiIntFunc, (PLI_BYTE8*)"$mon_check", (PLI_INT32(*)(PLI_BYTE8*))mon_check_vpi, 0, 0, 0}, 0 }; // cver entry void vpi_compat_bootstrap(void) { p_vpi_systf_data systf_data_p; systf_data_p = &(vpi_systf_data[0]); while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++); } // icarus entry void (*vlog_startup_routines[])() = { vpi_compat_bootstrap, 0 }; #else double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { double sim_time = 1100; Verilated::commandArgs(argc, argv); Verilated::debug(0); VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out #ifdef VERILATOR # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif #endif #if VM_TRACE Verilated::traceEverOn(true); VL_PRINTF("Enabling waves...\n"); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_vpi_var/simx.vcd"); #endif topp->eval(); topp->clk = 0; main_time += 10; while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += 1; topp->eval(); VerilatedVpi::callValueCbs(); topp->clk = !topp->clk; //mon_do(); #if VM_TRACE if (tfp) tfp->dump (main_time); #endif } if (!Verilated::gotFinish()) { vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish"); } topp->final(); #if VM_TRACE if (tfp) tfp->close(); #endif delete topp; topp=NULL; exit(0L); } #endif verilator-3.874/test_regress/t/t_var_static.v0000664000177100017500000000334412525171734021363 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; function int f_no_no (); int st = 2; st++; return st; endfunction function int f_no_st (); static int st = 2; st++; return st; endfunction function int f_no_au (); automatic int st = 2; st++; return st; endfunction function static int f_st_no (); int st = 2; st++; return st; endfunction function static int f_st_st (); static int st = 2; st++; return st; endfunction function static int f_st_au (); automatic int st = 2; st++; return st; endfunction function automatic int f_au_no (); int st = 2; st++; return st; endfunction function automatic int f_au_st (); static int st = 2; st++; return st; endfunction function automatic int f_au_au (); automatic int st = 2; st++; return st; endfunction initial begin if (f_no_no() != 3) $stop; if (f_no_no() != 4) $stop; if (f_no_st() != 3) $stop; if (f_no_st() != 4) $stop; if (f_no_au() != 3) $stop; if (f_no_au() != 3) $stop; // if (f_st_no() != 3) $stop; if (f_st_no() != 4) $stop; if (f_st_st() != 3) $stop; if (f_st_st() != 4) $stop; if (f_st_au() != 3) $stop; if (f_st_au() != 3) $stop; // if (f_au_no() != 3) $stop; if (f_au_no() != 3) $stop; if (f_au_st() != 3) $stop; if (f_au_st() != 4) $stop; if (f_au_au() != 3) $stop; if (f_au_au() != 3) $stop; // $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_preproc.pl0000775000177100017500000000364112473477707021062 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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"); $Self->{golden_out} ||= "t/$Self->{name}.out"; my $stdout_filename = "$Self->{obj_dir}/$Self->{name}__test.vpp"; compile ( verilator_flags2 => ['-DDEF_A0 -DPREDEF_COMMAND_LINE -E'], verilator_make_gcc=>0, stdout_filename => $stdout_filename, ); ok(preproc_check($Self->{top_filename}, $stdout_filename) && files_identical($stdout_filename, $Self->{golden_out})); sub preproc_check { my $filename1 = shift; my $filename2 = shift; my @Line_Checks; { # Read line comments. my $fh = IO::File->new($filename1) or die "%Error: $! $filename1\n"; while (defined(my $line = $fh->getline)) { if ($line =~ /^Line_Preproc_Check/) { push @Line_Checks, $.; } } $fh->close; } { # See if output file agrees. my $fh = IO::File->new($filename2) or die "%Error: $! $filename2\n"; my $lineno = 0; while (defined(my $line = $fh->getline)) { $lineno++; if ($line =~ /^\`line\s+(\d+)/) { $lineno = $1 - 1; } if ($line =~ /^Line_Preproc_Check\s+(\d+)/) { my $linecmt = $1; my $check = shift @Line_Checks; if (!$check) { $Self->error("$filename2:$.: Extra Line_Preproc_Check\n"); } if ($linecmt != $check) { $Self->error("$filename2:$.: __LINE__ inserted $linecmt, exp=$check\n"); } if ($lineno != $check) { $Self->error("$filename2:$.: __LINE__ on `line $lineno, exp=$check\n"); } } } $fh->close; } if ($Line_Checks[0]) { $Self->error("$filename2: Missing a Line_Preproc_Check\n"); } return 1; } 1; verilator-3.874/test_regress/t/t_case_huge_sub.v0000664000177100017500000004007712473477707022037 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t_case_huge_sub (/*AUTOARG*/ // Outputs outa, outb, outc, // Inputs index ); input [7:0] index; output [9:0] outa; output [1:0] outb; output outc; // ============================= /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [9:0] outa; reg [1:0] outb; reg outc; // End of automatics // ============================= // Created from perl // for $i (0..1023) { printf "\t10'h%03x: begin outa = 10'h%03x; outb = 2'b%02b; outc = 1'b%d; end\n", $i, rand(1024),rand(4),rand(2); }; always @(/*AS*/index) begin case (index) 8'h00: begin outa = 10'h152; outb = 2'b00; outc = 1'b1; end 8'h01: begin outa = 10'h318; outb = 2'b11; outc = 1'b1; end 8'h02: begin outa = 10'h29f; outb = 2'b11; outc = 1'b0; end 8'h03: begin outa = 10'h392; outb = 2'b01; outc = 1'b1; end 8'h04: begin outa = 10'h1ef; outb = 2'b00; outc = 1'b0; end 8'h05: begin outa = 10'h06c; outb = 2'b10; outc = 1'b1; end 8'h06: begin outa = 10'h29f; outb = 2'b11; outc = 1'b0; end 8'h07: begin outa = 10'h29a; outb = 2'b10; outc = 1'b0; end 8'h08: begin outa = 10'h3ce; outb = 2'b01; outc = 1'b0; end 8'h09: begin outa = 10'h37c; outb = 2'b01; outc = 1'b0; end 8'h0a: begin outa = 10'h058; outb = 2'b10; outc = 1'b0; end 8'h0b: begin outa = 10'h3b2; outb = 2'b01; outc = 1'b1; end 8'h0c: begin outa = 10'h36f; outb = 2'b11; outc = 1'b0; end 8'h0d: begin outa = 10'h2c5; outb = 2'b11; outc = 1'b0; end 8'h0e: begin outa = 10'h23a; outb = 2'b00; outc = 1'b0; end 8'h0f: begin outa = 10'h222; outb = 2'b01; outc = 1'b1; end 8'h10: begin outa = 10'h328; outb = 2'b00; outc = 1'b1; end 8'h11: begin outa = 10'h3c3; outb = 2'b00; outc = 1'b1; end 8'h12: begin outa = 10'h12c; outb = 2'b01; outc = 1'b0; end 8'h13: begin outa = 10'h1d0; outb = 2'b00; outc = 1'b1; end 8'h14: begin outa = 10'h3ff; outb = 2'b01; outc = 1'b1; end 8'h15: begin outa = 10'h115; outb = 2'b11; outc = 1'b1; end 8'h16: begin outa = 10'h3ba; outb = 2'b10; outc = 1'b0; end 8'h17: begin outa = 10'h3ba; outb = 2'b00; outc = 1'b0; end 8'h18: begin outa = 10'h10d; outb = 2'b00; outc = 1'b1; end 8'h19: begin outa = 10'h13b; outb = 2'b01; outc = 1'b1; end 8'h1a: begin outa = 10'h0a0; outb = 2'b10; outc = 1'b1; end 8'h1b: begin outa = 10'h264; outb = 2'b11; outc = 1'b0; end 8'h1c: begin outa = 10'h3a2; outb = 2'b10; outc = 1'b0; end 8'h1d: begin outa = 10'h07c; outb = 2'b00; outc = 1'b1; end 8'h1e: begin outa = 10'h291; outb = 2'b00; outc = 1'b0; end 8'h1f: begin outa = 10'h1d1; outb = 2'b10; outc = 1'b0; end 8'h20: begin outa = 10'h354; outb = 2'b11; outc = 1'b1; end 8'h21: begin outa = 10'h0c0; outb = 2'b00; outc = 1'b1; end 8'h22: begin outa = 10'h191; outb = 2'b00; outc = 1'b0; end 8'h23: begin outa = 10'h379; outb = 2'b01; outc = 1'b0; end 8'h24: begin outa = 10'h073; outb = 2'b00; outc = 1'b0; end 8'h25: begin outa = 10'h2fd; outb = 2'b11; outc = 1'b1; end 8'h26: begin outa = 10'h2e0; outb = 2'b11; outc = 1'b1; end 8'h27: begin outa = 10'h337; outb = 2'b01; outc = 1'b1; end 8'h28: begin outa = 10'h2c7; outb = 2'b11; outc = 1'b1; end 8'h29: begin outa = 10'h19e; outb = 2'b11; outc = 1'b0; end 8'h2a: begin outa = 10'h107; outb = 2'b10; outc = 1'b0; end 8'h2b: begin outa = 10'h06a; outb = 2'b01; outc = 1'b1; end 8'h2c: begin outa = 10'h1c7; outb = 2'b01; outc = 1'b1; end 8'h2d: begin outa = 10'h107; outb = 2'b10; outc = 1'b0; end 8'h2e: begin outa = 10'h0cf; outb = 2'b01; outc = 1'b1; end 8'h2f: begin outa = 10'h009; outb = 2'b11; outc = 1'b1; end 8'h30: begin outa = 10'h09d; outb = 2'b00; outc = 1'b1; end 8'h31: begin outa = 10'h28e; outb = 2'b00; outc = 1'b0; end 8'h32: begin outa = 10'h010; outb = 2'b01; outc = 1'b0; end 8'h33: begin outa = 10'h1e0; outb = 2'b10; outc = 1'b0; end 8'h34: begin outa = 10'h079; outb = 2'b01; outc = 1'b1; end 8'h35: begin outa = 10'h13e; outb = 2'b10; outc = 1'b1; end 8'h36: begin outa = 10'h282; outb = 2'b11; outc = 1'b0; end 8'h37: begin outa = 10'h21c; outb = 2'b11; outc = 1'b1; end 8'h38: begin outa = 10'h148; outb = 2'b00; outc = 1'b1; end 8'h39: begin outa = 10'h3c0; outb = 2'b10; outc = 1'b0; end 8'h3a: begin outa = 10'h176; outb = 2'b01; outc = 1'b1; end 8'h3b: begin outa = 10'h3fc; outb = 2'b10; outc = 1'b1; end 8'h3c: begin outa = 10'h295; outb = 2'b11; outc = 1'b1; end 8'h3d: begin outa = 10'h113; outb = 2'b10; outc = 1'b1; end 8'h3e: begin outa = 10'h354; outb = 2'b01; outc = 1'b1; end 8'h3f: begin outa = 10'h0db; outb = 2'b11; outc = 1'b0; end 8'h40: begin outa = 10'h238; outb = 2'b01; outc = 1'b0; end 8'h41: begin outa = 10'h12b; outb = 2'b01; outc = 1'b1; end 8'h42: begin outa = 10'h1dc; outb = 2'b10; outc = 1'b0; end 8'h43: begin outa = 10'h137; outb = 2'b01; outc = 1'b1; end 8'h44: begin outa = 10'h1e2; outb = 2'b01; outc = 1'b1; end 8'h45: begin outa = 10'h3d5; outb = 2'b11; outc = 1'b1; end 8'h46: begin outa = 10'h30c; outb = 2'b11; outc = 1'b0; end 8'h47: begin outa = 10'h298; outb = 2'b11; outc = 1'b0; end 8'h48: begin outa = 10'h080; outb = 2'b00; outc = 1'b1; end 8'h49: begin outa = 10'h35a; outb = 2'b11; outc = 1'b1; end 8'h4a: begin outa = 10'h01b; outb = 2'b00; outc = 1'b0; end 8'h4b: begin outa = 10'h0a3; outb = 2'b11; outc = 1'b0; end 8'h4c: begin outa = 10'h0b3; outb = 2'b11; outc = 1'b1; end 8'h4d: begin outa = 10'h17a; outb = 2'b00; outc = 1'b0; end 8'h4e: begin outa = 10'h3ae; outb = 2'b11; outc = 1'b0; end 8'h4f: begin outa = 10'h078; outb = 2'b11; outc = 1'b0; end 8'h50: begin outa = 10'h322; outb = 2'b00; outc = 1'b1; end 8'h51: begin outa = 10'h213; outb = 2'b11; outc = 1'b0; end 8'h52: begin outa = 10'h11a; outb = 2'b11; outc = 1'b0; end 8'h53: begin outa = 10'h1a7; outb = 2'b00; outc = 1'b0; end 8'h54: begin outa = 10'h35a; outb = 2'b00; outc = 1'b1; end 8'h55: begin outa = 10'h233; outb = 2'b00; outc = 1'b0; end 8'h56: begin outa = 10'h01d; outb = 2'b01; outc = 1'b1; end 8'h57: begin outa = 10'h2d5; outb = 2'b00; outc = 1'b0; end 8'h58: begin outa = 10'h1a0; outb = 2'b00; outc = 1'b1; end 8'h59: begin outa = 10'h3d0; outb = 2'b00; outc = 1'b1; end 8'h5a: begin outa = 10'h181; outb = 2'b01; outc = 1'b1; end 8'h5b: begin outa = 10'h219; outb = 2'b01; outc = 1'b1; end 8'h5c: begin outa = 10'h26a; outb = 2'b01; outc = 1'b1; end 8'h5d: begin outa = 10'h050; outb = 2'b10; outc = 1'b0; end 8'h5e: begin outa = 10'h189; outb = 2'b10; outc = 1'b0; end 8'h5f: begin outa = 10'h1eb; outb = 2'b01; outc = 1'b1; end 8'h60: begin outa = 10'h224; outb = 2'b00; outc = 1'b1; end 8'h61: begin outa = 10'h2fe; outb = 2'b00; outc = 1'b0; end 8'h62: begin outa = 10'h0ae; outb = 2'b00; outc = 1'b1; end 8'h63: begin outa = 10'h1cd; outb = 2'b00; outc = 1'b0; end 8'h64: begin outa = 10'h273; outb = 2'b10; outc = 1'b1; end 8'h65: begin outa = 10'h268; outb = 2'b10; outc = 1'b0; end 8'h66: begin outa = 10'h111; outb = 2'b01; outc = 1'b0; end 8'h67: begin outa = 10'h1f9; outb = 2'b00; outc = 1'b0; end 8'h68: begin outa = 10'h232; outb = 2'b00; outc = 1'b1; end 8'h69: begin outa = 10'h255; outb = 2'b11; outc = 1'b0; end 8'h6a: begin outa = 10'h34c; outb = 2'b01; outc = 1'b1; end 8'h6b: begin outa = 10'h049; outb = 2'b01; outc = 1'b1; end 8'h6c: begin outa = 10'h197; outb = 2'b11; outc = 1'b0; end 8'h6d: begin outa = 10'h0fe; outb = 2'b11; outc = 1'b0; end 8'h6e: begin outa = 10'h253; outb = 2'b01; outc = 1'b1; end 8'h6f: begin outa = 10'h2de; outb = 2'b11; outc = 1'b0; end 8'h70: begin outa = 10'h13b; outb = 2'b10; outc = 1'b1; end 8'h71: begin outa = 10'h040; outb = 2'b10; outc = 1'b0; end 8'h72: begin outa = 10'h0b4; outb = 2'b00; outc = 1'b1; end 8'h73: begin outa = 10'h233; outb = 2'b11; outc = 1'b1; end 8'h74: begin outa = 10'h198; outb = 2'b00; outc = 1'b1; end 8'h75: begin outa = 10'h018; outb = 2'b00; outc = 1'b1; end 8'h76: begin outa = 10'h2f7; outb = 2'b00; outc = 1'b1; end 8'h77: begin outa = 10'h134; outb = 2'b11; outc = 1'b0; end 8'h78: begin outa = 10'h1ca; outb = 2'b10; outc = 1'b0; end 8'h79: begin outa = 10'h286; outb = 2'b10; outc = 1'b1; end 8'h7a: begin outa = 10'h0e6; outb = 2'b11; outc = 1'b1; end 8'h7b: begin outa = 10'h064; outb = 2'b10; outc = 1'b1; end 8'h7c: begin outa = 10'h257; outb = 2'b00; outc = 1'b1; end 8'h7d: begin outa = 10'h31a; outb = 2'b10; outc = 1'b1; end 8'h7e: begin outa = 10'h247; outb = 2'b01; outc = 1'b0; end 8'h7f: begin outa = 10'h299; outb = 2'b00; outc = 1'b0; end 8'h80: begin outa = 10'h02c; outb = 2'b00; outc = 1'b0; end 8'h81: begin outa = 10'h2bb; outb = 2'b11; outc = 1'b0; end 8'h82: begin outa = 10'h180; outb = 2'b10; outc = 1'b0; end 8'h83: begin outa = 10'h245; outb = 2'b01; outc = 1'b1; end 8'h84: begin outa = 10'h0da; outb = 2'b10; outc = 1'b0; end 8'h85: begin outa = 10'h367; outb = 2'b10; outc = 1'b0; end 8'h86: begin outa = 10'h304; outb = 2'b01; outc = 1'b0; end 8'h87: begin outa = 10'h38b; outb = 2'b11; outc = 1'b0; end 8'h88: begin outa = 10'h09f; outb = 2'b01; outc = 1'b0; end 8'h89: begin outa = 10'h1f0; outb = 2'b10; outc = 1'b1; end 8'h8a: begin outa = 10'h281; outb = 2'b10; outc = 1'b1; end 8'h8b: begin outa = 10'h019; outb = 2'b00; outc = 1'b0; end 8'h8c: begin outa = 10'h1f2; outb = 2'b10; outc = 1'b0; end 8'h8d: begin outa = 10'h0b1; outb = 2'b01; outc = 1'b1; end 8'h8e: begin outa = 10'h058; outb = 2'b01; outc = 1'b1; end 8'h8f: begin outa = 10'h39b; outb = 2'b00; outc = 1'b1; end 8'h90: begin outa = 10'h2ec; outb = 2'b10; outc = 1'b1; end 8'h91: begin outa = 10'h250; outb = 2'b00; outc = 1'b1; end 8'h92: begin outa = 10'h3f4; outb = 2'b10; outc = 1'b1; end 8'h93: begin outa = 10'h057; outb = 2'b10; outc = 1'b1; end 8'h94: begin outa = 10'h18f; outb = 2'b01; outc = 1'b1; end 8'h95: begin outa = 10'h105; outb = 2'b01; outc = 1'b1; end 8'h96: begin outa = 10'h1ae; outb = 2'b00; outc = 1'b1; end 8'h97: begin outa = 10'h04e; outb = 2'b10; outc = 1'b0; end 8'h98: begin outa = 10'h240; outb = 2'b11; outc = 1'b0; end 8'h99: begin outa = 10'h3e4; outb = 2'b01; outc = 1'b0; end 8'h9a: begin outa = 10'h3c6; outb = 2'b01; outc = 1'b0; end 8'h9b: begin outa = 10'h109; outb = 2'b00; outc = 1'b1; end 8'h9c: begin outa = 10'h073; outb = 2'b10; outc = 1'b1; end 8'h9d: begin outa = 10'h19f; outb = 2'b01; outc = 1'b0; end 8'h9e: begin outa = 10'h3b8; outb = 2'b01; outc = 1'b0; end 8'h9f: begin outa = 10'h00e; outb = 2'b00; outc = 1'b1; end 8'ha0: begin outa = 10'h1b3; outb = 2'b11; outc = 1'b1; end 8'ha1: begin outa = 10'h2bd; outb = 2'b11; outc = 1'b0; end 8'ha2: begin outa = 10'h324; outb = 2'b00; outc = 1'b1; end 8'ha3: begin outa = 10'h343; outb = 2'b10; outc = 1'b0; end 8'ha4: begin outa = 10'h1c9; outb = 2'b01; outc = 1'b0; end 8'ha5: begin outa = 10'h185; outb = 2'b00; outc = 1'b1; end 8'ha6: begin outa = 10'h37a; outb = 2'b00; outc = 1'b1; end 8'ha7: begin outa = 10'h0e0; outb = 2'b01; outc = 1'b1; end 8'ha8: begin outa = 10'h0a3; outb = 2'b10; outc = 1'b0; end 8'ha9: begin outa = 10'h019; outb = 2'b11; outc = 1'b0; end 8'haa: begin outa = 10'h099; outb = 2'b00; outc = 1'b1; end 8'hab: begin outa = 10'h376; outb = 2'b01; outc = 1'b1; end 8'hac: begin outa = 10'h077; outb = 2'b00; outc = 1'b1; end 8'had: begin outa = 10'h2b1; outb = 2'b11; outc = 1'b1; end 8'hae: begin outa = 10'h27f; outb = 2'b00; outc = 1'b0; end 8'haf: begin outa = 10'h265; outb = 2'b11; outc = 1'b0; end 8'hb0: begin outa = 10'h156; outb = 2'b10; outc = 1'b1; end 8'hb1: begin outa = 10'h1ce; outb = 2'b00; outc = 1'b0; end 8'hb2: begin outa = 10'h008; outb = 2'b01; outc = 1'b0; end 8'hb3: begin outa = 10'h12e; outb = 2'b11; outc = 1'b1; end 8'hb4: begin outa = 10'h199; outb = 2'b11; outc = 1'b0; end 8'hb5: begin outa = 10'h330; outb = 2'b10; outc = 1'b0; end 8'hb6: begin outa = 10'h1ab; outb = 2'b01; outc = 1'b1; end 8'hb7: begin outa = 10'h3bd; outb = 2'b00; outc = 1'b0; end 8'hb8: begin outa = 10'h0ca; outb = 2'b10; outc = 1'b0; end 8'hb9: begin outa = 10'h367; outb = 2'b00; outc = 1'b0; end 8'hba: begin outa = 10'h334; outb = 2'b00; outc = 1'b0; end 8'hbb: begin outa = 10'h040; outb = 2'b00; outc = 1'b1; end 8'hbc: begin outa = 10'h1a7; outb = 2'b10; outc = 1'b1; end 8'hbd: begin outa = 10'h036; outb = 2'b11; outc = 1'b1; end 8'hbe: begin outa = 10'h223; outb = 2'b11; outc = 1'b1; end 8'hbf: begin outa = 10'h075; outb = 2'b01; outc = 1'b0; end 8'hc0: begin outa = 10'h3c4; outb = 2'b00; outc = 1'b1; end 8'hc1: begin outa = 10'h2cc; outb = 2'b01; outc = 1'b0; end 8'hc2: begin outa = 10'h123; outb = 2'b01; outc = 1'b0; end 8'hc3: begin outa = 10'h3fd; outb = 2'b01; outc = 1'b1; end 8'hc4: begin outa = 10'h11e; outb = 2'b00; outc = 1'b0; end 8'hc5: begin outa = 10'h27c; outb = 2'b11; outc = 1'b1; end 8'hc6: begin outa = 10'h1e2; outb = 2'b11; outc = 1'b0; end 8'hc7: begin outa = 10'h377; outb = 2'b11; outc = 1'b0; end 8'hc8: begin outa = 10'h33a; outb = 2'b11; outc = 1'b0; end 8'hc9: begin outa = 10'h32d; outb = 2'b11; outc = 1'b1; end 8'hca: begin outa = 10'h014; outb = 2'b11; outc = 1'b0; end 8'hcb: begin outa = 10'h332; outb = 2'b10; outc = 1'b0; end 8'hcc: begin outa = 10'h359; outb = 2'b00; outc = 1'b0; end 8'hcd: begin outa = 10'h0a4; outb = 2'b10; outc = 1'b1; end 8'hce: begin outa = 10'h348; outb = 2'b00; outc = 1'b1; end 8'hcf: begin outa = 10'h04b; outb = 2'b11; outc = 1'b1; end 8'hd0: begin outa = 10'h147; outb = 2'b10; outc = 1'b1; end 8'hd1: begin outa = 10'h026; outb = 2'b00; outc = 1'b1; end 8'hd2: begin outa = 10'h103; outb = 2'b00; outc = 1'b0; end 8'hd3: begin outa = 10'h106; outb = 2'b00; outc = 1'b1; end 8'hd4: begin outa = 10'h35a; outb = 2'b00; outc = 1'b0; end 8'hd5: begin outa = 10'h254; outb = 2'b01; outc = 1'b0; end 8'hd6: begin outa = 10'h0cd; outb = 2'b01; outc = 1'b0; end 8'hd7: begin outa = 10'h17c; outb = 2'b11; outc = 1'b1; end 8'hd8: begin outa = 10'h37e; outb = 2'b10; outc = 1'b1; end 8'hd9: begin outa = 10'h0a9; outb = 2'b11; outc = 1'b1; end 8'hda: begin outa = 10'h0fe; outb = 2'b01; outc = 1'b0; end 8'hdb: begin outa = 10'h3c0; outb = 2'b11; outc = 1'b1; end 8'hdc: begin outa = 10'h1d9; outb = 2'b10; outc = 1'b1; end 8'hdd: begin outa = 10'h10e; outb = 2'b00; outc = 1'b1; end 8'hde: begin outa = 10'h394; outb = 2'b01; outc = 1'b0; end 8'hdf: begin outa = 10'h316; outb = 2'b01; outc = 1'b0; end 8'he0: begin outa = 10'h05b; outb = 2'b11; outc = 1'b0; end 8'he1: begin outa = 10'h126; outb = 2'b01; outc = 1'b1; end 8'he2: begin outa = 10'h369; outb = 2'b11; outc = 1'b0; end 8'he3: begin outa = 10'h291; outb = 2'b10; outc = 1'b1; end 8'he4: begin outa = 10'h2ca; outb = 2'b00; outc = 1'b1; end 8'he5: begin outa = 10'h25b; outb = 2'b01; outc = 1'b1; end 8'he6: begin outa = 10'h106; outb = 2'b00; outc = 1'b0; end 8'he7: begin outa = 10'h172; outb = 2'b11; outc = 1'b1; end 8'he8: begin outa = 10'h2f7; outb = 2'b00; outc = 1'b1; end 8'he9: begin outa = 10'h2d3; outb = 2'b11; outc = 1'b1; end 8'hea: begin outa = 10'h182; outb = 2'b00; outc = 1'b0; end 8'heb: begin outa = 10'h327; outb = 2'b00; outc = 1'b1; end 8'hec: begin outa = 10'h1d0; outb = 2'b10; outc = 1'b0; end 8'hed: begin outa = 10'h204; outb = 2'b00; outc = 1'b1; end 8'hee: begin outa = 10'h11f; outb = 2'b00; outc = 1'b1; end 8'hef: begin outa = 10'h365; outb = 2'b11; outc = 1'b1; end 8'hf0: begin outa = 10'h2c2; outb = 2'b01; outc = 1'b1; end 8'hf1: begin outa = 10'h2b5; outb = 2'b10; outc = 1'b0; end 8'hf2: begin outa = 10'h1f8; outb = 2'b10; outc = 1'b1; end 8'hf3: begin outa = 10'h2a7; outb = 2'b01; outc = 1'b1; end 8'hf4: begin outa = 10'h1be; outb = 2'b10; outc = 1'b1; end 8'hf5: begin outa = 10'h25e; outb = 2'b10; outc = 1'b1; end 8'hf6: begin outa = 10'h032; outb = 2'b10; outc = 1'b0; end 8'hf7: begin outa = 10'h2ef; outb = 2'b00; outc = 1'b0; end 8'hf8: begin outa = 10'h02f; outb = 2'b00; outc = 1'b1; end 8'hf9: begin outa = 10'h201; outb = 2'b10; outc = 1'b0; end 8'hfa: begin outa = 10'h054; outb = 2'b01; outc = 1'b1; end 8'hfb: begin outa = 10'h013; outb = 2'b10; outc = 1'b0; end 8'hfc: begin outa = 10'h249; outb = 2'b01; outc = 1'b0; end 8'hfd: begin outa = 10'h09a; outb = 2'b10; outc = 1'b0; end 8'hfe: begin outa = 10'h012; outb = 2'b00; outc = 1'b0; end 8'hff: begin outa = 10'h114; outb = 2'b10; outc = 1'b1; end endcase end endmodule verilator-3.874/test_regress/t/t_tri_pull01.v0000664000177100017500000000373212473477707021233 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Test: tri t; bufif1 (t, crc[1], cyc[1:0]==2'b00); bufif1 (t, crc[2], cyc[1:0]==2'b10); tri0 t0; bufif1 (t0, crc[1], cyc[1:0]==2'b00); bufif1 (t0, crc[2], cyc[1:0]==2'b10); tri1 t1; bufif1 (t1, crc[1], cyc[1:0]==2'b00); bufif1 (t1, crc[2], cyc[1:0]==2'b10); tri t2; t_tri2 t_tri2 (.t2, .d(crc[1]), .oe(cyc[1:0]==2'b00)); bufif1 (t2, crc[2], cyc[1:0]==2'b10); tri t3; t_tri3 t_tri3 (.t3, .d(crc[1]), .oe(cyc[1:0]==2'b00)); bufif1 (t3, crc[2], cyc[1:0]==2'b10); wire [63:0] result = {51'h0, t3, 3'h0,t2, 3'h0,t1, 3'h0,t0}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h04f91df71371e950 if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module t_tri2 (/*AUTOARG*/ // Outputs t2, // Inputs d, oe ); output t2; input d; input oe; tri1 t2; bufif1 (t2, d, oe); endmodule module t_tri3 (/*AUTOARG*/ // Outputs t3, // Inputs d, oe ); output tri1 t3; input d; input oe; bufif1 (t3, d, oe); endmodule verilator-3.874/test_regress/t/t_lint_latch_bad.pl0000775000177100017500000000206312525171734022321 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( v_flags2 => ["--lint-only -Wwarn-style -Wno-DECLFILENAME"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> quotemeta( '%Warning-COMBDLY: t/t_lint_latch_bad.v:24: Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=). %Warning-COMBDLY: Use "/* verilator lint_off COMBDLY */" and lint_on around source to disable this message. %Warning-COMBDLY: *** See the manual before disabling this, %Warning-COMBDLY: else you may end up with different sim results. %Error: Exiting due to 1 warning').'.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_array.v0000664000177100017500000000241212473477707021405 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; parameter ONE = 1; wire [17:10] bitout; reg [7:0] allbits; reg [15:0] onebit; sub sub [7:0] (allbits, onebit, bitout); integer x; always @ (posedge clk) begin //$write("%x\n", bitout); if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin allbits <= 8'hac; onebit <= 16'hc01a; end if (cyc==2) begin if (bitout !== 8'h07) $stop; allbits <= 8'hca; onebit <= 16'h1f01; end if (cyc==3) begin if (bitout !== 8'h41) $stop; if (sub[0].bitout !== 1'b1) $stop; if (sub[1].bitout !== 1'b0) $stop; `ifndef verilator // Hacky array subscripting if (sub[ONE].bitout !== 1'b0) $stop; `endif $write("*-* All Finished *-*\n"); $finish; end end end endmodule `ifdef USE_INLINE `define INLINE_MODULE /*verilator inline_module*/ `else `define INLINE_MODULE /*verilator public_module*/ `endif module sub (input [7:0] allbits, input [1:0] onebit, output bitout); `INLINE_MODULE wire bitout = (^ onebit) ^ (^ allbits); endmodule verilator-3.874/test_regress/t/t_inst_first_b.v0000664000177100017500000000147712473477707021731 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_inst_first_b (/*AUTOARG*/ // Outputs o_seq_d1r, o_com, o2_com, // Inputs clk, i_seq, i_com, i2_com, wide_for_trace, wide_for_trace_2 ); // verilator inline_module input clk; input i_seq; output o_seq_d1r; input i_com; output o_com; input [1:0] i2_com; output [1:0] o2_com; input [127:0] wide_for_trace; input [127:0] wide_for_trace_2; /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) // End of automatics reg o_seq_d1r; always @ (posedge clk) begin o_seq_d1r <= ~i_seq; end wire [1:0] o2_com = ~i2_com; wire o_com = ~i_com; endmodule verilator-3.874/test_regress/t/t_pp_circdef_bad.v0000664000177100017500000000061512473477707022141 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. // // bug445 `define WIDTH 12 `define SEL_NUM_BITS `WIDTH-`SEL_NUM_BITS +: `SEL_NUM_BITS `define SEL_BITS `WIDTH-`SEL_NUM_BITS +: `SEL_NUM_BITS `define ADDR_BITS 0 +: `WIDTH-`SEL_NUM_BITS typedef logic [`SEL_NUM_BITS-1:0] d_t; verilator-3.874/test_regress/t/t_func_numones.pl0000775000177100017500000000071712473477707022110 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_bind.v0000664000177100017500000000251612473477707020153 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. bit a_finished; bit b_finished; module t (/*AUTOARG*/ // Inputs clk ); input clk; wire [31:0] o; wire si = 1'b0; ExampInst i (// Outputs .o (o[31:0]), // Inputs .i (1'b0) /*AUTOINST*/); Prog p (/*AUTOINST*/ // Inputs .si (si)); always @ (posedge clk) begin if (!a_finished) $stop; if (!b_finished) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule module InstModule ( output logic [31:0] so, input si ); assign so = {32{si}}; endmodule program Prog (input si); initial a_finished = 1'b1; endprogram module ExampInst (o,i); output logic [31:0] o; input i; InstModule instName (// Outputs .so (o[31:0]), // Inputs .si (i) /*AUTOINST*/); //bind InstModule Prog instProg // (.si(si)); // Note is based on context of caller bind InstModule Prog instProg (/*AUTOBIND*/ .si (si)); endmodule // Check bind at top level bind InstModule Prog2 instProg2 (/*AUTOBIND*/ .si (si)); // Check program declared after bind program Prog2 (input si); initial b_finished = 1'b1; endprogram verilator-3.874/test_regress/t/t_dpi_string.pl0000775000177100017500000000077312473477707021555 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["t/t_dpi_string_c.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_const.pl0000775000177100017500000000071712473477707021550 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_concat0.pl0000775000177100017500000000071712473477707021751 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sys_readmem_bad_end.v0000664000177100017500000000055512473477707023204 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; reg [175:0] hex [15:0]; integer i; initial begin $readmemh("t/t_sys_readmem_bad_end.mem", hex, 0, 15); $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_func_paramed.v0000664000177100017500000000303612473477707021661 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [11:0] in_a; reg [31:0] sel; wire [2:0] out_x; extractor #(4,3) extractor ( // Outputs .out (out_x), // Inputs .in (in_a), .sel (sel)); integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; //$write("%d %x %x %x\n", cyc, in_a, sel, out_x); if (cyc==1) begin in_a <= 12'b001_101_111_010; sel <= 32'd0; end if (cyc==2) begin sel <= 32'd1; if (out_x != 3'b010) $stop; end if (cyc==3) begin sel <= 32'd2; if (out_x != 3'b111) $stop; end if (cyc==4) begin sel <= 32'd3; if (out_x != 3'b101) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module extractor (/*AUTOARG*/ // Outputs out, // Inputs in, sel ); parameter IN_WIDTH=8; parameter OUT_WIDTH=2; input [IN_WIDTH*OUT_WIDTH-1:0] in; output [OUT_WIDTH-1:0] out; input [31:0] sel; wire [OUT_WIDTH-1:0] out = selector(in,sel); function [OUT_WIDTH-1:0] selector; input [IN_WIDTH*OUT_WIDTH-1:0] inv; input [31:0] selv; integer i; begin selector = 0; for (i=0; i ["--trace"], ); execute ( check_finished=>1, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/simx.vcd", "sub_t_i"); }; ok(1); 1; verilator-3.874/test_regress/t/t_display_real.pl0000775000177100017500000000252212473477707022055 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, expect=> quotemeta( '[0] e=0.000000e+00 e1=0.000000e+00 e30=0e+00 e32=0.00e+00 [0] f=0.000000 f1=0.000000e+00 f30=0e+00 f32=0.00e+00 [0] g=0 g1=0.000000e+00 g30=0e+00 g32=0.00e+00 [0] e=1.000000e+00 e1=1.000000e+00 e30=1e+00 e32=1.00e+00 [0] f=1.000000 f1=1.000000e+00 f30=1e+00 f32=1.00e+00 [0] g=1 g1=1.000000e+00 g30=1e+00 g32=1.00e+00 [0] e=1.000000e-01 e1=1.000000e-01 e30=1e-01 e32=1.00e-01 [0] f=0.100000 f1=1.000000e-01 f30=1e-01 f32=1.00e-01 [0] g=0.1 g1=1.000000e-01 g30=1e-01 g32=1.00e-01 [0] e=1.234500e-15 e1=1.234500e-15 e30=1e-15 e32=1.23e-15 [0] f=0.000000 f1=1.234500e-15 f30=1e-15 f32=1.23e-15 [0] g=1.2345e-15 g1=1.234500e-15 g30=1e-15 g32=1.23e-15 [0] e=2.579000e+15 e1=2.579000e+15 e30=3e+15 e32=2.58e+15 [0] f=2579000000000000.000000 f1=2.579000e+15 f30=3e+15 f32=2.58e+15 [0] g=2.579e+15 g1=2.579000e+15 g30=3e+15 g32=2.58e+15 r8= 3 n1=1 n2=0.1 n1=1 n2=0.1 r8= 3 '), ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_complex_structs.pl0000775000177100017500000000227212473477707024023 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t_trace_complex.v"); compile ( verilator_flags2 => ['--cc --trace --trace-structs --no-trace-params'], ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_strp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_strp_strp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp /); file_grep_not ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp_arrp /); file_grep_not ("$Self->{obj_dir}/simx.vcd", qr/ v_arrp_strp /); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru\(/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arru\(/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_arrp\(/); file_grep ("$Self->{obj_dir}/simx.vcd", qr/ v_arru_strp\(/); vcd_identical ("$Self->{obj_dir}/simx.vcd", "t/$Self->{name}.out"); ok(1); 1; verilator-3.874/test_regress/t/t_var_pins_sc1.pl0000775000177100017500000000410512473477707021773 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -pins-bv 1 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.874/test_regress/t/t_lint_inherit.pl0000775000177100017500000000064712473477707022103 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); ok(1); 1; verilator-3.874/test_regress/t/t_mod_dup_ign.pl0000775000177100017500000000110012473477707021660 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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->skip("Verilator only test") if !$Self->{vlt}; compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["--lint-only"], verilator_make_gcc => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_param1.pl0000775000177100017500000000102412473477707022602 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_regfirst.pl0000775000177100017500000000071712473477707022251 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_assert_cover.v0000664000177100017500000000645212473477707021741 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg toggle; integer cyc; initial cyc=1; Test test (/*AUTOINST*/ // Inputs .clk (clk), .toggle (toggle), .cyc (cyc[31:0])); always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; toggle <= !cyc[0]; if (cyc==9) begin end if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module Test ( input clk, input toggle, input [31:0] cyc ); // Simple cover cover property (@(posedge clk) cyc==3); // With statement, in generate generate if (1) begin cover property (@(posedge clk) cyc==4) $display("*COVER: Cyc==4"); end endgenerate // Labeled cover cyc_eq_5: cover property (@(posedge clk) cyc==5) $display("*COVER: Cyc==5"); // Using default clock default clocking @(posedge clk); endclocking cover property (cyc==6) $display("*COVER: Cyc==6"); // Disable statement // Note () after disable are required cover property (@(posedge clk) disable iff (toggle) cyc==8) $display("*COVER: Cyc==8"); cover property (@(posedge clk) disable iff (!toggle) cyc==8) $stop; //============================================================ // Using a macro and generate wire reset = (cyc < 2); `define covclk(eqn) cover property (@(posedge clk) disable iff (reset) (eqn)) genvar i; generate for (i=0; i<32; i=i+1) begin: cycval CycCover_i: `covclk( cyc[i] ); end endgenerate `ifndef verilator // Unsupported //============================================================ // Using a more complicated property property C1; @(posedge clk) disable iff (!toggle) cyc==5; endproperty cover property (C1) $display("*COVER: Cyc==5"); // Using covergroup // Note a covergroup is really inheritance of a special system "covergroup" class. covergroup counter1 @ (posedge cyc); // Automatic methods: stop(), start(), sample(), set_inst_name() // Each bin value must be <= 32 bits. Strange. cyc_value : coverpoint cyc { } cyc_bined : coverpoint cyc { bins zero = {0}; bins low = {1,5}; // Note 5 is also in the bin above. Only the first bin matching is counted. bins mid = {[5:$]}; // illegal_bins // Has precidence over "first matching bin", creates assertion // ignore_bins // Not counted, and not part of total } toggle : coverpoint (toggle) { bins off = {0}; bins on = {1}; } cyc5 : coverpoint (cyc==5) { bins five = {1}; } // option.at_least = {number}; // Default 1 - Hits to be considered covered // option.auto_bin_max = {number}; // Default 64 // option.comment = {string} // option.goal = {number}; // Default 90% // option.name = {string} // option.per_instance = 1; // Default 0 - each instance separately counted (cadence default is 1) // option.weight = {number}; // Default 1 // CROSS value_and_toggle: // else default is ___X__ cross cyc_value, toggle; endgroup counter1 c1 = new(); `endif endmodule verilator-3.874/test_regress/t/t_param_named.pl0000775000177100017500000000071712473477707021655 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_check.v0000664000177100017500000000246012473477707021325 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // verilator lint_off WIDTH // verilator lint_off VARHIDDEN module t ( clk ); input clk; integer cyc=0; reg [63:0] crc; initial crc = 64'h1; chk chk (.clk (clk), .rst_l (1'b1), .expr (|crc) ); always @ (posedge clk) begin cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==0) begin crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<90) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module chk (input clk, input rst_l, input expr); integer errors; initial errors = 0; task printerr; input [8*64:1] msg; begin errors = errors + 1; $write("%%Error: %0s\n", msg); $stop; end endtask always @(posedge clk) begin if (rst_l) begin if (expr == 1'b0) begin printerr("expr not asserted"); end end end wire noxs = ((expr ^ expr) == 1'b0); reg hasx; always @ (noxs) begin if (noxs) begin hasx = 1'b0; end else begin hasx = 1'b1; end end always @(posedge clk) begin if (rst_l) begin if (hasx) begin printerr("expr has unknowns"); end end end endmodule verilator-3.874/test_regress/t/t_gen_forif.pl0000775000177100017500000000075512473477707021351 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( nc_flags2 => ['+access+r'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_preproc_inc4.vh0000664000177100017500000000030012473477707021763 0ustar wsnyderwsnyder// DESCRIPTION: Verilog::Preproc: Example source code // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2000-2011 by Wilson Snyder. `define T_PREPROC_INC4 verilator-3.874/test_regress/t/t_gen_for_overlap.pl0000775000177100017500000000072212473477707022554 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_leak.cpp0000664000177100017500000000444112473477707020467 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test driver/expect definition // // Copyright 2003-2009 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. #include #include #include #include "Vt_leak.h" unsigned int main_time = false; double sc_time_stamp () { return main_time; } long long get_memory_usage() { // Return memory usage. Return 0 if the system doesn't look quite right. #if 0 // BSD only. struct rusage usage; getrusage(RUSAGE_SELF, &usage); return usage.ru_ixrss + usage.ru_idrss + usage.ru_isrss; #endif FILE* fp = fopen("/proc/self/stat", "r"); if (!fp) return 0; int ps_ign; vluint64_t ps_vsize, ps_rss; int items = fscanf(fp, ("%d (%*[^) ]) %*1s %d %*d %*d %*d %*d %u" " %u %u %u %u %d %d %d %d" " %*d %*d %*u %*u %d %" VL_PRI64 "u %" VL_PRI64 "u "), &ps_ign, &ps_ign, &ps_ign, &ps_ign, &ps_ign, &ps_ign, &ps_ign, &ps_ign, &ps_ign, &ps_ign, &ps_ign, &ps_ign, &ps_vsize, &ps_rss); fclose(fp); if (items >= 14) { return ps_vsize; } else { return 0; } } void make_and_destroy () { Vt_leak* topp = new Vt_leak; Verilated::debug(0); Verilated::gotFinish(0); topp->eval(); topp->clk = true; while (!Verilated::gotFinish()) { main_time+=5; topp->clk=!topp->clk; topp->eval(); } delete topp; topp=NULL; } int main (int argc, char *argv[]) { vluint64_t firstUsage = get_memory_usage(); // Warmup phase for (int i=0; i<1000; i++) { make_and_destroy(); } firstUsage = get_memory_usage(); printf("Memory size %" VL_PRI64 "d bytes\n", firstUsage); int loops = 100*1000; for (int left=loops; left>0;) { for (int j=0; j<1000; j++, left--) { make_and_destroy(); } } vluint64_t leaked = get_memory_usage() - firstUsage; if (leaked > 64*1024) { // Have to allow some slop for this code. printf ("Leaked %" VL_PRI64 "d bytes, or ~ %" VL_PRI64 "d bytes/construt\n", leaked, leaked/loops); vl_fatal(__FILE__,__LINE__,"top", "Leaked memory\n"); } printf ("*-* All Finished *-*\n"); } verilator-3.874/test_regress/t/t_unroll_genf.pl0000775000177100017500000000072212473477707021717 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_cat_reopen.pl0000775000177100017500000000151612473477707022704 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2013 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"); top_filename("t_trace_cat.v"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_cat.cpp"], ); execute ( check_finished=>1, ); vcd_identical ("$Self->{obj_dir}/simpart_0000.vcd", "t/$Self->{name}_0000.out"); vcd_identical ("$Self->{obj_dir}/simpart_0100.vcd", "t/$Self->{name}_0100.out"); ok(1); 1; verilator-3.874/test_regress/t/t_langext_1.v0000664000177100017500000000204312473477707021114 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // A test of the +verilog1995ext+ and +verilog2001ext+ flags. // // This source code contains constructs that are valid in Verilog 2001 and // SystemVerilog 2005/2009, but not in Verilog 1995. So it should fail if we // set the language to be 1995, but not 2001. // // Compile only test, so no need for "All Finished" output. // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Jeremy Bennett. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [1:0] res; // Instantiate the test test test_i (/*AUTOINST*/ // Outputs .res (res), // Inputs .clk (clk), .in (1'b1)); endmodule module test (// Outputs res, // Inputs clk, in ); output [1:0] res; input clk; input in; // This is a Verilog 2001 test generate genvar i; for (i=0; i<2; i=i+1) begin always @(posedge clk) begin res[i:i] <= in; end end endgenerate endmodule verilator-3.874/test_regress/t/t_func_regfirst.v0000664000177100017500000000240712473477707022076 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (clk); input clk; reg [2:0] a; reg [2:0] b; reg q; f6 f6 (/*AUTOINST*/ // Outputs .q (q), // Inputs .a (a[2:0]), .b (b[2:0]), .clk (clk)); integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin a <= 3'b000; b <= 3'b100; end if (cyc==2) begin a <= 3'b011; b <= 3'b001; if (q != 1'b0) $stop; end if (cyc==3) begin a <= 3'b011; b <= 3'b011; if (q != 1'b0) $stop; end if (cyc==9) begin if (q != 1'b1) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule module f6 (a, b, clk, q); input [2:0] a; input [2:0] b; input clk; output q; reg out; function func6; reg result; input [5:0] src; begin if (src[5:0] == 6'b011011) begin result = 1'b1; end else begin result = 1'b0; end func6 = result; end endfunction wire [5:0] w6 = {a, b}; always @(posedge clk) begin out <= func6(w6); end assign q = out; endmodule verilator-3.874/test_regress/t/t_sys_file_basic.v0000664000177100017500000001447012525171734022204 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. `include "verilated.v" module t; `verilator_file_descriptor file; integer chars; reg [1*8:1] letterl; reg [8*8:1] letterq; reg [16*8:1] letterw; reg [16*8:1] letterz; real r; string s; reg [7:0] v_a,v_b,v_c,v_d; reg [31:0] v_worda; reg [31:0] v_wordb; `ifdef TEST_VERBOSE `define verbose 1'b1 `else `define verbose 1'b0 `endif initial begin // Display formatting `ifdef verilator if (file != 0) $stop; $fwrite(file, "Never printed, file closed\n"); if (!$feof(file)) $stop; `endif `ifdef AUTOFLUSH // The "w" is required so we get a FD not a MFD file = $fopen("obj_dir/t_sys_file_autoflush/t_sys_file_autoflush.log","w"); `else // The "w" is required so we get a FD not a MFD file = $fopen("obj_dir/t_sys_file_basic/t_sys_file_basic_test.log","w"); `endif if ($feof(file)) $stop; $fdisplay(file, "[%0t] hello v=%x", $time, 32'h12345667); $fwrite(file, "[%0t] %s\n", $time, "Hello2"); $fflush(file); $fclose(file); `ifdef verilator if (file != 0) $stop(1); // Also test arguments to stop $fwrite(file, "Never printed, file closed\n"); `endif begin // Check for opening errors // The "r" is required so we get a FD not a MFD file = $fopen("obj_dir/t_sys_file_basic/DOES_NOT_EXIST","r"); if (|file) $stop; // Should not exist, IE must return 0 end begin // Check quadword access; a little strange, but it's legal to open "." file = $fopen(".","r"); $fclose(file); end begin // Check read functions file = $fopen("t/t_sys_file_basic_input.dat","r"); if ($feof(file)) $stop; // $fgetc if ($fgetc(file) != "h") $stop; if ($fgetc(file) != "i") $stop; if ($fgetc(file) != "\n") $stop; // $fgets chars = $fgets(letterl, file); if (`verbose) $write("c=%0d l=%s\n", chars, letterl); if (chars != 1) $stop; if (letterl != "l") $stop; chars = $fgets(letterq, file); if (`verbose) $write("c=%0d q=%x=%s", chars, letterq, letterq); // Output includes newline if (chars != 5) $stop; if (letterq != "\0\0\0quad\n") $stop; letterw = "5432109876543210"; chars = $fgets(letterw, file); if (`verbose) $write("c=%0d w=%s", chars, letterw); // Output includes newline if (chars != 10) $stop; if (letterw != "\0\0\0\0\0\0widestuff\n") $stop; // $sscanf if ($sscanf("x","")!=0) $stop; if ($sscanf("z","z")!=0) $stop; chars = $sscanf("blabcdefghijklmnop", "%s", letterq); if (`verbose) $write("c=%0d sa=%s\n", chars, letterq); if (chars != 1) $stop; if (letterq != "ijklmnop") $stop; chars = $sscanf("xa=1f xb=12898971238912389712783490823_237904689_02348923", "xa=%x xb=%x", letterq, letterw); if (`verbose) $write("c=%0d xa=%x xb=%x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h1f) $stop; if (letterw != 128'h38971278349082323790468902348923) $stop; chars = $sscanf("ba=10 bb=110100101010010101012 note_the_two ", "ba=%b bb=%b%s", letterq, letterw, letterz); if (`verbose) $write("c=%0d xa=%x xb=%x z=%0s\n", chars, letterq, letterw, letterz); if (chars != 3) $stop; if (letterq != 64'h2) $stop; if (letterw != 128'hd2a55) $stop; if (letterz != {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0","2"}) $stop; chars = $sscanf("oa=23 ob=125634123615234123681236", "oa=%o ob=%o", letterq, letterw); if (`verbose) $write("c=%0d oa=%x ob=%x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h13) $stop; if (letterw != 128'h55ce14f1a9c29e) $stop; chars = $sscanf("r=0.1 d=-236123", "r=%g d=%d", r, letterq); if (`verbose) $write("c=%0d d=%d\n", chars, letterq); if (chars != 2) $stop; if (r != 0.1) $stop; if (letterq != 64'hfffffffffffc65a5) $stop; s = "r=0.2 d=-236124"; chars = $sscanf(s, "r=%g d=%d", r, letterq); if (`verbose) $write("c=%0d d=%d\n", chars, letterq); if (chars != 2) $stop; if (r != 0.2) $stop; if (letterq != 64'hfffffffffffc65a4) $stop; // $fscanf if ($fscanf(file,"")!=0) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "xa=%x xb=%x", letterq, letterw); if (`verbose) $write("c=%0d xa=%0x xb=%0x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h1f) $stop; if (letterw != 128'h23790468902348923) $stop; if (!sync("\n")) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "ba=%b bb=%b %s", letterq, letterw, letterz); if (`verbose) $write("c=%0d ba=%0x bb=%0x z=%0s\n", chars, letterq, letterw, letterz); if (chars != 3) $stop; if (letterq != 64'h2) $stop; if (letterw != 128'hd2a55) $stop; if (letterz != "\0\0\0\0note_the_two") $stop; if (!sync("\n")) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "oa=%o ob=%o", letterq, letterw); if (`verbose) $write("c=%0d oa=%0x ob=%0x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h13) $stop; if (letterw != 128'h1573) $stop; if (!sync("\n")) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "d=%d", letterq); if (`verbose) $write("c=%0d d=%0x\n", chars, letterq); if (chars != 1) $stop; if (letterq != 64'hfffffffffffc65a5) $stop; if (!sync("\n")) $stop; if (!sync("*")) $stop; chars = $fscanf(file, "%c%s", letterl, letterw); if (`verbose) $write("c=%0d q=%c s=%s\n", chars, letterl, letterw); if (chars != 2) $stop; if (letterl != "f") $stop; if (letterw != "\0\0\0\0\0redfishblah") $stop; chars = $fscanf(file, "%c", letterl); if (`verbose) $write("c=%0d l=%x\n", chars, letterl); if (chars != 1) $stop; if (letterl != "\n") $stop; // msg1229 v_a = $fgetc(file); v_b = $fgetc(file); v_c = $fgetc(file); v_d = $fgetc(file); v_worda = { v_d, v_c, v_b, v_a }; if (v_worda != "4321") $stop; v_wordb[7:0] = $fgetc(file); v_wordb[15:8] = $fgetc(file); v_wordb[23:16] = $fgetc(file); v_wordb[31:24] = $fgetc(file); if (v_wordb != "9876") $stop; if ($fgetc(file) != "\n") $stop; $fclose(file); end $write("*-* All Finished *-*\n"); $finish(0); // Test arguments to finish end function sync; input [7:0] cexp; reg [7:0] cgot; begin cgot = $fgetc(file); if (`verbose) $write("sync=%x='%c'\n", cgot,cgot); sync = (cgot == cexp); end endfunction endmodule verilator-3.874/test_regress/t/t_var_pinsizes.v0000664000177100017500000000253612525171734021742 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. // Also check that SystemC is ordering properly // verilator lint_on IMPERFECTSCH module t (/*AUTOARG*/ // Outputs o1, o8, o16, o32, o64, o65, o128, o513, o1a2, o94a3, obv1, obv16, // Inputs clk, i1, i8, i16, i32, i64, i65, i128, i513, i1a2, i94a3, ibv1, ibv16 ); input clk; input i1; input [7:0] i8; input [15:0] i16; input [31:0] i32; input [63:0] i64; input [64:0] i65; input [127:0] i128; input [512:0] i513; input i1a2 [1:0]; input [93:0] i94a3 [2:0]; output o1; output [7:0] o8; output [15:0] o16; output [31:0] o32; output [63:0] o64; output [64:0] o65; output [127:0] o128; output [512:0] o513; output o1a2 [1:0]; output [93:0] o94a3 [2:0]; input [0:0] ibv1 /*verilator sc_bv*/; input [15:0] ibv16 /*verilator sc_bv*/; output [0:0] obv1 /*verilator sc_bv*/; output [15:0] obv16 /*verilator sc_bv*/; always @ (posedge clk) begin o1 <= i1; o8 <= i8; o16 <= i16; o32 <= i32; o64 <= i64; o65 <= i65; o128 <= i128; o513 <= i513; obv1 <= ibv1; obv16 <= ibv16; o1a2 <= i1a2; o94a3 <= i94a3; end endmodule verilator-3.874/test_regress/t/t_select_little_pack.pl0000775000177100017500000000071712473477707023243 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_inside.pl0000775000177100017500000000072212473477707020660 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_param_module.pl0000775000177100017500000000074612473477707022060 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # Compile only test compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_preproc_def09.v0000664000177100017500000000341112473477707021673 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. `undefineall // Definitions as speced // Note there are trailing spaces, which spec doesn't show properly `define D(x,y) initial $display("start", x , y, "end"); '`D( "msg1" , "msg2" )' 'initial $display("start", "msg1" , "msg2" , "end");' '`D( " msg1", )' 'initial $display("start", " msg1" , , "end");' '`D(, "msg2 ")' 'initial $display("start", , "msg2 ", "end");' '`D(,)' 'initial $display("start", , , "end");' '`D( , )' 'initial $display("start", , , "end");' //`D("msg1") // ILLEGAL: only one argument //`D() // ILLEGAL: only one empty argument //`D(,,) // ILLEGAL: more actual than formal arguments // Defaults: `define MACRO1(a=5,b="B",c) $display(a,,b,,c); '`MACRO1 ( , 2, 3 )' '$display(5,,2,,3);' '`MACRO1 ( 1 , , 3 )' '$display(1 ,,"B",,3 );' '`MACRO1 ( , 2, )' '$display(5,,2,,);' //`MACRO1 ( 1 ) // ILLEGAL: b and c omitted, no default for c `define MACRO2(a=5, b, c="C") $display(a,,b,,c); '`MACRO2 (1, , 3)' '$display(5,,,,"C");' '`MACRO2 (, 2, )' '$display(5,,2,,"C");' '`MACRO2 (, 2)' '$display(5,,2,,"C");' `define MACRO3(a=5, b=0, c="C") $display(a,,b,,c); '`MACRO3 ( 1 )' '$display(1 ,,0,,"C");' '`MACRO3 ( )' '$display(5,,0,,"C");' //`MACRO3 // ILLEGAL: parentheses required `define DTOP(a,b) a + b '`DTOP( `DTOP(b,1), `DTOP(42,a) )' 'b + 1 + 42 + a' // Local tests `define MACROQUOTE(a="==)",b="((((",c=() ) 'a b c' `MACROQUOTE(); '"==)" "((((" () '; // Also check our line counting doesn't go bad `define MACROPAREN(a=(6), b=(eq=al), c) 'a b c' `MACROPAREN( ,, ZOT) HERE-`__LINE__ - Line71 //====================================================================== verilator-3.874/test_regress/t/t_uniqueif.pl0000775000177100017500000000103312473477707021226 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ['--assert'], nc_flags2 => ['+assert'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_order.pl0000775000177100017500000000071712473477707020524 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_stats.v0000664000177100017500000000045512525171734021353 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (b); output reg [31:0] b; initial begin b = 22; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_case_write1.out0000664000177100017500000001674712473477707022022 0ustar wsnyderwsnyder[2] crc=0000000000000097 1410 [3] crc=000000000000012e 1410 [4] crc=000000000000025d 1410 [5] crc=00000000000004ba 1410 [6] crc=0000000000000974 1410 [7] crc=00000000000012e9 1410 [8] crc=00000000000025d3 1410 [9] crc=0000000000004ba7 1410 [10] crc=000000000000974e 1410 [11] crc=0000000000012e9d 1410 [12] crc=0000000000025d3a 1410 [13] crc=000000000004ba74 1410 [14] crc=00000000000974e9 1410 [15] crc=000000000012e9d3 1410 [16] crc=000000000025d3a7 1410 [17] crc=00000000004ba74e 1410 [18] crc=0000000000974e9d 1410 [19] crc=00000000012e9d3a 1410 [20] crc=00000000025d3a74 1410 [21] crc=0000000004ba74e9 1410 [22] crc=000000000974e9d3 1304a:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002031303039;17 1304b:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002031303039203233 1304c:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020313030392032332031333033;4 1304d:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002031303039203233203133303320313338 1304e:203130303920323320313330332031333820202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020 1304: 1009 23 1303 138 [23] crc=0000000012e9d3a7 1313: 1009 46 1309 1311 143 1312 [24] crc=0000000025d3a74e 1129: 1009 172 407 175 408 409 410 1106 [25] crc=000000004ba74e9d 1017: 1009 223 1014 880 885 1015 1016 1007 [26] crc=00000000974e9d3a 1231: 1229 967 1230 718 [27] crc=000000012e9d3a74 1410 [28] crc=000000025d3a74e9 1370: 1009 58 1369 19 [29] crc=00000004ba74e9d3 1036: 1009 194 1033 1034 1008 1035 880 [30] crc=0000000974e9d3a7 1409:i [31] crc=00000012e9d3a74e 1321: 1009 29 1320 137 144 141 138 148 [32] crc=00000025d3a74e9d 1383:§ [33] crc=0000004ba74e9d3a 1021: 1009 216 1018 882 884 1019 1020 1007 [34] crc=000000974e9d3a74 1017: 1009 197 1014 882 883 1015 1016 1008 [35] crc=0000012e9d3a74e9 1231: 1228 979 1230 713 [36] crc=0000025d3a74e9d3 1013: 1009 194 1011 1006 1008 1012 880 [37] crc=000004ba74e9d3a7 1409:i [38] crc=00000974e9d3a74e 1321: 1009 29 1320 137 144 141 138 148 [39] crc=000012e9d3a74e9d 1383:§ [40] crc=000025d3a74e9d3a 1021: 1009 216 1018 882 884 1019 1020 1007 [41] crc=00004ba74e9d3a74 1017: 1009 197 1014 882 883 1015 1016 1008 [42] crc=0000974e9d3a74e9 1231: 1228 979 1230 713 [43] crc=00012e9d3a74e9d3 1013: 1009 194 1011 1006 1008 1012 880 [44] crc=00025d3a74e9d3a7 1409:i [45] crc=0004ba74e9d3a74e 1321: 1009 29 1320 137 144 141 138 148 [46] crc=000974e9d3a74e9d 1383:§ [47] crc=0012e9d3a74e9d3a 1021: 1009 216 1018 882 884 1019 1020 1007 [48] crc=0025d3a74e9d3a74 1017: 1009 197 1014 882 883 1015 1016 1008 [49] crc=004ba74e9d3a74e9 1231: 1228 979 1230 713 [50] crc=00974e9d3a74e9d3 1013: 1009 194 1011 1006 1008 1012 880 [51] crc=012e9d3a74e9d3a7 1409:i [52] crc=025d3a74e9d3a74e 1321: 1009 29 1320 137 144 141 138 148 [53] crc=04ba74e9d3a74e9d 1383:§ [54] crc=0974e9d3a74e9d3a 1021: 1009 216 1018 882 884 1019 1020 1007 [55] crc=12e9d3a74e9d3a74 1017: 1009 197 1014 882 883 1015 1016 1008 [56] crc=25d3a74e9d3a74e9 1231: 1228 979 1230 713 [57] crc=4ba74e9d3a74e9d3 1013: 1009 194 1011 1006 1008 1012 880 [58] crc=974e9d3a74e9d3a7 1409:i [59] crc=2e9d3a74e9d3a74f 1321: 1009 29 1320 137 144 141 138 149 [60] crc=5d3a74e9d3a74e9e 1383:§ [61] crc=ba74e9d3a74e9d3d 1021: 1009 216 1018 882 884 1019 1020 1007 [62] crc=74e9d3a74e9d3a7b 1017: 1009 197 1014 882 883 1015 1016 1008 [63] crc=e9d3a74e9d3a74f7 1231: 1228 979 1230 713 [64] crc=d3a74e9d3a74e9ef 1013: 1009 194 1011 1006 1008 1012 880 [65] crc=a74e9d3a74e9d3df 1409:i [66] crc=4e9d3a74e9d3a7bf 1321: 1009 29 1320 137 144 141 145 149 [67] crc=9d3a74e9d3a74f7e 1383:§ [68] crc=3a74e9d3a74e9efc 1021: 1009 216 1018 882 884 1019 1020 1007 [69] crc=74e9d3a74e9d3df9 1017: 1009 197 1014 882 883 1015 1016 1008 [70] crc=e9d3a74e9d3a7bf3 1231: 1228 979 1230 713 [71] crc=d3a74e9d3a74f7e6 1013: 1009 194 1011 1006 1008 1012 880 [72] crc=a74e9d3a74e9efcc 1409:i [73] crc=4e9d3a74e9d3df98 1321: 1009 29 1320 137 147 149 143 142 [74] crc=9d3a74e9d3a7bf30 1383:§ [75] crc=3a74e9d3a74f7e61 1021: 1009 216 1018 882 885 1019 1020 1007 [76] crc=74e9d3a74e9efcc3 1017: 1009 197 1014 882 884 1015 1016 1008 [77] crc=e9d3a74e9d3df987 1231: 1228 982 1230 713 [78] crc=d3a74e9d3a7bf30f 1013: 1009 194 1011 1006 1008 1012 881 885 [79] crc=a74e9d3a74f7e61f 1409:w [80] crc=4e9d3a74e9efcc3f 1321: 1009 30 1320 149 146 146 137 149 [81] crc=9d3a74e9d3df987e 1383:ß [82] crc=3a74e9d3a7bf30fc 1021: 1009 225 1018 882 885 1019 1020 1008 [83] crc=74e9d3a74f7e61f9 1017: 1009 218 1014 882 884 1015 1016 1008 [84] crc=e9d3a74e9efcc3f3 1231: 1228 981 1230 708 [85] crc=d3a74e9d3df987e6 1013: 1009 232 1011 1005 1008 1012 881 883 [86] crc=a74e9d3a7bf30fcc 1409:s [87] crc=4e9d3a74f7e61f98 1262: 1009 1006 1258 846 1259 1006 1260 833 1261 [88] crc=9d3a74e9efcc3f30 1321: 1009 124 1320 146 137 149 137 134 [89] crc=3a74e9d3df987e61 1383:˜ [90] crc=74e9d3a7bf30fcc3 1036: 1009 215 1033 1034 1008 1035 879 verilator-3.874/test_regress/t/t_param_const_part.pl0000775000177100017500000000072212525172076022726 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func.v0000664000177100017500000000640412525171734020157 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t; reg [2:0] value; reg [31:0] rglobal; reg [31:0] vec [1:0]; reg [31:0] n; initial begin rglobal = 1; value = 2; if (add(value) != 3'd3) $stop; if (rglobal != 2) $stop; if (add(add(3'd1)) != 3'd3) $stop; if (rglobal != 4) $stop; if (munge4(4'b0010) != 4'b1011) $stop; if (toint(2) != 3) $stop; if (rglobal != 5) $stop; setit; incr(rglobal,rglobal,32'h10); if (rglobal != 32'h17) $stop; nop(32'h11); empty; empty(); rglobal = 32'h00000001; flipupperbit(rglobal,4'd4); flipupperbit(rglobal,4'd12); if (rglobal !== 32'h10100001) $stop; if (nil_func(32'h12,32'h12) != 32'h24) $stop; nil_task(32'h012,32'h112,rglobal); if (rglobal !== 32'h124) $stop; vec[0] = 32'h333; vec[1] = 32'habc; incr(vec[1],vec[0],vec[1]); if (vec[0] != 32'h333) $stop; if (vec[1] != 32'hdef) $stop; // verilator lint_off SELRANGE incr(vec[2],vec[0],vec[2]); // Reading/Writing past end of vector! // verilator lint_on SELRANGE n=1; nil(); if (n !== 10) $stop; // Functions called as tasks rglobal = 32'h4; if (inc_and_return(32'h2) != 32'h6) $stop; if (rglobal !== 32'h6) $stop; rglobal = 32'h6; inc_and_return(32'h3); if (rglobal !== 32'h9) $stop; $write("*-* All Finished *-*\n"); $finish; end function [2:0] add; input [2:0] fromv; begin add = fromv + 3'd1; begin : named reg [31:0] flocal; flocal = 1; rglobal = rglobal + flocal; end : named // SystemVerilog end labels end endfunction function [3:0] munge4; input [3:0] fromv; // Different fromv than the 'fromv' signal above reg one; begin : named reg [1:0] flocal; // Function calling a function one = 1'b1; munge4 = {one, add(fromv[2:0])}; end endfunction task setit; reg [31:0] temp; begin temp = rglobal + 32'h1; rglobal = temp + 32'h1; end endtask task incr ( // Check a V2K style input/output list output [31:0] z, input [31:0] a, inc ); z = a + inc; endtask task nop; input [31:0] a; begin end endtask task empty; endtask task flipupperbit; inout [31:0] vector; input [3:0] bitnum; reg [4:0] bitnum2; begin bitnum2 = {1'b1, bitnum}; // A little math to test constant propagation vector[bitnum2] = vector[bitnum2] ^ 1'b1; end endtask task nil_task; input [31:0] a; input [31:0] b; output [31:0] q; // verilator no_inline_task q = nil_func(a, b); endtask function void nil; n = 10; endfunction function [31:0] nil_func; input [31:0] fa; input [31:0] fb; // verilator no_inline_task nil_func = fa + fb; endfunction function integer toint; input integer fa; toint = fa + 32'h1; endfunction function [31:0] inc_and_return; input [31:0] inc; rglobal = rglobal + inc; return rglobal; endfunction endmodule verilator-3.874/test_regress/t/t_parse_delay.v0000664000177100017500000000072212473477707021524 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2014 by Wilson Snyder. module t (/*AUTOARG*/); // verilator lint_off WIDTH reg [6:0] myreg1; initial begin myreg1 = # 100 7'd0; myreg1 = # 100 'b0; // [#] [100] ['b0] myreg1 = #100'b0; // [#] [100] ['b0] myreg1 = 100'b0; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_clk_condflop_nord.v0000664000177100017500000000464112525171734022704 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (clk); input clk; reg [0:0] d1; reg [2:0] d3; reg [7:0] d8; wire [0:0] q1; wire [2:0] q3; wire [7:0] q8; // verilator lint_off UNOPTFLAT reg ena; // verilator lint_on UNOPTFLAT condff #(12) condff (.clk(clk), .sen(1'b0), .ena(ena), .d({d8,d3,d1}), .q({q8,q3,q1})); integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin //$write("%x %x %x %x\n", cyc, q8, q3, q1); cyc <= cyc + 1; if (cyc==1) begin d1 <= 1'b1; d3<=3'h1; d8<=8'h11; ena <= 1'b1; end if (cyc==2) begin d1 <= 1'b0; d3<=3'h2; d8<=8'h33; ena <= 1'b0; end if (cyc==3) begin d1 <= 1'b1; d3<=3'h3; d8<=8'h44; ena <= 1'b1; if (q8 != 8'h11) $stop; end if (cyc==4) begin d1 <= 1'b1; d3<=3'h4; d8<=8'h77; ena <= 1'b1; if (q8 != 8'h11) $stop; end if (cyc==5) begin d1 <= 1'b1; d3<=3'h0; d8<=8'h88; ena <= 1'b1; if (q8 != 8'h44) $stop; end if (cyc==6) begin if (q8 != 8'h77) $stop; end if (cyc==7) begin if (q8 != 8'h88) $stop; end // if (cyc==20) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule module condff (clk, sen, ena, d, q); parameter WIDTH = 1; input clk; input sen; input ena; input [WIDTH-1:0] d; output [WIDTH-1:0] q; condffimp #(.WIDTH(WIDTH)) imp (.clk(clk), .sen(sen), .ena(ena), .d(d), .q(q)); endmodule module condffimp (clk, sen, ena, d, q); parameter WIDTH = 1; input clk; input sen; input ena; input [WIDTH-1:0] d; output reg [WIDTH-1:0] q; wire gatedclk; clockgate clockgate (.clk(clk), .sen(sen), .ena(ena), .gatedclk(gatedclk)); always @(posedge gatedclk) begin if (gatedclk === 1'bX) begin q <= {WIDTH{1'bX}}; end else begin q <= d; end end endmodule module clockgate (clk, sen, ena, gatedclk); input clk; input sen; input ena; output gatedclk; reg ena_b; wire gatedclk = clk & ena_b; // verilator lint_off COMBDLY always @(clk or ena or sen) begin if (~clk) begin ena_b <= ena | sen; end else begin if ((clk^sen)===1'bX) ena_b <= 1'bX; end end // verilator lint_on COMBDLY endmodule verilator-3.874/test_regress/t/t_mem_shift.pl0000775000177100017500000000113612473477707021360 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--stats"], ); if ($Self->{vlt}) { file_grep ($Self->{stats}, qr/Optimizations, Delayed shared-sets\s+(\d+)/i, 14); } execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_multi_io2_sc.pl0000775000177100017500000000124612473477707022635 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_mem_multi_io2.v"); $Self->{vlt} or $Self->skip("Verilator only test"); compile ( make_top_shell => 0, make_main => 0, verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io2.cpp --sc -Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_blksync_loop.pl0000775000177100017500000000117412473477707023133 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( verilator_flags2 => ["--lint-only -Wwarn-BLKSEQ -Wwarn-COMBDLY"], fails=>0, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_repl.v0000664000177100017500000000543012473477707021210 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2004 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; reg [63:0] rf; reg [63:0] rf2; reg [63:0] biu; reg okidoki; always @* begin rf[63:32] = biu[63:32] & {32{okidoki}}; rf[31:0] = {32{okidoki}}; rf2 = rf; rf2[31:0] = ~{32{okidoki}}; end reg [31:0] src1, src0, sr, mask; wire [31:0] dualasr = ((| src1[31:4]) ? {{16{src0[31]}}, {16{src0[15]}}} : ( ( sr & {2{mask[31:16]}}) | ( {{16{src0[31]}}, {16{src0[15]}}} & {2{~mask[31:16]}}))); wire [31:0] sl_mask = (32'hffffffff << src1[4:0]); wire [31:0] sr_mask = {sl_mask[0], sl_mask[1], sl_mask[2], sl_mask[3], sl_mask[4], sl_mask[5], sl_mask[6], sl_mask[7], sl_mask[8], sl_mask[9], sl_mask[10], sl_mask[11], sl_mask[12], sl_mask[13], sl_mask[14], sl_mask[15], sl_mask[16], sl_mask[17], sl_mask[18], sl_mask[19], sl_mask[20], sl_mask[21], sl_mask[22], sl_mask[23], sl_mask[24], sl_mask[25], sl_mask[26], sl_mask[27], sl_mask[28], sl_mask[29], sl_mask[30], sl_mask[31]}; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; `ifdef TEST_VERBOSE $write("%x %x %x %x %x\n", rf, rf2, dualasr, sl_mask, sr_mask); `endif if (cyc==1) begin biu <= 64'h12451282_abadee00; okidoki <= 1'b0; src1 <= 32'h00000001; src0 <= 32'h9a4f1235; sr <= 32'h0f19f567; mask <= 32'h7af07ab4; end if (cyc==2) begin biu <= 64'h12453382_abad8801; okidoki <= 1'b1; if (rf != 64'h0) $stop; if (rf2 != 64'h00000000ffffffff) $stop; src1 <= 32'h0010000f; src0 <= 32'h028aa336; sr <= 32'h42ad0377; mask <= 32'h1ab3b906; if (dualasr != 32'h8f1f7060) $stop; if (sl_mask != 32'hfffffffe) $stop; if (sr_mask != 32'h7fffffff) $stop; end if (cyc==3) begin biu <= 64'h12422382_77ad8802; okidoki <= 1'b1; if (rf != 64'h12453382ffffffff) $stop; if (rf2 != 64'h1245338200000000) $stop; src1 <= 32'h0000000f; src0 <= 32'h5c158f71; sr <= 32'h7076c40a; mask <= 32'h33eb3d44; if (dualasr != 32'h0000ffff) $stop; if (sl_mask != 32'hffff8000) $stop; if (sr_mask != 32'h0001ffff) $stop; end if (cyc==4) begin if (rf != 64'h12422382ffffffff) $stop; if (rf2 != 64'h1242238200000000) $stop; if (dualasr != 32'h3062cc1e) $stop; if (sl_mask != 32'hffff8000) $stop; if (sr_mask != 32'h0001ffff) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_sys_readmem_bad_notfound.pl0000775000177100017500000000104512473477707024436 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( fails=>$Self->{v3}, expect=> '%Error: t/t_sys_readmem_bad_NOTFOUND.mem:\d+: \$readmem file not found', ); ok(1); 1; verilator-3.874/test_regress/t/t_inst_missing_bad.v0000664000177100017500000000060712473477707022552 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOARG*/); wire ok = 1'b0; sub sub (.ok(ok), , .nc()); endmodule module sub (input ok, input none, input nc, input missing); initial if (ok && none && nc && missing) begin end // No unused warning endmodule verilator-3.874/test_regress/t/t_func_gen.v0000664000177100017500000000155212473477707021022 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // 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. module t (/*AUTOARG*/ // Inputs clk ); input clk; genvar g; logic [1:0] mask = 0; generate for (g=0; g<2; g++) begin : picker logic block_passed = 0; // Just for visualizing V3LinkDot debug function [3:0] pick; input [3:0] randnum; pick = randnum+g[3:0]; endfunction always @(posedge clk) begin if (pick(3)!=3+g[3:0]) $stop; else mask[g] = 1'b1; if (mask == 2'b11) begin // All iterations must be finished $write("*-* All Finished *-*\n"); $finish; end end end endgenerate endmodule verilator-3.874/test_regress/t/t_lint_inherit.v0000664000177100017500000000170112473477707021722 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs q, // Inputs clk, d ); input clk; input d; output wire [1:0] q; // This demonstrates how warning disables should be propagated across module boundaries. m1 m1 (/*AUTOINST*/ // Outputs .q (q[1:0]), // Inputs .clk (clk), .d (d)); endmodule module m1 ( input clk, input d, output wire [1:0] q ); m2 m2 (/*AUTOINST*/ // Outputs .q (q[1:0]), // Inputs .clk (clk), .d (d)); endmodule module m2 ( input clk, input d, // Due to bug the below disable used to be ignored. // verilator lint_off UNOPT output reg [1:0] q // verilator lint_on UNOPT ); always @* begin q[1] = d; end always @* begin q[0] = q[1]; end endmodule verilator-3.874/test_regress/t/t_interface_inl.pl0000775000177100017500000000114212473477707022204 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_interface.v"); compile ( # Avoid inlining so we find bugs in the non-inliner connection code verilator_flags2 => ["-Oi"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_sv_conditional.v0000664000177100017500000003500112473477707022245 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: System Verilog test of case and if // // This code instantiates and runs a simple CPU written in System Verilog. // // This file ONLY is placed into the Public Domain, for any use, without // warranty. // Contributed 2012 by M W Lund, Atmel Corporation and Jeremy Bennett, Embecosm. module t (/*AUTOARG*/ // Inputs clk ); input clk; /*AUTOWIRE*/ // ************************************************************************** // Regs and Wires // ************************************************************************** reg rst; integer rst_count; st3_testbench st3_testbench_i (/*AUTOINST*/ // Inputs .clk (clk), .rst (rst)); // ************************************************************************** // Reset Generation // ************************************************************************** initial begin rst = 1'b1; rst_count = 0; end always @( posedge clk ) begin if (rst_count < 2) begin rst_count++; end else begin rst = 1'b0; end end // ************************************************************************** // Closing message // ************************************************************************** final begin $write("*-* All Finished *-*\n"); end endmodule module st3_testbench (/*AUTOARG*/ // Inputs clk, rst ); input clk; input rst; logic clk; logic rst; logic [8*16-1:0] wide_input_bus; logic decrementA; // 0=Up-counting, 1=down-counting logic dual_countA; // Advance counter by 2 steps at a time logic cntA_en; // Enable Counter A logic decrementB; // 0=Up-counting, 1=down-counting logic dual_countB; // Advance counter by 2 steps at a time logic cntB_en; // Enable counter B logic [47:0] selected_out; integer i; initial begin decrementA = 1'b0; dual_countA = 1'b0; cntA_en = 1'b1; decrementB = 1'b0; dual_countB = 1'b0; cntB_en = 1'b1; wide_input_bus = {8'hf5, 8'hef, 8'hd5, 8'hc5, 8'hb5, 8'ha5, 8'h95, 8'h85, 8'ha7, 8'ha6, 8'ha5, 8'ha4, 8'ha3, 8'ha2, 8'ha1, 8'ha0}; i = 0; end simple_test_3 simple_test_3_i (// Outputs .selected_out (selected_out[47:0]), // Inputs .wide_input_bus (wide_input_bus[8*16-1:0]), .rst (rst), .clk (clk), .decrementA (decrementA), .dual_countA (dual_countA), .cntA_en (cntA_en), .decrementB (decrementB), .dual_countB (dual_countB), .cntB_en (cntB_en)); // Logic to print outputs and then finish. always @(posedge clk) begin if (i < 50) begin `ifdef TEST_VERBOSE $display("%x", simple_test_3_i.cntA_reg ,"%x", simple_test_3_i.cntB_reg ," ", "%x", selected_out); `endif i <= i + 1; end else begin $finish(); end end // always @ (posedge clk) endmodule // Module testing: // - Unique case // - Priority case // - Unique if // - ++, --, =- and =+ operands. module simple_test_3 (input logic [8*16-1:0] wide_input_bus, input logic rst, input logic clk, // Counter A input logic decrementA, // 0=Up-counting, 1=down-counting input logic dual_countA, // Advance counter by 2 steps at a time input logic cntA_en, // Enable Counter A // Counter B input logic decrementB, // 0=Up-counting, 1=down-counting input logic dual_countB, // Advance counter by 2 steps at a time input logic cntB_en, // Enable counter B // Outputs output logic [47:0] selected_out); // Declarations logic [3:0] cntA_reg; // Registered version of cntA logic [3:0] cntB_reg; // Registered version of cntA counterA counterA_inst (/*AUTOINST*/ // Outputs .cntA_reg (cntA_reg[3:0]), // Inputs .decrementA (decrementA), .dual_countA (dual_countA), .cntA_en (cntA_en), .clk (clk), .rst (rst)); counterB counterB_inst (/*AUTOINST*/ // Outputs .cntB_reg (cntB_reg[3:0]), // Inputs .decrementB (decrementB), .dual_countB (dual_countB), .cntB_en (cntB_en), .clk (clk), .rst (rst)); simple_test_3a sta (.wide_input_bus (wide_input_bus), .selector (cntA_reg), .selected_out (selected_out[7:0])); simple_test_3b stb (.wide_input_bus (wide_input_bus), .selector (cntA_reg), .selected_out (selected_out[15:8])); simple_test_3c stc (.wide_input_bus (wide_input_bus), .selector (cntB_reg), .selected_out (selected_out[23:16])); simple_test_3d std (.wide_input_bus (wide_input_bus), .selector (cntB_reg), .selected_out (selected_out[31:24])); simple_test_3e ste (.wide_input_bus (wide_input_bus), .selector (cntB_reg), .selected_out (selected_out[39:32])); simple_test_3f stf (.wide_input_bus (wide_input_bus), .selector (cntB_reg), .selected_out (selected_out[47:40])); endmodule // simple_test_3 module counterA (output logic [3:0] cntA_reg, // Registered version of cntA input logic decrementA, // 0=Up-counting, 1=down-counting input logic dual_countA, // Advance counter by 2 steps at a time input logic cntA_en, // Enable Counter A input logic clk, // Clock input logic rst); // Synchronous reset logic [3:0] cntA; // combinational count variable. // Counter A // Sequential part of counter CntA always_ff @(posedge clk) begin cntA_reg <= cntA; end // Combinational part of counter // Had to be split up to test C-style update, as there are no // non-blocking version like -<= always_comb if (rst) cntA = 0; else begin cntA = cntA_reg; // Necessary to avoid latch if (cntA_en) begin if (decrementA) if (dual_countA) //cntA = cntA - 2; cntA -= 2; else //cntA = cntA - 1; cntA--; else if (dual_countA) //cntA = cntA + 2; cntA += 2; else //cntA = cntA + 1; cntA++; end // if (cntA_en) end endmodule // counterA module counterB (output logic [3:0] cntB_reg, // Registered version of cntA input logic decrementB, // 0=Up-counting, 1=down-counting input logic dual_countB, // Advance counter by 2 steps at a time input logic cntB_en, // Enable counter B input logic clk, // Clock input logic rst); // Synchronous reset // Counter B - tried to write sequential only, but ended up without // SystemVerilog. always_ff @(posedge clk) begin if (rst) cntB_reg <= 0; else if (cntB_en) begin if (decrementB) if (dual_countB) cntB_reg <= cntB_reg - 2; else cntB_reg <= cntB_reg - 1; // Attempts to write in SystemVerilog: else if (dual_countB) cntB_reg <= cntB_reg + 2; else cntB_reg <= cntB_reg + 1; // Attempts to write in SystemVerilog: end end // always_ff @ endmodule // A multiplexor in terms of look-up module simple_test_3a (input logic [8*16-1:0] wide_input_bus, input logic [3:0] selector, output logic [7:0] selected_out); always_comb selected_out = {wide_input_bus[selector*8+7], wide_input_bus[selector*8+6], wide_input_bus[selector*8+5], wide_input_bus[selector*8+4], wide_input_bus[selector*8+3], wide_input_bus[selector*8+2], wide_input_bus[selector*8+1], wide_input_bus[selector*8]}; endmodule // simple_test_3a // A multiplexer in terms of standard case module simple_test_3b (input logic [8*16-1:0] wide_input_bus, input logic [3:0] selector, output logic [7:0] selected_out); always_comb begin case (selector) 4'h0: selected_out = wide_input_bus[ 7: 0]; 4'h1: selected_out = wide_input_bus[ 15: 8]; 4'h2: selected_out = wide_input_bus[ 23: 16]; 4'h3: selected_out = wide_input_bus[ 31: 24]; 4'h4: selected_out = wide_input_bus[ 39: 32]; 4'h5: selected_out = wide_input_bus[ 47: 40]; 4'h6: selected_out = wide_input_bus[ 55: 48]; 4'h7: selected_out = wide_input_bus[ 63: 56]; 4'h8: selected_out = wide_input_bus[ 71: 64]; 4'h9: selected_out = wide_input_bus[ 79: 72]; 4'ha: selected_out = wide_input_bus[ 87: 80]; 4'hb: selected_out = wide_input_bus[ 95: 88]; 4'hc: selected_out = wide_input_bus[103: 96]; 4'hd: selected_out = wide_input_bus[111:104]; 4'he: selected_out = wide_input_bus[119:112]; 4'hf: selected_out = wide_input_bus[127:120]; endcase // case (selector) end endmodule // simple_test_3b // A multiplexer in terms of unique case module simple_test_3c (input logic [8*16-1:0] wide_input_bus, input logic [3:0] selector, output logic [7:0] selected_out); always_comb begin unique case (selector) 4'h0: selected_out = wide_input_bus[ 7: 0]; 4'h1: selected_out = wide_input_bus[ 15: 8]; 4'h2: selected_out = wide_input_bus[ 23: 16]; 4'h3: selected_out = wide_input_bus[ 31: 24]; 4'h4: selected_out = wide_input_bus[ 39: 32]; 4'h5: selected_out = wide_input_bus[ 47: 40]; 4'h6: selected_out = wide_input_bus[ 55: 48]; 4'h7: selected_out = wide_input_bus[ 63: 56]; 4'h8: selected_out = wide_input_bus[ 71: 64]; 4'h9: selected_out = wide_input_bus[ 79: 72]; 4'ha: selected_out = wide_input_bus[ 87: 80]; 4'hb: selected_out = wide_input_bus[ 95: 88]; 4'hc: selected_out = wide_input_bus[103: 96]; 4'hd: selected_out = wide_input_bus[111:104]; 4'he: selected_out = wide_input_bus[119:112]; 4'hf: selected_out = wide_input_bus[127:120]; endcase // case (selector) end endmodule // simple_test_3c // A multiplexer in terms of unique if module simple_test_3d (input logic [8*16-1:0] wide_input_bus, input logic [3:0] selector, output logic [7:0] selected_out); always_comb begin unique if (selector == 4'h0) selected_out = wide_input_bus[ 7: 0]; else if (selector == 4'h1) selected_out = wide_input_bus[ 15: 8]; else if (selector == 4'h2) selected_out = wide_input_bus[ 23: 16]; else if (selector == 4'h3) selected_out = wide_input_bus[ 31: 24]; else if (selector == 4'h4) selected_out = wide_input_bus[ 39: 32]; else if (selector == 4'h5) selected_out = wide_input_bus[ 47: 40]; else if (selector == 4'h6) selected_out = wide_input_bus[ 55: 48]; else if (selector == 4'h7) selected_out = wide_input_bus[ 63: 56]; else if (selector == 4'h8) selected_out = wide_input_bus[ 71: 64]; else if (selector == 4'h9) selected_out = wide_input_bus[ 79: 72]; else if (selector == 4'ha) selected_out = wide_input_bus[ 87: 80]; else if (selector == 4'hb) selected_out = wide_input_bus[ 95: 88]; else if (selector == 4'hc) selected_out = wide_input_bus[103: 96]; else if (selector == 4'hd) selected_out = wide_input_bus[111:104]; else if (selector == 4'he) selected_out = wide_input_bus[119:112]; else if (selector == 4'hf) selected_out = wide_input_bus[127:120]; end endmodule // simple_test_3d // Test of priority case // Note: This does NOT try to implement the same function as above. module simple_test_3e (input logic [8*16-1:0] wide_input_bus, input logic [3:0] selector, output logic [7:0] selected_out); always_comb begin priority case (1'b1) selector[0]: selected_out = wide_input_bus[ 7: 0]; // Bit 0 has highets priority selector[2]: selected_out = wide_input_bus[ 39: 32]; // Note 2 higher priority than 1 selector[1]: selected_out = wide_input_bus[ 23: 16]; // Note 1 lower priority than 2 selector[3]: selected_out = wide_input_bus[ 71: 64]; // Bit 3 has lowest priority default: selected_out = wide_input_bus[127:120]; // for selector = 0. endcase // case (selector) end endmodule // simple_test_3e // Test of "inside" // Note: This does NOT try to implement the same function as above. // Note: Support for "inside" is a separate Verilator feature request, so is // not used inside a this version of the test. module simple_test_3f (input logic [8*16-1:0] wide_input_bus, input logic [3:0] selector, output logic [7:0] selected_out); always_comb begin /* -----\/----- EXCLUDED -----\/----- if ( selector[3:0] inside { 4'b?00?, 4'b1100}) // Matching 0000, 0001, 1000, 1100, 1001 // if ( selector[3:2] inside { 2'b?0, selector[1:0]}) selected_out = wide_input_bus[ 7: 0]; else -----/\----- EXCLUDED -----/\----- */ /* verilator lint_off CASEOVERLAP */ priority casez (selector[3:0]) 4'b0?10: selected_out = wide_input_bus[ 15: 8]; // Matching 0010 and 0110 4'b0??0: selected_out = wide_input_bus[ 23: 16]; // Overlap: only 0100 remains (0000 in "if" above) 4'b0100: selected_out = wide_input_bus[ 31: 24]; // Overlap: Will never occur default: selected_out = wide_input_bus[127:120]; // Remaining 0011,0100,0101,0111,1010,1011,1101,1110,1111 endcase // case (selector) /* verilator lint_on CASEOVERLAP */ end endmodule // simple_test_3f verilator-3.874/test_regress/t/t_trace_cat.out0000664000177100017500000001177412473477707021534 0ustar wsnyderwsnyder$version Generated by VerilatedVcd $end $date Sat Feb 23 20:39:34 2013 $end $timescale 1ns $end $scope module top $end $var wire 1 $ clk $end $scope module v $end $var wire 1 $ clk $end $var wire 32 # cyc [31:0] $end $upscope $end $upscope $end $enddefinitions $end #0 b00000000000000000000000000000001 # 1$ #1 0$ #2 b00000000000000000000000000000010 # 1$ #3 0$ #4 b00000000000000000000000000000011 # 1$ #5 0$ #6 b00000000000000000000000000000100 # 1$ #7 0$ #8 b00000000000000000000000000000101 # 1$ #9 0$ #10 b00000000000000000000000000000110 # 1$ #11 0$ #12 b00000000000000000000000000000111 # 1$ #13 0$ #14 b00000000000000000000000000001000 # 1$ #15 0$ #16 b00000000000000000000000000001001 # 1$ #17 0$ #18 b00000000000000000000000000001010 # 1$ #19 0$ #20 b00000000000000000000000000001011 # 1$ #21 0$ #22 b00000000000000000000000000001100 # 1$ #23 0$ #24 b00000000000000000000000000001101 # 1$ #25 0$ #26 b00000000000000000000000000001110 # 1$ #27 0$ #28 b00000000000000000000000000001111 # 1$ #29 0$ #30 b00000000000000000000000000010000 # 1$ #31 0$ #32 b00000000000000000000000000010001 # 1$ #33 0$ #34 b00000000000000000000000000010010 # 1$ #35 0$ #36 b00000000000000000000000000010011 # 1$ #37 0$ #38 b00000000000000000000000000010100 # 1$ #39 0$ #40 b00000000000000000000000000010101 # 1$ #41 0$ #42 b00000000000000000000000000010110 # 1$ #43 0$ #44 b00000000000000000000000000010111 # 1$ #45 0$ #46 b00000000000000000000000000011000 # 1$ #47 0$ #48 b00000000000000000000000000011001 # 1$ #49 0$ #50 b00000000000000000000000000011010 # 1$ #51 0$ #52 b00000000000000000000000000011011 # 1$ #53 0$ #54 b00000000000000000000000000011100 # 1$ #55 0$ #56 b00000000000000000000000000011101 # 1$ #57 0$ #58 b00000000000000000000000000011110 # 1$ #59 0$ #60 b00000000000000000000000000011111 # 1$ #61 0$ #62 b00000000000000000000000000100000 # 1$ #63 0$ #64 b00000000000000000000000000100001 # 1$ #65 0$ #66 b00000000000000000000000000100010 # 1$ #67 0$ #68 b00000000000000000000000000100011 # 1$ #69 0$ #70 b00000000000000000000000000100100 # 1$ #71 0$ #72 b00000000000000000000000000100101 # 1$ #73 0$ #74 b00000000000000000000000000100110 # 1$ #75 0$ #76 b00000000000000000000000000100111 # 1$ #77 0$ #78 b00000000000000000000000000101000 # 1$ #79 0$ #80 b00000000000000000000000000101001 # 1$ #81 0$ #82 b00000000000000000000000000101010 # 1$ #83 0$ #84 b00000000000000000000000000101011 # 1$ #85 0$ #86 b00000000000000000000000000101100 # 1$ #87 0$ #88 b00000000000000000000000000101101 # 1$ #89 0$ #90 b00000000000000000000000000101110 # 1$ #91 0$ #92 b00000000000000000000000000101111 # 1$ #93 0$ #94 b00000000000000000000000000110000 # 1$ #95 0$ #96 b00000000000000000000000000110001 # 1$ #97 0$ #98 b00000000000000000000000000110010 # 1$ #99 0$ #100 b00000000000000000000000000110011 # 1$ #101 0$ #102 b00000000000000000000000000110100 # 1$ #103 0$ #104 b00000000000000000000000000110101 # 1$ #105 0$ #106 b00000000000000000000000000110110 # 1$ #107 0$ #108 b00000000000000000000000000110111 # 1$ #109 0$ #110 b00000000000000000000000000111000 # 1$ #111 0$ #112 b00000000000000000000000000111001 # 1$ #113 0$ #114 b00000000000000000000000000111010 # 1$ #115 0$ #116 b00000000000000000000000000111011 # 1$ #117 0$ #118 b00000000000000000000000000111100 # 1$ #119 0$ #120 b00000000000000000000000000111101 # 1$ #121 0$ #122 b00000000000000000000000000111110 # 1$ #123 0$ #124 b00000000000000000000000000111111 # 1$ #125 0$ #126 b00000000000000000000000001000000 # 1$ #127 0$ #128 b00000000000000000000000001000001 # 1$ #129 0$ #130 b00000000000000000000000001000010 # 1$ #131 0$ #132 b00000000000000000000000001000011 # 1$ #133 0$ #134 b00000000000000000000000001000100 # 1$ #135 0$ #136 b00000000000000000000000001000101 # 1$ #137 0$ #138 b00000000000000000000000001000110 # 1$ #139 0$ #140 b00000000000000000000000001000111 # 1$ #141 0$ #142 b00000000000000000000000001001000 # 1$ #143 0$ #144 b00000000000000000000000001001001 # 1$ #145 0$ #146 b00000000000000000000000001001010 # 1$ #147 0$ #148 b00000000000000000000000001001011 # 1$ #149 0$ #150 b00000000000000000000000001001100 # 1$ #151 0$ #152 b00000000000000000000000001001101 # 1$ #153 0$ #154 b00000000000000000000000001001110 # 1$ #155 0$ #156 b00000000000000000000000001001111 # 1$ #157 0$ #158 b00000000000000000000000001010000 # 1$ #159 0$ #160 b00000000000000000000000001010001 # 1$ #161 0$ #162 b00000000000000000000000001010010 # 1$ #163 0$ #164 b00000000000000000000000001010011 # 1$ #165 0$ #166 b00000000000000000000000001010100 # 1$ #167 0$ #168 b00000000000000000000000001010101 # 1$ #169 0$ #170 b00000000000000000000000001010110 # 1$ #171 0$ #172 b00000000000000000000000001010111 # 1$ #173 0$ #174 b00000000000000000000000001011000 # 1$ #175 0$ #176 b00000000000000000000000001011001 # 1$ #177 0$ #178 b00000000000000000000000001011010 # 1$ #179 0$ #180 b00000000000000000000000001011011 # 1$ #181 0$ #182 b00000000000000000000000001011100 # 1$ #183 0$ #184 b00000000000000000000000001011101 # 1$ #185 0$ #186 b00000000000000000000000001011110 # 1$ #187 0$ #188 b00000000000000000000000001011111 # 1$ #189 0$ verilator-3.874/test_regress/t/t_if_deep.v0000664000177100017500000001345112473477707020632 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[31:0]), // Inputs .clk (clk), .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, out}; // What checksum will we end up with `define EXPECTED_SUM 64'h966e272fd829e672 // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs clk, in ); input clk; input [31:0] in; output [31:0] out; /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [31:0] out; // End of automatics `ifdef verilator `define dontOptimize $c1("1") `else `define dontOptimize 1'b1 `endif always @(posedge clk) begin out <= in; if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (`dontOptimize) if (in[0]) out <= ~in; end endmodule verilator-3.874/test_regress/t/t_interface_modport_import.v0000664000177100017500000000162012473477707024330 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // A test of the import parameter used with modport // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2013 by Jeremy Bennett. interface test_if; // Interface variable logic data; // Modport modport mp( import myfunc, output data ); function automatic logic myfunc (input logic val); begin myfunc = (val == 1'b0); end endfunction endinterface // test_if module t (/*AUTOARG*/ // Inputs clk ); input clk; test_if i (); testmod testmod_i (.clk (clk), .i (i.mp)); endmodule module testmod ( input clk, test_if.mp i ); always @(posedge clk) begin i.data = 1'b0; if (i.myfunc (1'b0)) begin $write("*-* All Finished *-*\n"); $finish; end else begin $stop; end end endmodule verilator-3.874/test_regress/t/t_preproc_noline.pl0000775000177100017500000000135412473477707022425 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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 $stdout_filename = "$Self->{obj_dir}/$Self->{name}__test.vpp"; top_filename("t/t_preproc_noline.v"); compile ( verilator_flags2 => ['-E -P'], verilator_make_gcc=>0, stdout_filename => $stdout_filename, ); ok(files_identical($stdout_filename, "t/$Self->{name}.out")); 1; verilator-3.874/test_regress/t/t_enum_func.pl0000775000177100017500000000071712473477707021370 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_fifo.v0000664000177100017500000000527412473477707021024 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; wire [65:0] outData; // From fifo of fifo.v wire [15:0] inData = crc[15:0]; wire [1:0] inWordPtr = crc[17:16]; wire wrEn = crc[20]; wire [1:0] wrPtr = crc[33:32]; wire [1:0] rdPtr = crc[34:33]; fifo fifo ( // Outputs .outData (outData[65:0]), // Inputs .clk (clk), .inWordPtr (inWordPtr[1:0]), .inData (inData[15:0]), .rdPtr (rdPtr), .wrPtr (wrPtr), .wrEn (wrEn)); always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%b q=%x\n",$time, cyc, crc, outData); cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc==90) begin if (outData[63:0] != 64'hd9bcbc276f0984ea) $stop; end else if (cyc==91) begin if (outData[63:0] != 64'hef77cd9b13a866f0) $stop; end else if (cyc==92) begin if (outData[63:0] != 64'h2750cd9b13a866f0) $stop; end else if (cyc==93) begin if (outData[63:0] != 64'h4ea0bc276f0984ea) $stop; end else if (cyc==94) begin if (outData[63:0] != 64'h9d41bc276f0984ea) $stop; end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module fifo (/*AUTOARG*/ // Outputs outData, // Inputs clk, inWordPtr, inData, wrPtr, rdPtr, wrEn ); parameter fifoDepthLog2 = 1; parameter fifoDepth = 1< ['--cc --trace --trace-structs'], ); execute ( check_finished=>1, ); file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x); ok(1); 1; verilator-3.874/test_regress/t/t_lint_width.v0000664000177100017500000000063112473477707021400 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (); // This isn't a width violation, as +/- 1'b1 is a common idiom // that's fairly harmless wire [4:0] five = 5'd5; wire [4:0] suma = five + 1'b1; wire [4:0] sumb = 1'b1 + five; wire [4:0] sumc = five - 1'b1; endmodule verilator-3.874/test_regress/t/t_var_port_bad.pl0000775000177100017500000000105512473477707022047 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( fails=>1, expect=> '%Error: t/t_var_port_bad.v:\d+: Input/output/inout does not appear in port list: b %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_pp_lib_library.v0000664000177100017500000000045212473477707022225 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module library_cell(a); input [`WIDTH-1:0] a; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_trace_public_func.cpp0000664000177100017500000000205012473477707023214 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. #include #include #include "Vt_trace_public_func.h" #include "Vt_trace_public_func_t.h" #include "Vt_trace_public_func_glbl.h" unsigned long long main_time = 0; double sc_time_stamp() { return (double)main_time; } const unsigned long long dt_2 = 3; int main(int argc, char **argv, char **env) { Vt_trace_public_func *top = new Vt_trace_public_func("top"); Verilated::debug(0); Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; top->trace(tfp,99); tfp->open("obj_dir/t_trace_public_func/simx.vcd"); while (main_time <= 20) { top->CLK = (main_time/dt_2)%2; top->eval(); top->v->glbl->setGSR(main_time < 7); tfp->dump((unsigned int)(main_time)); ++main_time; } tfp->close(); top->final(); printf ("*-* All Finished *-*\n"); return 0; } verilator-3.874/test_regress/t/t_typedef.v0000664000177100017500000000236112473477707020675 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. program t; parameter SIZE = 5; typedef reg [SIZE-1:0] vec_t ; vec_t a; initial a =0; typedef bit [SIZE-1:0] vec_bit_t ; vec_bit_t b; initial b =0; typedef int array [3]; typedef array array2 [2]; array2 ar [1]; // Define before use // Not sure how well supported this is elsewhere //UNSUP typedef preuse; //UNSUP preuse p; //UNSUP typedef int preuse; //reg [SIZE-1:0] a; initial a =0; //reg [SIZE-1:0] b; initial b =0; integer j; initial begin for (j=0;j<=(1<{vlt} or $Self->skip("Verilator only test"); compile ( v_flags2 => ["--lint-only"], fails=>1, verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, expect=> '%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks: v.mem %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of first driving block %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of other driving block %Warning-MULTIDRIVEN: Use ".*" and lint_on around source to disable this message. %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks: out2 %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of first driving block %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of other driving block %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_math_signed5.pl0000775000177100017500000000072212473477707021754 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_for_local.v0000664000177100017500000000224712473477707021200 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [7:0] cyc; initial cyc=0; reg [31:0] loops; reg [31:0] loops2; always @ (posedge clk) begin cyc <= cyc+8'd1; if (cyc == 8'd1) begin $write("[%0t] t_loop: Running\n",$time); // Unwind < loops = 0; loops2 = 0; for (int i=0; i<16; i=i+1) begin loops = loops + i; // surefire lint_off_line ASWEMB loops2 = loops2 + i; // surefire lint_off_line ASWEMB end if (loops !== 120) $stop; if (loops2 !== 120) $stop; // Check we can declare the same signal twice loops = 0; for (int i=0; i<=16; i=i+1) begin loops = loops + 1; end if (loops !== 17) $stop; // Check type is correct loops = 0; for (byte unsigned i=5; i>4; i=i+1) begin loops = loops + 1; end if (loops !== 251) $stop; // Check large loops loops = 0; for (int i=0; i<100000; i=i+1) begin loops = loops + 1; end if (loops !== 100000) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_interface_down_gen.pl0000775000177100017500000000122012473477707023217 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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} and $Self->unsupported("Verilator unsupported, interface generates changing types"); $Self->{vcs} and $Self->unsupported("Commercially unsupported, interface crossrefs"); compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_if_deep.pl0000775000177100017500000000104612473477707021000 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--compiler msvc"], # We have deep expressions we want to test ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_bad_range.pl0000775000177100017500000000133612473477707022650 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Warning-SELRANGE: t/t_select_bad_range.v:\d+: Selection index out of range: 44:44 outside 43:0 %Warning-SELRANGE: Use .* %Warning-SELRANGE: t/t_select_bad_range.v:\d+: Selection index out of range: 44:41 outside 43:0 %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_flag_language.v0000664000177100017500000000052412473477707022010 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/); // See also t_preproc_kwd.v integer bit; initial bit = 1; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_uniqueif.v0000664000177100017500000000437512473477707021071 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=1; integer a, b, c, d, e, f, g, h, i, j, k, l; always @ (posedge clk) begin cyc <= cyc + 1; //==================== // Positive test cases //==================== // Single if, which is untrue sometimes unique0 if (cyc > 5) a <= 17; // single if with else unique0 if (cyc < 3) b <= 17; else b <= 19; // multi if, some cases may not be true unique0 if (cyc < 3) c <= 17; else if (cyc > 3) c <= 19; // multi if with else, else clause hit in some cases unique0 if (cyc < 3) d <= 17; else if (cyc > 3) d <= 19; else d <= 21; // single if with else unique if (cyc < 3) f <= 17; else f <= 19; // multi if unique if (cyc < 3) g <= 17; else if (cyc >= 3) g <= 19; // multi if with else, else clause hit in some cases unique if (cyc < 3) h <= 17; else if (cyc > 3) h <= 19; else h <= 21; //==================== // Negative test cases //==================== `ifdef FAILING_ASSERTION1 $display("testing fail 1: %d", cyc); // multi if, multiple cases true unique0 if (cyc < 3) i <= 17; else if (cyc < 5) i <= 19; `endif `ifdef FAILING_ASSERTION2 // multi if, multiple cases true unique if (cyc < 3) j <= 17; else if (cyc < 5) j <= 19; `endif `ifdef FAILING_ASSERTION3 // multi if, no cases true unique if (cyc > 1000) k <= 17; else if (cyc > 2000) k <= 19; `endif `ifdef FAILING_ASSERTION4 // Single if, which is untrue sometimes. // The LRM states: "A software tool shall also issue an error if it determines that no condition' // is true, or it is possible that no condition is true, and the final if does not have a // corresponding else." In this case, the final if is the only if, but I think the clause // still applies. unique if (cyc > 5) l <= 17; `endif if (cyc==10) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_case_huge_sub3.v0000664000177100017500000003140212473477707022112 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t_case_huge_sub3 (/*AUTOARG*/ // Outputs outr, // Inputs clk, index ); input clk; input [9:0] index; output [3:0] outr; // ============================= /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [3:0] outr; // End of automatics // ============================= // Created from perl //for $i (0..255) { $r=rand(4); printf "\t8'h%02x: begin outr <= outr^index[8:5]^4'h%01x; end\n", $i, //rand(256); }; // Reset cheating initial outr = 4'b0; always @(posedge clk) begin case (index[7:0]) 8'h00: begin outr <= 4'h0; end 8'h01: begin /*No Change*/ end 8'h02: begin outr <= outr^index[8:5]^4'ha; end 8'h03: begin outr <= outr^index[8:5]^4'h4; end 8'h04: begin outr <= outr^index[8:5]^4'hd; end 8'h05: begin outr <= outr^index[8:5]^4'h1; end 8'h06: begin outr <= outr^index[8:5]^4'hf; end 8'h07: begin outr <= outr^index[8:5]^4'he; end 8'h08: begin outr <= outr^index[8:5]^4'h0; end 8'h09: begin outr <= outr^index[8:5]^4'h4; end 8'h0a: begin outr <= outr^index[8:5]^4'h5; end 8'h0b: begin outr <= outr^index[8:5]^4'ha; end 8'h0c: begin outr <= outr^index[8:5]^4'h2; end 8'h0d: begin outr <= outr^index[8:5]^4'hf; end 8'h0e: begin outr <= outr^index[8:5]^4'h5; end 8'h0f: begin outr <= outr^index[8:5]^4'h0; end 8'h10: begin outr <= outr^index[8:5]^4'h3; end 8'h11: begin outr <= outr^index[8:5]^4'hb; end 8'h12: begin outr <= outr^index[8:5]^4'h0; end 8'h13: begin outr <= outr^index[8:5]^4'hf; end 8'h14: begin outr <= outr^index[8:5]^4'h3; end 8'h15: begin outr <= outr^index[8:5]^4'h5; end 8'h16: begin outr <= outr^index[8:5]^4'h7; end 8'h17: begin outr <= outr^index[8:5]^4'h2; end 8'h18: begin outr <= outr^index[8:5]^4'h3; end 8'h19: begin outr <= outr^index[8:5]^4'hb; end 8'h1a: begin outr <= outr^index[8:5]^4'h5; end 8'h1b: begin outr <= outr^index[8:5]^4'h4; end 8'h1c: begin outr <= outr^index[8:5]^4'h2; end 8'h1d: begin outr <= outr^index[8:5]^4'hf; end 8'h1e: begin outr <= outr^index[8:5]^4'h0; end 8'h1f: begin outr <= outr^index[8:5]^4'h4; end 8'h20: begin outr <= outr^index[8:5]^4'h6; end 8'h21: begin outr <= outr^index[8:5]^4'ha; end 8'h22: begin outr <= outr^index[8:5]^4'h6; end 8'h23: begin outr <= outr^index[8:5]^4'hb; end 8'h24: begin outr <= outr^index[8:5]^4'ha; end 8'h25: begin outr <= outr^index[8:5]^4'he; end 8'h26: begin outr <= outr^index[8:5]^4'h7; end 8'h27: begin outr <= outr^index[8:5]^4'ha; end 8'h28: begin outr <= outr^index[8:5]^4'h3; end 8'h29: begin outr <= outr^index[8:5]^4'h8; end 8'h2a: begin outr <= outr^index[8:5]^4'h1; end 8'h2b: begin outr <= outr^index[8:5]^4'h8; end 8'h2c: begin outr <= outr^index[8:5]^4'h4; end 8'h2d: begin outr <= outr^index[8:5]^4'h4; end 8'h2e: begin outr <= outr^index[8:5]^4'he; end 8'h2f: begin outr <= outr^index[8:5]^4'h8; end 8'h30: begin outr <= outr^index[8:5]^4'ha; end 8'h31: begin outr <= outr^index[8:5]^4'h7; end 8'h32: begin outr <= outr^index[8:5]^4'h0; end 8'h33: begin outr <= outr^index[8:5]^4'h3; end 8'h34: begin outr <= outr^index[8:5]^4'h1; end 8'h35: begin outr <= outr^index[8:5]^4'h3; end 8'h36: begin outr <= outr^index[8:5]^4'h4; end 8'h37: begin outr <= outr^index[8:5]^4'h6; end 8'h38: begin outr <= outr^index[8:5]^4'h4; end 8'h39: begin outr <= outr^index[8:5]^4'hb; end 8'h3a: begin outr <= outr^index[8:5]^4'h7; end 8'h3b: begin outr <= outr^index[8:5]^4'h1; end 8'h3c: begin outr <= outr^index[8:5]^4'h2; end 8'h3d: begin outr <= outr^index[8:5]^4'h0; end 8'h3e: begin outr <= outr^index[8:5]^4'h2; end 8'h3f: begin outr <= outr^index[8:5]^4'ha; end 8'h40: begin outr <= outr^index[8:5]^4'h7; end 8'h41: begin outr <= outr^index[8:5]^4'h5; end 8'h42: begin outr <= outr^index[8:5]^4'h5; end 8'h43: begin outr <= outr^index[8:5]^4'h4; end 8'h44: begin outr <= outr^index[8:5]^4'h8; end 8'h45: begin outr <= outr^index[8:5]^4'h5; end 8'h46: begin outr <= outr^index[8:5]^4'hf; end 8'h47: begin outr <= outr^index[8:5]^4'h6; end 8'h48: begin outr <= outr^index[8:5]^4'h7; end 8'h49: begin outr <= outr^index[8:5]^4'h4; end 8'h4a: begin outr <= outr^index[8:5]^4'ha; end 8'h4b: begin outr <= outr^index[8:5]^4'hd; end 8'h4c: begin outr <= outr^index[8:5]^4'hb; end 8'h4d: begin outr <= outr^index[8:5]^4'hf; end 8'h4e: begin outr <= outr^index[8:5]^4'hd; end 8'h4f: begin outr <= outr^index[8:5]^4'h7; end 8'h50: begin outr <= outr^index[8:5]^4'h9; end 8'h51: begin outr <= outr^index[8:5]^4'ha; end 8'h52: begin outr <= outr^index[8:5]^4'hf; end 8'h53: begin outr <= outr^index[8:5]^4'h3; end 8'h54: begin outr <= outr^index[8:5]^4'h1; end 8'h55: begin outr <= outr^index[8:5]^4'h0; end 8'h56: begin outr <= outr^index[8:5]^4'h2; end 8'h57: begin outr <= outr^index[8:5]^4'h9; end 8'h58: begin outr <= outr^index[8:5]^4'h2; end 8'h59: begin outr <= outr^index[8:5]^4'h4; end 8'h5a: begin outr <= outr^index[8:5]^4'hc; end 8'h5b: begin outr <= outr^index[8:5]^4'hd; end 8'h5c: begin outr <= outr^index[8:5]^4'h3; end 8'h5d: begin outr <= outr^index[8:5]^4'hb; end 8'h5e: begin outr <= outr^index[8:5]^4'hd; end 8'h5f: begin outr <= outr^index[8:5]^4'h7; end 8'h60: begin outr <= outr^index[8:5]^4'h7; end 8'h61: begin outr <= outr^index[8:5]^4'h3; end 8'h62: begin outr <= outr^index[8:5]^4'h3; end 8'h63: begin outr <= outr^index[8:5]^4'hb; end 8'h64: begin outr <= outr^index[8:5]^4'h9; end 8'h65: begin outr <= outr^index[8:5]^4'h4; end 8'h66: begin outr <= outr^index[8:5]^4'h3; end 8'h67: begin outr <= outr^index[8:5]^4'h6; end 8'h68: begin outr <= outr^index[8:5]^4'h7; end 8'h69: begin outr <= outr^index[8:5]^4'h7; end 8'h6a: begin outr <= outr^index[8:5]^4'hf; end 8'h6b: begin outr <= outr^index[8:5]^4'h6; end 8'h6c: begin outr <= outr^index[8:5]^4'h8; end 8'h6d: begin outr <= outr^index[8:5]^4'he; end 8'h6e: begin outr <= outr^index[8:5]^4'h4; end 8'h6f: begin outr <= outr^index[8:5]^4'h6; end 8'h70: begin outr <= outr^index[8:5]^4'hc; end 8'h71: begin outr <= outr^index[8:5]^4'h9; end 8'h72: begin outr <= outr^index[8:5]^4'h5; end 8'h73: begin outr <= outr^index[8:5]^4'ha; end 8'h74: begin outr <= outr^index[8:5]^4'h7; end 8'h75: begin outr <= outr^index[8:5]^4'h0; end 8'h76: begin outr <= outr^index[8:5]^4'h1; end 8'h77: begin outr <= outr^index[8:5]^4'he; end 8'h78: begin outr <= outr^index[8:5]^4'ha; end 8'h79: begin outr <= outr^index[8:5]^4'h7; end 8'h7a: begin outr <= outr^index[8:5]^4'hf; end 8'h7b: begin outr <= outr^index[8:5]^4'he; end 8'h7c: begin outr <= outr^index[8:5]^4'h6; end 8'h7d: begin outr <= outr^index[8:5]^4'hc; end 8'h7e: begin outr <= outr^index[8:5]^4'hc; end 8'h7f: begin outr <= outr^index[8:5]^4'h0; end 8'h80: begin outr <= outr^index[8:5]^4'h0; end 8'h81: begin outr <= outr^index[8:5]^4'hd; end 8'h82: begin outr <= outr^index[8:5]^4'hb; end 8'h83: begin outr <= outr^index[8:5]^4'hc; end 8'h84: begin outr <= outr^index[8:5]^4'h2; end 8'h85: begin outr <= outr^index[8:5]^4'h8; end 8'h86: begin outr <= outr^index[8:5]^4'h3; end 8'h87: begin outr <= outr^index[8:5]^4'ha; end 8'h88: begin outr <= outr^index[8:5]^4'he; end 8'h89: begin outr <= outr^index[8:5]^4'h9; end 8'h8a: begin outr <= outr^index[8:5]^4'h1; end 8'h8b: begin outr <= outr^index[8:5]^4'h1; end 8'h8c: begin outr <= outr^index[8:5]^4'hc; end 8'h8d: begin outr <= outr^index[8:5]^4'h2; end 8'h8e: begin outr <= outr^index[8:5]^4'h2; end 8'h8f: begin outr <= outr^index[8:5]^4'hd; end 8'h90: begin outr <= outr^index[8:5]^4'h0; end 8'h91: begin outr <= outr^index[8:5]^4'h6; end 8'h92: begin outr <= outr^index[8:5]^4'h7; end 8'h93: begin outr <= outr^index[8:5]^4'hc; end 8'h94: begin outr <= outr^index[8:5]^4'hb; end 8'h95: begin outr <= outr^index[8:5]^4'h3; end 8'h96: begin outr <= outr^index[8:5]^4'h0; end 8'h97: begin outr <= outr^index[8:5]^4'hc; end 8'h98: begin outr <= outr^index[8:5]^4'hc; end 8'h99: begin outr <= outr^index[8:5]^4'hb; end 8'h9a: begin outr <= outr^index[8:5]^4'h6; end 8'h9b: begin outr <= outr^index[8:5]^4'h5; end 8'h9c: begin outr <= outr^index[8:5]^4'h5; end 8'h9d: begin outr <= outr^index[8:5]^4'h4; end 8'h9e: begin outr <= outr^index[8:5]^4'h7; end 8'h9f: begin outr <= outr^index[8:5]^4'he; end 8'ha0: begin outr <= outr^index[8:5]^4'hc; end 8'ha1: begin outr <= outr^index[8:5]^4'hc; end 8'ha2: begin outr <= outr^index[8:5]^4'h0; end 8'ha3: begin outr <= outr^index[8:5]^4'h1; end 8'ha4: begin outr <= outr^index[8:5]^4'hd; end 8'ha5: begin outr <= outr^index[8:5]^4'h3; end 8'ha6: begin outr <= outr^index[8:5]^4'hc; end 8'ha7: begin outr <= outr^index[8:5]^4'h2; end 8'ha8: begin outr <= outr^index[8:5]^4'h3; end 8'ha9: begin outr <= outr^index[8:5]^4'hd; end 8'haa: begin outr <= outr^index[8:5]^4'h5; end 8'hab: begin outr <= outr^index[8:5]^4'hb; end 8'hac: begin outr <= outr^index[8:5]^4'he; end 8'had: begin outr <= outr^index[8:5]^4'h0; end 8'hae: begin outr <= outr^index[8:5]^4'hf; end 8'haf: begin outr <= outr^index[8:5]^4'h9; end 8'hb0: begin outr <= outr^index[8:5]^4'hf; end 8'hb1: begin outr <= outr^index[8:5]^4'h7; end 8'hb2: begin outr <= outr^index[8:5]^4'h9; end 8'hb3: begin outr <= outr^index[8:5]^4'hf; end 8'hb4: begin outr <= outr^index[8:5]^4'he; end 8'hb5: begin outr <= outr^index[8:5]^4'h3; end 8'hb6: begin outr <= outr^index[8:5]^4'he; end 8'hb7: begin outr <= outr^index[8:5]^4'h8; end 8'hb8: begin outr <= outr^index[8:5]^4'hf; end 8'hb9: begin outr <= outr^index[8:5]^4'hd; end 8'hba: begin outr <= outr^index[8:5]^4'h3; end 8'hbb: begin outr <= outr^index[8:5]^4'h5; end 8'hbc: begin outr <= outr^index[8:5]^4'hd; end 8'hbd: begin outr <= outr^index[8:5]^4'ha; end 8'hbe: begin outr <= outr^index[8:5]^4'h7; end 8'hbf: begin outr <= outr^index[8:5]^4'he; end 8'hc0: begin outr <= outr^index[8:5]^4'h2; end 8'hc1: begin outr <= outr^index[8:5]^4'he; end 8'hc2: begin outr <= outr^index[8:5]^4'h9; end 8'hc3: begin outr <= outr^index[8:5]^4'hb; end 8'hc4: begin outr <= outr^index[8:5]^4'h0; end 8'hc5: begin outr <= outr^index[8:5]^4'h5; end 8'hc6: begin outr <= outr^index[8:5]^4'h9; end 8'hc7: begin outr <= outr^index[8:5]^4'h6; end 8'hc8: begin outr <= outr^index[8:5]^4'ha; end 8'hc9: begin outr <= outr^index[8:5]^4'hf; end 8'hca: begin outr <= outr^index[8:5]^4'h3; end 8'hcb: begin outr <= outr^index[8:5]^4'hb; end 8'hcc: begin outr <= outr^index[8:5]^4'he; end 8'hcd: begin outr <= outr^index[8:5]^4'h2; end 8'hce: begin outr <= outr^index[8:5]^4'h5; end 8'hcf: begin outr <= outr^index[8:5]^4'hf; end 8'hd0: begin outr <= outr^index[8:5]^4'h2; end 8'hd1: begin outr <= outr^index[8:5]^4'h9; end 8'hd2: begin outr <= outr^index[8:5]^4'hb; end 8'hd3: begin outr <= outr^index[8:5]^4'h8; end 8'hd4: begin outr <= outr^index[8:5]^4'h0; end 8'hd5: begin outr <= outr^index[8:5]^4'h2; end 8'hd6: begin outr <= outr^index[8:5]^4'hb; end 8'hd7: begin outr <= outr^index[8:5]^4'h2; end 8'hd8: begin outr <= outr^index[8:5]^4'ha; end 8'hd9: begin outr <= outr^index[8:5]^4'hf; end 8'hda: begin outr <= outr^index[8:5]^4'h8; end 8'hdb: begin outr <= outr^index[8:5]^4'h4; end 8'hdc: begin outr <= outr^index[8:5]^4'he; end 8'hdd: begin outr <= outr^index[8:5]^4'h6; end 8'hde: begin outr <= outr^index[8:5]^4'h9; end 8'hdf: begin outr <= outr^index[8:5]^4'h9; end 8'he0: begin outr <= outr^index[8:5]^4'h7; end 8'he1: begin outr <= outr^index[8:5]^4'h0; end 8'he2: begin outr <= outr^index[8:5]^4'h9; end 8'he3: begin outr <= outr^index[8:5]^4'h3; end 8'he4: begin outr <= outr^index[8:5]^4'h2; end 8'he5: begin outr <= outr^index[8:5]^4'h4; end 8'he6: begin outr <= outr^index[8:5]^4'h5; end 8'he7: begin outr <= outr^index[8:5]^4'h5; end 8'he8: begin outr <= outr^index[8:5]^4'hf; end 8'he9: begin outr <= outr^index[8:5]^4'ha; end 8'hea: begin outr <= outr^index[8:5]^4'hc; end 8'heb: begin outr <= outr^index[8:5]^4'hd; end 8'hec: begin outr <= outr^index[8:5]^4'h1; end 8'hed: begin outr <= outr^index[8:5]^4'h5; end 8'hee: begin outr <= outr^index[8:5]^4'h9; end 8'hef: begin outr <= outr^index[8:5]^4'h0; end 8'hf0: begin outr <= outr^index[8:5]^4'hd; end 8'hf1: begin outr <= outr^index[8:5]^4'hf; end 8'hf2: begin outr <= outr^index[8:5]^4'h4; end 8'hf3: begin outr <= outr^index[8:5]^4'ha; end 8'hf4: begin outr <= outr^index[8:5]^4'h8; end 8'hf5: begin outr <= outr^index[8:5]^4'he; end 8'hf6: begin outr <= outr^index[8:5]^4'he; end 8'hf7: begin outr <= outr^index[8:5]^4'h1; end 8'hf8: begin outr <= outr^index[8:5]^4'h6; end 8'hf9: begin outr <= outr^index[8:5]^4'h0; end 8'hfa: begin outr <= outr^index[8:5]^4'h5; end 8'hfb: begin outr <= outr^index[8:5]^4'h1; end 8'hfc: begin outr <= outr^index[8:5]^4'h8; end 8'hfd: begin outr <= outr^index[8:5]^4'h6; end 8'hfe: begin outr <= outr^index[8:5]^4'h1; end default: begin outr <= outr^index[8:5]^4'h6; end endcase end endmodule verilator-3.874/test_regress/t/t_gen_div0.v0000664000177100017500000000130612473477707020726 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Wilson Snyder. module t (/*AUTOINST*/); Test #( .BIT_WIDTH (72), .BYTE_WIDTH (9) ) u_test_inst(); initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule module Test (); parameter BIT_WIDTH = ""; parameter BYTE_WIDTH = ""; localparam BYTES = BIT_WIDTH / BYTE_WIDTH; wire [BYTES - 1:0] i; wire [BYTES - 1:0] o; genvar g; generate for (g = 0; g < BYTES; g = g + 1) begin: gen assign o[g] = (i[g] !== 1'b0); end endgenerate endmodule verilator-3.874/test_regress/t/t_order_b.v0000664000177100017500000000062512473477707020652 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_order_b (/*AUTOARG*/ // Outputs o_subfrom_clk_lev2, // Inputs m_from_clk_lev1_r ); input [7:0] m_from_clk_lev1_r; output [7:0] o_subfrom_clk_lev2; wire [7:0] o_subfrom_clk_lev2 = m_from_clk_lev1_r; endmodule verilator-3.874/test_regress/t/t_inst_dtree_inlcd.pl0000775000177100017500000000112012473477707022707 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_dtree.v"); compile ( v_flags2 => ['+define+INLINE_C +define+INLINE_D'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_vams_wreal.v0000664000177100017500000000076412473477707021402 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. `begin_keywords "VAMS-2.3" module t (/*autoarg*/ // Outputs aout, // Inputs in ); input [15:0] in; output aout; wreal aout; parameter real lsb = 1; // verilator lint_off WIDTH assign aout = $itor(in) * lsb; initial begin $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/tsub/0000775000177100017500000000000012534632371017462 5ustar wsnyderwsnyderverilator-3.874/test_regress/t/tsub/t_flag_f_tsub_inc.v0000664000177100017500000000010112473477707023304 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module `define GOT_DEF5 verilator-3.874/test_regress/t/tsub/t_flag_f_tsub.v0000664000177100017500000000010112473477707022453 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module `define GOT_DEF6 verilator-3.874/test_regress/t/tsub/t_flag_f_tsub.vc0000664000177100017500000000013512473477707022625 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module +define+GOT_DEF4=1 +incdir+. t_flag_f_tsub.v verilator-3.874/test_regress/t/t_langext_4.pl0000775000177100017500000000101712473477707021270 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_langext_2.v"); # This is a compile only test. compile ( v_flags2 => ["+1800-2009ext+v"], ); ok(1); 1; verilator-3.874/test_regress/t/t_extend_class.v0000664000177100017500000000226712473477707021716 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; reg [7:0] cyc; initial cyc=0; reg [31:0] in; wire [31:0] out; t_extend_class_v sub (.in(in), .out(out)); always @ (posedge clk) begin cyc <= cyc+8'd1; if (cyc == 8'd1) begin in <= 32'h10; end if (cyc == 8'd2) begin if (out != 32'h11) $stop; end if (cyc == 8'd9) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule module t_extend_class_v (/*AUTOARG*/ // Outputs out, // Inputs in ); input [31:0] in; output [31:0] out; always @* begin // When "in" changes, call my method out = $c("m_myobjp->my_math(",in,")"); end `systemc_header #include "t_extend_class_c.h" // Header for contained object `systemc_interface t_extend_class_c* m_myobjp; // Pointer to object we are embedding `systemc_ctor m_myobjp = new t_extend_class_c(); // Construct contained object `systemc_dtor delete m_myobjp; // Destruct contained object `verilog endmodule verilator-3.874/test_regress/t/t_inst_mism.pl0000775000177100017500000000072212473477707021407 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_syncasyncnet_bad.v0000664000177100017500000000415712473477707023617 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs rst_sync_l, rst_both_l, rst_async_l, d, clk ); /*AUTOINPUT*/ // Beginning of automatic inputs (from unused autoinst inputs) input clk; // To sub1 of sub1.v, ... input d; // To sub1 of sub1.v, ... input rst_async_l; // To sub2 of sub2.v input rst_both_l; // To sub1 of sub1.v, ... input rst_sync_l; // To sub1 of sub1.v // End of automatics sub1 sub1 (/*AUTOINST*/ // Inputs .clk (clk), .rst_both_l (rst_both_l), .rst_sync_l (rst_sync_l), .d (d)); sub2 sub2 (/*AUTOINST*/ // Inputs .clk (clk), .rst_both_l (rst_both_l), .rst_async_l (rst_async_l), .d (d)); endmodule module sub1 (/*AUTOARG*/ // Inputs clk, rst_both_l, rst_sync_l, d ); input clk; input rst_both_l; input rst_sync_l; //input rst_async_l; input d; reg q1; reg q2; always @(posedge clk) begin if (~rst_sync_l) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops q1 <= 1'h0; // End of automatics end else begin q1 <= d; end end always @(posedge clk) begin q2 <= (~rst_both_l) ? 1'b0 : d; if (0 && q1 && q2) ; end endmodule module sub2 (/*AUTOARG*/ // Inputs clk, rst_both_l, rst_async_l, d ); input clk; input rst_both_l; //input rst_sync_l; input rst_async_l; input d; reg q1; reg q2; reg q3; always @(posedge clk or negedge rst_async_l) begin if (~rst_async_l) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops q1 <= 1'h0; // End of automatics end else begin q1 <= d; end end always @(posedge clk or negedge rst_both_l) begin q2 <= (~rst_both_l) ? 1'b0 : d; end // Make there be more async uses than sync uses always @(posedge clk or negedge rst_both_l) begin q3 <= (~rst_both_l) ? 1'b0 : d; if (0 && q1 && q2 && q3) ; end endmodule verilator-3.874/test_regress/t/t_inst_v2k.pl0000775000177100017500000000107012473477707021141 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ['+libext+.vi+.extranoneed'], nc => 0, # Error: Multiple +libext flags found vcs => 0, ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_unopt_combo_bad.pl0000775000177100017500000000213412473477707022536 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_unopt_combo.v"); compile ( fails=>$Self->{vlt}, expect=> '%Warning-UNOPTFLAT: t/t_unopt_combo.v:\d+: Signal unoptimizable: Feedback to clock or circular logic: v.c %Warning-UNOPTFLAT: Use "/\* verilator lint_off UNOPTFLAT \*/" and lint_on around source to disable this message. %Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: v.c %Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: ALWAYS %Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: v.b %Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: ALWAYS %Warning-UNOPTFLAT: Example path: t/t_unopt_combo.v:\d+: v.c %Error: Exiting due to ' ); execute ( ) if !$Self->{vlt}; ok(1); 1; verilator-3.874/test_regress/t/t_mem_file.pl0000775000177100017500000000071712473477707021166 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_intdot.v0000664000177100017500000000411512473477707021366 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003-2007 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; wire out; reg in; Genit g (.clk(clk), .value(in), .result(out)); always @ (posedge clk) begin //$write("[%0t] cyc==%0d %x %x\n",$time, cyc, in, out); cyc <= cyc + 1; if (cyc==0) begin // Setup in <= 1'b1; end else if (cyc==1) begin in <= 1'b0; end else if (cyc==2) begin if (out != 1'b1) $stop; end else if (cyc==3) begin if (out != 1'b0) $stop; end else if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end //`define WAVES `ifdef WAVES initial begin $dumpfile("obj_dir/t_gen_intdot/t_gen_intdot.vcd"); $dumpvars(12, t); end `endif endmodule module Generate (clk, value, result); input clk; input value; output result; reg Internal; assign result = Internal ^ clk; always @(posedge clk) Internal <= #1 value; endmodule module Checker (clk, value); input clk, value; always @(posedge clk) begin $write ("[%0t] value=%h\n", $time, value); end endmodule module Test (clk, value, result); input clk; input value; output result; Generate gen (clk, value, result); Checker chk (clk, gen.Internal); endmodule module Genit (clk, value, result); input clk; input value; output result; `ifndef ATSIM // else unsupported `ifndef NC // else unsupported `define WITH_FOR_GENVAR `endif `endif `define WITH_GENERATE `ifdef WITH_GENERATE `ifndef WITH_FOR_GENVAR genvar i; `endif generate for ( `ifdef WITH_FOR_GENVAR genvar `endif i = 0; i < 1; i = i + 1) begin : foo Test tt (clk, value, result); end endgenerate `else Test tt (clk, value, result); `endif wire Result2 = t.g.foo[0].tt.gen.Internal; // Works - Do not change! always @ (posedge clk) begin $write("[%0t] Result2 = %x\n", $time, Result2); end endmodule verilator-3.874/test_regress/t/t_math_signed6.v0000664000177100017500000000164512525171734021576 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2015 by Iztok Jeras. `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) module t (/*AUTOARG*/); // signed source logic signed [8-1:0] src; // destination structure struct packed { logic signed [16-1:0] s; logic unsigned [16-1:0] u; } dst; initial begin // bug882 // verilator lint_off WIDTH src = 8'sh05; dst = '{s: src, u: src}; `checkh (dst.s, 16'h0005); `checkh (dst.u, 16'h0005); src = 8'shf5; dst = '{s: src, u: src}; `checkh (dst.s, 16'hfff5); `checkh (dst.u, 16'hfff5); // verilator lint_on WIDTH $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_case_wild.pl0000775000177100017500000000071712473477707021343 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_crc.pl0000775000177100017500000000104612473477707021167 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2 => ["--compiler msvc"], # We have deep expressions we want to test ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_interface_down_inlab.pl0000775000177100017500000000112412473477707023536 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_interface_down.v"); compile ( v_flags2 => ['+define+INLINE_A +define+INLINE_B'], verilator_flags2 => ['-trace'], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_struct_unaligned.pl0000775000177100017500000000106512473477707022760 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. # Note: need to run at a higher optimization level to reproduce the issue $Self->{benchmark} = 1; compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_clk_2in_vec.pl0000775000177100017500000000117512473477707021566 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_clk_2in.v"); compile ( make_top_shell => 0, make_main => 0, v_flags2 => ["+define+T_CLK_2IN_VEC=1"], verilator_flags2 => ["--exe $Self->{t_dir}/t_clk_2in.cpp"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_package_verb.pl0000775000177100017500000000072212473477707022016 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_shift.v0000664000177100017500000000233012473477707021204 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2006 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; integer i; reg [63:0] mem [7:0]; always @ (posedge clk) begin if (cyc==1) begin for (i=0; i<8; i=i+1) begin mem[i] <= 64'h0; end end else begin mem[0] <= crc; for (i=1; i<8; i=i+1) begin mem[i] <= mem[i-1]; end end end wire [63:0] outData = mem[7]; always @ (posedge clk) begin //$write("[%0t] cyc==%0d crc=%b q=%x\n",$time, cyc, crc, outData); cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc==90) begin if (outData != 64'h1265e3bddcd9bc27) $stop; end else if (cyc==91) begin if (outData != 64'h24cbc77bb9b3784e) $stop; end else if (cyc==92) begin end else if (cyc==93) begin end else if (cyc==94) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $finish; end end endmodule verilator-3.874/test_regress/t/t_tri_array_bufif.pl0000775000177100017500000000071712473477707022560 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_func_outp.v0000664000177100017500000000317212473477707021240 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (clk); input clk; reg [7:0] a,b; wire [7:0] z; mytop u0 ( a, b, clk, z ); integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; //$write("%d %x\n", cyc, z); if (cyc==1) begin a <= 8'h07; b <= 8'h20; end if (cyc==2) begin a <= 8'h8a; b <= 8'h12; end if (cyc==3) begin if (z !== 8'hdf) $stop; a <= 8'h71; b <= 8'hb2; end if (cyc==4) begin if (z !== 8'hed) $stop; end if (cyc==5) begin if (z !== 8'h4d) $stop; end if (cyc==9) begin $write("*-* All Finished *-*\n"); $finish; end end end endmodule // mytop module inv( input [ 7:0 ] a, output [ 7:0 ] z ); wire [7:0] z = ~a; endmodule module ftest( input [ 7:0 ] a, b, // Test legal syntax input clk, output [ 7:0 ] z ); wire [7:0] zi; reg [7:0] z; inv u1 (.a(myadd(a,b)), .z(zi)); always @ ( posedge clk ) begin z <= myadd( a, zi ); end function [ 7:0 ] myadd; input [7:0] ina; input [7:0] inb; begin myadd = ina + inb; end endfunction // myadd endmodule // ftest module mytop ( input [ 7:0 ] a, b, input clk, output [ 7:0 ] z ); ftest u0( a, b, clk, z ); endmodule // mytop verilator-3.874/test_regress/t/t_pp_underline_bad.pl0000775000177100017500000000120012473477707022667 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); compile ( verilator_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_pp_underline_bad.v:\d+: Extra underscore in meta-comment.* %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_import.pl0000775000177100017500000000115712473477707021556 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( # Amazingly VCS, NC and Verilator all just accept the C file here! v_flags2 => ["t/t_dpi_import_c.cpp"], verilator_flags2 => ["-Wall -Wno-DECLFILENAME"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_var_pins_scui.pl0000775000177100017500000000404612473477707022254 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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"); top_filename("t/t_var_pinsizes.v"); compile ( verilator_flags2 => ["-sc -pins-uint8 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"], make_main => 0, ); if ($Self->{vlt}) { file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in \s+ i64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ i65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in\s> \s+ ibv16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o8;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o16;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o32;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out \s+ o64;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ o65;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv1;/x); file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out\s> \s+ obv16;/x); } execute(); ok(1); 1; verilator-3.874/test_regress/t/t_dpi_logic_bad.pl0000775000177100017500000000124312473477707022143 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( v_flags2 => ["--lint-only"], fails=>$Self->{v3}, expect=> '%Error: t/t_dpi_logic_bad.v:\d+: Unsupported: DPI argument of type .* %Error: t/t_dpi_logic_bad.v:\d+: ... For best portability, use bit, byte, int, or longint %Error: Exiting due to .*' ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_packed_assign.pl0000775000177100017500000000072212473477707023036 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2010 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_mem_file.v0000664000177100017500000001136412473477707021015 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=0; reg [63:0] crc; reg [63:0] sum; wire r1_en /*verilator public*/ = crc[12]; wire [1:0] r1_ad /*verilator public*/ = crc[9:8]; wire r2_en /*verilator public*/ = 1'b1; wire [1:0] r2_ad /*verilator public*/ = crc[11:10]; wire w1_en /*verilator public*/ = crc[5]; wire [1:0] w1_a /*verilator public*/ = crc[1:0]; wire [63:0] w1_d /*verilator public*/ = {2{crc[63:32]}}; wire w2_en /*verilator public*/ = crc[4]; wire [1:0] w2_a /*verilator public*/ = crc[3:2]; wire [63:0] w2_d /*verilator public*/ = {2{~crc[63:32]}}; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [63:0] r1_d_d2r; // From file of file.v wire [63:0] r2_d_d2r; // From file of file.v // End of automatics file file (/*AUTOINST*/ // Outputs .r1_d_d2r (r1_d_d2r[63:0]), .r2_d_d2r (r2_d_d2r[63:0]), // Inputs .clk (clk), .r1_en (r1_en), .r1_ad (r1_ad[1:0]), .r2_en (r2_en), .r2_ad (r2_ad[1:0]), .w1_en (w1_en), .w1_a (w1_a[1:0]), .w1_d (w1_d[63:0]), .w2_en (w2_en), .w2_a (w2_a[1:0]), .w2_d (w2_d[63:0])); always @ (posedge clk) begin //$write("[%0t] cyc==%0d EN=%b%b%b%b R0=%x R1=%x\n",$time, cyc, r1_en,r2_en,w1_en,w2_en, r1_d_d2r, r2_d_d2r); cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= {r1_d_d2r ^ r2_d_d2r} ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin // We've manually verified all X's are out of the design by this point sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("*-* All Finished *-*\n"); $write("[%0t] cyc==%0d crc=%x %x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== 64'h5e9ea8c33a97f81e) $stop; $finish; end end endmodule module file (/*AUTOARG*/ // Outputs r1_d_d2r, r2_d_d2r, // Inputs clk, r1_en, r1_ad, r2_en, r2_ad, w1_en, w1_a, w1_d, w2_en, w2_a, w2_d ); input clk; input r1_en; input [1:0] r1_ad; output [63:0] r1_d_d2r; input r2_en; input [1:0] r2_ad; output [63:0] r2_d_d2r; input w1_en; input [1:0] w1_a; input [63:0] w1_d; input w2_en; input [1:0] w2_a; input [63:0] w2_d; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) // End of automatics /*AUTOREG*/ // Beginning of automatic regs (for this module's undeclared outputs) reg [63:0] r1_d_d2r; reg [63:0] r2_d_d2r; // End of automatics // Writes wire [3:0] m_w1_onehotwe = ({4{w1_en}} & (4'b1 << w1_a)); wire [3:0] m_w2_onehotwe = ({4{w2_en}} & (4'b1 << w2_a)); wire [63:0] rg0_wrdat = m_w1_onehotwe[0] ? w1_d : w2_d; wire [63:0] rg1_wrdat = m_w1_onehotwe[1] ? w1_d : w2_d; wire [63:0] rg2_wrdat = m_w1_onehotwe[2] ? w1_d : w2_d; wire [63:0] rg3_wrdat = m_w1_onehotwe[3] ? w1_d : w2_d; wire [3:0] m_w_onehotwe = m_w1_onehotwe | m_w2_onehotwe; // Storage reg [63:0] m_rg0_r; reg [63:0] m_rg1_r; reg [63:0] m_rg2_r; reg [63:0] m_rg3_r; always @ (posedge clk) begin if (m_w_onehotwe[0]) m_rg0_r <= rg0_wrdat; if (m_w_onehotwe[1]) m_rg1_r <= rg1_wrdat; if (m_w_onehotwe[2]) m_rg2_r <= rg2_wrdat; if (m_w_onehotwe[3]) m_rg3_r <= rg3_wrdat; end // Reads reg [1:0] m_r1_ad_d1r; reg [1:0] m_r2_ad_d1r; reg [1:0] m_ren_d1r; always @ (posedge clk) begin if (r1_en) m_r1_ad_d1r <= r1_ad; if (r2_en) m_r2_ad_d1r <= r2_ad; m_ren_d1r <= {r2_en, r1_en}; end // Scheme1: shift... wire [3:0] m_r1_onehot_d1 = (4'b1 << m_r1_ad_d1r); // Scheme2: bit mask reg [3:0] m_r2_onehot_d1; always @* begin m_r2_onehot_d1 = 4'd0; m_r2_onehot_d1[m_r2_ad_d1r] = 1'b1; end wire [63:0] m_r1_d_d1 = (({64{m_r1_onehot_d1[0]}} & m_rg0_r) | ({64{m_r1_onehot_d1[1]}} & m_rg1_r) | ({64{m_r1_onehot_d1[2]}} & m_rg2_r) | ({64{m_r1_onehot_d1[3]}} & m_rg3_r)); wire [63:0] m_r2_d_d1 = (({64{m_r2_onehot_d1[0]}} & m_rg0_r) | ({64{m_r2_onehot_d1[1]}} & m_rg1_r) | ({64{m_r2_onehot_d1[2]}} & m_rg2_r) | ({64{m_r2_onehot_d1[3]}} & m_rg3_r)); always @ (posedge clk) begin if (m_ren_d1r[0]) r1_d_d2r <= m_r1_d_d1; if (m_ren_d1r[1]) r2_d_d2r <= m_r2_d_d1; end endmodule verilator-3.874/test_regress/t/t_lint_unused.v0000664000177100017500000000241112473477707021562 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2010 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs out, // Inputs in ); input in; // inputs don't get flagged as undriven output out; // outputs don't get flagged as unused sub sub (); // Check we don't warn about unused UDP signals udp_mux2 udpsub (out, in, in, in); // Check ignoreds mark as used reg sysused; initial $bboxed(sysused); // Check file IO. The fopen is the "driver" all else a usage. integer infile; integer outfile; initial begin outfile = $fopen("obj_dir/t_lint_unused_bad/open.log", "w"); $fwrite(outfile, "1\n"); $fclose(outfile); infile = $fopen("obj_dir/t_lint_unused_bad/open.log", "r"); if ($fgetc(infile) != "1") begin end end wire _unused_ok; endmodule module sub; wire pub /*verilator public*/; // Ignore publics localparam THREE = 3; endmodule primitive udp_mux2 (q, a, b, s); output q; input a, b, s; table //a b s : out 1 ? 0 : 1 ; 0 ? 0 : 0 ; ? 1 1 : 1 ; ? 0 1 : 0 ; 0 0 x : 0 ; 1 1 x : 1 ; endtable endprimitive verilator-3.874/test_regress/t/t_inst_tree_inl0_pub0.pl0000775000177100017500000000113112473477707023244 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. top_filename("t/t_inst_tree.v"); compile ( v_flags2 => ['+define+NOUSE_INLINE', '+define+NOUSE_PUBLIC'], ); execute ( check_finished=>1, expect=> '\] (%m|.*v\.ps): Clocked ', ); ok(1); 1; verilator-3.874/test_regress/t/t_lint_setout_bad.v0000664000177100017500000000107512473477707022415 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2011 by Wilson Snyder. module t ( input wire reset_l, input wire clk ); sub sub_I ( .clk(clk), .reset_l(reset_l), .cpu_if_timeout(1'b0) ); endmodule module sub ( input wire clk, reset_l, output reg cpu_if_timeout ); always @(posedge clk) begin if (!reset_l) begin cpu_if_timeout <= 1'b0; end else begin cpu_if_timeout <= 1'b0; end end endmodule verilator-3.874/test_regress/t/t_var_const_bad.pl0000775000177100017500000000116312473477707022211 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2005 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"); compile ( v_flags2 => ["--lint-only"], fails=>1, expect=> '%Error: t/t_var_const_bad.v:\d+: Assigning to const variable: five %Error: Exiting due to.*', ); ok(1); 1; verilator-3.874/test_regress/t/t_order_comboloop.v0000664000177100017500000000241212473477707022416 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // verilator lint_off UNOPT // verilator lint_off UNOPTFLAT reg [31:0] runner; initial runner = 5; reg [31:0] runnerm1; reg [59:0] runnerq; reg [89:0] runnerw; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin `ifdef verilator if (runner != 0) $stop; // Initial settlement failed `endif end if (cyc==2) begin runner = 20; runnerq = 60'h0; runnerw = 90'h0; end if (cyc==3) begin if (runner != 0) $stop; $write("*-* All Finished *-*\n"); $finish; end end end // This forms a "loop" where we keep going through the always till runner=0 // This isn't "regular" beh code, but insures our change detection is working properly always @ (/*AS*/runner) begin runnerm1 = runner - 32'd1; end always @ (/*AS*/runnerm1) begin if (runner > 0) begin runner = runnerm1; runnerq = runnerq - 60'd1; runnerw = runnerw - 90'd1; $write ("[%0t] runner=%d\n", $time, runner); end end endmodule verilator-3.874/test_regress/t/t_clk_vecgen1.v0000664000177100017500000000537712473477707021430 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; wire [1:0] clkvec = crc[1:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [1:0] count; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .count (count[1:0]), // Inputs .clkvec (clkvec[1:0])); // Aggregate outputs into a single result vector wire [63:0] result = {62'h0, count}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; `define EXPECTED_SUM 64'hfe8bac0bb1a0e53b if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule `ifdef T_TEST1 module Test ( input wire [1:0] clkvec, // verilator lint_off MULTIDRIVEN output reg [1:0] count // verilator lint_on MULTIDRIVEN ); genvar igen; generate for (igen=0; igen<2; igen=igen+1) begin : code_gen initial count[igen] = 1'b0; always @ (posedge clkvec[igen]) count[igen] <= count[igen] + 1; end endgenerate always @ (count) begin $write("hi\n"); end endmodule `endif `ifdef T_TEST2 module Test ( input wire [1:0] clkvec, // verilator lint_off MULTIDRIVEN output reg [1:0] count // verilator lint_on MULTIDRIVEN ); genvar igen; generate for (igen=0; igen<2; igen=igen+1) begin : code_gen wire clk_tmp = clkvec[igen]; // Unsupported: Count is multidriven, though if we did better analysis it wouldn't // need to be. initial count[igen] = 1'b0; always @ (posedge clk_tmp) count[igen] <= count[igen] + 1; end endgenerate endmodule `endif `ifdef T_TEST3 module Test ( input wire [1:0] clkvec, output wire [1:0] count ); genvar igen; generate for (igen=0; igen<2; igen=igen+1) begin : code_gen wire clk_tmp = clkvec[igen]; reg tmp_count = 1'b0; always @ (posedge clk_tmp) begin tmp_count <= tmp_count + 1; end assign count[igen] = tmp_count; end endgenerate endmodule `endif verilator-3.874/test_regress/t/t_cover_line_cc.pl0000775000177100017500000000152512473477707022201 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. top_filename("t/t_cover_line.v"); compile ( verilator_flags2 => ['--cc --coverage-line'], ); execute ( check_finished=>1, ); # Read the input .v file and do any CHECK_COVER requests inline_checks(); $Self->_run(cmd=>["../bin/verilator_coverage", "--annotate", "$Self->{obj_dir}/annotated", "$Self->{obj_dir}/coverage.dat", ], ); ok(files_identical("$Self->{obj_dir}/annotated/t_cover_line.v", "t/t_cover_line.out")); 1; verilator-3.874/test_regress/t/t_flag_bboxsys.pl0000775000177100017500000000104712473477707022070 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2008 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"); compile ( verilator_flags2 => ["--bbox-sys"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_math_cond_huge.v0000664000177100017500000005001612473477707022201 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2008 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [7:0] sel = crc[7:0]; wire [255+3:0] in = {crc[2:0],crc,crc,crc,crc}; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [3:0] out; // From test of Test.v // End of automatics /* Test AUTO_TEMPLATE ( .i\([0-9]+\) (in[\1 +:4]), ); */ Test test (/*AUTOINST*/ // Outputs .out (out[3:0]), // Inputs .sel (sel[7:0]), .i0 (in[0 +:4]), // Templated .i1 (in[1 +:4]), // Templated .i2 (in[2 +:4]), // Templated .i3 (in[3 +:4]), // Templated .i4 (in[4 +:4]), // Templated .i5 (in[5 +:4]), // Templated .i6 (in[6 +:4]), // Templated .i7 (in[7 +:4]), // Templated .i8 (in[8 +:4]), // Templated .i9 (in[9 +:4]), // Templated .i10 (in[10 +:4]), // Templated .i11 (in[11 +:4]), // Templated .i12 (in[12 +:4]), // Templated .i13 (in[13 +:4]), // Templated .i14 (in[14 +:4]), // Templated .i15 (in[15 +:4]), // Templated .i16 (in[16 +:4]), // Templated .i17 (in[17 +:4]), // Templated .i18 (in[18 +:4]), // Templated .i19 (in[19 +:4]), // Templated .i20 (in[20 +:4]), // Templated .i21 (in[21 +:4]), // Templated .i22 (in[22 +:4]), // Templated .i23 (in[23 +:4]), // Templated .i24 (in[24 +:4]), // Templated .i25 (in[25 +:4]), // Templated .i26 (in[26 +:4]), // Templated .i27 (in[27 +:4]), // Templated .i28 (in[28 +:4]), // Templated .i29 (in[29 +:4]), // Templated .i30 (in[30 +:4]), // Templated .i31 (in[31 +:4]), // Templated .i32 (in[32 +:4]), // Templated .i33 (in[33 +:4]), // Templated .i34 (in[34 +:4]), // Templated .i35 (in[35 +:4]), // Templated .i36 (in[36 +:4]), // Templated .i37 (in[37 +:4]), // Templated .i38 (in[38 +:4]), // Templated .i39 (in[39 +:4]), // Templated .i40 (in[40 +:4]), // Templated .i41 (in[41 +:4]), // Templated .i42 (in[42 +:4]), // Templated .i43 (in[43 +:4]), // Templated .i44 (in[44 +:4]), // Templated .i45 (in[45 +:4]), // Templated .i46 (in[46 +:4]), // Templated .i47 (in[47 +:4]), // Templated .i48 (in[48 +:4]), // Templated .i49 (in[49 +:4]), // Templated .i50 (in[50 +:4]), // Templated .i51 (in[51 +:4]), // Templated .i52 (in[52 +:4]), // Templated .i53 (in[53 +:4]), // Templated .i54 (in[54 +:4]), // Templated .i55 (in[55 +:4]), // Templated .i56 (in[56 +:4]), // Templated .i57 (in[57 +:4]), // Templated .i58 (in[58 +:4]), // Templated .i59 (in[59 +:4]), // Templated .i60 (in[60 +:4]), // Templated .i61 (in[61 +:4]), // Templated .i62 (in[62 +:4]), // Templated .i63 (in[63 +:4]), // Templated .i64 (in[64 +:4]), // Templated .i65 (in[65 +:4]), // Templated .i66 (in[66 +:4]), // Templated .i67 (in[67 +:4]), // Templated .i68 (in[68 +:4]), // Templated .i69 (in[69 +:4]), // Templated .i70 (in[70 +:4]), // Templated .i71 (in[71 +:4]), // Templated .i72 (in[72 +:4]), // Templated .i73 (in[73 +:4]), // Templated .i74 (in[74 +:4]), // Templated .i75 (in[75 +:4]), // Templated .i76 (in[76 +:4]), // Templated .i77 (in[77 +:4]), // Templated .i78 (in[78 +:4]), // Templated .i79 (in[79 +:4]), // Templated .i80 (in[80 +:4]), // Templated .i81 (in[81 +:4]), // Templated .i82 (in[82 +:4]), // Templated .i83 (in[83 +:4]), // Templated .i84 (in[84 +:4]), // Templated .i85 (in[85 +:4]), // Templated .i86 (in[86 +:4]), // Templated .i87 (in[87 +:4]), // Templated .i88 (in[88 +:4]), // Templated .i89 (in[89 +:4]), // Templated .i90 (in[90 +:4]), // Templated .i91 (in[91 +:4]), // Templated .i92 (in[92 +:4]), // Templated .i93 (in[93 +:4]), // Templated .i94 (in[94 +:4]), // Templated .i95 (in[95 +:4]), // Templated .i96 (in[96 +:4]), // Templated .i97 (in[97 +:4]), // Templated .i98 (in[98 +:4]), // Templated .i99 (in[99 +:4]), // Templated .i100 (in[100 +:4]), // Templated .i101 (in[101 +:4]), // Templated .i102 (in[102 +:4]), // Templated .i103 (in[103 +:4]), // Templated .i104 (in[104 +:4]), // Templated .i105 (in[105 +:4]), // Templated .i106 (in[106 +:4]), // Templated .i107 (in[107 +:4]), // Templated .i108 (in[108 +:4]), // Templated .i109 (in[109 +:4]), // Templated .i110 (in[110 +:4]), // Templated .i111 (in[111 +:4]), // Templated .i112 (in[112 +:4]), // Templated .i113 (in[113 +:4]), // Templated .i114 (in[114 +:4]), // Templated .i115 (in[115 +:4]), // Templated .i116 (in[116 +:4]), // Templated .i117 (in[117 +:4]), // Templated .i118 (in[118 +:4]), // Templated .i119 (in[119 +:4]), // Templated .i120 (in[120 +:4]), // Templated .i121 (in[121 +:4]), // Templated .i122 (in[122 +:4]), // Templated .i123 (in[123 +:4]), // Templated .i124 (in[124 +:4]), // Templated .i125 (in[125 +:4]), // Templated .i126 (in[126 +:4]), // Templated .i127 (in[127 +:4]), // Templated .i128 (in[128 +:4]), // Templated .i129 (in[129 +:4]), // Templated .i130 (in[130 +:4]), // Templated .i131 (in[131 +:4]), // Templated .i132 (in[132 +:4]), // Templated .i133 (in[133 +:4]), // Templated .i134 (in[134 +:4]), // Templated .i135 (in[135 +:4]), // Templated .i136 (in[136 +:4]), // Templated .i137 (in[137 +:4]), // Templated .i138 (in[138 +:4]), // Templated .i139 (in[139 +:4]), // Templated .i140 (in[140 +:4]), // Templated .i141 (in[141 +:4]), // Templated .i142 (in[142 +:4]), // Templated .i143 (in[143 +:4]), // Templated .i144 (in[144 +:4]), // Templated .i145 (in[145 +:4]), // Templated .i146 (in[146 +:4]), // Templated .i147 (in[147 +:4]), // Templated .i148 (in[148 +:4]), // Templated .i149 (in[149 +:4]), // Templated .i150 (in[150 +:4]), // Templated .i151 (in[151 +:4]), // Templated .i152 (in[152 +:4]), // Templated .i153 (in[153 +:4]), // Templated .i154 (in[154 +:4]), // Templated .i155 (in[155 +:4]), // Templated .i156 (in[156 +:4]), // Templated .i157 (in[157 +:4]), // Templated .i158 (in[158 +:4]), // Templated .i159 (in[159 +:4]), // Templated .i160 (in[160 +:4]), // Templated .i161 (in[161 +:4]), // Templated .i162 (in[162 +:4]), // Templated .i163 (in[163 +:4]), // Templated .i164 (in[164 +:4]), // Templated .i165 (in[165 +:4]), // Templated .i166 (in[166 +:4]), // Templated .i167 (in[167 +:4]), // Templated .i168 (in[168 +:4]), // Templated .i169 (in[169 +:4]), // Templated .i170 (in[170 +:4]), // Templated .i171 (in[171 +:4]), // Templated .i172 (in[172 +:4]), // Templated .i173 (in[173 +:4]), // Templated .i174 (in[174 +:4]), // Templated .i175 (in[175 +:4]), // Templated .i176 (in[176 +:4]), // Templated .i177 (in[177 +:4]), // Templated .i178 (in[178 +:4]), // Templated .i179 (in[179 +:4]), // Templated .i180 (in[180 +:4]), // Templated .i181 (in[181 +:4]), // Templated .i182 (in[182 +:4]), // Templated .i183 (in[183 +:4]), // Templated .i184 (in[184 +:4]), // Templated .i185 (in[185 +:4]), // Templated .i186 (in[186 +:4]), // Templated .i187 (in[187 +:4]), // Templated .i188 (in[188 +:4]), // Templated .i189 (in[189 +:4]), // Templated .i190 (in[190 +:4]), // Templated .i191 (in[191 +:4]), // Templated .i192 (in[192 +:4]), // Templated .i193 (in[193 +:4]), // Templated .i194 (in[194 +:4]), // Templated .i195 (in[195 +:4]), // Templated .i196 (in[196 +:4]), // Templated .i197 (in[197 +:4]), // Templated .i198 (in[198 +:4]), // Templated .i199 (in[199 +:4]), // Templated .i200 (in[200 +:4]), // Templated .i201 (in[201 +:4]), // Templated .i202 (in[202 +:4]), // Templated .i203 (in[203 +:4]), // Templated .i204 (in[204 +:4]), // Templated .i205 (in[205 +:4]), // Templated .i206 (in[206 +:4]), // Templated .i207 (in[207 +:4]), // Templated .i208 (in[208 +:4]), // Templated .i209 (in[209 +:4]), // Templated .i210 (in[210 +:4]), // Templated .i211 (in[211 +:4]), // Templated .i212 (in[212 +:4]), // Templated .i213 (in[213 +:4]), // Templated .i214 (in[214 +:4]), // Templated .i215 (in[215 +:4]), // Templated .i216 (in[216 +:4]), // Templated .i217 (in[217 +:4]), // Templated .i218 (in[218 +:4]), // Templated .i219 (in[219 +:4]), // Templated .i220 (in[220 +:4]), // Templated .i221 (in[221 +:4]), // Templated .i222 (in[222 +:4]), // Templated .i223 (in[223 +:4]), // Templated .i224 (in[224 +:4]), // Templated .i225 (in[225 +:4]), // Templated .i226 (in[226 +:4]), // Templated .i227 (in[227 +:4]), // Templated .i228 (in[228 +:4]), // Templated .i229 (in[229 +:4]), // Templated .i230 (in[230 +:4]), // Templated .i231 (in[231 +:4]), // Templated .i232 (in[232 +:4]), // Templated .i233 (in[233 +:4]), // Templated .i234 (in[234 +:4]), // Templated .i235 (in[235 +:4]), // Templated .i236 (in[236 +:4]), // Templated .i237 (in[237 +:4]), // Templated .i238 (in[238 +:4]), // Templated .i239 (in[239 +:4]), // Templated .i240 (in[240 +:4]), // Templated .i241 (in[241 +:4]), // Templated .i242 (in[242 +:4]), // Templated .i243 (in[243 +:4]), // Templated .i244 (in[244 +:4]), // Templated .i245 (in[245 +:4]), // Templated .i246 (in[246 +:4]), // Templated .i247 (in[247 +:4]), // Templated .i248 (in[248 +:4]), // Templated .i249 (in[249 +:4]), // Templated .i250 (in[250 +:4]), // Templated .i251 (in[251 +:4]), // Templated .i252 (in[252 +:4]), // Templated .i253 (in[253 +:4]), // Templated .i254 (in[254 +:4]), // Templated .i255 (in[255 +:4])); // Templated // Aggregate outputs into a single result vector wire [63:0] result = {60'h0, out}; // What checksum will we end up with `define EXPECTED_SUM 64'h36f3051d15caf07a // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test ( output wire [3:0] out, input [7:0] sel, input [3:0] i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255 ); assign out = (sel==8'h00) ? i0 : (sel==8'h01) ? i1 : (sel==8'h02) ? i2 : (sel==8'h03) ? i3 : (sel==8'h04) ? i4 : (sel==8'h05) ? i5 : (sel==8'h06) ? i6 : (sel==8'h07) ? i7 : (sel==8'h08) ? i8 : (sel==8'h09) ? i9 : (sel==8'h0a) ? i10 : (sel==8'h0b) ? i11 : (sel==8'h0c) ? i12 : (sel==8'h0d) ? i13 : (sel==8'h0e) ? i14 : (sel==8'h0f) ? i15 : (sel==8'h10) ? i16 : (sel==8'h11) ? i17 : (sel==8'h12) ? i18 : (sel==8'h13) ? i19 : (sel==8'h14) ? i20 : (sel==8'h15) ? i21 : (sel==8'h16) ? i22 : (sel==8'h17) ? i23 : (sel==8'h18) ? i24 : (sel==8'h19) ? i25 : (sel==8'h1a) ? i26 : (sel==8'h1b) ? i27 : (sel==8'h1c) ? i28 : (sel==8'h1d) ? i29 : (sel==8'h1e) ? i30 : (sel==8'h1f) ? i31 : (sel==8'h20) ? i32 : (sel==8'h21) ? i33 : (sel==8'h22) ? i34 : (sel==8'h23) ? i35 : (sel==8'h24) ? i36 : (sel==8'h25) ? i37 : (sel==8'h26) ? i38 : (sel==8'h27) ? i39 : (sel==8'h28) ? i40 : (sel==8'h29) ? i41 : (sel==8'h2a) ? i42 : (sel==8'h2b) ? i43 : (sel==8'h2c) ? i44 : (sel==8'h2d) ? i45 : (sel==8'h2e) ? i46 : (sel==8'h2f) ? i47 : (sel==8'h30) ? i48 : (sel==8'h31) ? i49 : (sel==8'h32) ? i50 : (sel==8'h33) ? i51 : (sel==8'h34) ? i52 : (sel==8'h35) ? i53 : (sel==8'h36) ? i54 : (sel==8'h37) ? i55 : (sel==8'h38) ? i56 : (sel==8'h39) ? i57 : (sel==8'h3a) ? i58 : (sel==8'h3b) ? i59 : (sel==8'h3c) ? i60 : (sel==8'h3d) ? i61 : (sel==8'h3e) ? i62 : (sel==8'h3f) ? i63 : (sel==8'h40) ? i64 : (sel==8'h41) ? i65 : (sel==8'h42) ? i66 : (sel==8'h43) ? i67 : (sel==8'h44) ? i68 : (sel==8'h45) ? i69 : (sel==8'h46) ? i70 : (sel==8'h47) ? i71 : (sel==8'h48) ? i72 : (sel==8'h49) ? i73 : (sel==8'h4a) ? i74 : (sel==8'h4b) ? i75 : (sel==8'h4c) ? i76 : (sel==8'h4d) ? i77 : (sel==8'h4e) ? i78 : (sel==8'h4f) ? i79 : (sel==8'h50) ? i80 : (sel==8'h51) ? i81 : (sel==8'h52) ? i82 : (sel==8'h53) ? i83 : (sel==8'h54) ? i84 : (sel==8'h55) ? i85 : (sel==8'h56) ? i86 : (sel==8'h57) ? i87 : (sel==8'h58) ? i88 : (sel==8'h59) ? i89 : (sel==8'h5a) ? i90 : (sel==8'h5b) ? i91 : (sel==8'h5c) ? i92 : (sel==8'h5d) ? i93 : (sel==8'h5e) ? i94 : (sel==8'h5f) ? i95 : (sel==8'h60) ? i96 : (sel==8'h61) ? i97 : (sel==8'h62) ? i98 : (sel==8'h63) ? i99 : (sel==8'h64) ? i100 : (sel==8'h65) ? i101 : (sel==8'h66) ? i102 : (sel==8'h67) ? i103 : (sel==8'h68) ? i104 : (sel==8'h69) ? i105 : (sel==8'h6a) ? i106 : (sel==8'h6b) ? i107 : (sel==8'h6c) ? i108 : (sel==8'h6d) ? i109 : (sel==8'h6e) ? i110 : (sel==8'h6f) ? i111 : (sel==8'h70) ? i112 : (sel==8'h71) ? i113 : (sel==8'h72) ? i114 : (sel==8'h73) ? i115 : (sel==8'h74) ? i116 : (sel==8'h75) ? i117 : (sel==8'h76) ? i118 : (sel==8'h77) ? i119 : (sel==8'h78) ? i120 : (sel==8'h79) ? i121 : (sel==8'h7a) ? i122 : (sel==8'h7b) ? i123 : (sel==8'h7c) ? i124 : (sel==8'h7d) ? i125 : (sel==8'h7e) ? i126 : (sel==8'h7f) ? i127 : (sel==8'h80) ? i128 : (sel==8'h81) ? i129 : (sel==8'h82) ? i130 : (sel==8'h83) ? i131 : (sel==8'h84) ? i132 : (sel==8'h85) ? i133 : (sel==8'h86) ? i134 : (sel==8'h87) ? i135 : (sel==8'h88) ? i136 : (sel==8'h89) ? i137 : (sel==8'h8a) ? i138 : (sel==8'h8b) ? i139 : (sel==8'h8c) ? i140 : (sel==8'h8d) ? i141 : (sel==8'h8e) ? i142 : (sel==8'h8f) ? i143 : (sel==8'h90) ? i144 : (sel==8'h91) ? i145 : (sel==8'h92) ? i146 : (sel==8'h93) ? i147 : (sel==8'h94) ? i148 : (sel==8'h95) ? i149 : (sel==8'h96) ? i150 : (sel==8'h98) ? i151 : (sel==8'h99) ? i152 : (sel==8'h9a) ? i153 : (sel==8'h9b) ? i154 : (sel==8'h9c) ? i155 : (sel==8'h9d) ? i156 : (sel==8'h9e) ? i157 : (sel==8'h9f) ? i158 : (sel==8'ha0) ? i159 : (sel==8'ha1) ? i160 : (sel==8'ha2) ? i161 : (sel==8'ha3) ? i162 : (sel==8'ha4) ? i163 : (sel==8'ha5) ? i164 : (sel==8'ha6) ? i165 : (sel==8'ha7) ? i166 : (sel==8'ha8) ? i167 : (sel==8'ha9) ? i168 : (sel==8'haa) ? i169 : (sel==8'hab) ? i170 : (sel==8'hac) ? i171 : (sel==8'had) ? i172 : (sel==8'hae) ? i173 : (sel==8'haf) ? i174 : (sel==8'hb0) ? i175 : (sel==8'hb1) ? i176 : (sel==8'hb2) ? i177 : (sel==8'hb3) ? i178 : (sel==8'hb4) ? i179 : (sel==8'hb5) ? i180 : (sel==8'hb6) ? i181 : (sel==8'hb7) ? i182 : (sel==8'hb8) ? i183 : (sel==8'hb9) ? i184 : (sel==8'hba) ? i185 : (sel==8'hbb) ? i186 : (sel==8'hbc) ? i187 : (sel==8'hbd) ? i188 : (sel==8'hbe) ? i189 : (sel==8'hbf) ? i190 : (sel==8'hc0) ? i191 : (sel==8'hc1) ? i192 : (sel==8'hc2) ? i193 : (sel==8'hc3) ? i194 : (sel==8'hc4) ? i195 : (sel==8'hc5) ? i196 : (sel==8'hc6) ? i197 : (sel==8'hc7) ? i198 : (sel==8'hc8) ? i199 : (sel==8'hc9) ? i200 : (sel==8'hca) ? i201 : (sel==8'hcb) ? i202 : (sel==8'hcc) ? i203 : (sel==8'hcd) ? i204 : (sel==8'hce) ? i205 : (sel==8'hcf) ? i206 : (sel==8'hd0) ? i207 : (sel==8'hd1) ? i208 : (sel==8'hd2) ? i209 : (sel==8'hd3) ? i210 : (sel==8'hd4) ? i211 : (sel==8'hd5) ? i212 : (sel==8'hd6) ? i213 : (sel==8'hd7) ? i214 : (sel==8'hd8) ? i215 : (sel==8'hd9) ? i216 : (sel==8'hda) ? i217 : (sel==8'hdb) ? i218 : (sel==8'hdc) ? i219 : (sel==8'hdd) ? i220 : (sel==8'hde) ? i221 : (sel==8'hdf) ? i222 : (sel==8'he0) ? i223 : (sel==8'he1) ? i224 : (sel==8'he2) ? i225 : (sel==8'he3) ? i226 : (sel==8'he4) ? i227 : (sel==8'he5) ? i228 : (sel==8'he6) ? i229 : (sel==8'he7) ? i230 : (sel==8'he8) ? i231 : (sel==8'he9) ? i232 : (sel==8'hea) ? i233 : (sel==8'heb) ? i234 : (sel==8'hec) ? i235 : (sel==8'hed) ? i236 : (sel==8'hee) ? i237 : (sel==8'hef) ? i238 : (sel==8'hf0) ? i239 : (sel==8'hf1) ? i240 : (sel==8'hf2) ? i241 : (sel==8'hf3) ? i242 : (sel==8'hf4) ? i243 : (sel==8'hf5) ? i244 : (sel==8'hf6) ? i245 : (sel==8'hf7) ? i246 : (sel==8'hf8) ? i247 : (sel==8'hf9) ? i248 : (sel==8'hfa) ? i249 : (sel==8'hfb) ? i250 : (sel==8'hfc) ? i251 : (sel==8'hfd) ? i252 : (sel==8'hfe) ? i253 : (sel==8'hff) ? i254 : i255; endmodule verilator-3.874/test_regress/t/t_func_wide_out_bad.v0000664000177100017500000000147012473477707022675 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (); parameter MSG_PORT_WIDTH = 4350; localparam PAYLOAD_MAX_BITS = 4352; reg [MSG_PORT_WIDTH-1:0] msg; initial begin // Operator TASKREF 'func' expects 4352 bits on the Function Argument, but Function Argument's VARREF 'msg' generates 4350 bits. // verilator lint_off WIDTH func(msg); // verilator lint_on WIDTH if (msg !== {MSG_PORT_WIDTH{1'b1}}) $stop; $write("*-* All Finished *-*\n"); $finish; end function integer func (output bit [PAYLOAD_MAX_BITS-1:0] data); /*verilator no_inline_task*/ data = {PAYLOAD_MAX_BITS{1'b1}}; return (1); endfunction endmodule verilator-3.874/test_regress/t/t_dpi_qw_c.cpp0000664000177100017500000000217212473477707021337 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- // // DESCRIPTION: Verilator: Verilog Test module // // Copyright 2009 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. //************************************************************************* #include #include #include "svdpi.h" //====================================================================== #include "Vt_dpi_qw__Dpi.h" //====================================================================== // Called from our Verilog code to run the tests void poke_value(int i) { printf("poke_value(%d)\n", i); #ifdef VERILATOR static int didDump = 0; if (didDump++ == 0) { # ifdef TEST_VERBOSE Verilated::scopesDump(); # endif } #endif svScope scope = svGetScopeFromName("top.t.a"); if (scope == NULL) { printf("%%Error: null scope for top.t.a\n"); return; } svSetScope(scope); svBitVecVal val[2]; val[0] = i; val[1] = 0; set_value(val); } verilator-3.874/test_regress/t/t_func_plog.v0000664000177100017500000000446012473477707021213 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; reg rst_n; // Take CRC data and apply to testblock inputs /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [2:0] pos1; // From test of Test.v wire [2:0] pos2; // From test of Test.v // End of automatics Test test ( // Outputs .pos1 (pos1[2:0]), .pos2 (pos2[2:0]), /*AUTOINST*/ // Inputs .clk (clk), .rst_n (rst_n)); // Aggregate outputs into a single result vector wire [63:0] result = {61'h0, pos1}; // What checksum will we end up with `define EXPECTED_SUM 64'h039ea4d039c2e70b // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; rst_n <= ~1'b0; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; rst_n <= ~1'b1; end else if (cyc<10) begin sum <= 64'h0; rst_n <= ~1'b1; end else if (cyc<90) begin if (pos1 !== pos2) $stop; end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test #(parameter SAMPLE_WIDTH = 5 ) ( `ifdef verilator // Some simulators don't support clog2 output reg [$clog2(SAMPLE_WIDTH)-1:0] pos1, `else output reg [log2(SAMPLE_WIDTH-1)-1:0] pos1, `endif output reg [log2(SAMPLE_WIDTH-1)-1:0] pos2, // System input clk, input rst_n ); function integer log2(input integer arg); begin for(log2=0; arg>0; log2=log2+1) arg = (arg >> 1); end endfunction always @ (posedge clk or negedge rst_n) if (!rst_n) begin pos1 <= 0; pos2 <= 0; end else begin pos1 <= pos1 + 1; pos2 <= pos2 + 1; end endmodule verilator-3.874/test_regress/t/t_sys_readmem_bad_addr.mem0000664000177100017500000000045212473477707023655 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test data file // // Copyright 2006 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. @121212 10 verilator-3.874/test_regress/t/t_param_first_a.v0000664000177100017500000000125412473477707022044 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t_param_first_a (/*AUTOARG*/ // Outputs varwidth, par ); parameter X = 1; parameter FIVE = 0; // Overridden parameter TWO = 2; /*AUTOOUTPUT*/ // Beginning of automatic outputs (from unused autoinst outputs) output [4:0] par; // From b of t_param_first_b.v output [X:0] varwidth; // From b of t_param_first_b.v // End of automatics t_param_first_b #(X,FIVE,TWO) b (/*AUTOINST*/ // Outputs .par (par[4:0]), .varwidth (varwidth[X:0])); endmodule verilator-3.874/test_regress/t/t_repeat.pl0000775000177100017500000000071712473477707020671 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_select_little_pack.v0000664000177100017500000000113612473477707023066 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; // No endian warning here wire [7:0] pack [3:0]; initial begin pack[0] = 8'h78; pack[1] = 8'h88; pack[2] = 8'h98; pack[3] = 8'hA8; if (pack[0] !== 8'h78) $stop; if (pack[1] !== 8'h88) $stop; if (pack[2] !== 8'h98) $stop; if (pack[3] !== 8'hA8) $stop; $write("*-* All Finished *-*\n"); $finish; end endmodule verilator-3.874/test_regress/t/t_case_auto1.v0000664000177100017500000000451712473477707021266 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2005 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; localparam // synopsys enum En_State EP_State_IDLE = {3'b000,5'd00}, EP_State_CMDSHIFT0 = {3'b001,5'd00}, EP_State_CMDSHIFT13 = {3'b001,5'd13}, EP_State_CMDSHIFT14 = {3'b001,5'd14}, EP_State_CMDSHIFT15 = {3'b001,5'd15}, EP_State_CMDSHIFT16 = {3'b001,5'd16}, EP_State_DWAIT = {3'b010,5'd00}, EP_State_DSHIFT0 = {3'b100,5'd00}, EP_State_DSHIFT1 = {3'b100,5'd01}, EP_State_DSHIFT15 = {3'b100,5'd15}; reg [7:0] /* synopsys enum En_State */ m_state_xr; // Last command, for debugging /*AUTOASCIIENUM("m_state_xr", "m_stateAscii_xr", "EP_State_")*/ // Beginning of automatic ASCII enum decoding reg [79:0] m_stateAscii_xr; // Decode of m_state_xr always @(m_state_xr) begin case ({m_state_xr}) EP_State_IDLE: m_stateAscii_xr = "idle "; EP_State_CMDSHIFT0: m_stateAscii_xr = "cmdshift0 "; EP_State_CMDSHIFT13: m_stateAscii_xr = "cmdshift13"; EP_State_CMDSHIFT14: m_stateAscii_xr = "cmdshift14"; EP_State_CMDSHIFT15: m_stateAscii_xr = "cmdshift15"; EP_State_CMDSHIFT16: m_stateAscii_xr = "cmdshift16"; EP_State_DWAIT: m_stateAscii_xr = "dwait "; EP_State_DSHIFT0: m_stateAscii_xr = "dshift0 "; EP_State_DSHIFT1: m_stateAscii_xr = "dshift1 "; EP_State_DSHIFT15: m_stateAscii_xr = "dshift15 "; default: m_stateAscii_xr = "%Error "; endcase end // End of automatics integer cyc; initial cyc=1; always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; //$write("%d %x %x %x\n", cyc, data, wrapcheck_a, wrapcheck_b); if (cyc==1) begin m_state_xr <= EP_State_IDLE; end if (cyc==2) begin if (m_stateAscii_xr != "idle ") $stop; m_state_xr <= EP_State_CMDSHIFT13; end if (cyc==3) begin if (m_stateAscii_xr != "cmdshift13") $stop; m_state_xr <= EP_State_CMDSHIFT16; end if (cyc==4) begin if (m_stateAscii_xr != "cmdshift16") $stop; m_state_xr <= EP_State_DWAIT; end if (cyc==9) begin if (m_stateAscii_xr != "dwait ") $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule verilator-3.874/test_regress/t/t_interface_top_bad.pl0000775000177100017500000000122712473477707023036 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ["--lint-only"], verilator_make_gcc => 0, make_top_shell => 0, make_main => 0, fails => 1, expect=> '%Error: t/t_interface_top_bad.v:\d+: Unsupported: Interfaced port on top level module', ); ok(1); 1; verilator-3.874/test_regress/t/t_package_enum.pl0000775000177100017500000000072212473477707022024 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_gen_for_shuffle.v0000664000177100017500000000344712473477707022376 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc=0; reg [63:0] crc; reg [63:0] sum; // Take CRC data and apply to testblock inputs wire [31:0] in = crc[31:0]; /*AUTOWIRE*/ // Beginning of automatic wires (for undeclared instantiated-module outputs) wire [31:0] out; // From test of Test.v // End of automatics Test test (/*AUTOINST*/ // Outputs .out (out[31:0]), // Inputs .in (in[31:0])); // Aggregate outputs into a single result vector wire [63:0] result = {32'h0, out}; // Test loop always @ (posedge clk) begin `ifdef TEST_VERBOSE $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result); `endif cyc <= cyc + 1; crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; if (cyc==0) begin // Setup crc <= 64'h5aef0c8d_d70a4497; sum <= 64'h0; end else if (cyc<10) begin sum <= 64'h0; end else if (cyc<90) begin end else if (cyc==99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum); if (crc !== 64'hc77bb9b3784ea091) $stop; // What checksum will we end up with (above print should match) `define EXPECTED_SUM 64'h3e3a62edb61f8c7f if (sum !== `EXPECTED_SUM) $stop; $write("*-* All Finished *-*\n"); $finish; end end endmodule module Test (/*AUTOARG*/ // Outputs out, // Inputs in ); input [31:0] in; output [31:0] out; genvar i; generate for (i=0; i<16; i=i+1) begin : gblk assign out[i*2+1:i*2] = in[(30-i*2)+1:(30-i*2)]; end endgenerate endmodule verilator-3.874/test_regress/t/t_select_runtime_range.pl0000775000177100017500000000072012473477707023601 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/test_regress/t/t_trace_scstruct.pl0000775000177100017500000000104212525171734022416 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 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. compile ( verilator_flags2 => ['--sc --trace --trace-structs --pins-bv 2'], ); #execute (); # didn't bother with top shell ok(1); 1; verilator-3.874/test_regress/t/t_inst_tree.v0000664000177100017500000000465012473477707021234 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Inputs clk ); input clk; integer cyc; initial cyc=1; // verilator lint_off GENCLK reg printclk; // verilator lint_on GENCLK ps ps (printclk); reg [7:0] a; wire [7:0] z; l1 u (~a,z); always @ (posedge clk) begin printclk <= 0; if (cyc!=0) begin cyc <= cyc + 1; if (cyc==1) begin printclk <= 1'b1; end if (cyc==2) begin a <= 8'b1; end if (cyc==3) begin if (z !== 8'hf8) $stop; //if (u.u1.u1.u1.u0.PARAM !== 1) $stop; //if (u.u1.u1.u1.u1.PARAM !== 2) $stop; //if (u.u0.u0.u0.u0.z !== 8'hfe) $stop; //if (u.u0.u0.u0.u1.z !== 8'hff) $stop; //if (u.u1.u1.u1.u0.z !== 8'h00) $stop; //if (u.u1.u1.u1.u1.z !== 8'h01) $stop; $write("*-* All Finished *-*\n"); $finish; end end end endmodule `ifdef USE_INLINE `define INLINE_MODULE /*verilator inline_module*/ `else `define INLINE_MODULE /*verilator public_module*/ `endif `ifdef USE_PUBLIC `define PUBLIC /*verilator public*/ `else `define PUBLIC `endif module ps (input printclk); `INLINE_MODULE // Check that %m stays correct across inlines always @ (posedge printclk) $write("[%0t] %m: Clocked\n", $time); endmodule module l1 (input [7:0] a, output [7:0] z); `INLINE_MODULE wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC; wire [7:0] z `PUBLIC; assign z = z0+z1; l2 u0 (a, z0); l2 u1 (a, z1); endmodule module l2 (input [7:0] a, output [7:0] z); `INLINE_MODULE wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC; wire [7:0] z `PUBLIC; assign z = z0+z1; wire [7:0] a1 = a+8'd1; l3 u0 (a, z0); l3 u1 (a1, z1); endmodule module l3 (input [7:0] a, output [7:0] z); `INLINE_MODULE wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC; wire [7:0] z `PUBLIC; assign z = z0+z1; wire [7:0] a1 = a+8'd1; l4 u0 (a, z0); l4 u1 (a1, z1); endmodule module l4 (input [7:0] a, output [7:0] z); `INLINE_MODULE wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC; wire [7:0] z `PUBLIC; assign z = z0+z1; wire [7:0] a1 = a+8'd1; l5 #(1) u0 (a, z0); l5 #(2) u1 (a1, z1); endmodule module l5 (input [7:0] a, output [7:0] z); `INLINE_MODULE parameter PARAM = 5; wire [7:0] z0 `PUBLIC; wire [7:0] z1 `PUBLIC; wire [7:0] z `PUBLIC; assign z = a; endmodule verilator-3.874/test_regress/t/t_inst_notunsized.pl0000775000177100017500000000077012473477707022647 0ustar wsnyderwsnyder#!/usr/bin/perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003 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. compile ( verilator_flags2=>["-Wno-IMPLICIT"], ); execute ( check_finished=>1, ); ok(1); 1; verilator-3.874/verilator.pdf0000664000177100017500000137015512534631202016237 0ustar wsnyderwsnyder%PDF-1.4 %ÐÔÅØ 1 0 obj << /S /GoTo /D (section.2) >> endobj 4 0 obj (1 NAME) endobj 5 0 obj << /S /GoTo /D (section.3) >> endobj 8 0 obj (2 SYNOPSIS) endobj 9 0 obj << /S /GoTo /D (section.4) >> endobj 12 0 obj (3 DESCRIPTION) endobj 13 0 obj << /S /GoTo /D (section.5) >> endobj 16 0 obj (4 ARGUMENT SUMMARY) endobj 17 0 obj << /S /GoTo /D (section.6) >> endobj 20 0 obj (5 ARGUMENTS) endobj 21 0 obj << /S /GoTo /D (section.7) >> endobj 24 0 obj (6 EXAMPLE C++ EXECUTION) endobj 25 0 obj << /S /GoTo /D (section.8) >> endobj 28 0 obj (7 EXAMPLE SYSTEMC EXECUTION) endobj 29 0 obj << /S /GoTo /D (section.9) >> endobj 32 0 obj (8 BENCHMARKING \046 OPTIMIZATION) endobj 33 0 obj << /S /GoTo /D (section.10) >> endobj 36 0 obj (9 FILES) endobj 37 0 obj << /S /GoTo /D (section.11) >> endobj 40 0 obj (10 ENVIRONMENT) endobj 41 0 obj << /S /GoTo /D (section.12) >> endobj 44 0 obj (11 CONNECTING TO C++) endobj 45 0 obj << /S /GoTo /D (section.13) >> endobj 48 0 obj (12 CONNECTING TO SYSTEMC) endobj 49 0 obj << /S /GoTo /D (section.14) >> endobj 52 0 obj (13 DIRECT PROGRAMMING INTERFACE \(DPI\)) endobj 53 0 obj << /S /GoTo /D (section.21) >> endobj 56 0 obj (14 VERIFICATION PROCEDURAL INTERFACE \(VPI\)) endobj 57 0 obj << /S /GoTo /D (section.23) >> endobj 60 0 obj (15 CROSS COMPILATION) endobj 61 0 obj << /S /GoTo /D (section.25) >> endobj 64 0 obj (16 CONFIGURATION FILES) endobj 65 0 obj << /S /GoTo /D (section.26) >> endobj 68 0 obj (17 LANGUAGE STANDARD SUPPORT) endobj 69 0 obj << /S /GoTo /D (section.33) >> endobj 72 0 obj (18 LANGUAGE EXTENSIONS) endobj 73 0 obj << /S /GoTo /D (section.34) >> endobj 76 0 obj (19 LANGUAGE LIMITATIONS) endobj 77 0 obj << /S /GoTo /D (section.53) >> endobj 80 0 obj (20 ERRORS AND WARNINGS) endobj 81 0 obj << /S /GoTo /D (section.54) >> endobj 84 0 obj (21 FAQ/FREQUENTLY ASKED QUESTIONS) endobj 85 0 obj << /S /GoTo /D (section.55) >> endobj 88 0 obj (22 BUGS) endobj 89 0 obj << /S /GoTo /D (section.56) >> endobj 92 0 obj (23 HISTORY) endobj 93 0 obj << /S /GoTo /D (section.57) >> endobj 96 0 obj (24 AUTHORS) endobj 97 0 obj << /S /GoTo /D (section.58) >> endobj 100 0 obj (25 CONTRIBUTORS) endobj 101 0 obj << /S /GoTo /D (section.59) >> endobj 104 0 obj (26 DISTRIBUTION) endobj 105 0 obj << /S /GoTo /D (section.60) >> endobj 108 0 obj (27 SEE ALSO) endobj 109 0 obj << /S /GoTo /D [110 0 R /Fit ] >> endobj 112 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚ-ν 1 àýž"ãuh®i›´utp..â ø 'Çá½¾­BH ù’mî†= P@Kì!ßÁ²Ã˜,ˆ÷(ÆB¾Â©?ªûÛü/Ë4+íÈõe*xu· ÂÄl+ É`H´7½oÀSÙÐ/Ë{3 ëºâ§¶Å{+]Š©å§ùQEpŒ\W4Àbm¤Äÿ&CÂ$V~?{ŒA³¤ mƒê`·ËÝOq5Ù endstream endobj 110 0 obj << /Type /Page /Contents 112 0 R /Resources 111 0 R /MediaBox [0 0 612 792] /Parent 118 0 R >> endobj 113 0 obj << /D [110 0 R /XYZ 121.4 736.262 null] >> endobj 114 0 obj << /D [110 0 R /XYZ 122.4 698.4 null] >> endobj 111 0 obj << /Font << /F16 115 0 R /F17 116 0 R /F15 117 0 R >> /ProcSet [ /PDF /Text ] >> endobj 139 0 obj << /Length 621 /Filter /FlateDecode >> stream xÚ}T]oÛ }÷¯àiªârcxt’Ñų¨Yׇií¤Iíªu•ö÷w ®—.hOFæÜsÎ=\XŽÉårb2£¸"ã7œg’\eÚ2Þ‘ºOµ ÷Ïß¾¤@_ÒÐ'\<§ !$™.dz;^]®;áÀ2ŰÀQµÍh›qðÈÄŽÉÏÄo1³ È€äëcrsËÈn]– £Éï#ð‘UdWdH>&Kïœk2Rñ¿Ö•Ö™Å$ûô#hú?Œ¾ü F¹91ÊöM„H†ç´)k‹ý¨‚r_4à àxÀ ‡¦í7¤ nð8VìÊUïºÑµ ÂUnÄ?ð€–]ö©àt³«15t‚'0ìêÿEXçq¹üœÀû+î ª€·×eÝmmЪ..ÂÂ^Ûj,Ca(˜˜fáÃhëêœG¦(‡ˆh–¶©Þc¯\³ åï§Åôj÷©ô!LdBú£A˜À¶v[‹f"eDnçŒÚfµMˆçÀ4åyŒ ád7¶g«c{!&råÿ¯ŸãÍæUDMˆ@²r=r„Â.´°é˺žY^¿~/hé·+¼ÁÇs’ô3ËÙªsøñÃÇJGµdÐÚÛÞ­]ur'ª•]íúr˜gQ=‰N“á÷¯ŠJ( "6 O êa˜‚mëÎmOä9^NEt@Í)¯Ý­½u=Íg’áS&b&Š@°-›ÍîØÅæu¾GÏU6+ÿ³ìW¡ça×uíñ–Ž~Ôs\ˆé}|ûÎjÈÈBêÌø?áñ™^Ç?A& endstream endobj 138 0 obj << /Type /Page /Contents 139 0 R /Resources 137 0 R /MediaBox [0 0 612 792] /Parent 118 0 R /Annots [ 119 0 R 120 0 R 121 0 R 122 0 R 123 0 R 124 0 R 125 0 R 126 0 R 127 0 R 128 0 R 129 0 R 130 0 R 131 0 R 132 0 R 133 0 R 134 0 R 135 0 R ] >> endobj 119 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 653.57 174.359 662.438] /A << /S /GoTo /D (section.2) >> >> endobj 120 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 619.7 195.829 628.568] /A << /S /GoTo /D (section.3) >> >> endobj 121 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 585.829 219.927 594.697] /A << /S /GoTo /D (section.4) >> >> endobj 122 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 551.959 274.113 560.827] /A << /S /GoTo /D (section.5) >> >> endobj 123 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 518.088 214.781 526.956] /A << /S /GoTo /D (section.6) >> >> endobj 124 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 482.89 300.702 493.085] /A << /S /GoTo /D (section.7) >> >> endobj 125 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 450.347 330.638 459.215] /A << /S /GoTo /D (section.8) >> >> endobj 126 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 416.477 344.72 425.344] /A << /S /GoTo /D (section.9) >> >> endobj 127 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 382.606 170.666 391.474] /A << /S /GoTo /D (section.10) >> >> endobj 128 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 348.735 229.002 357.603] /A << /S /GoTo /D (section.11) >> >> endobj 129 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 313.537 269.521 323.733] /A << /S /GoTo /D (section.12) >> >> endobj 130 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 280.994 299.457 289.862] /A << /S /GoTo /D (section.13) >> >> endobj 131 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 244.634 387.632 256.586] /A << /S /GoTo /D (section.14) >> >> endobj 132 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 210.763 415.77 222.716] /A << /S /GoTo /D (section.21) >> >> endobj 133 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 179.383 264.43 188.251] /A << /S /GoTo /D (section.23) >> >> endobj 134 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 145.512 275.87 154.38] /A << /S /GoTo /D (section.25) >> >> endobj 135 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 111.642 333.722 120.509] /A << /S /GoTo /D (section.26) >> >> endobj 140 0 obj << /D [138 0 R /XYZ 121.4 736.262 null] >> endobj 143 0 obj << /D [138 0 R /XYZ 122.4 678.574 null] >> endobj 137 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 156 0 obj << /Length 424 /Filter /FlateDecode >> stream xÚu“AoÔ0…ïù>Ú‡z=Û±YšÝ¦,‰6vZPÕ¢ !µBTHü}ƱA´„›eÏûæ½ÉdŸšÝ, 28íXúÂ@kiX«ôYz`wüFx䟟¿>~Àˆ àßèð,. Gé[#îÓõî€ê/‚’NS…ñfS?¦˜+›>5ß›ü¤üiˆTË>=5w÷Š=ÐÓ5Sƒg?×Â'†®•šN,6çfŸëðsç½4Ø–®àɤUüÔÇ¥¨ù±§ŠÓ¿';q˜ÆHy‚ÕÈÑfoħX”©Âÿ§áÝDp¼ÁòDòd*Uà^¡µ*Ä~ž3nšcáuãe9Ü Ð-ïæq+Ë(ÏßdAaHâùjï¼;Ìýy¡QŸ²¹ßö+Þpz‹©æ†-·a#·Ö…¼_²Jã;»éKåÕÓ4מšvǾÔzSêW·KºZ ½Ñš;·ÙÀAÞ yØ/©(Œ£»WŠ*pEpIŽV¥%5–Z´›-Ú¢ˆ}ý¸Ý)NÙ•ŠíËv¿üK> endobj 136 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 687.441 284.641 696.309] /A << /S /GoTo /D (section.33) >> >> endobj 145 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 653.57 286.771 662.438] /A << /S /GoTo /D (section.34) >> >> endobj 146 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 619.7 285.789 628.568] /A << /S /GoTo /D (section.53) >> >> endobj 147 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 583.339 362.234 595.292] /A << /S /GoTo /D (section.54) >> >> endobj 148 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 551.959 170.666 560.827] /A << /S /GoTo /D (section.55) >> >> endobj 149 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 518.088 190.876 526.956] /A << /S /GoTo /D (section.56) >> >> endobj 150 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 484.218 195.981 493.085] /A << /S /GoTo /D (section.57) >> >> endobj 151 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 450.347 233.567 459.215] /A << /S /GoTo /D (section.58) >> >> endobj 152 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 416.477 225.571 425.344] /A << /S /GoTo /D (section.59) >> >> endobj 153 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 382.606 194.086 391.474] /A << /S /GoTo /D (section.60) >> >> endobj 157 0 obj << /D [155 0 R /XYZ 121.4 736.262 null] >> endobj 154 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 160 0 obj << /Length 1451 /Filter /FlateDecode >> stream xÚÅWYsÛ6~ׯàä¥ÔØ‚x‰Ç££*gb'”Ž3Ž'S°…†WЊÚéï.ÔaËMfúÐ'‹Åžß.–/ƒñ+âd,‹ƒØYÜ9~°ÈI‚˜¥Yè,–εûû0 ]ÑÊ‚}WG¾[âŽÂ0rC–&Ñðfñfü*ôöäá„¥Ç#Üò<Ï=û0 R÷õÇ‹Ùåï‡îüãÅPAÃ'”2˜-ß>ÜókLÈ|/qòrp}ã9K8zãx,ÌRgmK'ŒÀªpæƒß/Ñ« uüˆ…QìÜŠÓ”EaB6ù`å^ž]Ìȃ@xØÇ’$ú‰ ŒÈ—i]¡{à q^<ƒû‘¹_ßÓ|ˆ"FÀ¿Ä¢k:™žœŒç¥E9%»]â²cݬóO—ïÞÏÏç6þ~.<–ùñ¡?Æ]ƒ“`âŽF+Ö ÞG¾Ï²ÉäæÃÜ* ÿ žÓêºÆ{†{êÆ’tÝ|)ă(ØÃ cxÎð$Ú2É¿ÜÉB(–7Í8çùé|\U}óSêÕÿ«¾x£Ò£º*6r/ËP¯¿§›Ëö¨OžÉyJB›ó_góé‡ó÷‹ów—ÿÁ‰ïæ[è¦À£R=Wm*IJ^ %ÿä·… ògoâUµ¦Í­Á°Xqs_Ö-/àܧíNƒz äù  ûÔs›¢ëuÕ¥?ß[ŒVuz,ÂT(û°¬&‰Ë«%.b—ÓG•¼(èHu·Jh"×wô=4gs+H)"MW’U5ñA‘¦ {ûØÜ¼¯s@VEî¹í RÑ—b •ÏiŸ×eSmÛ‚’%*î ¤N‰vÛ=½mY¯Zfæÿ ïA@&AïœIýÕô¯%¬¥^Ѫá-/ÁªÖ^»@fK ~_O§§´šò¥¨rA›½0®ÞŽ/§£½ÄM± kœ êFmÔ/«8I`âtÎèÔD¾­àKEK 9Uc &rùÙ #ô„mr0´ÉÄ-$aÞŠ“ÚÒ X ·6ýƒD¬f$ñ%hßw"Þ&~WTüƒÑKÂÅ8j#–»º-éD·<—Õ=n¢Cø@Cy….`|Óàð@jDsErRt†XêN7zˆìkÇ2@¸ØŠ¾FìƒG0¶0AŸø–B£hŸCf´‰=lnÑË ­·ù§F‰$Þ!¦°²× ×K¢‘^c0²x§¹ƒr¥Õº•Z(ºÂ‰TH­Á¬#^RGô–7 õ2”õ¾`ú¡f×+™£ù+â–•Òœ‚ä¤ ¨„=¸ Q »›Ô´-m*;+7´Qް¼ álåH»26@8Eµw´N RQ:!Õ¸€•Fh0#jRxp PʲLécóI|¼² 9’¥a:ÅçÌŒ$xÕàQÛ6 $Q‚P šs¤ žö"ÄÊ’zÙñl…ê mJ·â»È;m_&د¥iö ÌK5…ÝËà¹îxñ¤¹BQUmª¸ï…íÜü`m»ñ]ÙŽ¥)øuµ?Ð…î‹ÙÕÙÅû·³íxGäÙÕlúßîìßæ¼t7Bû4B‡þn„ÆI#tÐýÌö‘4Ð <·ÿb‰P°«ºÕDQ@¨ÝÐÆ¼”gÇüf¬½‡¼u¸( :·-9kúî’ %nž>xÛ…x$n)4·%nv*o%MhÇ$ûÐöɬÄwû*‘Ó5C¿3]eÝZVYQ7ìýü”œöÑú '?öð7þ¾D¼>ý˃)r\˜Ž–È_™ù°êX½’D#‘k ½„Ç)Ö»þ]1‚¦'x~B£è M­’búÚR¥¬žW‡Ã*JP5(KÀ»'ÊNvæ?R-ä뾆Çÿ‹±Çü,¬ÆÌËâ~>µ¿rÿVoÀY endstream endobj 159 0 obj << /Type /Page /Contents 160 0 R /Resources 158 0 R /MediaBox [0 0 612 792] /Parent 118 0 R >> endobj 161 0 obj << /D [159 0 R /XYZ 121.4 736.262 null] >> endobj 2 0 obj << /D [159 0 R /XYZ 122.4 698.4 null] >> endobj 6 0 obj << /D [159 0 R /XYZ 122.4 637.164 null] >> endobj 10 0 obj << /D [159 0 R /XYZ 122.4 510.949 null] >> endobj 14 0 obj << /D [159 0 R /XYZ 122.4 241.272 null] >> endobj 158 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 165 0 obj << /Length 1659 /Filter /FlateDecode >> stream xÚ­XYoÛ8~ϯÐCd¸RuÚàh®n‹d·Û¸A°%ÚÑF‡—¤ÒäßïpHʲ#ÙI·/¶Žá7ßœêd~ôî ؎'ÞĘ/ ×óìÀ˜z;Š}cž7æ÷Q䛄æE2rM>²\³† :²|?0};š£Ûùçw¾ÓÁñüÐŽBѬrÇüðuäEæÇoWç¿ÏÅzß¼þvuOAÃ_åè|~ôï‘ ëÃmÉø¶ëL´<º¹uŒ ^}6Û#ã –†?™Ú\ÆõÑŸG'Â*ßíZDv„Æ$ŠìÀŸJRcן–Ç¡°‰<òñ ~ŽGVÏÌoŒŒ¬Ð ÍïÂôz%o¤´¸ú‘ó;yµÌ wøsÍGN*–ו°`0´\׎ðËÀs÷å ¤ô/g¾ŠÁ/õAä8‡\?1NJÁCˆâ¢‘C&;âŸäÿ;~p½Ÿã Ö½šƒÚžo±¬„1BÅFw‚82Ï«d¡’¢P(‚ˆ®Éú옆×Ë¢aB(E±ç™˜& S§$)™Â\rBwô¼Ér¶.’§‹Eýh1xkÅA™'E’Þ/°B=ÊõMu_Õ?”Ýo:OÞ¤ cjS!ñf Ì¡Ô(ì .kÖëšr’ÉER­P>Y)_-IÂJX_ÂŽ\C„©JJŒ:„{â²?¥yÖî>ñR`^+Áò„>!t_O/.?|¼Ö Š©1~:ËW§u¹í 䄨J…c©u•É=Á\Θ4…•^OÍS(W¼[=uƒmc ½O3\ïL=ó´¨…hz/+I†Á,í­”ÖŒå•Êú¤JŠ'–„1-î•X¾IK`§…—ƒ)€_%TI°5Ióe®ƒ)åu¦+ÍE ¤úm¹q–¢ò‘¥ô¹Nè˜ó¦";¾ÝQÜz ÑcÛ›@i]A’¬05¬"/s®Ôu½¡ö ãvTjù*Uá\ïkž—dÈ6X…9;l»` ’’F+ÙHHXðšDž¿)Kº¸#^ˆÇëÕ A¦S@”nQÛ—÷¥˜ !}Æñúû¥ªL‡|ÐøI?p•ÊÒšÂ-L.Áü–ár÷,åÿß2-Ùà®?›=$ôøæý Ù$ECŽo1:±yMTz¬)YÓ:%ŒéÌ`sWû6wF( ®³ã |±»±×™øÚJïб¡§Ñt`ÓT„´h,lh®S< G ]ÙvÁ±žu('$½›O û´ZèXFSQ ; ½Ã÷§tÖ š˜ªQi)nÚF½E00åLµËj²aµLš‚c]ýgÓ{fâV §¡y&Å6}j#Çk• ed(¯Æ2CÆ3LLȰ÷3™\½înna§ze~5åÚ┨ç„s,:Ι֕6“ÍŒ3”)]Ø\:¨#†ƒÕVĆ• “ Ø%y{­R%Š—P±f/N!A‹ÙJª³Qõ–õý™ Y–Úä{_XDõáf~i+Æ[5{4 'SÙSÕ¼[±ó=w›¶0ÚÔ:ʶm«M)Q?,jÊŸM…ü.W͸jÊ…¬’Ý©~ 'È#уÆeŽ)¦æ ½RÜœ›¤ Lj 9ê¢3Ç«6ù÷“¤¶–ÕLÆ‚Jm%N¯·ò©d³^áyêµcù«TîÙ•«l¡]õµ©Úc ,W›A{™¼üxv"/ò B–¤{ è ®{Jÿv;9-`çH'Išî)D=rCpÏ™唤Àíi»t2’Ðôn‡\^¥ò “©êÔïã| 5|­Ïk°°<5²0é9bè‘èÓÅÙù—ùoꘗÐJwÞ¾š €üx†4Z1õƒ×ª8dDu—/rÙ…X^ª6ß=,›*åíéSë„ÃQ¥wïRÏÝe$óJL†ÎÄm+Û.›I·¬³F—<\ˆ.ö•uy6t\Âq*Ž,,r­åµêÅ?àËöì´ÿÜä<Óyù餫O›zŽA•TÏÄ Š‰!ƒ¦F†CúúcõlJÍE[Š“¢÷N Œ'U–Ðì5³°—ß2ä'¡ãñ ÜÞÚ6t2oÆœw?íZƒCÖ6dÖ}™¡æV]áÎ{RƒÄ¥ìŸü`ïÞkO«ê¤ºûmtâØn–Ù€­?mªÏ–ÿ•‡²ž endstream endobj 164 0 obj << /Type /Page /Contents 165 0 R /Resources 163 0 R /MediaBox [0 0 612 792] /Parent 118 0 R >> endobj 166 0 obj << /D [164 0 R /XYZ 121.4 736.262 null] >> endobj 163 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 169 0 obj << /Length 1708 /Filter /FlateDecode >> stream xÚ•XÛnÛF}÷Wð-4Œex•DDÄvÛ ¾´–SA¬È•¼5ÉewIÙÊ×wöFQ2©:O¢Ä9s=3«‹“·—Aâ¤^: 'ÎbåaèÅÎ4œx³4r¹óÕýr:‹\ÂiO·9EËàŸ¢(ŠÝÈ›MãÓo‹Ïo/#¿§'Œo–8¾Vƒ”ïûî‡?OÙûËýÕÅõBÊGîÝýÕü K-'‹“Oó 3&òêdåÉ×o¾“ëώïEéÌyRK'šL½ž çîä“Ò«(è{G^LœÉlæÅÑT…ÐÕÕ9úÓÐýĉô 7𑄉ëåú3'5©rRe[ý}E "¤¥€†‚ÀK“¤Óv+•%éT*ëÕL*®”|ìæòËÎó5iÆ´æ”ëcsx"™Nß¾Wúfîµ2»4hle>Û¦nó¼üG‰)w” +YŽjNVR'}ÖÏå—†Õ€hÄ©{Ý6̸ɥSòh®ÅL¡¨çB…à‰G² qʼn5¡b(+Ç‚®•N\ >ü-'R—J,OðGZ­õ¢&]Qb2(uàB?ca-`Ùãp¿¦•˜H¥P¶³4 ÝsÂ7±ÆùMÑÒª™Äß›7FñŠ£Mbý¸¤Mg‰´F*îP ͤÉñ‚wN^Qžª;OåQ•}¼—x‰’xa˜î#U¬¡%ÈgRìd`÷$LgîoëJšµ™šxãÛâÞ³‡Õ*Ï ón(«†ý»‰¬ð¯tý` †ð•F,q•íÔ¨²õq37gt·Â9T¦!j#ŽqïH¾g¡V©ì³ÐTñœ<“¬•Ò*ïMp®_ô׊v5¥DT¨ÔŽB¯’ÌxN”ÏHU ÊI·¦¨!®Ê§åòp—k]²±Ú‚N‚ú.•¹Õ‡è¢@J]Ørœ/· ¶§îv/¼¬®;¶SšMuC±Ûv§$#¯DCÙª­2a[ºj,•­ðЃd ·ªº³ñÂÀj8¶ÕôÿXò°ª ei鮟F[€’ä£@’B¿ Z™§ª-—j”p¡ÉOÑSeÈhYàêÑ„â‰6¦ÐÅ‘²‘l„–›3ª YØÒ¼Sdgɶޥ+vWzTX¢6Q-€;MéÖŒ•ŒB™b$Ir§hÅ/áÈ!ïõa”-…¶¥Ö¶¼nI×1™NaAP©ý Ô×:ªkg@òQú“®ƒLv 5A¦;úæ+ïrÉVËåÁ{\¶ÕºùÝ ý $Ï*°Fæw)†“ûµª¢‚¼f·>ÖšÀŠš›®JÚ±T˜‰¨³ÙÖÞpȸ–ɈQ¥v}L¯ÞãŸæoíGjÓs;q¯ð3-Ûò`©~¢¹Ü1µD|ZO|®žÑz6å;ð¤Â£˜µî\ 3Mûɰ6Û‚5$ “ad¾hºÞy›É†Ì2üb¿<Úr»¬‚8f²¦pØCEÆ´$½1³mÆ¿ë;×x÷ÞÏ¡Ëß[J¾‡Ëðª[ äM’3U±®6ĿĸšÔVœRî²Ö^çcuWœ‹Ö‚”2»ªJsEUr¶Ñ(„ýÈ}Æ‚iJ-›Ýn Ï? ¶dùÖ^ád·\:s¤oh@QFtÎÕKU;Èûëû»‹ón7múWáñ´|±»-°ç’u·\È>µìŒûwüL³ÅŠ—½ÝYå”0 eŸº{Ü\Ð%ÇÃÿGœmôÁ •0iÒcf}efÖÿ­¼dçh£ íËååÖõƒŸý¾ÌPþ"œ3Žæú‚&^›5,u?± à-‹a^umd/YJVÿ·¶ÿ]Ãsâ hæ¥a¨¡û÷Ùlk® endstream endobj 168 0 obj << /Type /Page /Contents 169 0 R /Resources 167 0 R /MediaBox [0 0 612 792] /Parent 118 0 R >> endobj 170 0 obj << /D [168 0 R /XYZ 121.4 736.262 null] >> endobj 167 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 173 0 obj << /Length 1966 /Filter /FlateDecode >> stream xÚµXYoÜ6~÷¯Xä¥ZØ¢ÅC`Èå"AZ µÛH‚@^q×j´’«c׋¢ÿ½3ê²å I“{9Ôp8çÇ!Ÿ^žs³8Áâr½àB0µEÀ¢X..ÓÅ;çÏe$]ey²äN³t¹S ZºR*G²(TË—¯NÏ¥7’#¢€I%Éða™çyΓߗ"r~þã—¿^^ಣ—Gqàó¼ß]2î…‹ÕöèÝo‘§W É8Zì ãv!ƒ å‹‹£ßŽž¢’ÍPó•¿¢ˆ)’î›uÛ´•vÏЈ­®ëd£/] å<Ïêä*×K×¾ÓŸŠr_aqÅÆ|UΉ¤*²bS£  ‡Ë9‹}¿Û§(Ý3\fÍA$ät=HÀï åA!yV€Ãc¥"»X-CäDä$©DV¹º9 QLJ5{Å’<§åzPb0’¸NTh^¢ýˆC}›Y%ËbF´ë3!â;»·nR×ÙÆ.8Û–(>E·úa(—EfÒ2ÍÖ†ÿÛš~›Òþ^gvf—ä­žul™ÔÌÄ=wuбD9/ŠäÊLÚ0dHVká[÷±g•(Ò~Š[óÓõISe›®Èì9«­%giV¡q¢c+½jÊê05¨ÖIµº¶®.+›µeŠšµ¹®©?‡Îa®:Œ~*Œ¬~hC *M³uo"hb¬L‰#+ˆ G{T<¡"圀ÚÜG• f3.ÝgJ¸$+Vy›Ú­úÙ&䢪–€‘ÓŸ4svlt¡+ˆ=&`‚0:ÆÄ(‚¾`aØbU>§¤ºk©Xû«¾Õ«¶A·ÂAä¼P”mcw²¾5„ñ&¬7Á 2ôçNÝŠøöèWt5å< %Ý(d*ð§–bøïÇ#ÆÄ¿È:Î<u¬?>yýš¡ó¡èòìªJ’@]P]ùá~º©tÝn5 QÙþd tWÉ™ùiu'­ød  ›¿0ê#lLT1ãPP+ƒt¦®èݲ%b_eîçQƒªÖù¢ ,Ú~Kòº¼ƒCî³ó×OL»rAðBUúÕ@‘œ²ò”ÕØ4};@†cå%€€8Á`?WôÛÅÃ}…"a@0$ø †Sø¶H¥©8ô½YvmYìS64×ÃÇÉ\…%¦´¬Sü©¯Ë ŠÓÉ5etฯŸ] 3¬£¦=dBu9x6ãÊ…ªOR ž3r ¦E_Ôw L0[L¾ˆü‹_]üÀOY‡€øÁ8~ qÔ! J4dœ‡ŠøN†Ž+ã8è´%¶!,"‘ÐÏ‹HUtÂ*ƒ&ˆ‰†jk£?p@ kË<Ø…ýîµ.hÔW§eŸ îõ<õE¨âvÌ“~r‚J)ç’¼%Iˆmº<$i ³èfÀ˜u›ÛÊ'µÍ,õÍ -°É=®ö÷žðag"¾´Òmd޹ ÌÄ ¡9¶N‘£Ud®'†Ã¡™“l™f$ Ïã?Lò÷Ó9è$Gž÷}%ûw$Ç?J2_'yšÎ~ÄDü%Pn!5rò¤Ø´ÉÆlÝ6&Uz®£®!ÁÓ»¬z²Õj|ÉÖ®ÍuQCrŸÌÔ®w·笄’õ9ï<Á,`ÑäØòs„+*!Û›¤É®²®jŸ8M6ਗX^S¬Øãlño ÜaW$ j<¯‘‰Îk_šu‡¢¤Æjk¯<“'@cõ¸¼£.˜Ç¸Ý¤rÅ4îA|>îSœÌì Prîz§‚ðP…I‰ÿ_¨§ƒvÆ>S~ÏÇõ¡nôv‡Î¯ƒ6h+ƇÓ÷+RC¨Š ˜Ï …§_w "QC¶Ò4¦Ü5M¥ 3ÎbcßWY2-±”f¯FBíÁ†CBöÚÎã:ö†¥DŒ+Ú:ÕÅjöe D±»n•}Zðú¨¤º¯]CmÿoO ûQâpóˆ¼`hf„ŸêuÒækn7Ý&÷ƒ &x'Ïc0CÙŸ‘ç{LF=³õŸ­ôBx¾-'–Kò¶èïµzx{íÛü¤Á’šW¼´4KÅŒ+«SÒ¬»Ö𤠦Ð÷ŪlM¹7ºÂë;Ü$ìm.õHò¯Ë<7‘Û?ðÚ¶§«AžN†î™@MÞ#ð §À¯çÝ +è0¶›«•:Ÿ§HxüÀ³ŸFó›Åœ²¯Ë«ù½| ÈÇæJÉb¸ááÃNìÙ—ßÝÐmâ“cŒØ; ƒ†žgg_¼Ønà°} 2((}&@CWAL”‰ {þ‡#·S endstream endobj 172 0 obj << /Type /Page /Contents 173 0 R /Resources 171 0 R /MediaBox [0 0 612 792] /Parent 178 0 R >> endobj 174 0 obj << /D [172 0 R /XYZ 121.4 736.262 null] >> endobj 18 0 obj << /D [172 0 R /XYZ 122.4 587.528 null] >> endobj 171 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R /F29 144 0 R /F32 175 0 R /F11 176 0 R /F33 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 181 0 obj << /Length 2406 /Filter /FlateDecode >> stream xÚ­YYoÜF~ׯyà@šdóDžlù@Çv,eó^Šì5ÌcÂnZ3YìOÝŽL`e`_4ÕwuÕWõUS/n.ž½“Uái”®n¶«0Šüx•E©ŸbuS¯þðþµÎ…'Õ”ëÐ3ëMèõ ë±'ü<‹×ÞüüìµfûDyê‹X¬Þ#eAxÏ?®£Ü{óÛ/¯ÞÝ\㲋W7]„0/X…ÓéƒlUµü¬júyø¢ÈW÷4±]‰4ó#šÕõů/¾½Fœù"HWižû±ÈX‰›;©åz‡™÷)I¹ÓÜ(ÛÛwÍ‘%è ½ªo[ÙÕ²æ¾m?°ÐÈ]YÙ‰­:¸ñ¦ìvc¹£½R¯–Zí:ýZ"÷J{”¹“xkÐ|†~‘$¬Ù~[9”· ,Žr0ðÞ¨¾cYiþ5=ÿÊZ”"ÚŒº*ÊàÈùÌ.±/» ›¼çñ/èy¼ÇŸ~¨QǨˆ¼~àá²®­°ßý~P¥‘ÖÃáÌÄ®ðï[¹SÝç/òˆ¹Ç}yÑ™_2v‡E…Ï3¢b6cc§lÂÄ/bž÷®_Ô@š…Ûìq äŸ&n ™6м’®ÚÈÑ>A¾ßñPÕwÚ ceÐVqìÝß© ÍwÇÃzód¥X±´‹hŽÈ¼ð3@°=š ö­zQè‡iê&NAÌlD˜ûQ$¬ÝSžC qâiiPˆ½~Ë'7gäfUšG$ø{Ëšóà «~ש¿eí^³Âûýœÿ•6xŠFëJθÞíÇŠöZvO±#wŠÁ Ù–ŽUé%ôß«¦Ál’Í”+½&1ç+A×C1¸!F@_¡ÒIæ½8òlpÞÝ ¥6 ð H6iìŒ}Š4Þ„E‘Ð ær ¿©Ÿ¤䤩ì‘€ °=²Ê·ÔÑë»(-ü@ˆó‹³‰„ðô‘5- ȉae4ÅLÙÕK¸ üpJ¶ç§ÈÛ®Y+ÉQ£ŸB°ˆý E]¡/²º~ ¢¤ÔZféøØ/ ÛÎcöUÇé O/Ù¿ ÐÚ´?—„¼æZâ‚€C5S tDtúaË!§Ú)`‡Ùê”Qe³‘õNþ> 2 £ºOòp‡È;õ×(ŸLÛ=Ã8›»Õù1OøNm‰¦>rc`A@I}ÑÈ“Íy4=ÒÓ¨ïgéç[#‰™b ˆ¯ˆ$9? ï‡Zé}ãTÄ9Ìb0²Å!´1»ÄUÇu{ÄX±çT ¹€bŠzjô£Ù†7ƒ¤(ËÖC¤yëÂQóÕéq¶a ›œYÕæ°Vj ĉX-„KEŒÄö,R@È5òò4vÜ¢"8õä…ÓX=V’gØ`oˆŠŠÀ &sœk=¦ÍùôEï»=x‹Š`Fd`¬OAhSƒ@ Ÿð ‘±WU¥Ü°©È€Õñ/¥ÚÒu]ñOËû=˜7¾DoÑÄX‹ÎyíkAí§‹YöDYN—tÁ#.£ü.NÞåpå_(_ÕBŒóæm‹½Íc#ýÊ&6S«žE4—þ®H¸ß¨KÖðç°ÑGý¸xxÑ”tÑ/èQGp=ö¸§ììÔ»/ ÞwÜñƒf’¡†)5m“zŒ—ÄÛŽ]ÅŶì¥6©9Më4‹Î'ª]ˆ­Ú=a:¼wï?áÖH¤P—ÙLxhð8m§Šæ¦=¤S‚T`Y»!ë8ÇN#Õsão9ôp‘‚øù°ñÕ0Ñ –M‚KüÕãT ‰É@õ¥¹±UÇ'å°{_š.% sD@2<èS÷JKnò1Òz—l„üFw”=Ji΀¤’êbÍ!‡¡,¼ïïdÇnÔ´Š™Cp”Î`ŽÑÏʸ„K…=³® ‹óš°âÎoúÿDønÜ<Ä©+Lð’[9ö­­!iWÖ» AVœ68g+Kƒ)Ý–yÕ8 `˜ÿÛ˶ÆDòÓÜÉ(ÆÎ»Å¨Úgf nK;|‚Ï‘(˜KRŒ¼$I¬÷qøDЮ¹Q¶""·âæÎ;;:pþ‰Ü‰Ãnˆßq‹b%:"W[,-Ø’`b{ôö<¡Š ÷}°P­Å‰'Si‹lÀ­\@Ì&ð“8?CÌGЊœ /€NÊšÂ,Êè½} ª–<ÌvÊÑNÛrl ÷Τ6³-§o Æu)£e³µüΡÝ%ÿÔr1ÙØ‚ÇyWY6Eòõk$^×F,ÓjKÙP­Ê71!ÑõÏõÅ6g+”l¶ªz7TòîÇÁµ´ê¸œW“ŠÁž.¦ûñDŶ,b4XÐ Dœ§ Ø*Lü«ºr8ž3¹€%DÓëS Ú–_f­ÁAôvTMíö”ß?ÛãñùisõúísLLo®À˜? ÓéÓË£ÜÏÃóÚµ§ïiúð•m{¯ø§‚kA V 2Ø1}âÁQþÒ'v²“CiÜ&ÎNÓÅÁ±‘Ec”&*;»U˜Jð]\žÚòYGú8<òŒ;ªª,¯,~!¥-£fŒU‚å]!Ýö®ÖÂnæ9xίøÔ–F,µœê'¿Ê<à¯r„D2ØKa’úQ¯ 4XÍÌýÃásfW endstream endobj 180 0 obj << /Type /Page /Contents 181 0 R /Resources 179 0 R /MediaBox [0 0 612 792] /Parent 178 0 R >> endobj 182 0 obj << /D [180 0 R /XYZ 121.4 736.262 null] >> endobj 179 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F29 144 0 R /F32 175 0 R /F33 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 185 0 obj << /Length 2475 /Filter /FlateDecode >> stream xÚ¥YYÜ6~Ÿ_ÑöA¸eݰXÀñÚƒ8‹õÌ:I8§›m3žýõ[Õ’FŽìK‹,ɪbÙßß\½|ëÇ»ÜÍ“ ÙÝÜíü p£]$n–‡»›r÷«óqŸ…ŽîL¥ö¾3ì¾ÓB£ÛÂ0rB7K£ýï7?¾|z³u‚,qÃ(Üy¼F Ó<Ïs^}Ø™óÃÞ¿ùùæ§]½¹¹út執ó§ÝC×÷Ò]Q_ýú»·+aèÇç†y¶{$Æz&©@«Ú]_ýûê{T#ÈŸ©‘d™…)‹ð›ÄEu/²†sYA‰dµ7ÇFU‡FÕšy—öq=ÐêàÇnîÉÂ×m­Së~ˆâÌ1~sÇHÿÓhͤҀá~ó¤+áºk;f»Xy°¤¡µÓúÁ4ÇÑô'(*;hÌ{¦±Ø½¬Úµ5 :|ßÍã˜Em‡“ƃË}§Tƒâ–Ìt÷‡ÄO…êM ”ê‰Ça7ÖÛÎ& ƒj°á9º)™2žùkšõZ¸ÆIÃ'uîA¹-i+Ð6L#§½ÃoxÙ ‰'ëp·ÔƒîjÓèžyÍÓïÆŽµÆŽ~ØÇ‰£ªQ  #ÓŒLh´.u fˆ‚ع9Yò£©*fvªDýÂP…Æ™L¦;8èZ5…PQ! Ÿ‡= â©ë’‡j6r©+wÚeæm¿˜á„&Ì—íû3'R7…`‡þû†C”Ùãç‹Å¾û‰åýÇ×{öógìÙÑrë¹Ócê@s¤Ž. „AD*ÃHÇ*·$Šj9fáá@ 8(pÉd¯í%[ÃHC–ƒÓ‰ÜÌ䘒u:ã@ 9âV©UwÏ-^ln«ž¿Ï%D¥:aBçÇeÏ]{VG5èÕŠ«8"©ÃЙÛqÐ[þ¥Æ¡­Áo M?dcÀׯµYq}47öKP•½¬d^Ê <û„'2euôü0uÞ5vÔÈ8\ÿ m÷©éÚŽ8…íH“»Í!yÁÇÚ‹¤j¸ý ( ,ƒgm)62ŽØSÁöÌ1p²Qfɜ˒˜K6ãéçÏ'ˆ²E!åÄ€Ãâ´`¯’nÙ&Ô&™±ñíró/q2Zu’¥@¬'¦žÕprÙYß"7Ú§êϪ>ãÙi°qÄ΃{'¡áÞªÎÝ2é»»Y<˜ÙYK¢üç%b@aƒr¢-ë1à¥_Gc ˜9„:ná«iêìp&x†Šø’ 4z Íô‚õñúA¬A…è§IÌú =A‘H5ÐpRLÍÈk‡ç+†öx¬¶8çÏÖaáCÀ7ÿ—±X²?g±ç^K€AõFpÅíú ‹î†½o®Œ"pü©7ýÄÃŽ&ðÆVô 0±·RÐ|ÀxÚ¸u¾^YÏzm™/¶ÌáèK*09‚)€µ¤k¡É›ZÙ1ìÓ#E)Ë‚QbFM¼°åæÍ ý707Û²•„C/¿ºÑæÛ!*÷Är·jäF.—ž¾àûî-~3IóXê_]¿‘Z=i ™¼§)Ç9ŽöEíÐë—h9h±Ùà3[e¡„¼P´G&ü$Ž´–ö˧AiÁs^Y˜xsC¯Y;|öÈgÚò¨b2\Œ>šIE;ZÐæÛÝNgßÒ›=a~Ž\ À¶ ì++4À¤X\1ˆ ÔRµ˜/ž ¡;Ü6‚;DÕRBE\Ê/ŒQ~áç›+¿Œw#VBHSÖO) 䥆öì)è«mJÎÛÝ^¶pÃźk#;}öAwãkeg†A7‹ þk‚Cº=ö/×9Ì=o?©®^²‚Ä›ÞÚDòsRKÓÛ„œxÎ<r²@*¥døŠ+dìøHNjàÖé‚d–âÏßú¡=s“®e4K×/6Ÿ yü†’Š¥à¸}?Ö â¦±¹)RE€§6<`ÑòLïôœ.SoùlˆÓ¦ƒM+âHš-Fy¶òãÄ > endobj 186 0 obj << /D [184 0 R /XYZ 121.4 736.262 null] >> endobj 183 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F33 177 0 R /F11 176 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 189 0 obj << /Length 2504 /Filter /FlateDecode >> stream xÚ¥YYsä¶~ׯ˜ò‹9ÎÅûðÖ¦"ïáĵÞ$–ì¯Ë 13ŒxŒ rù×»/ðÑvUò¢  ÑÇ×ÝÐWwW×ïüx“»y$›»ÃÆ7Ú¤Aâfy¸¹+6?:?l³ÐÑ]Y©­ïôÛï´0è¶»0ŒœÐÍÒhûÓÝ7×ïBo¶O%n…÷ˆa™çyÎÍwÛ s¾þþÛ·înqÙÕÛ»«_®|àó6þxzèú^ºÙ×W?þäm ˜úfã¹ažm‰±Þ„Iê0ª6·Wÿ¾úêù5¢Ô ½d“d™…) q³ÝE¾ï\ñ … õmÇÄ}‹4™PGýó}ÕnwðµGÒÃÏíG/ ¿¸¶Ìu­œè™ðXVδHw‡¶«™¢øÇ”5œG§yε84û¾M¶ *.³ó}7c¨» ÏEç<ñÇže*4–ÂÓŸTÏ£¥ÔLÃ+Ò‹VÑM_€ý¼xœ$¥¤¤‰õäùs½´Íõsš(g嬙0 ¢4ê¾Òü1n‘òLU];4«²Ñ†‡í}nŸÂíÝñ¤ØÍ#>èCÛã.I‚þͬ‹¤Z‰ñc~ôn'Š!q,‹_÷eƒ‹K…²'±óÑ‹½Æz> v0Ø/•Àéóš¥) ïÿx¿¡Qj^h,á‹<_ÅN§÷ºd#!w:6ª’ÙÇSIÜ'ž;©É>ÌpROõ'¡|ÿáŸÿº{÷þcûNvÁ¨®)íLÃ/á3öðì5C×­éÅŠûýЩ^lÚi3T½a -›¶_qŠþT ß#ÊŽ¢4Gž½Áh0BŒžù¦Ë8ä3 Ø‘›ì| "ëG/ˆaqÀbøC‹w}{{.%ú°¹v$<—gËßÃ…Á¸+Ñy‰¶Àïç6¿Ãh‚)ø0THä0©¬Á¥$ŽG½ÇÍû÷ÉàïâI×UÙÉ”ÞÑ%ðc0ThÃȾ:à*IÅÑ"[\~x†®$ÐyógÛ¼ÒØ-¥$¹wó­­ê€ƒØÃ@4r°=p­êô…hã™øÜ­F‘s«­±¤¢Hs­ˆÇ3ýŸš7\ýýù«óa˜9´ FS—Íô½ Ò“6Hzþ$²KãÔy=tT!B”šŒ’ˆq7–­~wŸ5à’žZðÛ\4GÔr§ãIñìõæö‡­ïûTcÓÏô„Ÿœ#L?áÉø2V§ö-€T5–·ýÉöA¬ ªk qÞaõJ•\ä9ú¿ª>s© •9?_xPíU’ÚYî3>{¥.)ªaR“¯$܈‰SÖXDÎÑ#›E#µÝê[Ûâä³7ú  žy½¨9?ûR^åçÝ3h É  @ž<ïO«÷xó‡/±÷ÁçˆOèu8„Šë z|â/lÌÿ†έáb‘Ø«îé㉶zõ*DÚ˵˜‰<7c,$Ù½‘ÃÅ?$ÜÄ l?ÿIu+»ù©ä#Ï«•]28%Ÿ6©†5ìÛù¡›åéÂQÞht_zŠŽ<ßV˜ø°c“$}ž±2õCÛNÿU²yªÑÄœÛ £Îg ¤îYÔÌÁ°`2çvüWžØòï_ ‘äåšGŒ³×Ut¤¯$AŒ¤aËZ¨®àÛuãÌØÊµG&ôR’T E®ÍNðÅi¿ªTB¢ i_¿~½^„Ög¨ï˱B[L?NÜÀ·í¿mrû¢ßs˜ endstream endobj 188 0 obj << /Type /Page /Contents 189 0 R /Resources 187 0 R /MediaBox [0 0 612 792] /Parent 178 0 R >> endobj 190 0 obj << /D [188 0 R /XYZ 121.4 736.262 null] >> endobj 187 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 176 0 R /F31 162 0 R /F33 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 193 0 obj << /Length 2436 /Filter /FlateDecode >> stream xÚÍÙrä¶ñ]_1¥'NÉ„ ‚g娲½Zg]9*–²y𺉱Ä!Ç<$ëïÓn^#hwµN¥ò4@hö}Í··_¿•á&iäG›ÛýFú¾6±‰$U›Ûbó“ó~›(G·e•m¥Óo]é4°h·®R£DÛŸoøú­òxü$*Pp„ðÌó<ç›·~â|ÿ¿\ÿõöŸ]\ß^ür!áž·‘Óו^¼É?ýìm 8úaã •&›Gsñ¸QQ,|XU››‹¿_|‹løé36¢$Љ„žz7ˆÚ×~ R/Ú¸2i@×ot¥sàÖb§¿Ó´(4p¾P„D°)+¾U³ßköô ¢ Ht}Óèƒz%g(Œ‡m:YYælWi8—_Áqâ9Y]Ð=]ã ­MË«²Æç½në¬Bž@®”" Câ ë:ÝöeSw[7H¥ù²þe(ðpGÏé¬oX‡r)D©„ 'Ntó;£ î-¢Œ|éüÆp*Ï1Oe}À/zÎQwÈëKise‘øk–'Kø¦:…À ^䟨”"qã£`º(Q-½&cß7í‘®ÃñD«ž *dƒ6ÌF9³€p+ ¾ï‰H+ñZ·oµfú•MÀ±HãdI¿ [+pUä‰M`:ÓàVùj~î?Ï!~ÌZ]=?`™µÖ….™„Î5['¬lÒ@jÇíd”´Íñ:Ò?÷*"õDz¿k†~y#« ‹•“K)? Ú4Å&pSððÄ®ìü„žÁD°t Rk6ôÍ1ëË<«Ð Ÿúx§ëQ«cä0Ûî„îéè¼DÝ£,⟈ân$ñ¥5à7éd ¿·àŒ—ŽUéÔ®,¨ ö…ÓÅ?Ú¨‹!À*õ‚q”îo'¯ksr y©¾œé5++F NÉèK9^Ù³›F"Š«A‰dƒ¦µ‹?:;í =VÕ°îùhè4ØT’Ä.z­=€ÞÏðVŒ®¢í¡jv`wLŠs7ùRÞ3Ó#èh›QBȃ\q²‘y1JÐdÊ`BzÕ˜Ûðdƽ•ÎŒ>9Obæn3´¹¿aôLÈ:G¤>,äƒ?U ù’ë™0*Â4¡¬€Üþ,%•î{õOôú²èï(v¦3€z IÃuì„9‚—‡;ÍUÍ$ÆŽö§¶1”ƒáˆ¦4Œg…î!{3È0¤¥Px2^ó=æºOGŠ•/êÝ b߀• C-Þ¦œrÊÏY5h›íGPÌ%±½º‰®n`1} v¤K„îHg´ƒ/F0@Ÿhͤ҆â&®PÉmÇ`aìä ã Ô…wÚM…fs˜˜@-lÖt‹ta° ;×S( sxÄ Hî&fðæ¥TQrOÃ˯Ðý†øž'× €‹k‰ç¹6šÆ[h"t é%Œ÷,¤936ëæ›z­ï/u»¬CïX’%&`Êä+ø£œSY6ª¬%ð襸ֿöºîL¦£Ðë4Ÿ‘1À‚ÄØ–ÍÐàŠ Ð_˜–’©ÔÇÕ¶êZ&"J§ð _¿"_Qʉ1}” ›~s2%+E,b ²²YÍ–¶DX•ÌÇɤ}4—½nuQDzæn-VkèC)îš°ù¤M}Æ,¡ý±;1Ÿ¨0;кDñBijÌiuÞº6 &á¢Ò‡,ç[9G$F9°S%c·°.;ZÃðLŒJC#>üÅâÇ,¦àk®nÑî¥4æ‡Pʰ8µdÍåìIyŒw¼ÜÐ/ÔÒýê9ð°%ÍËË­¶º×)+1ó‚fjýH‹{¨Ÿ1…4maH…¯á{YQðâèÔ¢ÏØZ8†Fvª5þ½Ó°ÿu¯ŸÐx¯Å®cê.ù d’XÎ[Ì–ôuˆLÀ ë i8–¿Žy¡?–êEÅ`¡»òPwMHhoÀ1£É1ñÄæ˜RA9öz·¤0u⦿ÖA%^q¢žü7è‚sò˜È $á{·çV5§KÞ°Oèèwò<Ì¿äyÜhˆh&ÃÛUðfÝßoG/µ ­ðk“8²ð#õ%Ò@Ì$ C•D-pç2–8¿%"9×d¯;nþnžº^1·Í nk¦ÔXécñ»ëëkÚMy‚ë7ìM»3ñNãqUh”m­¯,Eô×ÌEDk«Äcá§SÕõ –¾šX*‘g}G×þ/‰ó#Äš«Ф Z|%T¾Ž%E('›BØ ; âI’3Ç{Ãâ4“Ž8Ô‡+5Á!t/K2±Ü=™‚‰\½©ÌìÆwÆS*¦ª¾> endobj 194 0 obj << /D [192 0 R /XYZ 121.4 736.262 null] >> endobj 191 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F11 176 0 R /F33 177 0 R /F32 175 0 R >> /ProcSet [ /PDF /Text ] >> endobj 197 0 obj << /Length 1765 /Filter /FlateDecode >> stream xÚÝXÝoÜ6 Ï_á‡õ¡µcùë|Ø0 A’.ÅÖvé­ÃЃÏÖ]„úì›$çÃþ÷‘¢äøZ·½¼îå,‘”D‘?Rä.Ž/Xæ-ÂEçÞrí±8Soça±H¼eí½÷ßÍŠÄçR4åŒùz0¿ƒœI’úIXÌÓÙÇåËã‹$íy˜¤‰Ñ,‹¢È?¹šÅ…ÿâ÷_Ï_-ßâ²£óåÑßG ä" §'!‹æ^µ=zÿ1òj`½ô¢0YÞ­ÜzI>c5ÞۣߎNññâ‹käE¦ÉœTÎIͽëÆi¸ˆr/`Y¸HIîä;ÙÍгâJÍ‚4)|}Íi º^Vf<÷+’ªùs˜ç©¿ê5 Õ}ÛΪn»“+í¦·B_Óè馪hÏàüiH´×½Þ¹ …BÝá¾cá"ËHÓ[)´æ-8"›ûº£¯Òe[—²¦Y×kØ.c¹ÊoÑô¥äÈ)ünM¼-Wh74«ùªßl†é Pn¸Å“<1Š›³®ù=nEÓL©V6 õIc¿F?ÌH? ýŒ[öÜ ~’pÏQœq);4b+´õ&-Ëã0w[Ìý8±ñ<œ§…¸™¡3šžOlgá|;ÉŸ& Ì£0ÏØvNÖšK{ßk¡èÆ-Ú½ßâïÊÆ‰$[p)+ÜYžuV ®PD!Ïo+ˆ¿®‡}Á\òú¹ÝçN ·Ó4õÏøºì­ömŸEß7v62ö?,d^ð–ËRý2¿lé Ë«^º8*•EþŸ˜Hºž¸9$o±’ù-ç5´¥ìJ¥¬T]cꘃD×–fqî‡0¯v;š|ˆ’´ávAgÕÀÐ#Ô¢ Br H$Apç¶R“±Ä¶Þ5|ËÉÐŽo·¥híbJÝŽ¦kçÂ{\é‚fJôM‰êì‡àÂ&×dœÝÒ°xÈ­të O±(ŒòdÏSW¼Ä+³Ø^„1_픕À¸eÛM™Ø‚ôA¦FYi;P´^¬íÜøšßYÑ*Qs;ÖÄ%`+"NÍ®sÑD~±cˆYnQQˆ…±éóÄ„Ý= IÞ€Xþ}bV¦°R_+âSl‘ INÊ ‘eÎ^™_ É+ÝÉ{âWÁ£Dd¶”9Ù—¨³zO\°Aƶ¡û–[„=äÐ`mx™ÿªÓ– ¸0_aC|] ÙÜO¥Ø²’²RÃSÞm2b·Q§á`=…H²$ÿ>"Ȫÿg@…$¢œ–Ãê$ \¡#Ñ,!$Ÿ´‰ƒ”A"ˆ¡€PõRr³¹&Î4ÁÍæôÈÀé›tpÒÀ+E\ɸÒÁW¶¡é4A0ÒdI¥Uä/hJœP—4·]’‘Â8ÂwR83ŽV¯Á@üL¡Oƒ[9•qÝP@ mJ[Óq´ÄDxß • ÑŒwq Ô*QÈVp'SwÆþ+]¯]8ØÈœ%é,óhŒ·ª)yqÕ>ŒÅù{ |è¼ÌCÒÉO¦YŠ]™²4+mGåh6!™æ,õ/M–1èÃ×$B…$Æo©l»UInÊG¢S —vE«M¾Å+ÊMXï¼P?ØFÌ+o…²ÈU.ßÙç`¨y]ˆ»¢nõ(H_ófw¢Ï„‚„g”WN ÷Ù¦ÔF™+áxx]”â³)™j,†˜R‡Wß—µN²|è áɪsrè3ÓýwnH }ža8±j¾ƒ`üR›´‹d1´´£vv¯Y“p‘|Ö À눯zœ/LçeÐ˜Æ hŠq›Û=M‡›a©éK/má[ò zyqvþfù³zèb-ž7ØS‘ÄDâ"†ým»:•l£s‘Z …ÉYí7ݦžÛ“®lŸ‰¶>›²28”åßvz³°Øÿ?`ÊçË  f€Ž<yûïcîß°ÿrïüý endstream endobj 196 0 obj << /Type /Page /Contents 197 0 R /Resources 195 0 R /MediaBox [0 0 612 792] /Parent 178 0 R >> endobj 198 0 obj << /D [196 0 R /XYZ 121.4 736.262 null] >> endobj 195 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 176 0 R /F33 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 201 0 obj << /Length 2458 /Filter /FlateDecode >> stream xÚ•ÛrÛ¸õÝ_¡ÉK©‰% ð6m'ÙÉŽ½Ý®Ýît6;Z„$6¼¨iGßs(Êaºö‹ç~ÞÞ]|ÿ!ŒW¹È“(YÝmWa µJ£Dd¹\Ý•«ß¼®3é龪‹uè k?ô:ôk_JåI‘¥jýûÝßÁìœ(K„Trð1l ‚À{óË:ʼþqóþ§»[Üvñþîâ¿!à«pº]Š0HW›æâ·ßƒU K?®!ólõHˆÍJ&©ˆ`T¯n/þ~ñÙˆò¯ØH²L(™2 Ÿ‚(®Ú}u_ ¾©¦ùŒ÷H‰pÜÕ _1úvl7CÕµ¼kèªÛâ¾v¶%/–•!( Üúa(ò8fÊôÃ:N¼¢ < ¨JâÀ»ÛWv!,ÔÊú‘æÉðx8mºçµÎT]óØ =ƒxó Û ®ïírÇ_GÛ0ŸåXkKÀ°/{u¿È@ÛѺòªæÀBê Þò·àÏ®b*-u´5ñ À(ô«aßv?ê«jw \“W¡¨é4K‡erˉmNRÓ›aÑÎa÷½qíe(‰b ¨²Z& $U3¬®î{`ŠëŘª5V —jñ)`‘®ZÚ¼wbŒÁœ›œˆÂ×_~³òÄx73:A2·xA©VC½8;½òb)¢\ýaeBBÎ|ðÀþÏ[Vî±af ¾hžuÓHħ¤ŠTٺ̯Q@a1î–î†Þ(Ëc·tG9g%¼ 3'”"÷U ¦Æ¥‚±¾æQа¸ƒëq ϱ{¡äBàWJ=é[о®Èm¤tÉϸ Ž+O\q]'¦zôÙgç¢×`Wp_†× šQ‰HNÕ3 - êHÒI¨K§dpqþ‡(‘†ŽbÉ@BA(Ï àv*•·Ç³25Ç›tkNõ.×Ï82{×™S˜çzõ”<`2rêVÕ’†T-7JTBŸ—ü <öãöÉý¥hËmé¼e±E3~e, h[‘|YHë¡C ¸”&PønuM(Ô@T²d)”yÜ^f”ª]¸-E¨¢ÿwI4]'ŽˆDš$_éùÉ“‰ˆO"‹ÓÐû©4SÆöH‘*°7¤Oìm‹ªÇ aDzèK^)6}gŒs¦@„It.íém¦Û±ÛL¾èZxT!dâwÌ ¿âŽÞ`^Ô¬BÆÇªoð»¶>>óIåj¯©ÛþliA*]m«/žXs“XWØg$ö¡êêSÏ-^ b°µliy›‚üƾÔPÛNÍ¡t!Œ†ãp1ôŒÜáÙ݈É«@ %¶B¦ãÛÓÛ…Llš‚%ÿ×u¦<*êqÚìË´%)|§—¼@ÅX nñ®Þ"@Æ7U©±Xð>ÃÁº®ÌPmË%ËmßWº®À5ºSG¿(Œ‘«Ÿ£ä¬ 44 ¤'±2'¬ŽS G æ”Zôž†‹§‡EªÂd´ÅeÙ"È^¨ÈÞîù@jR¾øæh,vk÷³T/Ž­ÁçR<éüÈèonÞ=ÓÔßOš Ù ­îCîûá+Jþ–Úý¶Ô\¼Á©EìÔbqåÇqÜÉ)³åÉíæè€ƒÞðsÙ’ñT è¢?»Í†Ã¿ûsÎÒû舱åoídJ“oYS²>9šÉ¿£¸íü>ÇÝ¢Ü[âËÔðó3µÀMœÌ’(µl(ã‚;t„ Š·ù×BÃÅ“ìyÎ5¢[c¸døIþ¸v °f+8 øò2`RÁðo­´—zƒsÙKýÏçr‰˜Êª_(`$¤¾lJ}ˆC^ÇŸ T[K±Ü‡ƒÓø[¥Êôª[—Å÷a8"{§%?Mf%<¢LÄÀ J31A±!‡ªþ ÒXžµïñ,qà„g¹ø³ äC]l(B¯ÉÍEÀÏw™Ý-ñîDq„XHéÉ›&–& š¥WŽ“Ã)¯ì †÷¢ßÚãø!`tדÿVÈóíF$>„†" ¡”Žr‘AÇ@,„‘û å¤t—å endstream endobj 200 0 obj << /Type /Page /Contents 201 0 R /Resources 199 0 R /MediaBox [0 0 612 792] /Parent 203 0 R >> endobj 202 0 obj << /D [200 0 R /XYZ 121.4 736.262 null] >> endobj 199 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F33 177 0 R /F11 176 0 R /F31 162 0 R /F32 175 0 R >> /ProcSet [ /PDF /Text ] >> endobj 206 0 obj << /Length 2038 /Filter /FlateDecode >> stream xÚ•XYoÜ6~÷¯Xä¥Z¤R$Q'ZHÒ¤hÑÛNûWâz k%U”b»¿¾sZm¬öËjH‡Ã9?î««‹o£tSeg›«ý&Šã Ùäq¥Ø\Õ›÷ÞÛBxjÐÜFÞ¸õ#¯bØúB$žŠ<ÙþuõË·"\ȉ‹,‰Ø„,#…maz/߯…÷Ý»ŸÞü|u‰Û.Þ\]üs_¸‰æÓE…ù¦:^¼ÿ+ÜÔ°ôÃ& DYln‰ñ¸YÄ@5›Ë‹ß.^=¼F’"Ì6YQ‰ÈY‰jPrT5(ežÞÛïˆßÔ«»­ª)ÃÓm72¡î´±¤lkæ%#z9¨v瞤UÝ (’ðÐqìuãA ·ÚؽGI;'Ù4`Ò{4\Ê¢ LÓ¥ÒhláKü‡°ýw uî©}7(ž¨ÐKM£Ûkƒ÷öè°§âra*?N‚LåGe'Ÿú!ŒÓc‡:{µßêC(’;ëf±Øœ%A˜fÎËc×·ò¨˜ï̾(˜ð£4(Ò˜¹/{¶x¥Q:Y«í I<Õñô°[È‹´M‡ñu‹?j°Sê# -GÕHc” ¶~Z¤Þ·j/§f4çâfŒ½Í§N‘†ý€frÖy’mÛίšk¨h±ì”ç‘3è×+2sT:£¯[Ùø «/…¥e©ãýfÍ/Edeyî˜_k²GŽ£9ö̹Ûj;KŠ0½º#S;fµÁ( Þ‡ x1Z³\gʪá¬ðÌpO’$Þ¥²×ËkÅü"ÏݽО'c.o‡AÍѹê A­!<ôP¯[“%krWF{%YsŠ=9ØÛUݱ—£Þ5Öx²Ñî²L<£(‚³üîýh «xöÔˆ27º÷u nƒ´uþxœî¿C kîÁäQìµJÕªûgyé}«Ý .Ež¹Áº§Áw}ï(ô,nSwªšFݵ<ìö¼åÔ;F¼.Né=³PÎ’Øn*Å“Rö<àV“nˆ‰7üÒÚµuáDÕénûit™jãÀÕt oõx`îVÊ,ÔPuÍ£=ðú…>BœWhûƒ¢Ïy¤ý¿¿n¡~ןą‹Ý@ÍîYO§±àfâÒïˆ,Ùùñjû¿„Tñ tr·ýW²Ãifo[ÔÜ1Ý;êNµjž ‘x¤FoZ«”Ï`áÏ¡ðÓh©že «"Au,ΠÐ8åxxÖ'™UF5{^¾V­0$xéC˜†Ò¸Ó¸"v]HgtkqûÌýöÇ—„.Á>PÞà²Ï‚0AÚÜž£ì\ÞJÕ>+l+¶$ •bšÙd¤¢L64H=>cºP €IdâÑ•yg ÆAåÿ PÀ°±øÜËa…­tö/K|5píÁ[|¹ŒYÅ8fªÑx7éfd’^‡À?Æ®0…e v`\%áòá€ò;fÇsV¼²|&°H>‚ŽnüUƒúÈè\V?vC­Ÿà4`"fðzêþɈP,!`¹%"TµàYĽ!’œT@>ºµ ?…û<§Ú…h[à€"Ý ÿ êõ÷¾?Ž6ƒLÀå†sߢ¿TÚ7ˆ9tSc±¦òÙ;š“q`ìö ,À1P”ÝÂÎuÕå³¼vOÍÎzó P ½Ç€Õ7="¾•ÇväÅœX»{D#k#‚¢ŸK",<’?r`‡.9Âò„—a2¨úþE€Q‰£z†- o²°aÔ=¥¬³r‚ȼ?Ù‚0/ùóúùóõÁ#pÀ°» bA¸v³ž8KÊL„¬ÞG‘†¯ç‹¹&YH‘kA?q/¿Õô4±Q݇óßGÈ/WшmȽ³…|?µ•…É0bÝÔÖr¸Ç·Z©(¼ïíº¬kmû HcìƒøÃšqý–F˜ð‘á«|:ÁªÑ7²¢ˆMn[Ñûï¿/Âç×aIáò(}ª ЃÅÁ'$:ÿ1ˆÅ‹¯JR8Ü)W€*K¬äÌ>ë;ØP¯õaÚ™gÖÖ@,ì#k†‘‡†,Ü_w§])@á£Ô-'ÌŸ"¬0”ÂYFÝ5/95z9ÀK–þ]‚ÑQ®"0Æöè.üß)޼w¶¯¤åÃħٹJ}ü¿€-Piáê¬IþŒƒþ¨©¯Á@û±²rHMøö67¨,G6IÙVŠÊÓ&JEG€fãJ‡-H‘pÿÏþ ³ÉŸ endstream endobj 205 0 obj << /Type /Page /Contents 206 0 R /Resources 204 0 R /MediaBox [0 0 612 792] /Parent 203 0 R >> endobj 207 0 obj << /D [205 0 R /XYZ 121.4 736.262 null] >> endobj 204 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F33 177 0 R /F11 176 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 210 0 obj << /Length 2064 /Filter /FlateDecode >> stream xÚµXKsä4¾çWL傇Š[’_GvY (Þ p*x¿>j´%‰'ðyЭîáè[ºÕ<ÒoK­·Øx Ð@0F—šèVr(ɲ ̧p<ÑÝÛ¯]ÚÐ<Äc’93Z}X2wnΡ"\&ÂiàAÙk<@°öcØßæðO±`5šÇj`·”bÉ4§L“·á°¹d_1@r]¡f@;Ce Ie±74ndÝ Ï!ã|qßõMÑ–š¹æ‘÷ˆ!,Æ®8 _»~°":R[s(Èé¼`äó:޽¢vÓ@8üDDÞwÁSçªfŠüT·³¾Ïc–7¨%[^Õ2µPW€[µNΪt;L5.˜»T¡¤‹Pmg¸rOf«v¨¶¶züqÐùpéHÞW:L_”z±tˆ M³,)\0–ŽÓÊŠYå€!ë$rZDˆ}:_ÁÆ2KG(&¥#ÓÒ£†Ò´6 «Æ_ „­"¾RÊû\ß°j`Ï»ú>uú Ý0V = `ëöT¥&Ž]c¡A^‹äË*¼ÿ—GÁI}æB råùo®Þ¶8Ï‘k+!'±N!ÿϺj5³š¢ZS¡¡vLE~ÑnYvSíóp5ŒiÕ@³Ñó: e©®9?,Ã^ÆÅË.ºÀ>QrË¿*èV}¢rRô[Ž–6pÁÆÝ¼E]q𠺞‰K§ÊßàÚg^™Ä—¶†HIýÉ0ÉB»še혞‰zQbZýR€þó„Tqéx¨¶ø…La§jæ•›ùU†¶g©wóªzóšU À®9ÙH ã+ æèæéy`k!N[Žþk_Ôv²³f‹i˜RmÅ if±“ÚTÆšyÀ’‡HBÌ*’s@ ݾFœªÐÛcÑEb(ï8Š'd€_.P šCJ·5CŠëçšp‚DÝAt1è‘ôn±á’-»™Ýô2È%È, ß¶çƒ-u°©½Þ‚šÇÞ0,sh|“4bÒÚ@ ¹:å‹À…u’€ ÷:Yͨgt«aÉ^pæP­DµX…éì–3NäŸÞóxï&‰÷³7¸¼þôyM¢îÈe{RïùÓëKæÆôÕfoì2ÆÕ©…ƒ®uiómÞ­•Ìd^×›­® oXÖ®tÊ_ž©Cé#l ]ÍÇ•§óDDÄܼ£¢ËÉÈh'£P‘mtLFp2"%x%§ 2(mˆ:fHä2$ÂS;ø/¹ÖzÈ ]cC­B…ŠThï$°Âù ´^Üs# Ê-.Ù¸¦½Õ[^k»ºP:@¨ zÁ™”~p™x9ß­jé»Z|nßø!G=\h»²ùQ‰aÇyNec;›996Î¥cã.$úŽŒïø;<ò¦zpM(žÃËçš#ÖüÑî§ %æ‡õ#ŽÄ¿.XùŸ±+ÄñÁÁnG¸…ï·B:Üσ_ \!p 4Wpº¢éGÏ~¼ÿRÅþK-~‘ÿáÝ,5+0¼ïVV2±ß¡j×dàm'ʽ:S5Á¬¶jú8‡Ð_0ùò´ª ^!¤ÏS¸’A³GÐ zž€^Dî²aè‰ô"> endobj 211 0 obj << /D [209 0 R /XYZ 121.4 736.262 null] >> endobj 208 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F33 177 0 R /F32 175 0 R >> /ProcSet [ /PDF /Text ] >> endobj 214 0 obj << /Length 2509 /Filter /FlateDecode >> stream xÚ•Y[“›F~Ÿ_¡rÕ–‘c1@ƒ€Ý­­Šc;•TbgwäyIRSZe ÝXcÿú=·F̘]Û/£¾œî>×ïœÃ¼Ø\]¿“Eîçëh½Øìaùñ"Ö~–«Å¦ZüîÝ.3åé¾nŠeèÙå*ô:ôË•R±§ü,—n~¾~­‚É=Q¶öU¬ß‘À± ¼ïÿ³Œ2ïÇw¿¾z³¹ÁcW¯6W]…@,Âñuå‡Aº(W¿ÿ,*Øúyø*Ïg"<.Ô:õ#5‹›«_½ø\Œ8õU°^¬³ÌUÊL¼Ð»®×ËUf^¯‹ªn÷<ÑE¹ŒRïÀ3–—E ½MG„¹÷G âF?‡‰Ê'z±]ÏGÏuÓðèTÃgìAžäÃÝË»¾;Ê.)Î.Fšr»fnE*K€¾ï†=2“­ùjXtƒ…‚<5¼?Š4¤UÔ;9L/ÃÂÄ=`¦ïk+o‰Ô@Ûvíê“îå9c ;˜9µ>Š\¥¥?Ömaµ!·Œ½­eçà×öîä A\énê´x‹±Œ‹;wqÑò¯¾/ާFû#?.1³³Avé4Û{òÃ0蜙p¼{´éx.êê?òú`ÞЮ^É%'[“ÿ¤bX3ZˆN½¡´ÑÕœ™+Ÿã<Ê'q¾Šb?ð]…°%p5²{/ùBMÑ#ó£,và`»Óe¦² •¯ÒLô2ùX£¬ñz~8±ƒµ€-ŽH{s*¤éN¼ÒhF̆§eCøÃ¡AÅGŽÅ{Œ% *nt•x/õ®+§H­ð{Ë?¨Tà޵ռ:)ÄÂ5$EÄló8^_¶P—ÀùêØÑÕÐȆXàT† •‚Wõ¼qË?ÂF&lðƒF©zôc>(¡yd†ëIF /Ç´§+“‡A(ŒTvÇ#Ç7LšºÕßè<¿¶*wC[šç^bëWöäªÞa\$¡pƒR‰%^“Àû üÝw¼ƒ×C€8»&‘ʇÆf `“v½åsŽC<ô‰<“ÜvH׺ !¤k ŸãªG[6θ:ÕÇúÓc«¹œR`!@ÎÒŠŸl S—OÄ1 õQøÆ^·º/šæ#“B Ü;w*š3:gbÃkÛÆaü™MZäs`ásMÅŒ¼ªI!íÿ$Á›Î …=ÔÆ¢JEž—àõ3Ï*ž´E•±BÁ ,R} ¡~Æ¿E_ÉKæ§ÂÖ³­Ê¶n f¦ ]~Ê“T_Rä}v(è=÷Ûµg8bþa4Ó¦•±·$kî«·`8Ø£/£R!xßI …÷[þÅ®$õä è@ÅBÐ AmV¦>Rè€×qÄ#c»9E1¾Y>ÀV3W+¾ÔPšôTâ 9<``ê=8°[¥ ƒI”ËÖè4q9õE®oÅ‘zä8‚èƒÐSÓÛyŒµ#ä!ÐI7[_ÓXÃG©°I€áØÄÉ;9Úæùõ³±i庙ág×+Ð\ ÆÈq‚.|®ð’ä{Ø`ñ˜ÓÍV_$vENì8Rã}¼QþE¡p—1ŒÇ“BÌð GÇø‡„K§ÝÓ±|w“ ž]?çL;´pÛ¬~Gäzã„O*á’³;µ-æGñ3òæXø™î‰ å×wÓGBïÙõ7¡¡4äh@éÕЂó_Ia¿_ÝÛô§B,àÐãömgÆú©4¼Å‘¦Þ»7oÛ¼þå{ /qýÒ£©±S¹óúc¶l†JËL®‘¯A~ Âe Éî„]Zü“„wó红¿|X&Ð>ô5j^š}ªÒ¦ ¦×Çqxùª0RÐÍpäH¢Ó‡¢mµQãüͰ<>YQ±rN×ÜÒ\ÀØ[u…Ý1Ïw\ãAµx¤·#°^sbìx&(hëS#÷h¬|yã¾ާ•íù£BÄù9ÅôŠõ’äÞÍ0FìïÑBsùòÝœx™2,¬A>~¢otûÿ Ž ¸Ùñ¹…ƒ|™)Ý™e¢ÀŸ %¤Ø½fò:eT}5—©Vî‘ĵ¸4“zЇ‚.‰÷¡Ög.+`•3uˆÚúDƒÛ"OÄ{"£WÆ-ˆ»K¾)͵‹óÐEÓ¾k?U©ëmªn‡ÃÔWjìÆžz'V]”G®àÉ@?îc,ãŠ4¥¢SË‹Ó\8p†{|0dšÈûíåkž“ÖpŠgIï*5A½˜Šý ]?tÑÎßçÁÀÏò˜2Pm¬’(ñV›Sµ“á[þ½µw”¼0w`¥;(ñàê»èN%¸C,îøÿC©*òÓ^Œc?ËsɉûÈ„9³Ž endstream endobj 213 0 obj << /Type /Page /Contents 214 0 R /Resources 212 0 R /MediaBox [0 0 612 792] /Parent 203 0 R >> endobj 215 0 obj << /D [213 0 R /XYZ 121.4 736.262 null] >> endobj 212 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F11 176 0 R /F29 144 0 R /F33 177 0 R /F31 162 0 R /F32 175 0 R >> /ProcSet [ /PDF /Text ] >> endobj 218 0 obj << /Length 1778 /Filter /FlateDecode >> stream xÚµXYÛ6~ß_!äINb®î£ȵEôʺéCZ‰^³DE¤öhÿÞeËY¥q€öÅâ1Î=ý|urzîÇNÎò$HœÕÆñƒ€EN$,ËCgU9ïÜ·‹,ty/êbá»z±ô] ƒ~± ÃÈ Y–F‹«×§ç¡7ád £ÐñˆG Ç<ÏsŸ½Y™ûã?¿úeuÇN^­N>žø@ç9þîöù^ê”ÍÉ»žSÁÖkÇcaž97†°qÂ$eŒjçâä÷“ç÷ÕˆRz‰“d‹Â”„¸u Rç±{Å[Þšã,r Züíå9 ÞêõÐÊN¿÷¸Ðk%š®æë`ÆÓuVIͺÅô©6ÄhÓˆXè-Gí@Â¥ï³<ŽI‚—¿®Ðl¡ ,¢š32\O$_ËAò¥Ÿ³4ÎèÜ{/ˆU±÷z‘€À—5§£JïNÆ,‹­Î¯ZCl.mY•h¯h ƒ‚– h+ô\iÙsrñfhK-Ðç-:_Ì苚šÁhSË¢‘d^³%&r­ðX”øî xO£r9Túí.ÜŒpלHuv@‰uŽb²ã-Þ½FŒýMgs'ñƒð1ߦíZ‹†ŸaùŒ=÷ô”6(iŒ&FCC<(¼Ãhhl 0¢ª½µ„ÈPé¢éÓœëòajÙu$örÎ6Ÿç˜ìýaݽnLàû¯]òuëÿð ¤ã—^9‚ú(³}Ù"H¸ < mÓÊ#Ëþ…­ ¥ÀNÃm;¸Sš7/h"Ý šò­¡Ä­0ÐLkà6¥‹ZɱcqY~_ÇÒ…VG üÂÔw+§-,zg0€¤¡®I›7Bo­°pPZ”ö´l‰z×™*®ÄU{ض>u=Gv·Ÿ×keÒdeúV¿†KêÉýw«¤XÃ5HQJ]ˆ†cE S½tÒ¾qZU Gj€¹±{tp`l€;׋8¢ËïÛÿ•éœ8¼èjñ¹àÞ{Õñ/ÓžÑÖW‚Êú¡K9´x‰ÆÜ2u>r/8ß”áõØ:t+J$¶^#Îð%FPqi¹W¨o;+'Á—êú[ÞI¾š9Yb3ÇQH„QYêÖE{5Wœ7àÛ¡©­êŠè.‰/mp˪3ìµb>‚µUÔtDK¢~€¶š«e“»Ïø™ÁàA™ñâ ËO 8ËÑN £ Ó¸¦x àÇXVÇ€ÀqÅ7ÅPkôM’¹BÓ*¿…P³g7¦YÜÖt©Ë¹€¹5œ¶ÏÚÈâ J`AX¯6 æè|¤È)Ã9…ßêG,„SØäùÌ˃7ÕL<,Ó„ùÙéúÌ y×JÌw -lFwJà]’%ÙxÍ#p úÃLsÚ‹BÇÀËþ]2†±ï4³&òSxêäáý" h‰LT ãÃáÀ8IÂ’x;âœ}"Xû‡öùÓÀä0È÷('¢¥îÃP7) ¥£Á<Ô¯Ö$»g«¡áµ-ZZ“í¸$;Z©9›šÖG< º=&u?‡ ËÙ7™Ñu¦©©žašÙÆ‘¦öFX™Þë‡ ÁÂD„ñ$´I_‚’’®9dg¹}xÁ’â&½¦T6çD§b±!Zt÷ØØì΂^l0l¥¦ GDÝqš¸+ã² ‘© ÀiG ¾âV:›½° …»­Š¾EÄk9ŒD`϶¾›…H­m`€£+¸‰ä¾(ù‘uü:¬Â§Gä%î fîäù–khyÒÛ&Ó'(îIûÝÚ…é£v™$áô}ižœx•ù—GûpVT•À \Ôs•|ŠGV^¨êCVvQœ[è£èå É¡id/ƒú‰HÔ¦œÛ†ƒ,Ò«ñ5†.ñ`º?µ´;ÊF32Q?_Ñ Ö^’²Z«’D ÂÜ ‘Aäí¡&î¿)Bó87Dð/:ä9Ë&¤ô=£ÝŠ õcxƒû„OβÌ@?ÿeú0»ëx endstream endobj 217 0 obj << /Type /Page /Contents 218 0 R /Resources 216 0 R /MediaBox [0 0 612 792] /Parent 203 0 R >> endobj 219 0 obj << /D [217 0 R /XYZ 121.4 736.262 null] >> endobj 216 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 176 0 R /F31 162 0 R /F33 177 0 R /F32 175 0 R >> /ProcSet [ /PDF /Text ] >> endobj 222 0 obj << /Length 1958 /Filter /FlateDecode >> stream xÚ¥ÛvÜ4ð=_±§/õöteùúÄ¡¤@K/Ð$}¯’øàË"ÉMÂ×3Éö¦.´åe=FsŸÑ>;?ùæ‘nʰÌâls~µq&›<΢”›óýæ·àý¶ÒM[mE`·; èíNÊ$a‘'Û?Î_~óƒŒ|â" e"7óHáXEÁwï¶qüxñúù›ó3V#ÉCe›¬(ÂDæ,Äåv—+ü-ƒzèM«ö¼ªz´Mÿ'Šè7š>Üî’¸ ^\1b4h,Ð_¦Œ{ãX‚¡6”4£®U¯te=·×3ÿ=’I«ÌSdP ãXÜ6m‹fÕvB„eš>]&QPí÷È@Ã0h†Q׎ÂVúZY·q… pw#*”¥Á 8z5mä°ñXãqYý`yc4 jI,oï9¬gÜ¡"“Y³%Üý8 )jyÑ+RHÊÀü‚ƒT~ÏñѼ"›N73®«z¤«¶½GqÃIœ4,–æ§ I>°‚iX]Õn‘,¢WMÏ$¹g¤Vfl-o0A>蔃0J:ÐD`š»Pƒ;@¼¶o´ƒ1 2‹'‚¤OdÂŒ…¾½Q=«x‹D¬…²5ÎvÚ™ýˆ–uï-<8ûQ³º°ßeÝ^µ¼§îT=ÚfèCNí¸\äÖ.NÂrk';ßþÅ)ZPíöê`o\E‹c˜±²ð¡UTk˜ì(s!ÙB)ã#W9ÛÕÍ?É|4fû¹Ã_—#š7†+þ¶³E[è½R„RŽ(À¨¾ºlGè¤ôÉ$wUwð4³¶ ™¿å ±÷| dXß’øE`”b”ÓjÀp`ÌÄð±q´ÍuùÕLÜ"NÕU‘güÁ#N8 ¬m´[“o ô-Ï‚ ŸÔÄ‘˜®Z/;ëÖ…/Õ)‚öªÖª¢¥t2ÍeÓ6–Ríåór´Lq Ԗ싦;èÁÅp8z¤kmÓ9gÈä NÙ£…þVÿ¨ÙÃ@íª»]¥uµ•1ˆúqÀe˜‹)`a}¯Yâ8^ßA¢ŠI9ˆñ§ `ƒõ‹,~ËHAžKòÊË]Ó9‹ÓIÇ÷YÚÁèFTÅKŠ‘–Qö¦²Œí–‡}Y‹O4ÇžÚBÑÅ}APoÀBÍá»pŒŸ2¢2Œ˜Ë',Zì? ²ypïèæ ‹9`aZ …Û™w9Øqfi«ÝªüP¨ÌWÀm³_­VeFPtóTœŸ‡€Xó½ŒrjklX™>,b‘OYŽˆËÆ2Àè Z”SÎÂÇ»œUÖsòÖE.ÓЀ4”;"؇k&\Ô”© 'AœÂì)/*¿99ÞѺA sq}efgÃÂøÀðØíÌÚ·©ÙçŸéÞE#ê‡{øPéª[ë2ÓÉÙq§qMà¡’dyІ¸)«xú…°üŠ˜3VµýL‘žû¶äjK»¢•ïfJ™¸pñ@_ùÒI¢Ã÷PÕH8¶t˜Dµr%zìÁОJîÚÁ)¥×" ³j÷8Ϥ0ðÃð{ƒM#ɰiÃXF–­ c¸»nyÂ% ]ÔišUn¾=<îrÄFX$28¥ê¤ó¿ïñÀ÷§Ì‘ºÄ|^vMêB ,ÜpçÁèÍK·qÐǰ˜¿¼äÁ¾˜ ÞVóäÉq޾¨¹äÐŽµëdBŸs×°Õ ´:"ý„¥aÔþŠ û½Ò¦´ú²8ŒË˜Ä=~ýÄaø à›È7œµˆœJÀ£„@U ‹"1 3KDÕRoÐU4½'4BDÑôLâË ø™5«|<ü£=Ðôq4ôN9Ž&Ip¦Ü9àëʬæ[W×KÛ}vIÚ]¬4‡Ùô<þPéOIœ{O¦¼€ëÑñ½2ÓûÈ•×Æ¿hyÐ g+ìµ2fp¯%s¿˜æ†ö‹ÊêØë¡mwõÌLvE«< Ó¼œ†üa›–ÁpXŸóÓ0ËåzïL£Eï,3î9öN*/¨z*œêiô âa´ÄGs+lP=„oË–¡¡–ÅW:ö^»†š.Ç@ÿË Å¶a×£éÙ«Ÿ_½}ûË‹7/ΧÖÒžbð rعÁØŽ¼`ÖÝåÞ xVuª·ŸrƒÈ’OŒ0b9ÂÈÅ3¹!ònˆÄÃ1F|âù<Ë/|´8ŽTU£ˆGqä,Xò“Œ.^/æKúÅ_ ó8‹u%“¿äÿô×QÚ ŸF£ö;­®ÕÝaí­!Â,öÓ˜5 fêc§¥> endobj 223 0 obj << /D [221 0 R /XYZ 121.4 736.262 null] >> endobj 220 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F33 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 226 0 obj << /Length 2095 /Filter /FlateDecode >> stream xÚ•X[s£¸~ϯpÍ®9°€¸Öyrl2ã-‡äÄL²[»[[ŒQlê`ð oþýv«‡šÍ¼ØR«%õõë×ÉÕO7–; г½Yò<³lÛpf¾íAÈfI6ûM{œLã"/Ò¹¥5sÝÒ*ˆ¹Î˜£1#ðùÉÏ?Ý0spŽxsØÌ¤3\Øfš¦¶x˜ÛöéËm'[Üv%W]YÀgάþvfX¦?Û¯~ûÜe°ôóÌ4XÌÎ’ñ8cžoØ0*fÛ«ÿ]]£vøF / ‡ù$‚þHbŽÔµ#4½™n¹FèßöP¡Œçz®;f 5NƒoHåâë\‡ÿªSë¼*ÿÛ×òrW´Y^î‰aW•¿›ÌÙ·"m€ ‰Èó\‰cO@®ã)/xF³¼ÄS› %uË2B×½ôFS øGûÝtÍm~šô íòÿ$…墠©þh«EvÙKï 4$I‹}SŽeCË2à ¬Î¯¨ZÁËôÈ'Œ bÛ¶;2îOAGf3²+GÈyZ«üsP_Gê[í‰^ä_E*^Ð R}K[Hs½Ðò±’:gmÁÕA`Í©{Úïu4ô­¯qš´5ïDt„àuUûa[èk;iQ4É˺IɹôstO ƒëR$4Õ‰‡Ãðv8„x¤*>¨‚9WCˆ1ÌQÔjw¾/+Á34³µ¸j\Gb¨kŸÓ\/Sj ˜Y*2Št'ªº¦Ô[^EÆ~QÿBêôßæ b…¡Ëÿn@qÀ0ð»¸B¾‰+Ó(J‡Wئiýð£˜Õ=×0!¾GˆðRVbGeÈ^u¾5ØëÙ†gõ©ñÑbž££Òè>¸­Élñ™a›Á÷E²<Ã÷½Ž¼5q5 q|µ4Þý«ý¹"^Ê®É)ò)¦ÞD€àZãPПæˆ)$È»`8*Ó¯2I}SnÒ™jgÌT”€®5æ‚ áYw*ýÕκ‘~ë:ãLí'JsH:;Š©Dh.Ššey‚d£ÜQ¡÷µÃ‰Œ?§mѼ;3È\ˆJè±ê̺vgù#¯ët?…±º¾36Ý’¢•àD€zŽ¥Ç±<­÷aŽ8(K,,C„îJ9é ’œ¥%ýKáGÜ€C^èjÉqGnTÿ{^rÒó”¥C‡Šì‹ï*(—x9ÒˆEMKÏ¢:ñ[^A$·Ã4?’V•èP—6ÔyÃõsž©£V¬Ó–)sXùßéñTð‰¬ºU"wÅw˜U_â»ûäf³H&¼B:º}ó3…í†÷é¹mZÁ§"Â5 ËöÞ¶ ew\u!¶ÑÊŽ ÑÍy†5k†ÚoÛÓ ýä„Z[þ¿¬0nÎ%Fí‘ W9r2rMgÊ×¼"`URÖSŽ?çÍSGµXŒ…Ú^¡JIô>qm§Š!Ƙã™*Æþî`³@µ?!ÆõrDbLÏ"oº+Hs‚È;¦“"Ëq<{Çs40 4TÉVSG„ê™Xû*ª $™GFcI„¶ÌºsÔÉU¡(î°Ãüï\wÀa–ÑÒ(\Þ$–Ø·C?Y’<Ý!ý@³QªŒ„kÝt:v %êÙA ¦ÄÏÀag $'B ±Ö¥i=¨çCÞ & ŒÞHŠ„Œ–ÝL˪¡=ê2_ª—D沚JBfB‰wÞ‘„®áC]&አˆä©ÇÁ[4Fê(‘ðŠ¯Žm«Ø—Œ¹l8aT _HÀCjÚµÆ8)Œÿ‰¦CB–‹×R>ñy9òÓjùþkÅ®kGÁÒ¹€"›q÷•s¤ƒ$HY¥k5ìÝÅ4zW©½'¡DÅÖö½¯•Îm¨&t„ÍûúŒÞ-®£ HSÉÇ 'dzF“‘^.ëÚÚN|_=qýÁ—œ´òµ «ç¶ 8‚Ò­ÀÖ^7ú.­yM‹Xúñ¨îá;®°6£ÔÎÊ{¹È¦„?¥¢ÉyýãÅ œ øRðƒAë²<9Ð…ê+ŒGbÉ|B2œöЈ¬ã²„¾ÿ“¼ø™ª¤OŽÓ?žp¬OĬÈòIFòžf“ß/º÷~Ø’åÑìË£M.÷¬;ñùÉ»ç®KwÃú‡>©VÑrs³ÞDñâ6¢µW´´U„ays ¿xXÜ*Ž)¹z,L¸ÞÒ$%ŸœÑ±÷x*Á„Æ|;ñZWKß»wŒœï‚̈ø(ëÈâáózµŠâ„–Ë Ú A ußW­ ûžûÏ?» endstream endobj 225 0 obj << /Type /Page /Contents 226 0 R /Resources 224 0 R /MediaBox [0 0 612 792] /Parent 228 0 R >> endobj 227 0 obj << /D [225 0 R /XYZ 121.4 736.262 null] >> endobj 224 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F33 177 0 R /F31 162 0 R /F32 175 0 R >> /ProcSet [ /PDF /Text ] >> endobj 231 0 obj << /Length 2387 /Filter /FlateDecode >> stream xÚY[oã¸~ï¯æe ñÚ–¯8i›™f‘¦=M¦í`g±p%1Ö±3¾L§ûë—)'N]œì¾ÄEQù‘¢”‹ùÙ/Ÿl¯™‘ïø½ùªg;ŽéöÇ7ÃHôæËÞoÆC?†,’4îÛFÕØF¢?Â5„nÿ÷ù¯¿|Ö'ôMኞE2<˜fY–1¼ï;¡ñùËÍh:Ÿá´³Ñüìû™ |VÏnV¦m½Åöì·ß­Þ†~íY¦ˆÂÞ‹bÜö„˜´ÒÞììg¸ 'z³ ? MW¤Âà±ùF–Vq§¤rkëŽkF–ߨži‡>MzÜÈ 7*Œ—¾q‘%Ùº$J\Hj,e%•\žSwW$î²" U¹å‘çºâ9}³œ™äÏ„‡€e²E)uWya¢¾°_RÎ#å®cdøÁŒ@©²ŠHpŒ­,Ëx-Kê%±=×I \–ÔMx¸LóÝ%¼¢¿ÍþÀócL.oñUEž­ÓW¢‚ lc‘o·2[Ê%Ñ^QJ^7*Ûfä±=©Œ•qêòFÈoA½Ø—(mÙF]JK²4ɸ²…ÿÈ¿YB0gÎBšàñm<0MÜNèÀíÅÊ0\Ä`kž£`½‰3-Mx¨>[¼Ú$ìü|W%yfŒZÐ48ðÙþ!ø^úÂA 8`ÄÁ40-Žö\JQ¬ã´Q:ÊâçT–ÇÂ=™ÁÀr‘ÀÖ]å 6–‰ÀËýÛí ; YT¤.xĆéiŠ »q)‘ °Gu±ÓÂ5¶ˆµ=e$ÕFú7˳ ¤Xô3Yµ—r×)  ½Ò¢*„IBÆË×.ŸK¥ídÛ4Ï )ŒÝÀUaìÆHˆŽ ˆ\VJÜ*êh,†¾kÌ–p€¾c¿×ɾç6RéUN|Ðnã½A—¶ÃI߆=âôËÛ›‹Ûû«Ñ=`@øÚ˜ƒËál4žÏÝd4½Ër‹‡Ñýdx×µ^ÇŒ'å8]#ãùõ;£7w—·ÓÙ¼sp4½š /F“®„rÄ:†ÝŒ/ÇÝr&ã9ˆ§ûÑkÞ§7˜îfˆ«¶¦Ÿ‘Qƒ>ôPÒ=òŒÐÖÆåÃü»|™ÎÆŸ§£+ ·£ÁÇñÕüúÿ >@´eÿ,úø[EŸÞAâUôäb·‰Fd=JÞ!®]Ïa\ã4ýe\û‡¸Fz•Ó÷CÛ°ž¡ý®&È÷µÓ}W£Ëɧñd4ÞŒÞaøt‡„áýð¦ ËÙÒ†ø3¿>Á±€šé-@w:ºœãnÞ,;û:E” `†ˆ®¯ÓËé耵’«ûñÃhzž¾ÌÞAÓƒJÃûëñÕÕhz¬¸>úf9ÞÏA\–ÉAi5Š ï-›}Û*.+jašæ„ŒYµ5ý]eê,ù^ŸŠñËœpVä)b0Ò§b„‡8F+‡Ð‰+IãŒÏZjö¸"þ„r—Æ @}¡ºèªf éºE€ÏUž§¶(ÙºyMZËB.±`QËÿ "Œªs*ÄhK¾§·sª¾´÷ø#‹ª$Šth<1Aéߨ©df¢$Ìñ¬R‚T^ƒî ê«­wÄUÀð6ÎRŽ®RàþÖú[ï*TROLP Â×*Ï q¦êK—+QœR2bë`áÆbv·ß¬¼>4ž˜@Îó ×wm¡‹¿ˆ°d2.T!Œó™Æ0.M±x>Uÿ0°ÍÕ͆ÒäO¥…¢×ÄbMíh…,eÕµçZU²žK+áwQA¢Åzú›d½¡Vš¯“5_µSÏU«ÊaVжÛÿ"Ö­˜>«:[`L=¥<|—²Þë-ðû"Õ1¸Þ©å9õ÷6,–£q^¸_€ÿómò *æE±_5Ü$àI—Á9õS¢eJ¾ŠÑ5ÎaX uÁé(0öå4«£ì[VÇWº2^Q¨Àmn¥®"BðâM™Ý±¾K×2!ZwŸÎëÞx…µ¼Ë·Õl§I5ˆžÃ ã+ÜÃõ‹¶1—ÅØ¡CC§,¤ Ùð[JLuØâÛ\A=ò¶=ƒ.rê–ʹ‚™Ö2“^[» ZÖ œÀÄe)Ñ:P%ćôB®ÁZ%ùF‹:£µT ¤˜ËDÝž´@v‹F ð•P†HJP®ë_Ô-XÑÁp-_ËJn?ÂZN% tC<¹Ô‘¥ˆèeü’»-ËxL`UÙfZ{Ò>f°§Ì ß%þ¨ À2r^^D`ãЮȟ¡rë¼£èLhy)>K@—x^©ƒÞ.u3m3BK']»U!H•ºš„v!ÁKûׇ—D¿mxúºËÔñVǘÔWTµÑ C$Ît 5HŸz!÷ÕUìXíÒ` ÷C³£ŒŽi»¶¾ë"6ä‹>µãÝ.Mèž •©¬ dJ5!ç²"Áw²gÜ7>³H–ó²I|£(z<‚˜ù 2I¥…Q0“‚Fô“²Û€•lYOåÇâDæ½._¡„è]ð r# …eŒ³¤Jâ”›d\R_%Wœ”’±ÕþäAÚŠW9 5ÈékѧÎRˆ`jS¢Jh±ÎãA.×xO¶#º£Ü£· Ð8°iŒ‡@JlMåVÒtTéêDPzæÁ&|8¼ÉSJÌH'à9zFqõöÔÜ6â²ûI(¯Õ)«Ò}«j®Ñ¤0º‰Ûœ,õËbÉ%Ô~Ÿÿ¨b×FUü?å±wü^yE6ÏŒ„óˆL("P‰‹ ÛØWµrb]@ÑÕ{eÀï•%Ñô=té\H©ÚdW$뵪:¡³½ãcCéfQÖ‡O™µLXeè¯ <•°…Ŷåé‡jÕ¶i1¿¼Ù­·b×~óô¶ËËwL)|Ó·\ÍG)åRúç•ùZ _‹gUO˜¶ia™\Ÿ¼¨:> endobj 232 0 obj << /D [230 0 R /XYZ 121.4 736.262 null] >> endobj 229 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F33 177 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 235 0 obj << /Length 1778 /Filter /FlateDecode >> stream xÚXmoÔ8þÞ_õšU»Æ‰óªr§TåE„¼‰w×"›,NÒR~ýÍxœÝl_šÙ™ñx^Û}ruôðY{9Ë“0ñ®–^†,òÒ0aY.¼«Òûà¿eÂWFWrøÝlø f6"òËÒhöéêùÃg‚ì„g |â^ ¢çg"ϼ«¸ñD’²¨Ê{}ôßÑ LãÀ’Œ…¡ð’,c‘HÉ-£VèXÌj?׳yÆþïô Nü£ó0f9wùÕ¼mIéϰ¸V+Ub^V ¹æ&ðÛîs Ò€j¥kk-ˆY’¥Þ<XÇdR/I ­\è<¹ò«¦F<Ú/(’ùÔ U—?Þé’yÈY¤‡y¹„m£ Å~‰¨_ºÆœOdþbfþ-ÉKµ”}Õ9I_ëZwZVú»‚¶*I§¨šÙ–¸îKKLi+}|å6”ô¹žÅ §wJÍ’¾ß•iì^©ß6ÄêÖj(ì8V¹°{6h›6p=î£Û(úÚõÂý ‰ˆ%y<¨-¡¦¿Aºé«’©n:âwF¯VÊ0ªIB¢[›< ÈÚ»µ®0È<÷uç¾-}­$V¸!$Án[okdÑéBA6âˆcŒ3#¢m6Ž*U«Wµ3Û­¥³kTuKTSÓ÷½KR4ަVdbÿ#ÁDŽ‚ˆåb—JN ‘2D‡•q9Ñõ £âPñû…‰(Òt°fgr¥¦*“Œé $ü­4™¾’ÃÃ-`Äì×Î2vf«:ä ñµWu¡Z …ÿ¦Ýùõ‘‡ñ·¹kè¹uÀòot·¦ð²œñ,8Œn°00ÐQ ª ©¾­t!;E?»5–©…-°ZË|®ucÐ4÷/;’ßhpz°"+ì}¤TÝöfgL:å©"†iÎÏVD0œ J3LõržNUkæ!Ky|˜‰mÓþRÕi„ùØ¢S¡Q!½—M§Ø”5ØSìœ~m›^¡ß·Cµ­ïð1½ Õ¤!˜0¢>²\A½§^@ÒU ÄͶÓ8-È-dML ùªpë ïPǬ°½ÎÜ<«”¦Ä¡NGÙ®€™åþF:¤E&ᙢµ‚–m¥q²®¡oß:9öîÞÔº1¯ôFөƇ5º.Œ’ÃBDSÚ×öüëv6$(ž€Û‰˜A=O e$¦ ',H¼¢Tæé(<ÐÛ‡?$@ßÚnˆêg†²¿ñ,ÀïÖ4‹JmZúe§ÒR?86>UUÙRƒ+‹©)û@µë=»¹¤²,á@†¦žìØcmº=ç·nZÄá%Ù)Km¦1€ƒ)>hÿǘ¬ýŠCW& `9ô]cùÍy¥ÛŽ(›¶Ñ ­ÚAW:•]ä@ïë%=îÖʉ—Ü€€ö©úò0ãÉd¢ÊîíÖ¸ö©ôÂHÜ.çÐÊõãÚ¨]÷ŠX®ÜBÈ! êív ÛaƬš›P¹$†ƒÏÙ~N,`Óo i+7¬çh2Ù™œºCà‘ÈýÓ[ºßÐÑ Œ¥ÔöpAºí@OšÒ©¦i[’ì΂fEÂŽz°©œÂ;üA„1 Ëþh§¦ßp—’NÛæe=}:=ƒ›-ÌÉBW v²`{¶ÓÜ·Ò3*Šóá‡;%Üúi¿X½1pCƒìvNßw¨ˆwÝã¹ûÁŽé~‹z”B`Êz¸5–PW{{ u´^€á³©à:èÍ•ðݲx•‹ÁoâCôë–H[)TH,kÙ¤D{gðhÒ½ïÊ÷ƒl(D2¸Š[$›è{YUöÚyc;8ðO榹üó´µ²st|B„Å|Œñ|t~•¤… ÈEÛT=]"7eµÜФq:HÞŒ¸4°‘;íEˆ8܇•ó©”·rem&êºí”t°i‘ð®Ðn»qÉÈ—#3¼Š( @2ŠàIšîŸ“ÁÁs2IÜs2IŸ“wP’ã “¥©këw¶­Oì5I;v¼Þµ E}“›íÀÖ¶lú! Ø”M½8]Û¾ÝûhóžÈ:¼¦ŸD¢œÖ›*~íïÑÅ«gDþºìšÞ…œEqv÷,+ûJ‘*hžïwÝíuüÖ´äƒRÛîÚVòÖÎîß ›ÖÊÞ5¦*íŸ;å%˜±êkÇ9|ef÷^™Î?Rûï&ãüÕL´zón ˆã5+¶Û&å·á(²ëŽß6=.2l}<ù\IYQQó¡B>üÏâü"pG endstream endobj 234 0 obj << /Type /Page /Contents 235 0 R /Resources 233 0 R /MediaBox [0 0 612 792] /Parent 228 0 R >> endobj 236 0 obj << /D [234 0 R /XYZ 121.4 736.262 null] >> endobj 22 0 obj << /D [234 0 R /XYZ 122.4 332.761 null] >> endobj 233 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F34 237 0 R /F29 144 0 R /F33 177 0 R /F28 142 0 R >> /ProcSet [ /PDF /Text ] >> endobj 240 0 obj << /Length 1236 /Filter /FlateDecode >> stream xÚ•VmoÛ6þî_¡e&§­7K¶‹HM‘4Yâ9-Ú"%ÚVC½L¢ìÃþûx<Ê–]}p?ñxw¼7>wäûi§i ´y¶§MšeÛÄÕ|Û#Ñ£M#í«>ë1 º–놥g‚(º†ã¸ºC†¾Ûý>ýØ¿t̆Û2‰gºš‰6j&qFCm#Íñ|b Ši¿:ï!1Çj&6pˆï»š7×ñ1¬ßã4dUD»ÆÀè'kZ@z"SN#²:p„IòÈh0À#qÊQ; âô›90·Œ X†p¼[W—ô*(Pxv&Äën›¦kaÅÂí¿Ò£m’‘åï»É aÇ`7Ì’$H£óbYB ືB´ô·m ̲ª8C]žåH¼Ã%¥$@gÿ°‡‡7«˜©jßß0,ð%C[fü2NãrBˆ¢™ZíÒø“®áDÀj­·(û¯-܈2ÊéöpkJô%æ`K £­ˆè@ ‘¸ƒá¾hr{‰(Þë´âi†c¯ÍÕB Ötõ×®=Ô³ 7qZò€1ÁÖiô Ï ÔXY‚T)ªRÑC¥‚‹cŽôZ-À…Å\ØSÂyÅ‘fŠJ\ó àè2Û…å‹° Å7,¤EÀãtÙV¼òµä4ÁF”X*±³ƒy÷w7PÖ^­á¸EÉq£\á&¥2yAñ WtÅ)Š£ÕZÆW‰ç˜Õüh¶k[áéKžªÙf“û«ëó)ðöþéþövú®Ÿ|ÕçY³6-h]_A”}ˆà×÷Ԃ»óé‡w§38®”›þ£9ùA¨dßõ¥žhŠ4¤(¬説}~3íl¡=“yP–SHÕbtÙd‚òjèH.ÌX%®@(Rv›) –ú ¢]LÃûÕq |yÇ °2CÖ¦ˆ¹r³{D¤SÙéÖz‹ü™ ÊUöZ)›ÿƒ1D~¹jvUœ4ÊÃaüÊ<ÜòBÂf%òG¡œ‰_áȲÐÙyª^ŸtgÝU®Fí/™¶ô¼û³Lbâh n#ÝçêKª¦A]´¬âyul (£JÆú˜¬VFc²í±j0@ŽŒ‰ÏÀéBþ€á×’5ð‰/~õ†="Ãá ÛVýmÿL ì endstream endobj 239 0 obj << /Type /Page /Contents 240 0 R /Resources 238 0 R /MediaBox [0 0 612 792] /Parent 228 0 R >> endobj 241 0 obj << /D [239 0 R /XYZ 121.4 736.262 null] >> endobj 238 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 244 0 obj << /Length 1336 /Filter /FlateDecode >> stream xÚWëoÛ6ÿî¿Bó L.lYoÉéKM‘×b/íÐ#1¶YT%:®1ôߊl×ò‰§ãñž¿;Rï¦á©#kº¡1½7×µ|#rC+yÆ45>›·½Ø3y•å¬ç˜²7pLDÕxžozVù½¯ÓÃSÏÞÖû–ĆM:"8fÛ¶9þt|q}>Ƴž9ùg2_œÐÇøÓøäïéÙÕ%*댧oNÛ†óä“g9vd$ËÎ篶‘ÂÖö¼Ql¬•àÒðÂÈrÊIç¯Î»_Ʊå{9vÃYžo0Â>øûæ¦çF¦XýQqøŽ|ó®7pc“KÉ+bˆ/¶ç!˜ë*“Y1'>#Þ{èáòs­C ÚK…ÍsbÈEVë^TÄÚài±²zƒ ŒÍé‚Ê10äŽH…™‚hŽc‚€â©Ÿ Ù04”[°bÎkbd’Öu–Csú`+)–Lf‰J„bU«BïåZHÜãŠóZk¯%/ktÓwÍ ×LØ×¯å,!:Í*žHQm9œT: DšÕ²ÊîV2aŒr[LËòïlYæÜ"ܹ±áø–ç‡.ÖÔû>€7nçìjF»ÀÛ (ó<+Št'L©\àA³2í¢öˆ˜u¶„fÑ>«ÚoÇÇQ‹óˆ`ã}Ú€‰XÕ*l‘M '9Ôky¢öœ-]Û9¡ò3nü\>@Ê¡2n@u@¬€–Yª@’îŠn‰m+M˜$¹×¯ÇW§D¾qëQI;¶êwÒj?DºÂ¤ ¨ò‰/v`'ù,Î+:XÐ’û¨(WÚȾÂ騿pH¬“\$Db!p­ø·À¬ EÐ:çZIVd*ˉÁ™=2…±)aùšm´æ?[·KQótΟüB•GF´«çŽÏß(þp]æl£ÏØÝ÷<ϵ›E•§]Ê ߃ÃõBñ"UžcAÿMf%²S-‚åznAëd¶d*W…•”å/Kû{V$ù*Õ¹èÞŠž©¬E÷p“kS¤¾ÀÅWÃNÏ“¾Îí‚i´¼|ɪù£J²úþW©W ßËõ­º¢$OŽPY"–KV¤ÇÕ¼Fk¬UÞ*tÌWgh2KZ„©:7èêªwûŽ­ÕÙV )O¯²ZñÞ{Ê!SÕË¥åAà“ÀZ ¾&Ï*/@¢Û†0p¸Ašæ˜\ÏNÆçç­ÏØ ŽYöwtì9>Y¼¥æ„Åc *an›¸>ÃÝKlL¤Í”ÈêSAõéþS™õ"kfªùêHSj9òT5n¢’m,4˜ª%SN¢£NNf—“­¦úqÈzÊs.ùÿ׃Ï”b»ap?´`¸Ó‚{×ËàÐð>ëÖö›[ž>²BÌsœožím=ɤºAâ¾K¢ôÀ1k]Ï™£òuúô&Ý<À.„&XMkÉ*I&EëVDÃ\qKzUL=„5Ó KºÍT#Ötc6wùÍõ¦µßHx~Uë{P›¢‚«à·nT2-`ÀÂ"IëO·íC&žykò泌ôœºßœO1W7³›««é›aÉäb(Åp½@6¯øð±)ÁpÍê!NzHº®ÓAµ®§ïß¼¸ÅdJ›ÞeÅÑ d£Äs1s©^k y­DÓKÎû1Àz‹Š DžIIo˜æA âÏ}t<¶Ú1ÀÁG¦F@Nó`€ô^Íc€ž ûô ²"ÛWŠG‘OŠ]·ù%øãÃ?P endstream endobj 243 0 obj << /Type /Page /Contents 244 0 R /Resources 242 0 R /MediaBox [0 0 612 792] /Parent 228 0 R >> endobj 245 0 obj << /D [243 0 R /XYZ 121.4 736.262 null] >> endobj 26 0 obj << /D [243 0 R /XYZ 122.4 647.581 null] >> endobj 242 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 248 0 obj << /Length 1509 /Filter /FlateDecode >> stream xÚ•ÙrÛ6ðÝ_ÁIÝ–j*Šowü`;qìÔvR[ÍÑ$ãDHBÌC! ß],hÉ3Iž¸X,ö¾¸?Þ±“{yÂg|ò®^:¾æ™sc+'LRT:[ÿlíÃÄ$˼(LI½·ÆDÒD/DMДw@S-ei略æ<™ïåAâE91­ø<‰Yì?ÛošUëUWëÃ%zõrïäÄãÈ”—ÇÉOqò¼‘šN—µ×öÚ„N‹FñÎöi¾Wh«ï–²¾"èFêAwJ‹êÀ£ÓY£Aw–¹ –¼£·CðBtŒ!…&-^qJ¦ÀE”Pt_ñK¥9\âÄåíéODn!–ƒ!PˆºõœÈšz-dÓ‰1Õà‹ ™kû$t•±ÅûN@-q»lZMN½x1~~z`œ}r¼ÿìø|w„&t3ºY Z´bTÊ I˜z|$n%â•V}Úm2?y†<Ï‘zïüýåë½ñÑî¶•xy‚h#qgÛâÇG}¼!¶§r¾°&6j! Q,mJÙøÒyÈ6ôüïé¼éƒwï.Oö^\ì—zÑ ^t¯7¼9úÔ¦òÉö×ÞÜHèÉü XþèKqƒø„¦)91óXB·n0éo¨Þ l›D»ª²[L‹ÎæÞä|¾,d;zÓ ñ ÷w*ù±¢kÝ"w.ô}§³eÀ+ 5+½\i¢ãêÙ† qË«e)v~д#Q–Öço›¶,ú Ò=¶³ë¶c#„q5ϹÛ3Ó(j©?èsÁ˲ëQumê÷ŒŠs'Ô´-!š~"~6kº9œò+lNè¢RЕnè®°_J€^HEЬ±îð5ŽPà , |w SÇjxc¥¤–Úã0ø© LîN‘ã‚×sjŸ9fÝ0Œ°k£ˆá+ÝTÐù¦ÆÕùµ½7„ð›W‚@¨Ž¥U£$t/„K‰„BéK=ˆ…4SÝ@»îÑZÖrªJ·r²Ò’ÚwD~«núÚl³]šeNya”0 9°"/cñz;^3’ĬIº^3rv¿f<Ê"jSij·ŸCÌ£RžvÉ¢4»‰*W¼ž `Ð?Ü{sʳn¢9€'ÃW!A}ß¹Rr^ïÎ8 Ì ºn-Zý¤£ c>W^ßÞ0¦E.ñ€¨ ¶ÉP+¾¬dkiËòuŒbH,P¹Û}àNËJ(ÁQ á):ž_ë oq„gf„¬§0TǦB·RÁ¶ù‰ÛÌð›‚b ›¢&«¹"s¿Æ¡-/©¾x•¿°¬˜«ÌTƃx¯#=§¨šV~mû$â±–á4]UPhNIŠï…Qôó8.°·Â 2W§²Æç,a˜!‘ÉfNˆ) E£Ìw•Í’€vR¼á¥jšËNkËcŒ_t‹»¢A7iñ÷¤Æ'kóñnÃ|¢™t>–x‹q’ JIll„ZGÚŠlúçö‡¤´¹‰®~%ÔFÁ;ûuCß9עﹲã¾Ûæ°ouo­¼Äÿ•€Çµe—œ —Ã`ì¼K¹¤™ÍŒò²,#3XØýßý;0¹ô endstream endobj 247 0 obj << /Type /Page /Contents 248 0 R /Resources 246 0 R /MediaBox [0 0 612 792] /Parent 228 0 R >> endobj 249 0 obj << /D [247 0 R /XYZ 121.4 736.262 null] >> endobj 30 0 obj << /D [247 0 R /XYZ 122.4 250.966 null] >> endobj 246 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R >> /ProcSet [ /PDF /Text ] >> endobj 252 0 obj << /Length 2648 /Filter /FlateDecode >> stream xÚ}YmsÛFþî_¡ñÌÝQSKá;¥›éljS÷;mœdîz-®$Ö©ò%Núë‹ÀR”Ãö“° ‹Å°«—w'/.½h²œ/c?žÜ­'žïÏÃIâÇóÅ2˜Üe“_œÓEà˜:/Ò©ç´Ó™çTDÔÓY„N0_$áô×»_\îPOΣ8™¸¢cAÓ\×u^¾¾¹øáíùÏÿ¹ºyóOù¹}wwõöêçXëîêö*O^ßü~â‘wâõ–sÏM&«ÝÉ/¿º“Œ>ý8qçÁr1ybÁÝ$ˆ“¹OT1yòÓÉË¿Øb¼XÌà ó^š¯SáTe6…¾ï´Û´=#2 ˆ4ÂÛOg~B~XWõ.-WÊ­ÖøõœT†ä«P|ÕšL¾ì*š¸p2SˆHfÈ{{æ™2k„¹«š¶ø*ªRxbRW ÷â»ïàÚ×ÌóæË(ËWÕnŸ¦/¦Øˆ&ÿÃqPmà^¼ûð¯FÈUºšÒƶ¦™ÛÈÇKO=CFù4=3ë´+à? Å)~9Eþðâ34Û=Ïw2áÿnFèmÚˆxµoó]þGÚæØ$>µ]]ÂS +šÌi»žïÜmóF¸¹Î%¿ë”­ª}P'¬Õy'ëyó~ì”æ Dât©›3¡a~óV„òݾ®°—Ïð‡i„«–Yoùi+³Ùl”eW­»êx¶Ò¶ß•jÈ2•¯PX¤³±3oYlòB]âp,Á2vÓ »*õ;›Âj£¬ÏÓˆÖ®óô¡0ìŠe‚ì;“¯DÝ_N=ÏsÎß[Ý·È}úþþúûú4fëX@ÐÞ£„T׬ˆ$Öm1»¸¼>‡×ß¼ò ^¯_ñ×…~‡±Kè«ýU]‰3X4Œ§ÌŽ%t}²®ÕVò»O›F9œún€XŽÒr³¼6+IÖÁ,•õ ‰QU÷Ë<Š]äŒ8òÈp&0Æ[:¿uÈ­íœàˆíRg’¶bf ù°Ó\/åW|ܶ[Å@¶ÊßęޥbØ¿ĽRú.á@­•…´!»N›Ö µÛ³±£é!ÜC(æËPÖ•S’7Bš/fÕI•ÀH@G «çX=S&=& ƒØYxì˜>Yî[¿€;Àu ¸ëgY¡PÙŒ}O3l$±Bxc‘»/:êÕ)LÊË ñ½39ã§m¾‚®”AU²oˆªÉßDžð4­L@.|mŽpRù)ªr£Ÿ K•ªþ¦B$pžrÙIø¬î0§$g.–ÅÂ9ø6†­ÃïFÏ 3¥¡N‹B–øV± }JQÍ)t:¦üµÁ Ä.º*º,ÇvýeØGï2ü&–º”¿Dó[‡AÁŸÅ4m¨>ï\NÍñY«'Ç5 kÓP!±v¢G¬%#¾çL‡™"ØâF‚oL‰ÓAΚ–³:åÕ#çÆ¤5‚ß¡ˆhÒRj€ Vi)„Z)ƒmš=_d‡ wÒÁŒY¬óÛÖhÃz¨ç€N­çDªÊà™§±]Oø³u7·uÎ>¥Ež6tT¼¿0q~È7[»ÊQ\Œ˜Õt6S‚Ø“²3ˆ§ ]‚Ylé« ¶¦ØÃãñÂyèZ‘ݬVòñ°!âÚ  Ñà±8«00_V¦ir)”ÂêÊŒM'ò6_.&¤ÿ€LånìL–w¨?Ñ‚»NœP´$èkòM‰¶'¢w^ÿKò†è*Ö‚˜‚ â EZo؃ ùPIÏ  ÆñÁCÓ÷П¸½k8µP÷È×ÍéXÇû¡$ mGÖ`*HÜ~n¬Å>ˆûô×ù6†èÃû¯Mkv2èq2ÙÄ•xf®<‹º a!ðˆV‹"£ÍNZ ‰)rî8 uMyÀöW1úÜ[…ujÅ9Ñ%rë€oª,-5‚D¼m ý’—è%2¬»re+ï2²u•¨¬Öãíi-Êà#æsš5s”–£Òºä&3¼hcGÕE›Bº°×U5ŠBé;iΛ‹ ‘¦Û†çB[…¥Åý'ÁzväâÙ_hÁ?šhËyÄí])éÝ8à> endobj 253 0 obj << /D [251 0 R /XYZ 121.4 736.262 null] >> endobj 250 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 257 0 obj << /Length 1321 /Filter /FlateDecode >> stream xÚWKoÛ8¾ûW=Éh¥èiÉ{k“f‘¢²ˆÑ=´…!K´Í$ª$å$-òßw†¤Yñ:Þ^ìEÎ7o†£‹ÉÙ¥[sw> fÖbmùAàFVÌÜtZ‹Âúj™¦¡M8-³©oË©ãÛ >uÂ0²C7M¢é÷ŧ³ËÐè ƒÐ‘åis8æyž}yõùã-nŸ|\L~L|xïY~º¾—Xy5ùúݳ xõÉòÜpžZ÷jce…³Ä @*­ÛÉ_“ÿaþ,MÝ(L4tΪ&ãD¼CƒC;« -TÙ4HìGý°š:Aj³eUI2ý/Ú͆i^•”ÕY©C@«†³)ßá©HÿR¸:,Ajù‘F³ ô,'Š ¶És\üa\FþÀö0t“$ÒÛß—€Å‘ÍZÙ´åÐþæ…QI„~žj¡)³œz­õšÜ’ññÈ.('¹düQï­³ÊlJN¡ÓuOåv¤Í¹h<šëûî<޵¹¬Á8™À3®ÿß0v<³ÿY©7z®õͤŽi L3ðn‡,™û'P3ç$“•É­Iéš•¥ÊÖ=­7z õãÙÎêý‘ ÙÞ¹.d(÷!ûÃ0ߤ,ðÀ¼™Ê[š˜úÕp²¦On…8wðúoŸA$‚ؾÎp ér—mAôë5-; ƒˆ’š–èÁ0ì³}´e®¼Ê„ ­"áÔh¥‡Át¦êÐ"ÐC™*Õ9äú%¦¨Ë½“ç£*tD®^A©A=ÄÐ…&d¥0Ehòù¿c®¢Ð¡ü ž'½ÿ Öh¡$;RjñüíÛA0ºWºÅ΢ãê¶$Cì‚ðcº~Ü”åÛå©Ì6ËŠmIž\\Ï•åqõHŸÙ=ánéñh- W}é…3â÷-Whå‡ñÇØºŽ·Š(YÑmîÍ8…6W¦þrÂeÖ#ö“Šþ̰«˜&ÎTŸ(úöN»&mhý.m–K4ÿ¢¡*Õ¾}.n®ŒÏUøԲb4 ä¡axT¿€þªÂ%Ä•ÝG¡A¯j¨l(Ùí¨bõº–EÛÑzÍÉVѤ6 :"šy´i¼ÇJÀû³d«Ž«â±Z1#K}ÿv~ÝTIò¢Ay+í6ŠG|8ˆ²Õ$}hÁáJÕŽìååïl÷¢ynHM¸!ªnØ]ƒýæÅžƒê‰úàÑ:/rW>@äçóˆˆKgÚ¯óRå=¿3Üd•*=΄P·œ²`Kò;1°Á¥xö4 „Ì`¤Q6ì9 ëTHšï©ÆÝêT§ü¤šÕn8¼ÂÕ•Œs•épÝÅ]>ßð™9Ÿgµ>±RW é.!K3îÑMÍ8)Nî ¤ëŠPƒþ¸C2ÄÉ ;ߌaNàÚUÝ_çi§Twª «vóZܵ¾È7b¹[av÷2ðE @² Òº€!iC×çPñ‹ú¼á¤sd¤[(”œÐk h—Ø÷ݳ“„ý Z쪣GÜÑÆ¡à0 Ò}ìòR ù“[Œ›À󌃖+³A¥²ü9×ׯ%`ˆ#ê^œ.0…›¾Î6ÅBz7š‰Õ„¡*N£Ýq¡¦Öâ<]h%ø…¤.ê6'ÇrU‘–Ÿ¤ðñæÅ`²ùR âî³ñ_~¾õß endstream endobj 256 0 obj << /Type /Page /Contents 257 0 R /Resources 255 0 R /MediaBox [0 0 612 792] /Parent 254 0 R >> endobj 258 0 obj << /D [256 0 R /XYZ 121.4 736.262 null] >> endobj 34 0 obj << /D [256 0 R /XYZ 122.4 671.491 null] >> endobj 255 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 261 0 obj << /Length 1943 /Filter /FlateDecode >> stream xÚ¥XKsÛ6¾ûWh| 5­h_Ó“£Ø3NÜFjÚNÓñP$d¡¥H•:žLþ{w±EÉlk·'.Àb±ûí|¹<9»ôƒIâ&! 'ËõÄgÌ“ˆ…nœðÉ2Ÿüâ|˜ÆÜ‘µ*Ò©ï´Ó™ïT@ÔÓçÂán‰é¯Ë7g—ÜÈaaâúlâ‘߃mžç9ï>\½Ÿ²Ø¹y÷öâÝ7ž\,Oþ8ña©7ñûó¹ë{Ñ$Ûžüò«7ÉaêÍÄsyOîõÂ턇‘‹ò‹Éâäû“—xî/"¸ËýpƱ+xDz|ÞÕr­>}mD˜DÎÙÙt°À¹TeZ)?ɬkÓU!iüÑ ¼û3¼õlsÄLë»n+Ë&}¼è1ó}7 ‚Ãsnoqãùõµ›á{ŒõG^«UÖ4¨ÖFna´øöÆ­EÚÊܬYý&³¶ù§ã>oqj²/n…ƒ+^•­¬qz+sR =»d1XÍå"dhÀóÜ 8°é÷ŽäþÀ‘ 8td{Eׯn¯¯^¾??MBççÛïðs>Mg `zMûÈ„›xp¼¸‰ çÓÌÝÉÌ“ÑàZ•S9ݧ³›qþœ!xH‘œfߨ‘pR¦Öª¼#þý&miO®j°CU+Ùc“¢Ô?§z›æ4›´F_àF €X0tÐ|4@q›ê$BÒý£ÇE!v±³Ü(8ˆG¾³CŸô‘µ!f³©º"'Z•YÑå’‹‡¦•Û9 ÒR/a@ žÄ­Ú :šÄʸ¦B}‡Ü­gK)s˜ÁZ…sîÔ¶m«¶h:wÄɳÞKÀcfûÍË7óó)gÎüõÅÓ{³kU!XÀ„Ç{‡e ͆‡74‘Ò'K3¼ñF{UMß\5m­VŠ#ή®îêtKƒ¶2Ì"Í$’ ÌK¬u]i+¶FàÚ9b!° %öôBü‚Õ‰˜õQâÌ«íN²— °âå4ZO\$?¥Û]!¿†Qâ;§Ö9ö^FÔGµLóýè¾V­<ÕÛ¼^ØiÖï;uǰwµF §k´ÁDCeâÜUKÌ{b‘g⌜‚Õ "4Hf™Ü„#•…žpnéá¶ÊLï5þ D—”cvÖVE(æ•>=ô«Ý”’‹qn]™bÔnªÆ¬7nož ÚÅÏ‹åÅÛùÓðúJBÆÍ07ƒs#¸Ï Æ™pÃRƒ(µ¦¯‘|{õn~ýë ³¬>œ„Üø *mMòe¥½‚©ZÌ"p*ù5ÄàðuvkµCcŠŸ¨ð‘1&¬·Ùî†YEaž*Qˆ –’NtaZ ŽjŒ€Žôþq0稣0 ̹WXôpaVm%QŒ[šM‰‘ËuÚF`5ȸæè¶¹Ý©s*’pAœ¹ëj#_g´c70P(íûŸ–€Æ)PÒ†ÅyŽ™ÿ¹p»…z¨åÀ]yw< îÐ]jMœch!ªNðLž³8t“Yh@€-I¹³Ñ8<‘u±°¤Ú ³3êaµÜW(#Ó;¬f¿+­ ÔÔ}q´ß~Ç.­[SüÖ­-sýlž6[4÷S#Ø,ÔjöÙuÝ/˜Hƒa<àôG*«1ª¨Ãñ ãĬJéób›þ®»„4Æ“ñKõˆþ’tÒAôh 0ˆõ©à’Ë‚ƒ0``á#ú6v€ju0#QÑWQšìt˜qk$ 3O!pB AoN±¢»FmÜÇ ?ˆÁ1¥BžŶ‡á ŽšÂÄd¶¢ˆþ· Œt”7”ýÿWÎúéöòZw-ß.žŒ#Ã,y®È44†¹ ½3“­n89<R}1`ÕòNQ—ÆŒ÷`ÚÜŸ»´iøÎ·ó9MÞodI¬U§Š³÷àû:º9°Ø¶ÒÇä²@, á,Ðöz­f.w="·©``ëhK®2i`d¼YÑ÷t¶k7ؾœ>Û¶T>ɺ ÂFJï¡y²A Ê_ ¨üaG¡Lí®m´52wCà \GÇM LG9Ë‹z%(±âF«Ãh¾”Â0¡Rö¥0d¶eJaH¥>û0„ÁA) GK!îl­ÔaàÃPÇ•oCÏ©ƒ_Ë6f055O®Å”jÐc.Çû>è̼vžS䞘ط€IØ`lK ‡€~Ö¿èåfqûû-òWÍ®ÑÂTjæÌÓ̉è‰Ã^#B±Wh6Þ§XôÀ _£',z€2è‰{Ǻ\!#·­¢L€(>z.÷8B­•?ÄH58ŠƒÄQ0Š#Æ#“ÊõÓ;‚Ò=¢XÑ›‡í:ªË0¢k"eq„~Ðc>ó×ÿª験-n_ß¼}N‚M¶Zó#š01©˜ Š³Çih¸vñPV;ÈE4ú€æš/¬˜Ã–ÒøXþ¶—\çá³}ó‚C8N6í šÑÏbøj 8ò²ŽÛ¾M`H¥ES¥:u¥•‚žXÐ`•6²P¥9 –£P¿«eÓôO=ÔÞt?ànä‹ d[ðŒùÁÇBûKñ/vK endstream endobj 260 0 obj << /Type /Page /Contents 261 0 R /Resources 259 0 R /MediaBox [0 0 612 792] /Parent 254 0 R >> endobj 262 0 obj << /D [260 0 R /XYZ 121.4 736.262 null] >> endobj 38 0 obj << /D [260 0 R /XYZ 122.4 647.304 null] >> endobj 259 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 265 0 obj << /Length 1819 /Filter /FlateDecode >> stream xÚXmoã6þž_a¤œ´]sE‰zÛÞ°›î¶)ö¥ÍÝ" %Úf£W¢â‡ûïáPŠœ¸Ý~"5$‡3Ï<3CûõêìÅ[/r–'a²Xm< ™X¤a²¼¹X]~øÏGÞê#_ZÎÞ¬Î~;ãp,Xðɘˆñ ]õÙÏ¿‹–~X,ʳÅÁn¬Q’²fÕâÓÙOg¯Ñ«0âU’eLD©óêÍÕå»W~ž€ W7¯/?G`„‚åA²Xò˜Å© s—)À‘^™ç0ã™×ïýe˜zªÐŸƒH¨×¹'Ú'+£ºF}燙§h±‘µ¢åÖ©3;·h BÛ´‰Öº‘Ý=Ê™¿LDâ½—¨ëÞ­ÂíNqà ½*i¶Óà€²äœåqBæ—j=l·ºÙì²)iÒ«Jf’;¥ï9øèjh¥FÑP½¯IÚ=mîäÃùþ¾7ªvº]•=#|²œÎŸèv˜ï¾}ý¥Àĉ"2T!U!>‘pÐFQîm]û|ô9÷LK'º¡!ÁaG^‚ƒ½s%gÞç Œ·åš¤íÞè¶yNýP F;Ú'{’ž—eyIà]½7­9 Œ3¿w(:•Ï ³y~î/Ó,&íom+ÆÙ5õÛƒì!jŸ;pmÑÄMÏ`ö ÷C¤SÀ“njz#£]Xq/BcÝŽ¹0éûP5èÆ$âÆ¸I̽êâ(ú7 Á7¶qˆÉ‹zRãÎAl&Bá7§ì?Ô¨€²gã(iHÄr­b°Nm‘tVkëâ  ¸¾‰îl×–¡önܯû~ãˆã/Œ$o3´|„qxÀxÿmÇÙŒ{{gˆ}Ï,/Ûam‰…¯AkÁ†,¼·ÍÓ):è~ÇNEÙwûÂÆàB`k義ðiD_ÿ{pkÎ×÷4þã!”º™¯ÝZÂò<9n2C×<0,A3jˆÓ—áñw§,ø¦?¹òüXXKSìì­\$L@Y>‹ƒí.8ûdÚ]Œ*ÕXEá'xItúÿ§Õ͌؈Ý$ݶpæ;i}xölZº›cüg0¹üUåK<þ+°ìU·íñ¦Ù ¹‡¹ÏBv¥jU¯ Dâ ³íOù3•—•r¤½¦²dጠ®üSè±:§"”–¥€f˜³,Ëè¢0ÿ"ù0ÿà endstream endobj 264 0 obj << /Type /Page /Contents 265 0 R /Resources 263 0 R /MediaBox [0 0 612 792] /Parent 254 0 R >> endobj 266 0 obj << /D [264 0 R /XYZ 121.4 736.262 null] >> endobj 42 0 obj << /D [264 0 R /XYZ 122.4 516.9 null] >> endobj 263 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F28 142 0 R /F32 175 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 269 0 obj << /Length 1465 /Filter /FlateDecode >> stream xÚ­WÝÛ6 Ï_á= uÐÅgY¶åôë¡·ë°¢½n»´EÑ_¬$Fe+³ìËÃþ÷‘¢ì|œ‹uÃQ´HñãGRy¾˜œ½`‰7æi”z‹•Ç¢(ˆ=¥A6çÞ¢ð>úï¦÷eSª|Êüv:c¾¢™Î8}d"ž~^¼<{ÁÃ=Q˜sžy!é`È…a蟿¹¼¼8_ü|ùÊsñ†Ö«W‹‹×ç¨ir±˜ü>a zl0ˆ,Þ²š|üz|zé…ŸgÞά<žŠ JyW“_'ÏÑ3Î=Ë’€Ås/Ͳ æ‚ìjõvö¬‘FZ¿®Õt–D±ÿ—ÄÃ*DìŸã !at%‰*ëm×4®O .l»M©Ü¡Oa~÷ŽB×´²xôh­Ûe]š ~„ÃÿÓª‹Â`ÎRoÆX0OÒY®ö «¼¬¯Û²7ä-,Õ#ŽõìݾFƒŽÝfà6KD2¸ý£Ì‘óÄPBÚgcêÿêãa™é}Ûí·ÊÈ€ïïûð´7ê›ÝZª/Ntï`cŸÅ…^ãë>;K¥—_¾Õ™äÿp&ýÏÎ$ÿ]Ô­y›+´¬‡D$æÙ‘ øÞå­‹G¥ ë†s|©;‡ƒ'Ohµ7Üãʺ°Wžÿ7™Då´€$TÐØUgþǧF/èož&ÀcApŸô+ñ9¬Rkýª¬ïHÀ‘}èÚÝeʪSy[Öë1“ñ|}nD…‹îÖ¬Mi\€þÈ«mÁBKS?p!\÷]f#›‹–‘Û ©dŸ4ðãñˆëéë'~³ ãü8—Æ<G׃áçã’AÐþ1‹öKíˆ]S¶­¬éXîä*YM£Ì¿¨d>zƒo§ d¿)ó% ±ôŠÎ·wÒ(·›Fb«´ÕRtJBªEûp0én¦¹Rˆ¼Tò¬¦{Õ”ÒìÒÍèT%ÛÓO§[Mz)*#…½AR˜ƒÔ¿Aÿ­ôƸ Þ ¨Ñî;‚×¥F ôš­Ñ#ÎPT¢‰Ç”¥Ä<2h:®»&ß"•úÝ–8yQ½£ÍÕi!=ÂaÀcc<¸‡67Š´/Qö‹ù|e¡Ë;èÀ7ç2ð•P£Ówc¾Ð$@˜€0e‹§‚NÇ1<=²ƒg;}6¤)=Rqøl87Õ¹ÿôˆ‰RÀY‰h‰@ßRÛÝðZbÚøã9(2â(€"Zß"AXhöé\NÛ«óë×o~|ûê" öÂvQɽ)[Õö˜¢lä²Uwôn*­½­ðËÝcʦöœ6µlUiÚ ×/©9c¤kA8{ i -È"4ë‘,|“WŽÚ–µm÷Hç§Çް„ŒÁCzh@‚8àdW¶:â„3¥•+ü¯ô×ÖâwKí„ài3&|ÊGcY =Àî—²6IÛ^„9¸5 ]9ñ›²u)]Ú—ÝžAØ×Xâ™`ƒÎÄf<T¸{ve!ïkñ£siãÑuû'>·H7Âç|–ÆD’r¤H9FîÈTüd–×7¶ÜYÝÐz«ú›Òo"n!]ëãL¶j-‰é±ùS%µžAö ‡p/äж… ¸B&߃ }ÛR¤BêþbˆlØ›+Ð\+—Ú†üÖYê¤lçÌ|¶NŒÚ +„Ö±¡×ô@9õšVZc±7² ÊØÁ€•DR@´1% ¥àpà–Ë«~*Ñ0‹"~8• qì¬D¢Ö-Û®g …‰›e??²×uøB«-gÜ®äд@”O'¶òðcgl‘¤>uz $bôKÑ– P ›N ©ÁÄld%iïú\sçb…<;•u§ Ú6²è–î“ÃU³ÒM•×=÷†¦¥aÙU7)QšØêDV•¯ë²í0h/YCa6àÎè(ëÿ þ PM½– endstream endobj 268 0 obj << /Type /Page /Contents 269 0 R /Resources 267 0 R /MediaBox [0 0 612 792] /Parent 254 0 R >> endobj 270 0 obj << /D [268 0 R /XYZ 121.4 736.262 null] >> endobj 46 0 obj << /D [268 0 R /XYZ 122.4 344.661 null] >> endobj 267 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R >> /ProcSet [ /PDF /Text ] >> endobj 273 0 obj << /Length 1252 /Filter /FlateDecode >> stream xÚWëOÛHÿž¿ÂâŠÎ‰ë}ØŽ¯ê‡BE%Z¢J§R!co`U?r¶‰N÷¿ßÌÎ:¯sEÕ/dvwÞó›ó~6x}Î'öâ‡Îlî0Î=éD<ô&±pf™óÕý2œWÕ:O†Ìm‡cæV@ÔñÒÞ$’Ão³¯Ï…¿«G0/dÒñI çû¾{vq==¡¬p¯®‡|â~þpýîòòâÓº¼ø4›^Ÿcî»!ÜÓ)Ýßúvu? Í ¦³Áßú}‡m¼ó#'-_¿ùNOßñÄy6Œ…#ÂÈã@åÎÍàÏÁ{ ŸO&=!C¾?œD^ðßÙŽï\Jô]øä;$ƒÜç2ظÏ9¸/˜qùÜ?Ⱥï@Œ^½”qén³\,@çÄ­ê¶¡«›uÓª…@RÉêžÎt­Ò–諺z¨“¢Ð¥y”îE‰n)gî=2é3Ϻ¡ÇÝl¨lD–UK¯d Ø«Z?èÓ™ï¹Ë7ë²Z4ëf\‘›€70èY\ñò®T±7‘$\Àît•‹\ý ¶Bik 9ýë7Ý̦—§tPV9$÷&ò ÿ(ˆOHâ˜#Oì®ñ¾Z’À3J¼Ê¬ŠuB;Å·Ó“zœ/Ë´ÕUÙн&luÆ}‰C (a‹eK„.i4TËÚ{úÃæíΆÀƒ3Ÿt´·¸¶Øt˜/™äÝè²Uª¦C’eD Jtiœø?Ó¨»\m†GGá°å»G|½éâÜs¯Ô­Nr˦K†«‹d7%¯2Ý,òdm`‹ŽW$vBV»ã[ú9^Yï˜ýå£Ð˜ Œ8º¶uoÜgY•Y›4ß{08îKùìQa¥|á&óS |¾3zZXZ?ÞN•¤­jyÖyNi­ ß­"ººõ…Ìí•QP¸»;[huûHÏÔ@,ꪅ¶Ü­ ¥ŠX…=3&MŒy Ì(ªqä¸ïÅ,Ü_­ ê-¦zñÔ¨=DÊa¦û,cê æ8…Ì#á6é]‘èÒKÍ‹¶yÃG´ÉÆûÚ£ªé¡cÄN‹¤i°ë‘ÆÞݳuPB¼J«¢03s]ÂtéépSpÑ àüŽÑ¨Ëíú=Û°ýt~Óeš/3e»¾yÊx@ÉQŸ'ì_TÈnÕ+òKe%òú©U»ì@’œÜ¿!ê߾Ͱ-}Ï~°ËÎгa,]hÔ×çHlFï‹«ãÇb Ñ\fØ ‘´ÅÂÚ—f&­}­èzÈì–g:.óa°'ß$EG¥Èú¨ºs§D ÃTÛuo¶'ª†|÷Ô£±Y’mw|!D!ìAX(ŽoËF‘ÐOÖ›çI=nôC‰÷†~»` à Ñì}fèTšxÌ= ŒµgÂì|þØwß-8èFÛ º¥&(0øecßï7ó ªI;Ð2ï'—!|`ýÒ2¼eB¾*Ö×ÐÕ/o1ÚS¨Ïî*|{œu ɪê–ÐÞ:ü·!ä^,„3–‘'ý˜Ìñ¸ûRÿ«Í) endstream endobj 272 0 obj << /Type /Page /Contents 273 0 R /Resources 271 0 R /MediaBox [0 0 612 792] /Parent 254 0 R >> endobj 274 0 obj << /D [272 0 R /XYZ 121.4 736.262 null] >> endobj 50 0 obj << /D [272 0 R /XYZ 122.4 698.4 null] >> endobj 276 0 obj << /D [272 0 R /XYZ 122.4 581.471 null] >> endobj 277 0 obj << /D [272 0 R /XYZ 122.4 223.7 null] >> endobj 271 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F35 275 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 280 0 obj << /Length 1564 /Filter /FlateDecode >> stream xÚ­WmoÓHþž_aõ>àˆÆõÚNì€î$ZÚRt®ø¨rì ±p¼Á/-ý÷7o›¸‘‘àtŸ¼;;;;ó̳3ëÓÅèäBM¹7Ÿ3g±rTx‘3/™‡Î"w>¹ÇIèêº(Ó±rÛñD¹õx†‘zI¿,Þž\„~ßN¨¼™ŠŸm¨öù¾ï¾¾º9?[àÞÐýp3÷ýåÍ«wï®®/Yxu½8¿¹+¥ÜWã vÏÎYþÙŸú¯?\ÁGáq£óÅèûH}ßQ;¯COù±“mFŸ¾øNKoß ç‰ó@Š'œÅ^£Ò¹ý3:ýIø³$ñ¢0f×/MQ}’Øm׉k`T³,G@ Dgmaªãñ$ò•ûˆ¾›Žu²´â}úÇv<Á…ºeÁ[cH›o ¯5fwê#KÄNì.Á X³ÒŽ/uÎÓUm6ˆD9QÊ›O§ÇÙóç/$QªñÔ›%±3 æžÏYÜ$§ÁÔ=Ð'gGæÔ똤셱[[“ß©ü˜PT¶`+aÝ/3ûjb¦TÒk} lt‹lž&–Í¡m¶‡š¹©4‹»†ûyh@;-ð3­s[ÔžJÈ15÷9ò [>0ÉYVô jè9DbàÄÈñ6€½Ê€ói-w «ŠÎ½]WÑj@oû‘n¶Te£hF4D)ùEÌJ}X—<} ú@€ÒHÜËUº‘ÑQÞµG¬GŪ „Ç›B±WºÖUF¬WážÂ°fŸ[0d> endobj 281 0 obj << /D [279 0 R /XYZ 121.4 736.262 null] >> endobj 278 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 285 0 obj << /Length 1298 /Filter /FlateDecode >> stream xÚ­WßoÛ6~÷_!mA§±"Š’%·ØCëØ 4ëbc/mѩӯJrcØÿ¾;¥È‰†eØ^â»ãñîøÝñó~;:[qßšÛó™;³¶;‹»®íY;³Ã¹°¶‰õ™ý: “•J£ gÍdÊYB5™ á1a‡7ùºýp¶N?ŽàöŒ{–C1¸€}Žã°óõÕr±Å½‚}ºš¸!ûùâêÝÇëË 2®/·Ë«Õ„sÎÞMÜ€-–dÿâøÎù§5üpL7ZnG?Fâ;ïª6w+ÎFŸ¿:VK,Çóкӎ™%fí‚”Z›Ñ/£÷x|á[œÛsßwÎ? CÛÕY¡„Àgçª.ÁÙ [Mæ‚íó¸QE^G`:ÖT@~ï9@FiZ w5÷®RʯIy‘PjÀã@–TýŽÞ’´]W„V÷»Vÿß)œ‰SìŒwu½Ï$JM{šÂLPÔ¨zwhKÒ*l›™:ºWxævè=ºR €iä}C¸RÞÿq¥ÜÙœÕû’p‚Ñ­É´^.—(…ì± T° <¥.ýV·-ÞL=Wviƒjo…ÄŸŒ›¸ÁŒ¸ôänô‹rªM¢ø&ªNz!õ,Ç”Oc_‚yUÙ¦_÷’ _B NY5ÚW3\$°ò_V¶SH|¸ý¸0Ñ8~;ÄÀ]G°yqtg˜2vÝÃÑ'^À­Ãqäl CæWT ”a®ÿ+]¢Ú‹N ½fÏŽÓ”ðjvš†I;†tlÌiD;@ûI»_Âjyqˆ™0u;¥G/ Ýbj/g†±Rz¡Fm™í®d³¯ò>¨Æùè”þ?ÉO¦µü'@úq¡~òa)Xz¹n¤ú`ò ´õ£3´×¥ ¢ûOæ/Ö‰€¼ endstream endobj 284 0 obj << /Type /Page /Contents 285 0 R /Resources 283 0 R /MediaBox [0 0 612 792] /Parent 282 0 R >> endobj 286 0 obj << /D [284 0 R /XYZ 121.4 736.262 null] >> endobj 287 0 obj << /D [284 0 R /XYZ 122.4 679.68 null] >> endobj 288 0 obj << /D [284 0 R /XYZ 122.4 520.165 null] >> endobj 283 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F35 275 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 291 0 obj << /Length 2103 /Filter /FlateDecode >> stream xÚXëÛ6ÿ¾…?PX+zKƤ‰u$¹­oïC[¸½B=*JÙä¿ï¼hÙ[á¶_¬áçñ›¡<ܼ¹ ÓÕÖßfQ¶:WaùÉ*2¿ØÆ«CµúÕ{X±§‡Ú¨uèëMèu@ ëM'^ìy²þýðó›»8¸”d~…«€e„ ì ‚À{ØÝïïöïÞ®‹Ä;ì?}d)Ÿï×Qá}z·{ÿŸû·{û‡ÝýÝ: Cï-ξÛñÚß‚4xø¼‡OˆçÞì7ÜàAÁ*<«ûa¯Êææ×߃US?¯?Þ«gZجâ,÷# Ìê—›ßüˆvˆÓUúÛ4fCdEá'qΗxÿy*ä©÷“V•˜ÞÛΨ±îZ6•1ƒÕ&†c“× ™™×Uj‹tê'ÍÌýn·c–U[©¡bþIÀ™ß‚81¼3óìT¢­N<¥÷kÕ×¾0ëWŒO)¯{5¨QŽ­Û Þõg‹°þ¥™*\·®êA—c7|G?Þ®7)xé«íXñ<9I®û¯{ÀA7ðì/4¢ ½G?úÌþïI·L•]ÓצnŸxØtvdJõ½©A\I&·KZþCìÃ[<áðéþYŸoê–ôãÔŒ³Ì{ÆÉn22|\o¢ÜÓ<;Ñ—œgh81r{5ž˜­L‡z’¸š™¼iA·¶e0Žó×ôD›¤¹÷S‡|ÒS¥ßá÷¬…”X ÌÒbP=±üt EÛ¨+^ØttÁJ›kËe¬ÝEd€;;¸ÃÀ¤­œ™@T7Xæ=Ÿês¨Áð¤pÀ2¶×²ŸïЊ°s0Âb‰MÝys°Ãhp<M¼`Ùª†e±4ßî›ä`åÞ(L‹–KCñ(ÌŸCè9¢aXxö$aSm'ò0>è~8?U¼­†Ü~7Íz^ϦúB«¦~é < ‘ýh4c`¥ñòmMÁî Ì^ÁBÌÖ/–ðyz4pÓÝz›xS[žåÿƒÓ¾µ#  ìÅD=ò—ãè[O¡Ó #\í¸¥ ô–—*c;¦f˜1á‘Õ;½€>:DÊE áIjмΚúéDF4ß—¬uT 0'Cì=N#WY ­åÁlN±]T¬Âîœ9Û% Ô¹â¢F…—5jIBˆ„5 y®FEÔ¨8Ä…šÆ¡Ÿ¦ ¨›ûÛ8bé/ÊÖ glÜ–8öóFž›Èí|fNµu§¸ «Æt˜NÏ–ÇukYMþ¼]r’þ¦šºUžŠŒ2ö%f{ÅŒG”ÿiNE wÌ5¬êÆð€êN×M£«꺑ýÐõê‰û7–C¥HI7Pð¿Å¬%œ_Týg×#hŠÖAoñеñ¹í$ô‡-ç ÊÄÑšF'i9„1‡?Œæð‡A¹&„áSï#µJ”Ô×rÒ3*$µ9H®e@;.56\Î\áâ܇íTŸ¸‹'^c¿{¹I™*MGÇ2F‰˜êIãÍ©ªÅÒ3Ÿ’¢ˆX7âüE›³Dúý%/Iæ7ê y,GœÈy0ô˜‡#^”¢¹t2|)¼pýÐM€¢ZäÁýÝh¶yH–—Q(ƒ±`t²üœ995:ÀâÌYPúºƒ|Y´KÕ ôwíq²9¶k„µ7âé–Í£­(A ”ÅJAV)…Çù‚FP¢fqÒ€×— èc7jv8*»á’ézüA\|.‡; *PÉ’¦7Úá9Ì"Ènc˜R†Z|…¶ünÝ!î5ƒg¦¹Q‚ÓÌÅÓ`pš*­ÊÍR&` p҂(TȺ,¥8v7Æ}Ü*3ÐG‡¯8…‰cÇa*ÇiÐit‹F'J2  ÷¿À¿z¡ÜÏ“­[Ðp¦U“Y§~¿*í¼€ »qyå1¥'ÞÃ=Ø6Ñ6÷³ ¾_v|šP Q!¥wr.3 9±'àÐ}™z^B/É;_Œ¾‘Ž›r9òw˜8>jŠzdè?¦zàR »ÝºÇsx[7ò,uÊS[ àz"r~ñ©Á^r}8T[h4èÙ‘'ð`çi¤Ïž¶¼ˆ›˜Ð.Vä¡™'s~ä®…Èy¦b>ˆjêH´ÌÈ̺]Ò—5îRL½Ñ×íßå¥þÆcéÁý³ƒ&…ý7Ø>ÚJâD[ç‹s3ƒ<ÍÒ0¾Ò@Ò“g®ßÈÈ  6B7jøBSÕ<·q ªH#‹áäóM½ÛyÑ"â°>Îkðé»ôv¢6K&[ÓŸA67.ë¸ð§¨€º¾ÃÕ&«GéFú°º´¼ŠÊ þût”ïèÊþE?D µ®â‹|Ë ¿CÕjÖ^dˆ,ÈŒëa^øðâÛô¤¹ü—GîÏÃ?ÁŒè endstream endobj 290 0 obj << /Type /Page /Contents 291 0 R /Resources 289 0 R /MediaBox [0 0 612 792] /Parent 282 0 R >> endobj 292 0 obj << /D [290 0 R /XYZ 121.4 736.262 null] >> endobj 293 0 obj << /D [290 0 R /XYZ 122.4 682.004 null] >> endobj 294 0 obj << /D [290 0 R /XYZ 122.4 540.09 null] >> endobj 54 0 obj << /D [290 0 R /XYZ 122.4 487.279 null] >> endobj 295 0 obj << /D [290 0 R /XYZ 122.4 155.786 null] >> endobj 289 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F35 275 0 R /F28 142 0 R /F11 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 298 0 obj << /Length 2008 /Filter /FlateDecode >> stream xÚ…XmoãÆþî_ÁHA9§5ÉåëhÏÈ¡|çKí^Qä&WŠT¸¤£ÈÏÌÎ,EÙtûEäîÌÎÎË3/Ô‡û³Ë~äd"‹ƒØ¹_;~ˆÐI‚X¤™tîKçg÷ë"•®êª:_øn¿Xún /Ýb)eèJ‘&áâ—û/?Jo"'‰ˆ’ÌñH†Á9ÏóÜ«.‚Ô½½»ÃãÒ½ºýôåúæïxÃýõígtöÃýÙog>œôÔG ßKœbwöó/žSéGÇ2KGøsdœˆÞjçîì§³h˜ô§†…RH?vâ4¡LH­][µZ,£ rûwx»ãGXœ¥ï‹,Šˆ­SâéT^î€ß’Ƚ¼8¯ômGÔýðP£{ªbµ†íUW^\’Pïy]Õ+#Ћ¼£@ãã‰ÐQà#íýí°ï[­Ê +_˜‹…}7B÷×|ûrÎ&Õ”l½ Þ –'2ðÕR ØW÷[ÕÁm‚˜Ó‹ïîÍ"HÜ'¢´M]5ÌÕà™*¯5ñæMIû‹%@ å_ÐUÕö<ŸÝò _¿\ËZ< =+Àlê÷|·¯™µßæ–\Jk¥ç|O’z¹Õ~ø£ÑøÞuIlÄ¥ÞZY€ÄÌ'QæT[c+0rU ?¶ª@*FÄ£¨ ÏéqØWÿNTÜ,·L~‰äÕÖÐW(äiÕä;Å’¼/7׫ÿ¹ÿ!½@¹ç½ Pž¿9±6&?ÿëæÙÞ!*·ZãSº(ç/p­Å‹Ñ ªëÚNˆô÷"m£{b0Vmóî‚–¨ñ¼§ Ô}£ú•î;¼–Ÿâ%žË7ÎæÄ¾«”ݯñÜù'Â¥'Æoz»X†aè~§³á4¿AX¥¶à43°E–#Ã9û…_^Òó‹Q"q{Mësö-¸i=Yf‘È‚s„Ý­Whÿ!¯Ä´¢T<ÌÚ{ë¶Ûå=åï{zÀéëÆ¤ÿ×¼~7PëßCŽ\õ``~}CþzøŸfç~µ‡éP»æÛß’Âß!µüæË°9g¹F)"ÔFuì:ªZ—Ä‚¾ë9•QÊyg|0úïXU¦ZýA® R(ÐB†q€¾ÍÃдcóð©yHŸ›GœŒÍ# Ææñ,â HJ‘$áÿëd€\=ì÷T:~Ä}×jlK`+Úݾ‚ê¶!v’¬^•´U f·TqêCŬ4Q*¸Qêòº~¢¥A‰V œ%ô-=»¡!Öx9PÛz¤ŸQÝôS7§å åÒð;-õ“†6CïT†áeßÙ+¾úþ{"LQ´ä Æ³£ËŠ^Qå©ÿ®š²ÅDzÔâ¤prå¼"Ç™ukÞWx6€P’êT[k*Ìš(ÃžŽ —ÌsK[˜TC޲úæI }ŠJ ±ÝÞ)‘E{C…_­sÌݬÔ#õ:|}B3Úa.Páºp3tdlŸ¸%žà†½,°ˆÛV÷ôv S‚4mH}¢¾D ðM`8еÀ;æZ`ÞA ¡ 7Þ‰;üܳ°uRõiìö!ó«º&z§ÖX`ª/Xv>Î÷¾œ–¼97S£zÆ„‚%˜ŽpéQ*f[˜¸š­@·…q³hm„8¦Q“äšžÈ`“p¢yÜVSnÓ¦@"„²´ä͆6O2—´˜Iàokëʘ×ᮥBÍ7“9׃ÆBFuœEÔjXV:/‹(2žpä¦`H3'à[¾‡øäÖܱÔ¹! )ê¡T—Ô(¹·Ú8²{‡±LîÀJ«z½,U¯ Þ0yl@”Œ5tÇFBY0XKl*b9±¨Nl2bÄ SBà¡Ìsåœ0à%3@AvLB9Œ}|6A(ÉâI>Mz¥LŽ ð½ÙÒÛC UV4ÔÇ\×›¼±û)ÿÕxoÀ)z}c¾d¥MˆÙ쀆¿"­†3u' J»çöµ>]qâž4Ô|<þ¼“IÊž)÷ØO |áD`Çp™ øªãŽœ—ŠªB¹Ÿ¯–wæä­?™ ­¿Ö¯ÌáŒ÷,é®Úõ4áHâ“ù¶_ö;'o©tµi4q>Vý–¶7EÁKãÓùó3GÈåXè2úÙdÓ•nà[¶5`‡ž“¹¦¼U¦ºa¶™¸j"¡f¾Ë&à±gvhêF‰=~;;RÕ8ÃFQèÞ6ÊŠk®Ž—5?I|OÁ+Ò4% `|à¿Øþâ«Cì endstream endobj 297 0 obj << /Type /Page /Contents 298 0 R /Resources 296 0 R /MediaBox [0 0 612 792] /Parent 282 0 R >> endobj 299 0 obj << /D [297 0 R /XYZ 121.4 736.262 null] >> endobj 58 0 obj << /D [297 0 R /XYZ 122.4 465.4 null] >> endobj 301 0 obj << /D [297 0 R /XYZ 122.4 127.142 null] >> endobj 296 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F14 300 0 R /F28 142 0 R /F35 275 0 R >> /ProcSet [ /PDF /Text ] >> endobj 304 0 obj << /Length 1836 /Filter /FlateDecode >> stream xÚíXYoÜ6~÷¯òbm‘e$RgQ´pœ¸q8h½I 8ÆZ–¸k6:¶:ìøßw†CÊ»%q€}铆äp4ç7#=_<;ñC'eiÄ#g±r|ÎYàÄx"ȳ^55ퟪ—l6Dâ~ðBï•Zß”÷tÖ¢O%ø4oª9z,™û>KÁZ×JÖ…,Üóí1ø$õéô]§êõlÎy€ª!jiŸP,Ƭڔfµ*eGÌÙ5<Á,ÔžL“yY)»jÊŽc÷NzIˆZVY]Ë*K¢®U{jT 9òÜÐÚ„µ˜D*ó$—D®n s2o Èc¿âm6áÉùè‘Æ£ÔB,úÓ85[ËeBG]Ì©¢heqc Ó”qÞšxiÌâ ± $ÁyB (!ç–õç/ÈJ-ë#À#Mûòæqÿ[ºòPÌ„?fi}M+OÅ–ã‚ÔšO‰ X$¢E¡øñ ]^^N>Æ»Õñ‚`Z¡abŒã>&íjÜFBW»Èp„»c¤iТ­Ð³·ác È³¶°+lÑHþpH„e<Ä)Èw9¤  ©Ù}h1SÃàC8A!<›Jõ0£é"½AUD›Õh˜f2ÌÚëšÒ0ÂD#ø…`! øÿ#Ø7"9 `‚Cྀ`øy˜þFA…b픂Î1¡Í×,¬¶†ZüϦôa7%ÅŒ¸‡[ù¡oX¨ÐrôðW†þJ(ˆ°)ľ 0Ðåì';H(¸7îùñöÁ®ÆØÜÅ>dר'û|ó¿ žæÃ#ü%välìþ@Šy{âRë=eÄí`Zæ‡ðeê •”%IBöÑ/ ü÷[f+ì endstream endobj 303 0 obj << /Type /Page /Contents 304 0 R /Resources 302 0 R /MediaBox [0 0 612 792] /Parent 282 0 R >> endobj 305 0 obj << /D [303 0 R /XYZ 121.4 736.262 null] >> endobj 62 0 obj << /D [303 0 R /XYZ 122.4 484.924 null] >> endobj 302 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F28 142 0 R /F29 144 0 R /F11 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 308 0 obj << /Length 1869 /Filter /FlateDecode >> stream xÚµXësÔ6ÿž¿âša`cY~N¡4”À„a(…Ð/¹8¶îNƒ‡eî¿ï®VòÝ¥0Cû%Ñ>üÓjµ/ÝÓó£‡ÏY4˼,âÙùrÆ‚À gI{iÆgçåìƒó÷<åŽèd•Ï™ÓÏ]æ´°èæ.ç¡Ã½4 çç/>çþ>N’x)Kg>a°¾ó}ßyuòúÅû“y:/N;ïÎÿäõ3dž¼}f¸ïß¼ùó-JÎýèôüèó8ÆF#¹ÇüdVÔG.üY ¢—3ßãY:»ÖŠõŒÇ‰Àªš½;úëèé¿O&÷ãYœ¦^Ȳõ½’Íjîiêܽw‰s-«ŠX-šùÿˆ®“¥ nÞ gKD%5Õ/Ú†¥ìDa'aß'ŽP„-V¿6`ªºB<"‹é oî†A¶“_#zÞ5£™Ú:ðœÔeÌË¢ˆN¢zm6ú³i{Z\á'Ž bÓY‹´¨¥7âD^ÌÙMIŒ`“[«±¤"N[˾›¹:¹vˆ­'ˆÚ³Û|–w‚D¥TùU…Û»!œó5ŽÇ-Œã“ãaÜ*ïE7å„ xâk°¾C†hpcEIJíh¡Šñ­6[ò£ÏCQ’X»M€ÛV²m< ÿ Û ,7½ ËeÀCZÒwyû.Z€âÁýÁEØJuLHŒí!eÌ‹’1Mì•xI˜Y‚kòZL`…€Võ·[°ÆÍŽ­àBðÐ^èù;¼GßÃC˜ –xY’|Ë*¸Î(5>YîTèÅ<þagýœAã>%:(ö2ÎRéÅ9ÆThòaWO új’˜HAÂ%r)Öa±úAgH•\5y¥HPŠ¢‚œ*I¤ ¢­­î†’Ì(> ™›éóÑ|m@a2–EÞáw˜/û5ñ©L‚CHÆçÉ]H]¸c1LÂÚmqåÒÔÒÖÉó«„í™ù°)iÑåÍJõ%aé‹ÔëCM¥ëÌæ GÌm‘¤8×K4ó¿­Á ]ÛЛê)Fãà ×!Rh>»†Çv 3jxq‚ / tÃã¾ixql^ƨáA;fd¤ÞL摗ıíÉpjìÉ-–±$rßg´ÂsžžžÅxº($G"ëݰ8ƒZ]Æú‰ØÅÝ “†ß2ßQ<Ýv=:/ÍœºU= Ç/A_› é²»Õ3AÛ•êàfL¦é²ƒN¾M‰_$ºñoñ<:žô‡Z£h묄!ôÐ×K*íȼS€ïCèÐNÜPùZv†¤Ý¶v›¸áw[q‹× wÍì®Sß¿ý®æžCœeï9„y÷ñã's &•~±œÖ4(üV'nÄÎýûôQOÀþ ¢v8½K[ â-嬸ÚÛïï\I\OdÝ¢H½mô…!¨ÃxÙv–€“,ñHyŸWÔÌ4[6Ëv\«¡ùÔèñôº±L\·½¦"KùV84²·ë½¡øÁtsÚ¯Z ˆ1 Š+]N²=)Ÿ–Ó ¤×(Ž}çJ÷YKhð^’ÁÝÕÈiõÁÅÂhðËÖ½^ËQCØ7ÄPOC|ÃÀ Øÿ¡€š'ƒ¬iжr¬wúf)Ñ-sý4BmYy5Z¸Â†MÏ£WS1.oZ°ÉõI?Í¡`C=±Ü®]Q½F\µ}wª0ìÙ©ªúnÀÝ ãVÖÐ&Œ˜Š»‰îR, ¡mÌú‹6£)4U–ìCM¶ìõešb“+ñP.K‰Fü<ˆ•ñIï匙'é09¶æ7Ú8ØïÁL8gŽy [x÷̈d¯r®ÁRgžB7¶º}x€Ã@kÅ0†m‰{Ó–@çu1tßrøŒSJtv­­ÓŠ{ïDwÐÌEfæ(!HJÅÕ¡aà˜¢ìãn²Sû?Ðì‚W-TË\»¥pÌ¿š7èZRŠ?wÃù©ˆhìoW{öåžß(÷,øÏË=èëMEÞ†#ëÛƒùˆþ-=iÃÊž†{½~E"c8¬6€dÔe¡Jé¢Ìn:;½à5j£ƒ¨ÜèNÿ@íÇí=ìÔ`»º,Q¿†YR5‡‰ïPˆ„k·ö'DT¿\,žŸ½:],vô«³×@À-ÃßåÐXh0žrˆ%©Ï øÌcæw)Ù_Âþùp j endstream endobj 307 0 obj << /Type /Page /Contents 308 0 R /Resources 306 0 R /MediaBox [0 0 612 792] /Parent 282 0 R >> endobj 309 0 obj << /D [307 0 R /XYZ 121.4 736.262 null] >> endobj 66 0 obj << /D [307 0 R /XYZ 122.4 571.311 null] >> endobj 310 0 obj << /D [307 0 R /XYZ 122.4 498.726 null] >> endobj 311 0 obj << /D [307 0 R /XYZ 122.4 404.633 null] >> endobj 312 0 obj << /D [307 0 R /XYZ 122.4 322.494 null] >> endobj 313 0 obj << /D [307 0 R /XYZ 122.4 144.715 null] >> endobj 306 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 176 0 R /F28 142 0 R /F35 275 0 R >> /ProcSet [ /PDF /Text ] >> endobj 316 0 obj << /Length 1814 /Filter /FlateDecode >> stream xÚ½XÉrÜ6½ë+]Â){(.àV99‰œØe;•’²TÅ)b$–¹™ -Ïß§7r82å’‹¦Ñ~¯M}{}vñ<ˆÜË“0q®÷N†žrÒ0ñ²œ°Ïw‚Ù›È üÔÙÕgüé;L½t|/Ê3çÖN”¤^Rå\ý|öí®•d™§¢ôŸ®åÇînì{Ó ›Cu@•rïµeÁ¶µiìºÍµýÀš}Û³pu°ƒ©ñˆùœöNvØð½±¥˜Üµúq7Xo³UQì>³³™-†®¶ /cvþh[-lÇîÞèaìå‘ÜÀL—jëºmX­¾3,‚#–t/*]¦øä v» Âb´•©·~¤ªiÿÜŽrz¹?Ñ‹3kþбvd5O(x@!ZÔ¥µesç ·b‡·‡ˆ&‹r/Sù")ïõ W„O>dç„hh¤þ‰ç!è˺«ÐÍcšºƒEuˆ7ÅŸxÓxdk]U"Ž·Ö l¢Ý³î4T¿(¼õcÿ„.4ÛèYÖMÁÂëò“)N™‘ð-®Ê;Ø€1ŒÝËOƒil äËê÷¡îYÜyÙä$*w-ß"«S·m @@·¼–ârßZÙú+…„÷sx \ûžƺ_#‚ù0–7qâêêYÄ¿løW¼|œG }?f©•b4%Z]œ³Téænò[oòÊK°;LXÕéÞÊå#á$€ÖèÛŠ‰Íw‹Üó·~Of'gƒ @kçKW—™ï?9®_õŠÒ—ûnðH¤X1ÓI|ŠÏd­%û-ëv¦¬ž¢©ö© ’9në^TU3 íÝS9’kZ{Iû¡&qè!P²”ŠÚ‡Þh,›¿r½+(ˆ°e.ˆ¹ß—½Ù ÀŒ(tdµµ¦'ú•TÄRµÌoÔÿ‹ÿAS¯&]kkÑ&8Ur˜·€ï¯|WSÉgq†5pGb:ˆš‚}àÁùÅù¶³™ÝãÙÕôœg&SË-+it„šbª›o ³Ô-¦aí¡‡#ÌÝk¼V˜e®ÕµáuºëªÒXVc“rò•p¸®q|[²{ùFCÂ<ÅeàûN¦Ù+nÎ4¿¸èz}Wk¡ÿÑÕ”‚,ù„ñ$ÇÙi”à!­×Rá·{ õVÁÓˆ¾í{òª¢ú4@¬£'NÁãT”vG”–ÚmЧÁðX:'‚—?”XÒÑ‚ ™žeôp9ð¨ë'ƒxË•ÚL÷T@éÏP08uKÉ&ë '0èÔGrT{MžQm¢%÷z%â#(ˆs…È Àƒ¾íúRb}G\p‹GfçÖàų碈L”Z­ƳƒrBQÊ”S¨sSÈ>æ '5'4¢˜BHcú~*ìµþ`Ý”²òˆ_|¿<˜Uùž‚ýPi2Ge[žÓä„õ”8s>6凧Z±uf;´ß—ÔBÒâYuÒùzÜÈ.,ɵBzƒ¹u\ VÚA£ÁÀ•²OhC©µöæ2ßËÞa2bæ6‹ÇG"òKªå—‚¬"Σ™¶Å~­fúM¡{ìûâä´¯AÅŽŸïÂ`ýr÷îZpJ $ŠÇϵã`ËB¦¨+%Cõ¢c¥âàï»r_X•fî×2Uëéõ€Á-¥RI¿_e4×K*ô\qÚÊN`矔M ½»¹yþâÕåÍÍ ž¡òr?sb/W Lñíš·ñ+ið‹¥‘9h} œ–§Ø›ŒDÅDWê­PÁ;<¥e½žòJN­O˜'\a°ðÓŠïž<ùz5%&ï¯Z¾ë{jyâ˜3NË l ŸyZLj{ñXzò8"‚[É­tº ?RGøqHÝŽƒLÝê·åLÔ©Ó½Z›H}ÞmBFƒ³†gáìxð}n|ðv† ta2ÃüêÅ›ÿsš»ó6ðÖ_ sG˜aÀ0K¾¢bQ•x†`¦+HsuŵšHûK¤aêof13‚´J¹bÒ*C¤éy6ÍÌ`«ôøË}kv6è`«”Àf aåÿ´ÄP^Eìgr@”LÿÒù òÔm endstream endobj 315 0 obj << /Type /Page /Contents 316 0 R /Resources 314 0 R /MediaBox [0 0 612 792] /Parent 320 0 R >> endobj 317 0 obj << /D [315 0 R /XYZ 121.4 736.262 null] >> endobj 318 0 obj << /D [315 0 R /XYZ 122.4 615.93 null] >> endobj 319 0 obj << /D [315 0 R /XYZ 122.4 474.016 null] >> endobj 70 0 obj << /D [315 0 R /XYZ 122.4 315.931 null] >> endobj 314 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F35 275 0 R /F28 142 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 323 0 obj << /Length 2221 /Filter /FlateDecode >> stream xÚåYÝoÜÆ×_qHl˜—è(rII}H\9p¸ ¤-C^‘{:B<ò²$-)}çky¼+k¨O-Úqvvwv>~3;{úþúìâm˜,r?_«õâz³•òãEªÖ~–G‹ërñÁûu™Ež±U­—¡×/W¡×a—«(нÈÏÒxùñúÇ‹·Q0‘£Tà‡q¾XF˜Á¾ ¼Ÿ¾{ÿÃ_¿[ªÌûá%DÞåß®/ß_½ûËû+svy}öûYû‚E8jùa.ŠÝÙ‡Á¢„©åÙâîÑ:õPõâêì—³ïÑ,•ÿ“Yë,óã(e•>k[+ªG“µ‘òC•9Í»ÞVÍ/;òÔ NTj± ?yíõ¶êب‡ª®™²f¿\¹­í™¡öÏ«·¦aÊ4E;4èžÞXSžóÒü]Ý/Uê^öæÛo_ÉI_“Ÿ<²y¥b?Ö !ðTÂ*¾(~ ’`Æj0C¥jÎê#¡*óó|têàð}¤†¯ç¼‡GëXÜ:?q¢ðÄSöÁiÀržÃÉ[ò›¬4;tаÊÒ”¼º¬¬ÍE_?1£jx}ÏGD^;ôû¡g&¸™E ‚R¯”5º?Ù´§é„Á§G³ÀâUúy"~„Y †Zó.$ºB14%zŽcæ´Â s3:‡„bïöUmJNCï"Þe5xâe¦‚£,Ó£sp åü^7¥®ÛÆÌi ³½ÙlÈc¡ðBq‘øôVW5›£× ’ŠÉ­4I¶ÑaÜ$yÀA Æ'’bo34E_a±h˜ÑouÏ+¬éÛtÌö"¼uÛgÔÔê¶ÂÝiä‘ Ã–'œAí +5Ø&A2^£Öàîd¹¬nA¹ ÄÁ»©ò4µC˜•"­uË)ÉÓˆ…„˜ –͘°±íŽ“ö £Ú’þ ¬©‚Hù¡þ(i’@Wœž|™§íÝàŠvd9ä#ݲlb ((]ÞYÃɃûÈCù–Wq¸pY„4 Ĉfpä:ȽËǽ5]æÏYªgœ¸* ÔV#ÿóR4 Ä4gßò×|^&€üzTŸì0=h\5±=§WšC¼ >ݱ< æœÚˆI)Î#P‡!-eõ+œ$â\Ÿ…£?,AŒŠjÆ»#hÕ|­¢pN3å½r‚4îÅL7)9¨AÉ3ÚOC‡¡÷v™Å”¦*ÂÓh;’GÁ›A«¹Üà±”_¾£‹`vïŽY£Kf?Aé‹FŸžÏ”Sk,Éc=ÈVw®¥çÚqéÙO‡ S¥)jmMéÚ@º\ºø†‹¶Ñ½ëûöÃm]ß\Ìyñï¨óÞ´À1lj[qöÒž»Lƒ‘¤|-ÜšV[Ù8{sâD/‚^˜iYèÝl, W6Š'1%Ú„$ÁÍÉ4€j5çY¨4xKÀuû]y©P­ãúù'WF#EY%%àëØÑÍÇAzH6Ù¼A"}àòîú^PƒlŽR ã™\è*Ž)mÉö*‰ÖRËòûPQr‡ƒKÊ r,2ÔƒòÅIþʹü•LþüÓ;^}tu ñ2 £gäϺôÐÊQê@3¾|©ç? ʪÛÃ/Rà¶|íZû˜ŒÆ 6ÿbÑÆ­Jà‰÷¢kvºw“Mμ F5¨K¨ÇݰJÙiÓ¬–Ðâ`è oø³ÙÛŠWo˜Ñ¹>ç#ûõ¦§RæÊ(/ùcºBKaåÏSïgzt.Ÿ–¡ùNúp‹¯7•¦ÞËGL Èv§ZÇcÄÐZIJ¢šcZ¦’–®€ %¦¸íŸâä(ó)Ür¤æ2y/ƒGžåÃS9\ñáóôLzHƒfxW5’*;fÊVI’O~)àÓ˜ôV€ÒDm6ú‘nÅW |_&LL}„ã„w”Õ]åXûIÇïbì7_Š'V–ªç‡3¼:šŽŸy¦À,‹ÜU3^.ÈÜ <3‘>Asùñÿ@½37·5š©¼Y÷7-æôóÒáJŒ ±ÞERlã(w€ªŽ%„wUsA.¦ÃKeåž×uð@ªË£=¼*sK—ÎpY¢hÍ9Ä\ Eü©«&-ÀÄñWTÙ¨·èÜÈî¹Gù)¿‚ÀëFíÅu$GnÍ/FDÐû©{‚®qWÜl¡Û0öy®¿F,ë{÷"Éð¥´Ó€~~wAn{ž ÷+rZË« ʼ,QÞ§Ñlj(`ŽŒÇ§\yEð¬ÚM<™T0zÑQ»ë§0ÍçîÚZôCFàɶ˜ZEÒà.ÈL2|ZÉÁá“8÷ü-ó~µÁÔÁÑÄ®S¸¦þlº=–ø‰ØË·IÜ0‡ ›|Fï.l+-i?þ”]—4¤ÔPÚ{™p‰ºäAå~Qåž>ÿ.NоýÿAI-sÏ߈`A˜þ"€K¤öHGô»]'$ôÕ½Ð}ˆ x{)ü2tEè ÑÕ,’X”Ï€Eø?ƒ‹4b\¤Ñ).ÒhZ:RéMb÷;þŸHñQ4EmÇÓÝ  iôÄ"L"? ã¸ÓÏbùoA”ºÿNüΉ٠endstream endobj 322 0 obj << /Type /Page /Contents 323 0 R /Resources 321 0 R /MediaBox [0 0 612 792] /Parent 320 0 R >> endobj 324 0 obj << /D [322 0 R /XYZ 121.4 736.262 null] >> endobj 321 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F33 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 327 0 obj << /Length 1694 /Filter /FlateDecode >> stream xÚåXÝÛ6 Ï_á§Á¹^|þŠc¯+°kw-Zt=ì’6´EN±•œU²/Í?R”85Öëз¾D)Qù#)çùbtñÒ™‘n`,ֆ㺖oÌÜÀ #ÏX$Æóvz&iÆÆŽY'ŽY!ÆÏóMÏ gþøÓâÍÅKÏ>Òãº¶åø‘a“'„}¶m›o/ß½z9vCóÕjðÌ«¿Wïæ¯¯ßÍQÍèj1úÙF¢7†myQhìÔÂÜð‚™å•óÑ_£çx-7úêZAZ¾7#“îä^Ö<—i1ö\³æbÍbNWé¹Äõ­ÈŒ‰3µ"Ÿö.Ð%l‹×àp‹ÜÁs–i±Á)jûR“ ©4§¤y}¯wz‰kÞ=(EàárC²RhIk£eYãÉ4 ÍÔÀâD+‘Ž]Ú&FE÷$bE‚—§LÇŠ¦S2½Êð– cj¦5úø«Ó\K dÕ%Í”ÉH¼xò„ˆ8cR–ÎZï‘>lüƒË*­ùÉî‚åš*×­(ÕZr‹ò|È^Zƒ@a™, t;´®[-ÔX5‚Óe(²âÖ]¶ŠIYà!«‹¼ZÞs–pñÓ`"Š0>`T˜@É0£¨¡]4ñ ¹U\DzŒˆ¶çg\Òd7 ½h(iá $-®ð¸¼ÊxÎéP°¢,¬!Ó;¨a´É@Ô h‰Zi¨õ¸>˜Œæü¾ü_ÞÂ^Ž…úãà„kþ,hóB_¡Íûª)I‡6”3bJ¸]¦·´H¬‚ <}3]¨£¥4j2Õj°øœÊÓ€ò¿¨Q­”1‡ˆ¿Æä fæ3³lh²KUªµR[1)ƒ°ñ`‰ÎUæár‘Ö“)WìIÒ5ùrCŒ‡ñü.R¶¢ZŽ#å>h ¼κ)bô¨€'Ýà(œ¸fŽæ4²¦Ywœ$xˆ¥à 1v)¤.Î:ì²Z¡˜U³ÊÒøìûQ™s®õè E‘*D-,Çä‹1Àä–³欆 =Õam}©¢­ƒÊâ˜K©ÌPÈÐÆõ‚Ë&«ûˆ3Î .¾»–hÓîæÿÌWÞ^ݼ~{ýê‘…ƒ íš½½çšw»|qøº]Î¡Âøæå †lARÌgEô†\®"ÖËÄLè Çü,¸Ô;Å`zI®ý±Â3÷D'|Í:Gíî¹vÕGÛf¬Ø4l£3±-ÝNhÛ“³Ç`uåËq˜‹ë›Î¬c·>àƒ°CÔ7Wxßáyx~šÚtìõÍ9ñN@Œ,åî¯dñŽ¬Ö ­[¹‰•†-Ö.U+J÷ª,5CyÚÃífÆTèF)ʦHZÄæUšµø•¥lœ¢iq»¤µhâZ>Õ=ç.AêÛü¯¾è½¾SÝR}9÷ü„(º5'8Çí¦*Q×ó`®s” ¨D¦zd’Æ[Ì,Ð9ʉ¶Š‘ïÔÍ¡ÚUçó‘Ç{çÎò‘>œßÉÌS³-ÍTO†±ä ,xä]?8­ðµ¹ ¦l]+¸ ICÿáÃö¼¿åØÃީ֏*—œ×ïb¡w|¼b †^H’Ñç×~ xàzYÓ:ì]­AF~¬Ç£GO¥XîXQB ·`Þè&¶I‹%Ar¿SÝ[$rðc§ü\ù/Ów(V=ý -ÊB×ÁAT?&ä‰YN;l¤ÇeMØ 0Ú.<ëàg»ä>Î.¾…#‡T¾—èß™¶q÷ãŽjýÄJ8öv rd`hpQZ$iÌðy¯¸ª€žìÅ.€¼FŸuؼé6ê#Õe± ̓ š Ÿ$t Wh–.+’¦ÐÏ©àA…KW©z@Ôº¡\}î oãB!¦”(ôý$ô ¬%ŠRk†÷qwHÛbq–§õà§ÐG{j/Tá®ÀiY†/»0êz+Ò,ÑoB¤iý”]øt‹Bò DSÝb‰/æ˜hx£”@ö2•î`_±Í—XÝÔƒäü Ãg÷¯ú"çø/™©„!`c뿚½SwjЖ‚fM®Þ-4‘ ÑŒˆ|:ä‘]Š®Åň…dg[š>kUèù/ǧâAK1¨e;¶—ËõšÖÿN:¾*þs£N„/œd[åÔ¤®;ë«ëßò·gGV¨Ö’3‘íŸdþŸåy‘1 l+ÔeÛ Û?Ðþ]:0š endstream endobj 326 0 obj << /Type /Page /Contents 327 0 R /Resources 325 0 R /MediaBox [0 0 612 792] /Parent 320 0 R >> endobj 328 0 obj << /D [326 0 R /XYZ 121.4 736.262 null] >> endobj 325 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 331 0 obj << /Length 1966 /Filter /FlateDecode >> stream xÚ¥kÛDðûýŠˆ/8¥qü~!QʵÁµp) Qmì½dUÛ¼öEǯgfgœ89C)ÍïÎkgç½ùfuµ|ádzÜÍ“ ™­îf~¸Ñ, 7ËÃÙªœýîü2ÏBG¶ªsßéæ ßѰhç‹0ŒœÐÍÒhþÇêûå‹ÐÉ Ïõ£|æ‘ ?>ÏóœžÝ¼|ûldÎËk”:׿­®on_½¾¹E1W׫«?¯|àófþQ›Ðõ½tVÔW¿ÿáÍJ@}?óÜ0ÏfKXÏÂ$uXU³Û«Ÿ®¾y|­(uC/™%YæFaJJ­vr¾ˆƒÔ)*=_€Jêõ~-±©%º®U›¾ãíAUóˆÞ0°›–C°­xÙtv½ºÔ±ˆÌQ`Îm£[Yò¾9É“Àµ¾ïæqLj+~'˾RÍű#ª­nU·«Ÿ¢`Ï1º–ª¥!t+ÿì••Ä‘s§[ºmeÑñÆ*Ÿ¢ò)*”{¹xâ½Ò­ï;¢aQ¢: ¹Å?˜)mU½o5±£²a;{’Ú‚µh éÎQš;¯0¼>7D#*£yEŸ-iG. ¦JÉØÎGÎà: ÛñâÕo®~qý|uûü»)¨žhPð)ŤÑ­Ó·’`=‹K/#ŒÎ5LI,‘7ß“£Ûê@`o½…‹6 èø¿déRþù(`Aäæ° `BE—Oîça@¹Ø¡ÃŒÕh¨÷„²<ÞÙãaoôúŸ%\dÑQ§ØÍ#’ùÖ`TE>„Â]'[^ÒǨm#*Z—²¨D+:¥éòC+ãW5¥*lšXèN>fW†¾ýé8†\†-Â4ëÑèÎrøj§l˜„ VÃFÐA¸ÚØØ¦5”Âhl?QäùN-Ú÷ ¡¸óÀµ`¹êÚ<`ІĨ‹3½ÙÿTKÂÄã3’3yŒ6ÖˆdT¹ì¶ï4^´€8~ ^«: J¸Ñ½U¥$)n\,C‰s+%x ™ç&I<øw^Õûé ‰¡x3­=xF õÎÞqz±ë§ÁEÙ89æÃéñoñ]h„1BlåzsíkýÎ Ãÿí·\º \æ{”$± ˜¾A+vª•„àò¹UÍR¢w-ì¢z ŸÙé¾*Ïx¡†¶€k:„TO)xàJ„ಣ&‹ð¾oIsm¤ùÄrsiÏO4`èaƈŽVwºªìíÔ-MŽèGߨ ˜/±†J &Ä5·«9Ù[ éJe°j—Ø 4¿†ÖÆfÿ„©/„ì®ö Uö±ó^s«ê+Pè‡áI›ô¨•Ãþ³»ôØGe€n>ì.ÿŸý•ý•?öW~òWÎþÊÈ_` Ià“¯2ë«tä«§¤#ppW­s!±yXŸè{êŽÖb…s1ý­¢Â™æT§ÛßbÂXl m¨…Ãb/Œ¡0ƒxã|´©74;¤à„¥ûÃ~ˆ*ÚIÑVj =À„Füè({;vÔ„Ö—1;$Ú§ƒjÐ?ëšj ç¸ÙÿÏÞ pðN”‡°9ú äN`Ö5çaÀa$N´† 8øâ·CÏ…ÍqT& T¿<’£4ÍâšÓH 3ÕI)‚íD8w`î!¨æòÌXü˜¤h€í®¯˜SÌð}ìœ ð~ÏpU£j}Ås†åᜰœц–T׬ީqàœˆ‹J¤¥W &nÑGæ^µQ•꓌æ Xœ®'Z¤HÆìöÐFntÇBx  3ú¦¤(ŽF>@¢~32×dó¡7SÉ~êm°iDME‹`wI⦧yäÇ>EÔã(b× ÏÌõúÛ׫õzBjºq˜Œ¤òp6!1r½È(í˜ Ú>ÿâ \@zÓmmï‡-Œ˜D †BHÛÏÜψ‚ÔN9—»™O¹aBû£=Àƒ¶Ú /òØùug »VTa ‡MO/@BÜ”ñðŒ4#xtè¾ãª (ò‡…Ë}%Šcúµ9˜Ôö8.`áÖØ¨ø1§F=ùÓ& e4ìä*/½Œ±lUg>îQb›×i\róLîe£GICH[K¬Ó†‰…Ú»¢ rÛ*¯ó¡ò³ž£2—ÇäTÖP®PV>Ÿ ¹û$WÁìXÉBçepP <0×ÙkúVTœÛ£L.£ô»l…ب}¤Dõá ãq¬ è¡khÙJÓW…&búÚc=çíÍë7«?<ÿœV„¹x£Š]'(ŽbØð?j‚á ™É+zCBº7iJüzgÛá·§¦dÿ€®EË~–öÕý¿>½Èÿå”ZÓƒU'sÙALF%}ê|çr¬ur†¼üo2 Ü49Qæf—°0þ ýï¨C endstream endobj 330 0 obj << /Type /Page /Contents 331 0 R /Resources 329 0 R /MediaBox [0 0 612 792] /Parent 320 0 R >> endobj 332 0 obj << /D [330 0 R /XYZ 121.4 736.262 null] >> endobj 329 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F32 175 0 R >> /ProcSet [ /PDF /Text ] >> endobj 335 0 obj << /Length 1588 /Filter /FlateDecode >> stream xÚÅXëoÜ6 ÿ~…ÑOv0ûü~´°KŠ]º5×m@[¾³œ3â³2ËÎ5ûëGŠ´ïwͶˇ˜¢(Šü‰é^.fós/22'‹ýØX”†çûNh$~ì¤Y`, ãƒù«•¦h«:·<³³lÏ”@´–¡8iZŸ¯çç»§Ç÷]Ç 3Ã%^ ë\×5ßœ^¾zjù©ùê 5æÙ˫‹·—W¨fv¶˜ý1ó`kx£5㹉±ÚÌ>|r¦^®d©±Õ‚#ˆÇª6®f¿Ì^>v+LœÀ8M0HŽë$¸ãG±¹­êš¨ªA#;Ñ6y]?OÝÕUGd·D,k Dj®Püv˜ÌµXbæJU7b¶¤ï3­g#žìÄ“¶–Ÿ˜rjõQOm/r²¹èJ^æ™}]Ðñ€™ Íûƒ¼e+ò[¬º1I£nä*Ùv$#KËNdzÏùȽý#wÌK 0ÚÉ\Žùܲ#?2OV$h:E ñ#jU÷EÕÜ«[K%˜”ôeÄFß='‹"Ú"¯·ù+ûᄾKqŽ °ç:a”®¨J’BïøC‡­‹œ8M×I@³=pM×®àû`MLkDSðä„!Ãä‘G_m4ᄆÝÎG‹~O\ÿb™èéÈÌÏýl/Âì0rR?8 ±“{+ð÷ò8€¬®ÁV`v×ò£¬Ážª,s’,ÊÓFÝLl»á s2'‘ƒºbg‘B¡ÜÏÆ+•/k,YÀu"ó!ÅbUE¡(ˆ«36oûÈØ¥ò^\ê²D®³ò[¤i¢E¥¬¡H€¦í¨‡÷ Ì•Ü@àè¤v¦ õC€2€çGO‚´™Æ3L’o‚§—Dx¾¶hÑ ËÈ3¨ýˆâô:ÄÅ5Q䎈­QÄaDSFtoß …k$§Á7Fº ˜â¶›kT¸Ãê´ì°D…xˆŸTï€(;à\ÍeþZåø½ÇØ'óï`6MÂUÞ‘¬ö5©._¡à- W’täa½¯—F#ò¼ºÎT•z 6s“êÖ•â~¤ˆÓ+Qö5Ñy7H Z‚¡ÐðºNdìPÔŰ¡ˆ¡‰a-Ô×Ï$~Ê™bð%‰“'žÊϽZƒš„¯ H¬ú¶XÈÐø©½€ïV_#ÚáŠ#ÆUÑ(oyY×·ÎTÑð·˜Ó%‘Ø’uL 7Ü9ËŽÓÌ|“SlyXÐå¶®,š v&=“s^á€n¡îN64%YÓn‚¬BÞab¯HÃàôwS¦ÒF~œš­@W‰ÖWª˜#"oë }ÀÁ®ÒÆé€>’Ë¡ÔÝ+*¨ äQáühý©sÀ*ôóÜJCôqÂVñ9ßÜÕâŸÞ îw;ãvî®±÷«ü^üÝ%âKëdÉ­þêíOg׿¾»¼¸|5UÓ ‹ãÝ=rG•+Yp§o„Ø]ÛX*'etUáÈC÷ü¦2¸Síb ±‹;_ÆöXžç™ìfS±W4ÀpÄï’"®Äm4ƒûgv P!á¡oËZ=€j¨[h£[_°^9l<ÈySp+¹Ò› ÉÑpœ’oñû¶ÔÇãäÒŠ‡·‚6©Vl †sEÁÿÖ½y]5°³¸îruûÔù^‰b|hSr–}³ê*9Ø×²‹ š8÷V„5°â ÌËFSíV)1ªƷͮʔãcéñžÁÒ˜-À›ÝZÒ{ èF"¼™· äÍì½°ðOŠAŠ—êÖch}–^ß5ë9ÖW”lõû"¤èõ#Êò†ù²ÆU –åTv“ ë. OCˆÏbÕw ©Hwh?Ö§ö(m|{:À]*,¶ò˜uÞÞ°N C¿Áÿ VKºýáÕ»¶†þXOi®13ÔÔÉ€'QŽ—¶ÄãçQîÈöó7u‡6ì ~E™Ç,E$ÛU¹<}JðÕ†÷ª;ÄkÞõ­x ëHb•7 ´N½YM?ÚÆ›éQt™ßwª*ŽS}HLp%êÒá§Zà$^hØQê¤!ÿìºÃ-<¥o endstream endobj 334 0 obj << /Type /Page /Contents 335 0 R /Resources 333 0 R /MediaBox [0 0 612 792] /Parent 320 0 R >> endobj 336 0 obj << /D [334 0 R /XYZ 121.4 736.262 null] >> endobj 333 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F29 144 0 R /F33 177 0 R >> /ProcSet [ /PDF /Text ] >> endobj 339 0 obj << /Length 2196 /Filter /FlateDecode >> stream xÚå]“Û¶ñý~…ÞB9'Áo5m§ŽsqéØi}é—ã¹(œcŠT ð.7þ÷îbtÇÚñL^Ú¾‹Ý°ØoP__]|+ŠÅ:^—i¹¸ºYˆ4óE•–q½ÎWÛÅ»èÏË:‹Ô [¹‘]®DÔ0,WY–GY\WùòýÕwßfI°Oš&±È׋„ö5¬K’$úÃó×/x¾Lëèå%îE—½º|ýöÕ›×oq›³Ë«³œ X—,Ä$M‹¤Z4û³wï“ÅHß-’8[׋{Ǹ_de§µ‹·g<û¯•®Ÿ\«¬ë8Ï*éâÙÝ2Kéb¶ÇëÀ5ã¦Õͳ šý˜‰E¦‡ €w«nˆ¢:D{àtû-¦y¼NÊÅJñ:§ã~0j kó<’7V v4Âv ‘qO3‹<>2Ï¢-j^æ›VÒêž×ÚžFÝmu#­bì-¸b¯­õ§¿ ¡éÝö[æ2·ýØnñ& Ä•ñº(Hî[‰ÒÜ-Ó*BÞ$å­À­;$8Áq·,ÊH¶£2<×FoZ/W9¸Ê7£ß §ñÅ—_ÐÊn7Ê“eì ¼¡9GT GjÞrïÄy Ißµs2oHuä_#) §1¤ÌAðÕõ©É¥ë\¸:9 =rOwž\];#YµdK¬ÞlŠìabºB¯EµX¥à G”}8]‹´€MP}µýN7¾KQº_%ïiúOòèüÓBþ†"¿Ø$„ü!ˆ7×–°àëG?G„÷ó¯Hâ“XYåE\§Ù©È?3Zî–%xõ %˜ý³c4êcÁΫý0Ús¶àh“Aí´vOãu÷zP´rû8Z2Žà ¢fäÒ½ëÀº¡O•$#GÈ*…Pœü+ÍS8PL2=aí­´„yAƒ ¸ÊN'?ÆÉ ä––á%s?hËœN6¤At.º˜õæ„îeÇ`yt…3÷ºeç•­a]ð ¼*\¨ªö,ñز>ÉÜ ÓsŽ8z¸×æh ¯ ~޾HöÈ–ëæúÇ$+¤}vO2½áUVu ©ÝÆÑèn‡`êÅphÊ8äo˜,Òu šîŒÞ¢!‡wÛ˼ˆ$ ß|ÿŠOžn3vÍjNäP¹X³¡’¨šFƒéHŠ€PJ°O•²#ú±sªE±ÝfžÊ›('ÝÁŘ"uÔo0OÝé~4„P.'Ûa65RUé9—y“KÎdúÐ7š~€ðÙ´l[Ù ½1>Xö.ÿ9+´o<—N¦€\Z~^ñ•æÃõýÙùD$h}íjœä€$÷IF5Ç zŽ’VùÓ™8Ј‚ÝmFE|ÊbA!fA¹Æ Á¹fΑœ¤IpÎðœ<|b|þAxÊ?8ÙË-ClÔž–JBº"Q’çG7G-I0½:uÍÈÙȶUƒÁìRdÑ÷¼8ËJ'¢!Ð'—2¬Àe!q&™YÒà: l(µ£WÜ%ñ‡àLOúDŠÛ)_Þƒ/KFJþiÔõÝŠ¤ Rçztê’úöœ£¦ØÊÒkË(eç˜\’ì8t|`ØÅ¡Þ ÍzÞùîÅ• ¨esÃz 2&(+-3¾SZ¦^³—ŠHN_H‘Îwpå=fךWPÅÀ«1&ó?wÜÄL¥–øNš)Ž,^q4¼ˆXBÀ‘„ êF ªk²mLYmÒ2´TÙúõTñÍÅÔ‹)L̯¿pºÉŸl¨þØJ„VÔmO—íºÞ2vŠ"˜„‰¨`Osý±¨9Ó@ç5@¾ (õ§|* ˆÍ̵C«~ÒV+g‹¬ˆ~ïÛ`+ú9e´{ºeòô–€j\ç–„â'ÜÆ]W™¯HP©ëä ³¤¡T°œ öÉ¥ØZ¾¿óÝ#4ó2ˆ9—ÜaÌÒÕFsÑóo/øåÃsjZAg½Ttú-¼9 ªIÑÜNÌ>äé™gwäF×kˆ3¨nPÐ!gì•ìŒß„—tœ¹’ nõŸô==î$9x`:n»‚¨ËƒCÄœ|jäëÙúôvÎ'ZÝQ)C? î†ËäW§¸ZÙ¨_0ˆ®‡íÿW9#…ÓÂVþ‘rèHÔ‹Q¾ÕöM4u%° ª‰¯°y‰Ëçr»r¥Tûiƒ?ß`÷„ýÊÅö ¿Î‰"+QúÏÔ¿ž9ºŠ«ãwlµÝ©ë,1³W^ÆuVxÎß~j+*öä„Ïô)Ð~[ÏN›“ÿ*·¡[‰ð’¦ïL×øŽ™BX&>æ`š£Ž÷“øÑÉÐnLܨ`f„FdPGŠ2‰: ‰zúܤ˜HÚ©Î'NÌ‘bšh÷ažYMâÜsG5é0Ÿ@×^Çu´Ó´qÇ«È`õ¶sí|u¶·‹SEÞŸ/Vèºë”ȹðÿÃüªç endstream endobj 338 0 obj << /Type /Page /Contents 339 0 R /Resources 337 0 R /MediaBox [0 0 612 792] /Parent 320 0 R >> endobj 340 0 obj << /D [338 0 R /XYZ 121.4 736.262 null] >> endobj 337 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F11 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 343 0 obj << /Length 2230 /Filter /FlateDecode >> stream xÚ­Xëoä¶ÿî¿bn`ËõF‹—'¤yÔN¿ä—–¸^ö´ÒF¤ìº}g8C­ö¢ô®¸~Y ‡äp8ó›÷ó»‹ë¯“|SGu!‹ÍÝn“He›RQU§›»vó‹øû¶J…M§¶‰pÛ«D @ŒÛ«4ÍDUe¶ýõîÛë¯Óx!G&UTÈr“Œ¤†}q‹ï^ÿÍϯ·²ß|…RñÝÍ_oîðˆ×Û*w7?|‹ò.¾º»øí"ñ&™ÕJ£$.7Íáâ—_ãM Sßnâ(­«Í³_xؤEI ºÍíÅOŸãýdý»ûUeiIº]ö´M%ÝÐ x/Pæ8=t¦¹? 0”¢:ýÙ5]óÌ\2‹ê¸Ø\%y$³‚äýlu»½Ê’J¨Ó#’¥PÄAypw”G|ë”ÓÝoe‰¶E–h­é[ÓÀ,s÷úD쇩ãûÁñàñ Ów¦¥@0ÍU’Duž“²oâ<žúN[ +a´±›7qš5ªë^hnÔ¿MÚ:ݦ„—£}bÔN9â|AŸµ,E«ixPèr–£šf>Ï_ %,®Öi¸ËN^YÑ]Mn8(g‚ŠE-¬v–(·7L)çFó0¡!qø¼kóf™ÍУ¾N™>éÃ`@ààÍc¯:{¦±$Ë\üþ€ÕÍ= [3êÆ™'¨-^Væâugš†+ Qˆ]Ø×#âÀF=-­¡ËàÜdMÿH¤¿ob™]½ègãN>p)¼,KÛÃô¸§%¯ØÆ»hMK.îuŒG hÕgWÐv‚óÙ857 ÀýòÇbÛñjB%N¼j…hæ9y»å2£ß]è½OpOf!èê$·Z“(4Üš=¡Û¿õãAqí®Ý}{4÷˳ŒO„Uô¿oŸ¡ûp§rM_ý/éFp!Ç4à…ûsâÃ÷KcÕ*&«Š»©9yhtͰp„t\ê¼ØMn5Í†ŽŸöù‡²ÕȇP1Ç@A6vŽ´Ðð–E¹fu24>ºë,‘\-ÄãNZ/b6Íkñ‚šŽþ|i%Â<Øè–èNÖ‘ îS©xÝh&¼U>åÍï)§'-œ|É™l dð;¸=·z¼úGX²¸ 1”µ+_UqÃl—tÅ.©0|€uè>â¥ÿO ì?üÍ£¯tODuË3 z“ â€cˆ®0ôÅ0 ÅAC„€›m³4õl‰€Ì`‚j“dQ õÿÌðÿÚ$§m còÿÚ%ÿkSK(ð3ÿkóŽ9i•e2Ÿ¦WBÁ:a‡SBM¹ð)ÂÛfÔé1A…¿;H–` ^ ïJ€ÊOÅЧ=6k”?Øpñä{¹þ$ä'?>/æ„ÏxÅHË2lòÇ3,’{G=§~ì‹¡Qöo|®H¥‚+Xƒ×2ÀcxÝÃK`¤¶ÿã£éQïð=}:‹Ä€yÂkp`ZÚM%<Á0«“÷“ÿ”†¬£ªªèN™ ÿ6ÿ·}· endstream endobj 342 0 obj << /Type /Page /Contents 343 0 R /Resources 341 0 R /MediaBox [0 0 612 792] /Parent 346 0 R >> endobj 344 0 obj << /D [342 0 R /XYZ 121.4 736.262 null] >> endobj 74 0 obj << /D [342 0 R /XYZ 122.4 296.642 null] >> endobj 345 0 obj << /D [342 0 R /XYZ 122.4 127.142 null] >> endobj 341 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 176 0 R /F32 175 0 R /F28 142 0 R /F35 275 0 R >> /ProcSet [ /PDF /Text ] >> endobj 349 0 obj << /Length 1835 /Filter /FlateDecode >> stream xÚ¥XëoÛ6ÿž¿B†UncEÔÃ’[ hú\º.ë·_ÒÀ %Æ&"KžMœ¢ÿûîxG?Rµ+°/&y<÷øÝÉÏ&ǯD쌽ñ(9“+G9I0òÒqèLrçÂý8HCWÕºᶃ¡p+˜ÔƒaFnè¥I4¸œ¼9~ú;r‘z£ q|’!ÆpÎ÷}÷íÉÙë'ƒ u_¿D ¡ûöôÏÓ ^q2H#wrú×Ù9Ê;x99øç@€ßµBOø‰“-..}'‡­7Žï…ãÔ¹1ŒK'%^³Â9?øûàÙwÞ7JS/ ÒíJɶ«U3FaìVW4¶ E“¨>¿š¡å¼“så †I4vO["Ë¢©hÖè%>°+dk¥JÏ×eµjÖ ZñX‘É/T£ç%ÍŸWË•.TF€‡ …ðÆqLªÞ Üª+ò'd»R.U±&OH"Í Ð"HÜl?×DÃ7áhÞ„“«ªF – ÁcvžØ1R$¼4 `ïrÈâF¢Þq»OiøäÇþ-ü'±»&òo4ÜÒð+ wOèž=g û.š,4\Ʊ{£‹‚fµÊÀ*]«h¹æý…*if¢gÂR¸Ìfå¨Ïh6Ë+iX•À–-alµä«Œipb ¸_[i|þ–Ë&7Üé–{äjÐ¥ìsáÝ2@"-$hF © #?'JÙO@úä‡1Ä -ȺœÓò–x°¼£ÞŠJl72bÿf¡IÁÝS¸Ñê`ç? @ã’(‚È]“ápòNyÉ(…46û¨m¡¥1²åSÛÔ@Å‘´‰iZV%´‘ ‹Ìä-™ª¯h¼e¦­—@ºG*|hÔžò#RžÂÀdòpYÿçêÚ" Üã‡'çinl ãù0õ‘ø¾° !PžDÖL{úƶ¢<«UÞeŠhKÝ4ä<<œµú³nQÀš(ºUKÐ¿Çæ'!)_i°R(R#AŒÝ_rݬQXCû&Xa+«TKTqfP¡"ò>H4’0 …‡Á§kâC€ òµµ&¯ÛmãËV¯ ÅGõR±g˜•UÛ÷®" tD¦ÚIR³ª$*GÑæR í…PÃØ×ÜbÙARƒM2̉O3?jFB T¦!å"•{ŒŠ±CW 8öÒˆÔ¦Ë¼Ó JRô3Å“bÝÜß­ê–u;œÁ‡ ÜÕÆ·²ž+ÖÜrW¨mM8º÷<ÉfÕeÓÊ2cΕl?ñÐUÛ*Œ;€ø¬®šf¸Ðª–u6tñ‘DŒ½WªVpEó?lÅ}‹ )gE¢±oq^¸›ë  G@Á‘+k-g…ÂðŽCß½êJȺªdVY²¨Všr|ÝÐSÇ܆¡¢tЦžÞ±=BOùîïrdà`¬Mvu¬e¨ìcÂm’I˜Ä |㼜6)GSª,×|Â(û˜¡ÍdS¿‚{/çCµ¢ÉýDd\Ü55†þ0 FP† NÝ͖ƤDÊŒr*%³´–7ǀà ¥hcVcÀg\’9h_ÒU& ¹@ …Ô/:N0N¨ㆺ•K3æøEpéÍú\b3[f™ZµhÎ(6CäÅ-žÞA‚M³_è2ǂĽ߆3•uòXE«9¸R• ”¨yi'uM€lÛÓ”~,¬k¸Y zozŒM~ƒY >%[|ÚhÓc’½6å—mŠ©Á^“ËÚô‘B°¶É޶¾¿§-,)ŠümŒÂô ÈÌTQœéëÅ{â¬3þç8©¿^Z}ên‹,›£· ©ÞkXFVT£M»_ðZÔäëtúìýÉtúÝ˧Ó?^N¦SL:ïm6½ñ|Ç£°|þèEHF‰–«¾8ù>Ì=«} àÂÐ¾Šæª4pçʤ¬¸>$ ×P8&‰ÀGæº|  Ú‡f\I-î§;e ö¶‘ƒâêª+í¼Ï+ûè |k¼aäQ$YcÑ ] &àÈŠàHÃg6O·ÝˆÂú—œ+fa—Vüâv «hÜ©Àe5I6=Aâvþ§P£p„ø¹³;Ñ@ð÷]Üû¾Â7FË$anædSoQ ]#¿¡Cj›·Ô âh²onøn“áF3ðóé~Œ^P‹¼SÖ#jÏÚ֖º/2OÍ÷lH©]u´0¹ŒFfÓJ⺅¸˜fÞªZU/u¹Ù…p´% ›’ ì+IŸa´šï ÖU‰ÉŦäÌGÐ0¡¯kâÏBl`vÚQÒ ÷ Ý´ûß½×%ù†» &«Nüm»¾PÅŠfl-¾1W³n97ÿ‰néUQInÍ¡_z‡íQZâcÿ»#Ú9 J¼£–ß–G$áÇ IAŸ[&z“Ê4‹µú¶¹äÖÖ þ?ã ÓЋÇXÚ?^þ1_¾ endstream endobj 348 0 obj << /Type /Page /Contents 349 0 R /Resources 347 0 R /MediaBox [0 0 612 792] /Parent 346 0 R >> endobj 350 0 obj << /D [348 0 R /XYZ 121.4 736.262 null] >> endobj 351 0 obj << /D [348 0 R /XYZ 122.4 502.687 null] >> endobj 352 0 obj << /D [348 0 R /XYZ 122.4 430.18 null] >> endobj 353 0 obj << /D [348 0 R /XYZ 122.4 168.714 null] >> endobj 347 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F35 275 0 R >> /ProcSet [ /PDF /Text ] >> endobj 356 0 obj << /Length 1981 /Filter /FlateDecode >> stream xÚ¥XKÛ6¾ï¯PÑ‹ ¬½‡=l€6Ý MÐÆ)49p%ÚV£‡KJÝn~}çE[^8MÐ^Ìág¾yÈÏ7WÏ~Œ2¯ ª<νÍÖ‹â8H½"΃²J¼Mãýîÿ¶*_›¶S«ÈŸVëÈ0«u’¤~”Eºú¸yùìÇ$\ȉ£2Èã YFTÁ¹0 ýW·¯_¼»]Å¥ÿâ”ø¯î~¾Ûà·«2õ7wo^¿EyW?l®þ¼Š@@èEGµ’ ¯î¯~ÿz ,½ô ©Jï6ö^’A Tç½½úåê9¾/ɼ( ª,‹OÌË2H“‚•{¥¦z•Dþ^[~É™EBoÀéW­QV~kq,ýñ0µ}ûY7<ÝŽ† Ýì4SV¶Ú¿Vqá ëC˜…Â$<¿WV7ÀŒxÚhÛî¬ÖyúwsÚ®cJM“îžF94â‹ð l~ô‡+Ó8õëÑ]O8É€Û;æ“ÂHthp˜æ8iáßÏøæ‰—ûÑ :Ã6màd¯†Zä‹ÔÔŽƒe+Œ÷ÝÃz°uF3Y٥ȪŸðABÛ@C[£|ËrIË/˜IsÀC vùõ¸õH ê3{æâ~µC+¤àŸÇ^÷(ù^œ(«Êh&lÛð5HG£¼¶Èý[BnYÚÏ’}`-Ÿ4za'-;•Ûu °ÙáiÈ!‘êi4×È(ü‡}Ë(Åi¯Qt#löjbj§mˆqœƒv»ÏÞ.«[ï9¾Ž¹[3öLÝw#cï€ðë‹vèUÃ6<Ù¢·Y̆qX³´Â'TbUñ”ÅÈïÅ\–™”j´¯à«ð1h;Ô|CHlÚ^÷ìa¸°Ñ}PàQ.Ætõ½¤'T’ŒƒŠ1@®îǸ}äs§ö‘†ÊïQy‹T‹Ä7¼âÝði1{? ÐvRÓÿKäqÄÖ…!hÅÄÊ>àÏÈ ºPÈ–°4CÚdpÆèØéìüvœÍ¿ÄØJCÿ§ñx“fȳHˆA’ú{e/Æ÷RÃ^¹ÕJBg‹h‰ËTˆ7¹‚™œØqw;@™R$q^½Ÿw" AÐu77„V:ªÈ¼)ÅËü|dðó/ÆúÂŒ)sŸ~…Þ±!OC[PE|ö®‘0i'§EBëÊ´–22Pï››žà%8~wsÃxÆ Á”Ï’@®Ô†²²±Ââ¯e„{sóì;'öa¯¦ÝN„lsù¹ Á"&Ôá¨pHðf”NÏL”yäoö¼'3Ëûð@¯¸2ð—w`ë¿1ÍZòÎa2wojZè5Ð ]Ž NjÇë§péÛ<%•èvàÚEæÅy2>/å`|Ï»–ª]G UhéG©€’–y²UÕ”ósߊPÇ€w̨977rú„û 1#]çqÉp[‡>¨a. ´dr¸¤aÓ…z‚a‘¤FðyK¹œS{žSNÈ1ö2 M‹-/P+ЧïyWÇ:Y‚Ф:ÊN(‰ó 7IÀ|*·¹¹“Kà€Dƒ°_ªÔÍrÆjýån2Ġг¿×N䨇VúGŽ×užf€a âJk»å­G)‹‹qJxÇJ||-ÎfK&ŠÓAìwÂ,$[±ûqî.ö–µQˆò_À{€˜3ZõÌÓÆŒ{¬”º“~eG.G¤"¹ðZeaê2öÀ«Ü¿Ûó‰ÎñšñŠŒ8 ÁþÑÅ@“þºÆ¨MkÉÅT=EyYfbAâgi™É÷°é³6ã96£e­‡(bó1n,³¸lƒÆüR‚ݲ<ð·ÄŠep—)a «TÔ¬˜U™ÿ\Nšy\¡w'¬+tª[^ö•ÔöHÔ6ƒôAÕofv­d½Ñ“6}KL¥9„íØŒN̤Ê#×O#]Jáo%x8(o‰ÿv½ M(øítTéú‹Aƒ­¥³Îâ…9¹BÞ2ˆ…Ež #ñ$¤Ý”U #'8[Býh¤CÞ«S‰ç}ÔC,oÄRðo^xôÐx{VñíIé>Ïp¾5”1+×ã×p×qk#néÔECŠâx2»ª—Ó‘ìÔçnûD.}öÒ+z÷KÝU|CTAÀ_YeÁ×#5m–K$ßý¸Ÿ¹‹µ‡Þ€ËšŽÔ   ÏpþŽðK]R$¶~wo8H{m`åþ˜Yê¨<>\Azǘ!$ ð÷nž8;@‘7Ó|8°¡‘#Ü âžƒARïúò¸:o¯u­\hÂÐ9ÊÝßB窇®eÔI ‹å3¥–¹ÐÝtmÝró3$7Ì£ Žbé Çe¹PUž¿sõ}M¦]‹’g(á ðuvöÍg™ÉíbQœ'DdP»#Æê5,±éd;¹ ù0DR¾ ÜtÖEñ4.¿xí¥t#^W< FþâéٵDz˕!*ðÿ;oVAX–,$MÝsÿAwe¨ endstream endobj 355 0 obj << /Type /Page /Contents 356 0 R /Resources 354 0 R /MediaBox [0 0 612 792] /Parent 346 0 R >> endobj 357 0 obj << /D [355 0 R /XYZ 121.4 736.262 null] >> endobj 358 0 obj << /D [355 0 R /XYZ 122.4 682.004 null] >> endobj 359 0 obj << /D [355 0 R /XYZ 122.4 587.911 null] >> endobj 360 0 obj << /D [355 0 R /XYZ 122.4 481.862 null] >> endobj 361 0 obj << /D [355 0 R /XYZ 122.4 411.679 null] >> endobj 354 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F35 275 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 364 0 obj << /Length 1781 /Filter /FlateDecode >> stream xÚkÓ8ðûþŠŠ‡+ÑlœwXq§·ˆãÛã¡lã¶iܳ“]–_3žIK8öK3=ï‡ût~rúB¦“2(³(›Ì—EA2É£,(Êx2¯'ïÅÛi euSM¥è¦3) v:‹ãDÄA‘'ÓóW§/âðàžHAå“î%œ ÃP¼>óòïóiTˆ—Ïñ†X¼¾øíbŽ,ΧE"æ¿¿¹ÄûNžÏOþ=‘pA8‘;±â@†ùd±9yÿ1œÔ°õjqYLn<áfgyÔL.Oþ„iÈNÊ¢sâÁ[㼞ìÈ&qda2ÐÁ]<“gÂXú¾£J€ß>ßá™ÂeY:\ÖªÕ½™ÓYšÇâWƒ¦¾ñæ''ØGÀ±ÈÅ®n‘{.jÆZzÓÐ#Ð`x2©ÓíB‘œ‹䆃 <ýÙ²²¼«[°{Õ诪Þi‰žÉ8ò$;¶óWe rÈSÌŠ„²¢óvÊrŽˆ8ËDk:Bíb± ˆdžLJBå“T\‚×¥PD· ÁkE”hðme;½€8´·D³4|¹UNuÞw#ñ±©ØtQ%ZŠoQ^Šw3öÑ¡/³$ˆ²~ñb6*‚®bu»"è –@Ö4‰²ƒªâ퇷ֻþZ×Ê Gý†»ÑwßšÖh §Ñ|£ôËl°©3d²3Ä,‚PÆlŽŒõ‘ 2¨¶ºjÁÝZclDfÀD¨5Ø,aŒE‰“H<30¿W ؾutk:ʪJQïwLßsÈ}r±È|àDèã8iù°ë™fÄ¡`*|ãÎÀtB»:hã2("OËDX}zÑ¢$ߺ©¡†&?¬öY Ùz£PZvްÎl|ˆÂ!=–±ÍÖÛ5óÑສã•ël¿èz«ø¨¦ªk˜–3?†ïÓ˜i$þèÑ»M¿õ Xˆmß45ÕŠöј®z´æ2ú$‡¥ÄeTbŠêÝž_ ;ÛqžÁÈëb† D%R"J2Ê*ghÓõÛ­$c;Uƒ—Kí 3"ì‚‚ËTq<@Ož UŸÐB>¼úJ•0Ð5KÈkÏç¼åCÎéU»Ùu=ìåfI{Ýšo†â²yïÞXõ™Ïøð2ÀÙ(Äî¼ÊÌ×püBÞÞ´Æ´`»ç¼á¢0”=@~þê„øì-qKÙkù²­U4쨶öÚ%qä½sÁÜâ)ÓÓ¢6íÃnL…Ï-¿ý@S)n|Þ#Ä“3 û/eT²Œ¿yá*å@X›ãKB!÷"àçgpü-©/[ΦÅ7Å]!ží/FÒ}­>Ô`>ŒNµZV}Óõ•uEy`ìñ¼E,9ЈDs?©µcËiìÞ72ÇÿY&³" Š”‹H’ ü£«J endstream endobj 363 0 obj << /Type /Page /Contents 364 0 R /Resources 362 0 R /MediaBox [0 0 612 792] /Parent 346 0 R >> endobj 365 0 obj << /D [363 0 R /XYZ 121.4 736.262 null] >> endobj 366 0 obj << /D [363 0 R /XYZ 122.4 579.4 null] >> endobj 367 0 obj << /D [363 0 R /XYZ 122.4 245.206 null] >> endobj 362 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F11 176 0 R /F35 275 0 R >> /ProcSet [ /PDF /Text ] >> endobj 370 0 obj << /Length 1674 /Filter /FlateDecode >> stream xÚ•ËrÛ6ðî¯à­PZÑ|?Ú“‰=N8Õæd:°I˜ ‚±•¯ï.”¨„‰Ý‹°X,ûÞ…Î'§aê•~™E™·Xyaù‰—G™_”±·¨¼÷ìŸY3¡eÍg!3³yÈZôlÇ ‹ý"Of/O/â`Ä' ?‹r/ a ßAÀ®Ï^_þ}6‹ vù9ÄìúêÕÕ¯8› [\ݼ¾E~'/'ŸOB`xá^¬ØƒÜ[6'ï?^G/½ÀË»·„g¹T{·'œ£~qê…¡_¦itP0+ ?‰sîR(¡¹”§ìyݲå ~>u¤Ü‘‘oõÉcŠŠ€qcD³5ìò’™–ÖJðš {i6D¹>ˆ\9@(~WØ% Ö[¢ ?9®ËVk±4õù peÀ6-RÜÏ¢œ æ‹4Ñwm#P-T„LCŠ,y'–¼ï[ÝÂý;Êi²qÇe#ª¾–jíd¯×­Å§ãF‘cáXµ[#ùÅsÚ­Z'áÖ*)4 ®–Ÿw"$EÎ:¾!™¶Š`¼W´:®ŽR|Á÷%¯k¾³«=uëVˆëcª¶½ù†±$i¬Á½5¸!2† áÁ½Ô¢›R¢’Îuð]ÑÂ{†"¦8È€’ÁÖpÅæ ÉÚÁv„¸£S]t¤oîô%ZG›Æ~0ˆUwN %@°±©a-€é|úŒì‹é`ZW%–õ “â`à1KÐñöÊg§DÚky×r÷·™‹YWúEB¾åj²bÆ6˜©=F@œ'¨q¡ƒñèN®çwÒÌ…ª$Wçò¹D.ÀNünPfâ;gQÜLa^õ–Àáµ­#pD™_8ã„ìÕíù›0¸Wö† 6![kEAO2èˆcÇñÉð"Â0e׷羃¤1µ[Å¢ïúÎffì=x&ø=L?Ò–kÇDµ†€®ßR˜µšê&àxG+\¹s-Ô/†xÞIŒ‚m^M— ¶Ùr#!((œ#Æìù¯¿>!,.ÁVäù70ÒÈ/â UœªI–²hÞË7ke6åPà徤vD÷!H¨ØõI >ìWR²ãéÙíQÃiÉZ ÜBâkMÀ¾NLM 9$ "ªN°—€AüVc Âsñ¹3¥pY-,#[Z²4t6’xoØØÎ„À«›[Öû³í`u¼±sôÚbøLÔŽã`ª–À €½ÌÕ#t?Å ƒt¨ }šŸ>·[ÛÛÅR®v®Büßv†=à à*­ã˜»o»ˆ•\UTÞ å|Â\?¦%-&×®3†ì ŠiÍQ§Õ•/ðZ~å¶>ªÔ»À:a;ŠräAe Î8.«¹^ ‡Ákm£ ÑïÞ!¢í‰iŒH\ílœT«æÐ, ̧Šx× šQ<¦IŠ“Vrh-™p/mCOá1@{qpsoõ´;¤ÔÓhS&¥"œÛ!6‚8yÕØÑ¡â ‹š>œŸ_ÿy}sóæê5̱!´¶}ÀÕ4èÎ ‰¥²3zé§^'Ý|ÓÚ­çm¯ª'ñ;ôŒh4²aûÀ%bhlm@÷ïèDÀðçü@4fà ÙI0-L#²„¤É0ŽœI ‹8$ šÔN8@OCŸåë8‚Šdoh00$(„ÔIàCû$F$hÕÚù ` DZFˆ“ŠÄG˜Ü ÀH ‹oiÝ·ÿ$€ÉLhlD#8° Æ ´°õ>¹úæFrŒy»šGSzt0c$#;t˜YPãßÒPÄÇ áCSrŸ•í¡â)׊I”»ŠæÄTLªv¶ÌÊÃl‰`²N+2¥´QÐd_ׯš`}S•x ³`èôC] Xñ`áýž€eè’á-Xûðæps«sµ}9E®}´ØÈÅ zxƒì#÷ð¦f°!rñ‘ó}äæÅá¹² #×>îêšH×Òyf:rã¢Üû Aä±÷SáƒqF×|ëPå#˜¼W”?Œ3{ˆþÀà Ñ_‹ò'~}ˆŽK‚˜Ió㺋þÒÂôZ9¯“¯{ÕQ“™ Te۸მð;[Ì`uS.< ¶ø®Ñ’†;,`+Љ0Ç<΢‚ÄI²á/„ÿê\kà endstream endobj 369 0 obj << /Type /Page /Contents 370 0 R /Resources 368 0 R /MediaBox [0 0 612 792] /Parent 346 0 R >> endobj 371 0 obj << /D [369 0 R /XYZ 121.4 736.262 null] >> endobj 372 0 obj << /D [369 0 R /XYZ 122.4 682.004 null] >> endobj 373 0 obj << /D [369 0 R /XYZ 122.4 561.677 null] >> endobj 374 0 obj << /D [369 0 R /XYZ 122.4 469.907 null] >> endobj 375 0 obj << /D [369 0 R /XYZ 122.4 373.489 null] >> endobj 376 0 obj << /D [369 0 R /XYZ 122.4 303.306 null] >> endobj 377 0 obj << /D [369 0 R /XYZ 122.4 209.213 null] >> endobj 368 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F35 275 0 R >> /ProcSet [ /PDF /Text ] >> endobj 380 0 obj << /Length 1880 /Filter /FlateDecode >> stream xÚ¥XÝsÛ6 Ï_áËËäk­êûãz{ȶ´—.ën«·—¶—Òmó*SE5õvûߤ¤dj›u/6€ ü‚ún}öäY˜.J¿Ì¢l±Þ.Â(ò“Ee~QÆ‹u½xíý¾,b+Ѱeèéå*ôZ ÔrljûEž,ß®_ûã,Á"ÜŠý0ÈÕáìõÛ`QƒèÅ"ðã²XÜÅÃ"Îr?ªY¼:ûåì;Ü_œ.ÂÐ/Ó47˜…ŸÄ99wÑu\iÑÊŽ6r' ÁbÃÉ—‚©':úßàŸÇwBJ!wÄÓ-ý³º&¢ëG r¯Uš8ÛÖÚaƒCþr•€©qUítª^).1º9«•ŽªZ#ù€?`Éì wBq Œ‹@ 3è`„^'džï\l‰x¤ïûð‚Gw®T«ÎIØi¦ùÁ:Ó=Ffî1Y“´j—°Ië Ûñ¹9´2yxBVj͹®÷œ°Ói©ªí%®£9¥öA‚šw•6# « ·B’x0…nšˆåƒ›Àíx…!òÀ2 ¿t.òÌ«[“[ÞÑP¶‰!ëe9¯.½ìˆ<™ iHzšÞEÓ{È”šÈæé\dq…û‘Þ}7LšU¥còæŠwE0ôži¢ªÕ´U4±Œ–Qª†#t“È çBíz¶Ap¢ÔmH¦ìŒÐͽ5¶u‹ò9¯mmó1ekÓk"ÈHó°qʦf&ê èÚ¢ávy3˜á„n*ewJ–€ÒOÒ„–¾f¶ãÂý#?Ý.cȽ2YI¼kq‚‡•“õ^tw6Z§@[æ•xÄIåÀ¸˜a˜‚äˆÊ ú·ª£Û0zoP®›TûäjTÞs5ô³8"WßÝÜ<»º¾¼¹Á`òa|}õÒ﬷Áœ™Âwó~‰Æ&°,¤p¶ß}^%*Â/¨ ¢Ä/ƒì. þ“apUbâïj" Fåšcœ%wcÞtSZl‡¬?áç=Ì¢ædVP7ÛA¸DzæãHVM_«cÕstwêà´W7•u`ɲkÞú’Y_ÜÄ=g5WSs0P f„VÒ˜ ›%ðÍowÐ'M®¶¬â=Zä¬Ám;õvÓFრ)”×v7ŽÂÔOJ ÎgX‹ûÆ”<+“*ËgÁ½0TúHèJlLþœ:ëÈ]æ ”>¤6óR€Llwì/Vˆ á \à²öö8@-*K#,òb'í`IJcôÛOCc×Ú$‚CϺ)ùqBÿii3ë=ŽŽL±ƒ¶«Û½hœ ‹{Co-µšË¹[®Zµ Þ ¡ÖÕ=]¹‡h¡PÀ¡pé0‚v'*Cg@ËÝh¥V©ÖÄ0t14ì;QÅ©’ †BÉw21{h¥‰X%ز ®bÇ‚íÒ.q`|„@Y-JÑŽ¬®â;«‡îûÚ ÷p6‡½ÌT(<¤ µts ¨VŒŒÐŽ,*²ÚX¨+Ž«„£Ì ± ZÄ[ɘhÔAÑÄ•gÂãý[¡ù‘ÂfH¸€¿X®žÐýßrõè‘]óM¥Dµv  sýÇ`gâÍÕ´ß~Rói÷½Š²)‘ÈÜ XC׈ì2NlÖ:-Y³ÆôaȿߔcŠdBÒ?=2D9ãØùs9Xï9:‘Çè—i¬‘‚u(ãüw¢¶2¼ÖcÈ1ZÛUÙ€ž£ö¡U–2=¯¨˜vv&íñŒ—Ø÷ž3Êï·Ô’m=zzŽMæƒ3üÍ_Ïäõi½07Ê$“P"ŽLÉÅf1Š@°Þz®ˆ¹n*E:½'p¯JÌëÄœm¿¡ž(bà®™R Ù'z-¢ÍÖŠü°ú̵҃à“]Óé·4¦;­úJ?é%DÝZý÷æÑvêhdÞ8áþ©Z%aéýÀ4#=³NÇ6d¨p†JzgýÛ>”ûN™{T«á9y€RÉkÛ•C& 0'ž†9#œ¬¢³DOǯ¯p%ë¯Ñ÷0Û|ÃH fã[%‰î{B2* Hmèåkâ{k" é¤yxcóMÌd¸ˆÖ56#Ø~%If¯R0AC½t·ÃìfF@̱õ²‘Tîˆ0êBÓ²Áê `ØÌ-Å!À¼áéC£á¹½É1ÿçOWæŸüd`¿ ×”)÷)€NÛ[iK_”0ÃöILûlÏÝsXî-‰OD:dõü'"Š—h¾c{[@阠Ø:¦±Ÿ‡ İô‹¢ Iî¾æý¢Ën9 endstream endobj 379 0 obj << /Type /Page /Contents 380 0 R /Resources 378 0 R /MediaBox [0 0 612 792] /Parent 346 0 R >> endobj 381 0 obj << /D [379 0 R /XYZ 121.4 736.262 null] >> endobj 382 0 obj << /D [379 0 R /XYZ 122.4 682.004 null] >> endobj 383 0 obj << /D [379 0 R /XYZ 122.4 538.152 null] >> endobj 378 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F35 275 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 386 0 obj << /Length 1741 /Filter /FlateDecode >> stream xÚ¥XKsÛ8 ¾çWè™Ê3±ª—õ8¦ÏI§Ûín¼{i{ e:æD¢\R®7ûë @ÅJ½Swz±@AàúÅòâù›dÔQ]¤E°ÜIšFyP¦ETÕY°\ŸÂ¿gUJ£Z1KÂa6OÂ3›gYfQUæ³/ËwÏßdñ‘ž4©¢"-ƒ˜t$5¬‹ã8|ýáí_׳´ ß¾F Yøþæ·›%nq=«òpyóû‡[Ôwñzyñõ"qŒfeQ—AÓ]|úk˜zÄQVWÁÁ vAV”Q TÜ^üqñÏ—Ö߯¨ª(ÏJ²m­¬Xµ’1qFšGu\ódÕ9 ¿ba0½í ÙIÇ,òʰ߈YZ†$³šÍa–ì­\Õë–Ô†¾ÃV’†UÛÚ2lPí=óXK*}G,6›õ)K_Á»:Õ‘ÚÎΙ'IT/ÓãÏÓ¼::Q‰¡F–¬l7L[üÖ`„UkÍæyR„Ë-±«ð€» –iú®£Sâ)F£w¦Ç%ß@-â£÷;®Œ÷§Œϧ° y_¹Ï]˜'áf¯q—«z-Z5øÀ,;sÓ¿}°Î*ôo‡P!ßß‘„X¯%ïHqB5Î8Çcs’‰9%šsl{A¶ß£„|8 DoÖ6"äM`:¡¼”M^?§7$;ÏÊÂë<ßÎ i‘´à„L¹;=¬îâ*Ý´{¯a¯w‚¡„¶¯‰+Œ9^:Ðè›1V´Äî )¼äE–¿`‰fí»EÄœ 5E«ßë5â-Ï×ÂJ*Ê …˜Í8݉Á½•–ÂxáÖû¡§™½¶ÞŠÞ rýã˜>&³ 0!ÍF4g‡ÆA„–€y\‘õHt”·ëÑ{iÁñpÙr5l‰º“ZÈZV°ƒ jp±a×ú}ÐHœ8îSÇ¿eÅà¡4Å0$!ºí¸° _Sô+†‡èŽ2øè^†€35á ™9Ìš‰|ÅÁ {&X¬¦¾;a5)p!Õ¢£ò˜‡Ê¡ ‹/=;évFõÊDquAm®ˆØkõÕUÇüQðÒ÷‘õQÞ¤uB±GÂëCo…² ŸY–1Ì è¸X;.Ï™;ô-´OÔ:‡“¸•f\<ôô/(löm;ê<å^²ñlïÙÆ-”Ú°÷FÎNÑ—1×hÆÔ2šYp¦ÏsÍaTÇ÷er)˜ ú‚ îà¼?‘öv0¨ø,ëoIö©øšvéç 2Ýväû¶ váA·UȹÂà'…§PÝË;¯o„¦™£/g G¥lC¡^7'-\ž7\â''?–©¬ÎÂb‰ig)|_}¼!“­{Ì(Ûdöí«…áE¶\)ˆÑˆ¶µDöš¾ädfb¨N¦ûÀÐøÉúÍë!0=pJãnÉFÁýèJÆyI=t8îŒo™[ÂÚ÷]ãÄì| ú|ÄÂtPæÌ»ç±—°Næ5\wCÔ59ù„M(—P\hŠÚ;£éª«iJ\ ~÷XoÑ4¼Â€6Åš] ³L#¼Yºò4ÊOZ&öûŽèÌ©Gÿ¨a‡rþdc‘DÚíã„5#rÎ/—+å®fÍeןkz-G¦4¦7~°[¹õƒÏq–ke·èx]*½é¯» Ðv¯ïu=o]-·ýà0š;?¦9 äbÌWHšKðôº“ª[My˜£[Ï‹0 ýÎÓƒËìqj¯ç§‚õXað°Ü›@Àh<'µmûðK9} Oš¼VÝ•]áh Ü»rŒÈÿm¼” u£3«€ß—[âÂ7¥@lŒ’zmiй§Šk?âl:g^I¨!P.Æ’šÆL[³àVNxQf,K s·÷%çTÌ>Ç‹˜ò)æÖ©—Ï\óVcDÝv%%J'ÜŒ/Ýv b¸„Åp2qÇäa«¨FаUvàM¾Íø€Pøôd–uD Ø&hG¿hRœ²zôf¿¥„þÕ á<+Š#Þöú ÊV@n´ÌyI ¯“ó€åœœÂʪ]ûVæák8oÞf W©cA LË2ü ÇiÍzlO êqò[éý¯Eø§„Ͷ Ö ‡NFÿBäî¼þ?#é+¯— ³ØíL£§0Ú¨iBZšóCyThû±–wO.½qÞ{h‹ÿ÷:”ý­@#×ÉJxYðÁøM9nÿäJfvzëÉ"‹Ê$æØåÿ¤Ê+ÿ§Ø•.&O endstream endobj 385 0 obj << /Type /Page /Contents 386 0 R /Resources 384 0 R /MediaBox [0 0 612 792] /Parent 388 0 R >> endobj 387 0 obj << /D [385 0 R /XYZ 121.4 736.262 null] >> endobj 384 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 391 0 obj << /Length 1719 /Filter /FlateDecode >> stream xÚ•ÙrÛ8ì=_á‡tFžÖŠnÙíîCš£›Nš¶±ÓÎlÛñªms«ÃKJÉd¿~”z¦Ù' â¨×³£“K?LÜI$ƒÙbà Ò qÇ“p0+_œOÃqè%Ëlè;ípä; j8 ÃÈ Ýq ¿ÍÞž\†ÞŸ ðÜh<âxpÎó<çâövŒ÷·S<:§7çÄèóÐ÷}çôöæ ˜ß¼™"Ï£‹ÙÑ?G>0ñ~/Zèú^:È«£/ß¼A[ožNƃCX Â$u€ÊÁôèãÑkÔ1˜ü¤c2»Q˜’|Ç‹f rލ_À>^äe£E¿*¤^ƒ€äq8Iœ/š……¿zaÚé,cÐôx±mÞÓÁB÷ gulñ d+Ȇ;¾"wâ%ƒ‘»“ˆä¼”¥€cÞÄ)„Ε\·Ò€ð=gi- Úlþ®m‚h‘=ùáúŠ€<+KM`5 R§Ó-­¾Gà#&ß>ºu)JïGNÝ´tû³sÀ`ø‘ﻓ8&‘V2G—¯Èá²ÎËø×I@@W¹³àå:SY%Z¡hiô CvÊV‚%•õ’Ùdu‘x³.ÙtÇ÷£Þ¨€CyÇ!Ú¬žæ÷uù8EIŠ¡–­X¢ÐQâ;‹Fa²TÏY«‰(S‚Ý­I“Fµ¢x!ÄÎ3 ·h9ÏÀÓV¸7@耲ÄíÙ¿;ì}㖾ؽõ×ö‰­}:ˆ”üâÁZiÕ”……ëÆ$OŽ«¬^öiÃI¥$67”È$¾7<•M©`ì›=%*»ÂR#*&N"'+íŽm·¦ë…ÞÒ•ö·¥Ü× ••ØÇ=È¢]p½Ç^÷‰ùiYRÀiŽÇ\.9$K eô?4!§LÀ˪VJ ±K¨Êeݨÿã#w4ÕÓ¢Ö‚4rІÓÝw4aLR#°/„1 ¤¡Ó¬M+pª©³’v3µì*A‰Àô sû ´@íFÄýfœaÙ ‡¢xÑÕy+(‘‡…¾gôÁ ñ›åyS­K©WŒ_I¬YQàqÚôvW(¥¦oC™m Þ²V3gQÉÎÔM,B)Dñ!Y—¢ +¹÷«{T2Áņ¯©v½¸«šj˜:EW 8á?½)‘•¨0¦¿ÛfÜêi¡q ÔXìcÎ`!50ØK«é‰£WMW2ÕÃЄÇZ­•-Ъä<ŠÂع1–F ;M€²%Û8R~À65„-º²Y¬d}ÞaÊ3Ї Ž÷Ã9N8œa‹{-öb0¦`#`­h&‚á[‡—­P7j-9ìa+S*ÃÝGýôtm…n×e§!gúÁ€+\'ìŽQâ~ã’4Ý©í/¸u-wЕ­+µn3ÊP V³µèìùó“é£nEuÆ@>î®õ¦GlÍlq„àéÏß–Ïs'~ šƒ|^Àc¤!A´—/1Ë9¢NA{L Ðg%ì‚ÞcÔ#Õ«Êv¸ój'%–Roæ[OŒ¬t#-Ji“•ç‹N½]výD8›Ìà.tþ–»ôÓ3›ÜYeíÓòòÆTØßëá„Ë4}7£:e j(³¼kl߫Р€‡M/‹ÍÀâpLà߈…”æNdr»‡2ò©t%Í À)Eìp¸Õÿm‚Iä¢ !<+‚šŽw)¬ÒLŽr"51 EÞbmñR®-¸‘•ši?]ÏgWï.æïî®Ñ$³«×·‡¤ÎQ¬&¦ÍÌ› …°ªÔƼ "1†EÖ¶ï•L&a¨¡/Ôo`vÍÁî¬zÖp2—Ö\³/¥mšˆ{X –Š_X[È- ùë€&fšy±7Mó”S°¡9ø‘´¸›Q¾ñÖcÍçÇZèóc-Iù±–$øX#ãc_j?OKaè¦)'çgôA¦jPÁ4WxoN´èM Ð8û^¢‘ BP‡· Z“º ! Ü×ÝQ’ð> endobj 392 0 obj << /D [390 0 R /XYZ 121.4 736.262 null] >> endobj 78 0 obj << /D [390 0 R /XYZ 122.4 280.955 null] >> endobj 389 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F28 142 0 R >> /ProcSet [ /PDF /Text ] >> endobj 395 0 obj << /Length 1588 /Filter /FlateDecode >> stream xÚíXÝoÛ6÷_!`“†˜õ­n–¬i.s±$X0´Á K´MD=I®Ûÿ~w<Ê’2mËÞ÷bÉãñx¿;ùâ~ñê-­”¥‘Y÷‹{ ¬Ø‹X’úÖ}a}°uß,3‡Û³ä¶¢q–¾Ø>KâÀy¼÷ê­ïŽäxžË‚4´\’á¹pÎu]ûòöÖñûýíž÷íóÕôàpÎíóÛÕ5_]Ý¡ÌÅåýâ!®ÅOªùŒ»±•W‹®UÀÖ;Ëe~šXGÍXY~3¨Òº[ü²¸ø›7FIÂ?&ýðYSËzÛ:K/Žì*C=¿à$¶³²U´¼†!±M¶¥Zgei˜ ÙfëR=ãp\Ö8ù„?ê ® U°k@víTCKGÙíèx·ƪ|¤¹ï,yoÕåC­–†-?b<8ÙþHï"¾‰!Àð. ÓÈZrÎÒ0$þ´ÈQ×s–QÌíû£nj·;u( ¢O–ÀI6x(#Ï€WB/´×Ct Hˆ*€³£$žê‘ã÷†ÿÛ9]×N<ˉ´ˆ8ÂsÀ›Óõz[«†P9òÌ›‘¼Y˜ H©Zƒ>Pía Ó¶ýa¬ ‘Æ ÌÿŽ–'°vF/»çBG‘ Ì9Õ4"ï«.%7¤›É¾å)`Í3æ:¿»»¾Z]¯^–v—M£4´q“rHaÊé±Ę Òš® ˜qT ÖquÂD®j,EÖûƒ9ŒâtÌB‘Ià¸)2#±YY)@£™0ÈEÓeRû@G- ']ö„fg'·;C“ùwµÌ©dãb)¶YùÒ˜6Êcäe³ÑI62ÓHýzMÁú<^­ÞÜ8idÿöoAÉÿZ ¸/@™š†xÌЀÚÖµÇg‹Ü'/õ—>@C!JƒØP…¹]VF¼4â¡k‹™¯ä²3¹Q¦m`»ÏhDì©«})^¿X) ¾3õ4Õÿ˜ãxç ö¿E¦ï†}upƒidâÖPìôä©÷ Ìžu½¸4-Ff!?º¾/ 5gH™æ Y†s³… Ëš¶;SÕP áAkÙѨjT6öË”<9ÕKû‡E5“ŒÌ¨·ª¦) >]78U4¾nU¼X›G÷›ìPš«Ùs°74œLã›`zD™ä„'äÅÍOð¶‚á…Ù8:EB P’R¶%hW]C4™š¡ÌÎ0u\°A¶02Œ“¤?PÉÏ´£{QXX—“¾ýXô÷Ïöÿ5tTÓC<“g¸Ð2üŽðì+Q‹F×@DÆ„Ÿ˜^‹£nßð;z÷Þ•Z&-5b ¥C ‹Föß z~ú0Ô´Ž6€žYw÷m-ò˜‚¥ô׃®zu1* éªýŽøœùq8× ü@ÃG7t÷ ¶´—OQ°Îñë=)õ—ÜÇ1 XáÏvÀ“‹¾¡ÅðÇ 1Æf?PgT¿“˜¦€S=¡GÛaoðǃuqÄ•‘å 3õY̸ك¨7QèöÿFü ;|cO endstream endobj 394 0 obj << /Type /Page /Contents 395 0 R /Resources 393 0 R /MediaBox [0 0 612 792] /Parent 388 0 R >> endobj 396 0 obj << /D [394 0 R /XYZ 121.4 736.262 null] >> endobj 393 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F36 397 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 400 0 obj << /Length 2195 /Filter /FlateDecode >> stream xÚÕXÝsܶ×_q“éLxâ÷GmÏTN”T©*9’&×ö¸8wÇŠG2Oªúп½»Ø?NìÄnŸúB‹Åb±Øýí‚oîNN¿wÃEj§‘-î6 ×óì`{‘¤þâ._¼·~^&¾%Û¢K×ê–+ת¡Ó.W¾X¾ÄÁòãݧßûÎHŽç9v† ‡dx¬sÇ:¿¹Yz‰u}s‹ë}ëìê;ôËÒu]ëìæê„_ýp‹2OÎïN~=qAˆ³p{Õ|ÛuâE¶?yÿÑYä0õã±ý4Yç«×ÔÚ¶eV®k§a8³Ùï©Qýò×=éÓÅ÷Ò_~‰4w*u9ºð•ïÚ~.V`]7à+¿ÛŠî‡ÚÀÚÖË•[øM¬œæ2Õ–M+²®È$Dµ„Oxß?Oj0Fhûn@›]€OùaL[…GÕDi´üZ©b]J"u51å…‘Ô…žlÛº%ŽÇ¬ˆXWÌWo ¿ä­@ô¶Ú#ìÓ©±ÐVªÈy¥˜³{sX—EF‡í„ºŸ?ݶª[²MÀ"³´U?µ'™Á=Ž$ ŠÀNŸHªØ#ÃHE]±Ì¼øàø¾d–M[ï©WÃ[bÖ­æŽò{‰—Ž½Ä ìÔ‰€B'öˆùÍåŸoÏšñ©žydr© ˆÀ®y‘‰Nò°Û‰Žz›ØZ—K—-C]﵉pÆ\Ìkßâu§¯)(µ||€È5;òz*ù민%ÑÖåxÇÙ ýAV²e Wäù A]­¦«@ÏÓ\–|x}9±>s3$¢Öl» 8¥±º‘ÎW3æí8H \oÓJêÐɱ‡'ÇöøÈH#åcT>¶îÕ }æ•ç„¶…ÇnVxÖG{ÀO]äDÒ±„Q°eѱ3ã †]à:–B(+àòö¸ã½g7$øÝ*Šc ¸*uÖZ°dN)T]QèëíY³¼6êèëÎb3ëà:ô#×ÚêÛìÐP8Ä BÃø‘C3bïúê“à;â:œ":MEÝ^²{îMÝãkWãH‡¿Ô¦4²P‚±ìȹƒ€Þ^‰CÀŬ>´b«UàÈ»1 û=RKÓBrÔOå\jø¯óäç"Žïé9ç¬ H‚޹܈CÉç2çd+Â4Þ wÅ4aq‚b3—<|D¯$D~9µÙcQ–¼d€]id¶­Ì:°?8È—@çåõõÛ‹«‹»ßÂÏiJ†D0ÂO~ROŽüø§NDÓ¹ZÁcѶBçgVRæF`M-¸?ÏÒp-Ö¸¦e¨Ù$2;Œj€^†‡¢+p0b1-cƒ»„&Ž.\.[©:¢hõŠ€ô…[ ðž7,ðz‘ø z‘HÁ×Nã*"å1è_ àÐ@Û$Ùb…$¢>”k§mù°4@20àM…!@G»eº¬ŠhlÀ€9³§¬ÄD‡öKRc«³‡xÔ˜1=NÝ(D›ÔxcŽu¨Úº,©æ€¡@xÐýQ‰œ(NÙœñ`N½`bN^QSK&iïyçnW¶;š*º¯Y¼ f ¡5ç9åÀ¿+qjæÝQCÀX9ÛTõ'¸ë¯U_•j±òbß”rõ×N|ÿC=<¼€R7>BíͰø_àÛ²ûT’žH]Ëm"ªa}4]¿Aÿ3Š×ÎK¯þvvss†kß}º½øë¹¡óÍTzõ\3ö{tǧ÷ÅôÉ€ò7M­ÓS"\iÛëÄ$žÐîôÖ`¥ú•K‰çU>ü‰oGQ4ÿq,]ñéêA ´¶ï¥”Ç ­+J} RüšFŽ6Mj‰”Õpë>AdÎl}Ð/™ Êð¦HwgÁ¯OÆ‘ÏѦh £–ºC {B€‡àï°Æ¯Ä0¼"Ÿ_ ¦àEŠŽ8l[fÑšamD¡ ¤ŽÒþ+(úxÕ3¡#莕çr%9PdésSYªÛ$5 9w….rv8 8ab¯yNÆ–À.— O8\‹–:=£àYÁ‰Sè3À­ šÏNÀߞݞ_\}{ý—·—çw矙ƒA7€ o4pLæ…^ÿT \R@Jꩼm™z%fÍ^°0a˜M®9(bhDi°¢ijØ™Hà*!T¤£P PŠh&£fø| dŽ) hSqp¬ãZäDè+'Ì”Ž¯a M›M’~ûb?yËëe^Ÿ(äÈñ¤swk~7øƒ$ îyÖW\ þ‚ ôùêÿS5Øy ¯h6 ´?(ŽX ÓÃò`Ì®L¨Ñ]ëùõùD[ç³Ï)uØ7ºè𹋇¢žë“²²âô%<Ÿÿh˜ôVTÏjP5ýéàÿtð@C*‰±7ùé  ZìŽbOšR“2‹ñQ‰¯žÂ@’Éùdÿ²ñâH—ËS¡ÓrY¯Óå²ù‘ˆ@øe…3ÆíõÒ÷¬ŸÏo.ÏÞ~æÏ‡qàbÒeb1ë‘óz½óá8paò‰Ê>yãdíÃ2„¯Ç+Æñê{=–€¾'?£¤á1DãDÝæºþòøá-^/8:^ïÊȦ³æÌ)ÌÏ©Ážƒã³% p8KØÿkÑþÁe ‡o 3´»Я‚gq><6“ñù‰£KIÖãȪ¿ñ'ïÿ)¨nèÛ1œaå¥v’$t*Qñÿú¿£T:Ý endstream endobj 399 0 obj << /Type /Page /Contents 400 0 R /Resources 398 0 R /MediaBox [0 0 612 792] /Parent 388 0 R >> endobj 401 0 obj << /D [399 0 R /XYZ 121.4 736.262 null] >> endobj 398 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F29 144 0 R /F11 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 404 0 obj << /Length 2500 /Filter /FlateDecode >> stream xÚåYYsÜ6~ׯ˜ò>˜Så¡‚ç¦j·tzåµeGRÖÙJR.hˆ‘Xâ1Kp,+¿>Ýè‡#щⷭ¼hš@£Ñèþútxµ·*âYîçI˜Ì®V3†~4KÃÄÏr9»*f?yÿ™gÒÓ]Y©¹ðúùBx-Ý|!eäI?K£ù/WoöOe0’†åñ, aë‚ ðN..æa潿¸ÄõÒ;8?&AçBïàâü „Ÿ¿¾D™{'W{ÿÛ $˜‰A5é‹ -뽟~ fL½™¾Ì³Ù½e¬g2Iý¨jv¹÷ýÞ!ž1ÌŸœ1É2?’)éwtpyò#cÇaäçA2[ˆØqH¼ÑªkÌ|‰ÀëoUOTé~yÆ”õºz úz¾€cë¾×Oöh‡‡J³”–~7†–Êè__æžj 6±ØÑMúAœ:ÿsB}!ü<Ž£lHôºRKÞ¥]MŽ…eƒÜ/rc?‹2ÃKãÏI{—Z³´tÄ» EF`DÔ&¦E·}¿þûþþýý½o6Íõ¦3ý¢Ð¦¼iüe[ï¯Õš Ö™ý£M]—͹<ÿ ñZäy~Øš¾m>ÎÃÔÛTÕ4¥Â?ª*]í>uú³ø$|’S¬&N°_çg7MÛÁF° Á­èF¤î­ô®¦î˪"ªmпH™ÍzÝicÜb„ð*°9èØÓð%Ýjûs¾ ÓÄ‚fW(À6•ê5¯k»VqôU@< }:Ó¶b3_FùÝÏ®þõ‡—O&1#9z{zööäüàÝÉ7”õ,tÉ06EÁ@My¨ØØŠ“ñ­?Pdaów¥:{ò—,ªQµæyjQ´i^ö,ÕEµÛ•9ÁXQ…°‹'¬AÏC2 ¼µ"ÊeÒ_à†eJÛføœÚ•ãÛZ Çã¾0ãÇø†3À_Ù`*Ébnma„4sg ÈsU^w˱ºV­s›`²ÑŶ ÅÞñöd»Á­…^)›³­,ãžJ~àªäp ¤Ãñ®£ÿ$ØŽr{cùŽÕê7¨»ÉÄά¯ž× )èôƒ}€¸8x÷-7‹‚©K @¼{ÀmBÕ/ˆåñ3cêYC…†r¾ä;R*8šÂmÖnohª‰ òmеÕШV±'†¨4-½ ?íèGWýá%èoà9¼Ÿû¾·j|ûµoµb‡Ð».lÁ‰kY®_Ö‰Ù“ü?Ó T÷SŒr?Ë2:Fºÿòý]¼js endstream endobj 403 0 obj << /Type /Page /Contents 404 0 R /Resources 402 0 R /MediaBox [0 0 612 792] /Parent 388 0 R >> endobj 405 0 obj << /D [403 0 R /XYZ 121.4 736.262 null] >> endobj 402 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F37 406 0 R /F11 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 409 0 obj << /Length 2405 /Filter /FlateDecode >> stream xÚÝYÝsÛ6÷_¡éK¨4¢ø)QwO®#7n]'g+—¹i:Š„$L RȨþïo¿HK>fšöñž´‹Å~üvAý°º˜^‡éhá/fÑl´ÚŒÂ(ò“Ñ<šùÙ"­Êѯ޿ÇYì)«M>½f< ½;žÄqâÅ~6OÆ¿­~š^ÇÁ‰œ( üd‘Ž–°/oy?Ž2ïíýî½Ë»×,èÃ8 Cïòþî„ßýø€2/–«‹Ï! Fa¯Zì‡Á|Tì/~ý-•°ôÓ(ðãE6:ã~Ïæ~”=\üëâ¼c´øŸ;βÌOâ9ë÷z¹Z^­Æ‹hp‰¿ÿáK'JüE0MÂÔÏÂŒw.­­É ï¸SSO&kºÅÆj儬á7 ¼RåFvêfÇTÎ?E½G3­u…tÇg`'L×´Ë›Ž¿5%“Uݰø5ðÎ=…÷cLÂÐ_¤3Vúc§yÓ¨J•¯Æ“$H½¼Âí‹.¡ œ_ñ¸³@©\aµÄ¯Ü|ÉŸ_Îç,=KïIŸ¦ –…’¦w¯o/XÞþYVË¥ÈO¹­ÈŸQ—h@åücòÎ:2Ý4K;ŽÁˆïý´á;U•ßM\½WÍN“ñaÒAê¨=x9°¢©’M¢ä`ÉÈÛçÍ׳âÉ §j¡AÏÕ:qG¿e-NL`O6¹m}³­ŽPÿh†fA/#%áUõKGm Su…i‚”k«œë6+$BÏ0Æ4<-ê²:¯0fžnž ušð±#Ñ"Åîã"{ÐöõàŸFâ§FŒÙz¯ä]É£+PN7p àn®¿ÄQÌ££B·æ ²úK_p:wt;Âó/b8*â<è Ûž'‰ª˜°ªl Å´xØ2íóªø †R™Äs(+f_;TyÎÕ¦6yÁÖ›ª “TO¨b fH³À»Foummtba PÊÝ+®«Ýuø ËÛ[&ίåä̶q\=€CWC­ÂÕ÷ßOá´ýìGLÁN‰=à9üˆeÏÔÁê}ny «œ!,5ÿ>R7ÑZõXoE.ÆéZ*ƒa}!–©7µ˜%ðDGÛ!“×U!Іñ,h'eSNæI .þ4£¸¢J«+%u©¬« Kp|>÷]`Œ²Ô­¹é÷8KåxfÏÁ3†ŽKb>HÎÁ—öy64èÌŒ£çL`!h"2KÄX ËÆB?IT ~²Ìò´o2XTjëþ=#¹Úõëå»Õ›¿ŸI:øDJo¦zä2N1õT%U¶ô¾#Ãÿ¸Î"eºTl­ÈW‚äù)$#·Þ¸þ1ˆR½´IÁb”-j£91ŽÉlˆ|š»IªyÈUóç(Ï!êᜓ֊G6xgTU0Œ— ]1I¢™÷¾ÒŸ[9Ž3žmPm'éy¿áxŽ”(² <h‡ï%žÐó mðëª0-A ¨¾@ó¾¥–wnyë rt7ùšËe5wêDµAÛwúJ.ÖòðÌyÈЄñÔgF½å¥­Ø ÙÑ`©Ò>K/ùâÜèÔ·"cæ½l^k—¯M‡*=¸S˺ÉÉÁO}lÜ¥8öqgŠÄu- 32$ðgHø§è%²¹¢-g=ËĨ1ߨùt¹ûË»åý5<®Þ|ã£÷4Á›’ÀI—w@¸®íl Á²Õ›3¦™·ïažÇÚ1u½HäkzTP6!C_rá–øZœËÃ×°'ŒŸœâ§EˆNf‹SÃãP€;&{ØÅA—°HcÂâ/U]ËôóêÙ’¥‘¼‘á ÕqBBÄ ƒ-ðÄPïµñfÐÑòÍ`’ÝŒÕGÝóMk+B²Ì[ñœúã`t¡2ÚɆßP!ï‰P~O ƒ$Y[#+Ï(8¥ÝP—p°Ò]@{¯Êonº!ôno®nV£n„]Û„ôȉ£F0CJ ‹¼!Ù8¿?± ŒK4KaKžÀFC7çBr>Ä#ò×Ï‘Ú'\†^ Z!çrõMjû(9Úõ¤‹}°57 €:sïÃNÉ £¶²  Ü~q¯¸=îîÃ|¥Â«tmîàÇ®Q8ÖöÓ ‚ ½OäŠiwExLÈûç‹ãZŠ™Ûþ]àø6¡‡*f1½h‘¥çÍM_÷P|ëØ;üzIN^IÉÓ“4ô ‰ÉUÀxæ_ÊòÞ¹ø9Mº~¤sþ)”1¨hÚå[$Ý>Få2EùAC­@ƒÙJ5X—ç°pÙ@ê6 ômc2”/ò$ˆø•ȳ•ª& ¦//ÑBïWoQã7÷Ë—S^Ù@ëÙRɆ½¨ø{“_Nê ,ñg –ØVç½¼>}ÖK¡C/¹6;†*ÍŸ$ã3kïšæðéôx<ú_àX†BÆŽÚøä\»$õWâÿ›¯ O5õýýò¯ÃZu›Êe"wŸâæg6mUpo oˆHH*á€÷?"J–ÃM/®L_ÊWÄîE“Uý»®Àêw<úåt(ã¬Ú( ª"œyü¡€_¨!õ;U²ÈÁÍh=ã– † ú·)ì2'[j¡w²ÕÁ²‹øùCW»/ÊH;nM©‘År6üÕÌIãÄÊ[-*÷R£0ýy˜€Ç~–I §q÷OÅj^žã endstream endobj 408 0 obj << /Type /Page /Contents 409 0 R /Resources 407 0 R /MediaBox [0 0 612 792] /Parent 388 0 R >> endobj 410 0 obj << /D [408 0 R /XYZ 121.4 736.262 null] >> endobj 407 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F37 406 0 R >> /ProcSet [ /PDF /Text ] >> endobj 413 0 obj << /Length 2249 /Filter /FlateDecode >> stream xÚÝX[wã¶~÷¯Ð[©ÓÃ;ÅöÉ^{SåìÚ[[INÎfO “…³¼(Çýõ(ÉV’uû" À`€ùðÍ€ë³oÞ…é¬ð‹,ÊfëÍ,Œ"?™åQæ/‹x¶®fŸ¼æËØÓ½©Õ<ô†ù"ô:úù"Ž/ö—y2ÿ¼þî›wqp`'Š?)ÒYÀ6¢æAà]ÝÞΣ¥ws{‡ócïüú’ ý8ÃÐ;¿½^ñëoïÐæÙÕúì—³Œ³pr-öà Ÿ•ÍÙ§ÏÁ¬‚®ïfËÙ# lfq–ûHõìîìŸg/÷˜ä~d³l¹ô“8gWm×›ö¼ RoØ‹Râ=¢»ªo§®F¡æÉ5¾`Ks N*ᓺžUÖ48`•éZ±Y™Ÿƒ8Ö2dÓw Kݰeer0o'»Y„¡_¤){ ö­ÏÇ[[D‰_ÀÖ!è"¼º~{~q÷q^dÞ9þ¬ÿÁ3eš˜úEòÄ1ò°wp;J ŽýV ÜR-ü§÷oÓ–õXiÖÂÆ’Z·ªÑÜkwðz%î:Ñ–;Ütuo»zdúN [¾HÂÜ[SPÙhÕÊ,8 Êþs–=q:¦®qÙÐk» c×áV×ò?8Á±$%Ÿ>Šöɺ‘™fØÊhþsÑÓ4Yìó¾_ή-¸ú8àÖÀëU T%ËnNma´ ¸0>8¡8Lè„ì”s¯×«_a,õòÀŸƒ4Øõz£{u_?q7îÜ»àîIOez]ª¤éÂ&1«Nž2@Aóâ=,bØ2ÏÂu…rêÝKì©1Z]ßIœÁÊ2ீXy?€% Ú¢h£¢ìšfšT›VÔC'kî àíæéämA;È6C·c¶1€Çá\‚ÀèEµíƾ”±îDŒæ›FFñr°ÍKcá\Ñc|ï8ŒTz£Æzàeee&YZDÅ}„å¥WÉÂv cµ41JL@gÛ sš²gílöè>®ðŸ3Eæ˜bµ^¿¿|4ñÓŸ±Ä ’ˆÁÓ"ÞƒžÕ[…Û˜ Š[âQRC­ŠØ[I·µæ¡m¦K†cMkM%ÓáÚð¸Öõ™Á¨Z:{þGð¶¬\z÷5Ÿs‰¿àUL"oµ9 ŠðL£­UšNiÇÜ,Ë€ŽÓä E2ñà RÕœgÚ~?°~¿âÿÿµ]»¨ôsЙ`?ÉÉ„àж•zwxªjUÛÎPÐñöæÃœþi™ËrÇ`ÿï³ãûÕúêúru~ýj¸'ÁRàŽ’â¿*1Ô_\ÜPÇq/iÛØ64¹ì—5ÄIõ<°\ƒCj3 È(ë¶2s”ï,Gá\ëžÙãƒ}HýÆ×þ©³ùü-ÿŒt HIƒÜ»0Œa· Ê´ ¼ %øÑJqšÊ€qv?rƒaBwúÇ­®™€ÎUÏ÷§à„€zÙö¡ßBMÓ~—.­ˆHˆÂ§{/ì4CººÍ [!öqÊž¸?¤åfWË!Câ9ܹ­#!äo—¼q*±zÀ·oº„/óÅþEY$7¥£D .^@êZÌÛ(9Âq“±ÐÈBÌ„x«‰×¶šéí F*£Tqlô8UÐ¥bþ• vk*éÚj+£Œµ£¶R™¿CxЙ@íóÀˆ©–²°æf«‡ŽÌr«wµ -Üˬ±=ò««7§"ÃdqTSi(÷ ˆÊ2)@¹ ãŠíëý=ÕAëÕåíꇫ×ç‡(uù%ÚgqP­JmMݘÙUÍ#¨bhø€ É€8æø FÕ̲gª,Q\ëpà ÷¤J9¡m¤E*…O=AZ¤†g?P ’Xéò£dûÄü8¡Hd\Êà„šÞ(Y.Ѳr#ÊŽª¸~2¨dÀT÷bfŠ2o5°^*)*•LÆe»‚Ã)t×]û  ýèêGax-ˆy‘ÀŸ±tå|·Lcþ£„^þˆÍxT¬?¯Ñ™Í)ßÔû<•<¯ÞüaŸÿNŸx¯Gõúæu¤Í”Àp&rà‹îoðs|Füà:A <ß®pÇQ¶<0mìÁ æ4Ë+ñs‡´XAPhž½OîM–Dáþ­‹ )$Q<ðP—Cíô¬J¥ñ9”/„ËÒ§z 3n…iÓøîM ¨ÖO/#l´úôóºéz-`({=]1jžS>ÃPIòØ« RMøÛ=÷ŽÎùØo¤v '¤‡ñD¹¡”_áĶ%]LþŒ@É¥=ä±±6K]×'-Ñ+]¾‚ô\sá V>Ü»/nÁƒã}Gb£ràÄáâ¡c&X¤¦5H¸òÖܤÏ.?FÄY!üU0aäXUØO:>y4—ÿ[n—4FŒUlklÍ/£ qÉe!Ûßý¤Q@þ¥Om(áG7ØQµÍ "üÑXPd‡1œÂ~ƒÄàa*Y°Á §…\nÔJŠˆÇÙöp²'¿Åá“a¶øõͳ/XHƒ\¹];]dXJ-LJF^÷AããêúíÍõõÕÛõÕ‡ëÿá‹Ær nÁ…*(¯Ëb¢¡œhˆ¡j.\÷vF:·f‚ÇRЀ»¶"§ìSÈçPû0ï_U|Ïá“íd9¤ý¤.°JðOè›ÈDqSazˆàPº5Ø!Mù†‚ý–f†Ÿ¨p_hg‰|uÁþ2 pQV_É⚨6Ÿ 0ô;Lc?“tÀ‘Ëg÷4qúÿ Keoy endstream endobj 412 0 obj << /Type /Page /Contents 413 0 R /Resources 411 0 R /MediaBox [0 0 612 792] /Parent 415 0 R >> endobj 414 0 obj << /D [412 0 R /XYZ 121.4 736.262 null] >> endobj 411 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 418 0 obj << /Length 1537 /Filter /FlateDecode >> stream xÚÝXKsÛ6¾ëW°9Q3Mð!’Éôà8JÆ™XNeMÒN’ii²0% …+î¯ï.v©‡ÃŒ“ôÖƒ…Å»ØÇ· ÐÏ—£Ó—"´'™zSk¹²„ç9yS'N|k™[ìwãØ·e­Št,ìv<¶¢O|?°}'Ž‚ñ§åëÓ—¾{ Çó\'HBË%ž r®ëÚ³ÅbìÅöÕâå}ûlþ‚½ !ì³Åü”Ï_]£ÎÑl9ú< ÄµÄÎ4ßndeåèÃ'×Êaéµå:~[[³±´üiäx@Öõè·Ñó¯} "Çw§Ö4ŽÀÈÂ\6ªNo 9žxqd·šÆ\5{æÛ‹ùùÕ|>;_Î.ß.ÿ8Anl§ ‹¬SªÊU–¶r7E—[ ìRàŸ®H´?eâŽ;ü‘è8?ÂIÂŒK)X•ždºªdÖ:»]¡Æ‚v½ [sÚ|ƒÚî)¸¹\¥]ÑÒÚ‹#Ù‹Ëh“|Rf 9š6­QVðt‹Ž¤u¥ªÛgÄQ¬{«Š‚ET‰2]qèuÖ5˜^Ü#žÂŒ—äeâNy™ˆÄñ`4NAÌ//®¯/æ¯Hâ(“;ƒ(¼Gõ`:úØ5C×ÉCJö°+`IomBÓïñí dÎÌ·k•¡7kš*Ö]iÖYJJ±Ò• ?î©h—I˜‚ÆA)K¥(è %þbBk´À@a,€‘,¢TMéàUf6kÝ9Ó-¥Èã¹ÉJb7šeê£ë’wk>§]K"Ø~ r™imL&ÆVµëÞÊd¹i ˜ø#†AÁ ñ:6@ò䣺øùg•–'ð'ðïÉ æ/n+]ioêõ%Ô$ˆ2ø”®‚†jºÍ¦–MÓ c™O…](ªTbSâ¥þÆ’¦&ÀÇJánä Üû–‰(ûaàϯ¸Ý<ý¯˜Ü¥-RÑìrˆ”ª¾¨± þ Ü üGˆÿ€ÑôèÃýÜ•=ædÍj`ÃZÖG¨`ïu[¥ÅqJÿÇ]l1;{sþnùã-Ìó'©”†Z¦Q¦tÆF®êšË2—Êùå¦P™j ÀòìZwUŽñ6gi>©âý|wÝʱ .w\£Î¡¡ñà 9Pú…n8KzE‰ÙPI¨¦oxß¼³——gc°õ|¿W?qÄ}A uNéŽ&»Ë72=1J ¾¹ÄnHÍ<îÛ  4%¢Ê4«5‘ÜcjÓ0äØK}Yó­@Ì»q8µÓ¢“ØôÏ^éšä—Éà™’Oùi%=uDD*߉Ñ_PªÓB/´/ÏÎWD[ )?=uœÁ ç[Š´ @Ö¢?2ji¢&‚„MKÓF_‚/Säá¼kX*¥áë`³¢<€…XmZ#¡åD›,9Ðü˜îR³‘ŽÜ}l Gø>á¶“scâƒ¥ÃØ6`á×_ߟä`3R}e îèåW×*ß]„;9ÀMhpó(ÂÄÂô1,°s{=ÿ 0Ç…„NìùÇ–_ÏÞ,Îæ¯f?QÞ&bi{´%¸œkxE€C_öø[ΛîÚãfE°ÅîØ|onUÍ¡¸“Ù‡éS÷Ó³¡ ©JÁÅ[p¤ð\$~ÝKF L¡ Ù!.S¯¡ƒc¥iŒ-Èðá—\«ùû Â0Æ× ]›MÓaÎJ~ëiºP«^dãî yÒ‡·iešÓ¤âïsÝÊ^%Šɘ)]òZ–6ðÙ4€R:5þñÓ.9ÖÐ=Mv[œ¬Ò¢AãLøZVÄMIv Åàv›¦…‹µ¤Et¹¹©Ïmµ_óŒg¸>Ô¸³Lö÷^)Ó=<ÙEXÇø6İóa÷ªf1M·UM\ùEf]ßot}¨…™ÐSsç;ÛÇÏ@øFÞB*q—Ñ8}ðÖ“wúˆGƒ*¿Ñ†· ü8PõK¯ ?¾]I,!lª¨ ÙUÔVL‡Â)TÒ&Ò¸hn¡}5T˜chE/‘¯aØÿßâ_Rßnc endstream endobj 417 0 obj << /Type /Page /Contents 418 0 R /Resources 416 0 R /MediaBox [0 0 612 792] /Parent 415 0 R >> endobj 419 0 obj << /D [417 0 R /XYZ 121.4 736.262 null] >> endobj 416 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 422 0 obj << /Length 1851 /Filter /FlateDecode >> stream xÚÝ]oÛ6ð=¿BÀŒ^kEÔ‡%-°4I‡t«‹9^Š¢-Ʀm"²ä‰RœüûÝñHÙNU¬Áö´ëxäïûŽ~5=:~Í/÷óQ8ò¦ ‡¡{i8ò³<ò¦sï#»d“µ*Ä€³f0䬠 £(f‘Ÿ¥ñàóôÍñë(Øã†ç‰0º ØÅd23önr…ô;Ÿ£÷Î9;Œ/ùø×+äyt1=ú눓Àãh‘σԛ­>~¼9l½ñ?Ê3ok®½h”ú!@…wuôÇÑ+Ô1Ì¿Ðq”e~¥$ßÕôíôü÷A>bH™£„±Ÿ#oÈ?ˬUÞ£UD]êÁ0X³ B){Dýª–+«{ü‘„ôÑhäZ–¸Ó‹­jVgæ²0䆣œ²QkIçUI˜E]íØ¤¬ZØíæ%YÀUM;òA¬7…ûþd=Æ÷• üœ§Þ0Lü$ÉIÉïÀgƒa&ìû…*•^ôXgØGy¹,«Z•Kpn€u”F(f[”ÌÖm­­ŠvqgM…+¼˜¯A¥Õ´€RUiyÎÕ§ Ф=æXT5+BÆ{tCÔ‚cȹŸ' I üµOªDʰó|îgœÛXùðvru}>ˆBøy79fÌåÃ0wQºÔ gÊnaž,ho-šJ¿’zïpÎÎ^¼  –ZÖ÷]”Ƙ¹ªíJ”hõÞÕÊq;äjDÈŒŠÐc®R˜Ì{O[Ìi ‚´jŽ3á ¸Ê0šÏ {FÈYµÞ¨½×à¬,þ`Ãéèy“CÙ^„àb®´¸-$Ña¾p¦  õž8d` þ Ø[õ@Uëà)dxRY–Ê~[ÝŠ‚îÃ{ö…‘ðk°¿í;xc°)¥Eð¤[b×­Â`¯2À¦¹%´aiª*" EA|SanS‹åÚjQ#$13PÎJtaÉ]•‘Êv9€)¤)º"UL¹ó;V{åá|'úAUƒÎ*ÂtSÇ´+^¦À¶­¼ WÏÈ宺RÔv¹Åt'sžFYÞ[Eå6Úïð]¬k9k Fÿ\&I§)Îr§W¿¯®øN¾±V^`/‚‹S(^+‰éœ’1FJ€LmO©–À~#ô!í}ØB`Ú‘MUYn&Ç:jìŸÍ¦mhÏN/xUi„,w¸G/ÐÑeUÁŽê“¡MaÓ[SvYêF ÓŽ9öŸlKÇ({0"äDóME8aɵ-¹µ¨éHW+t±ãÚ¿b¥`S+r³I™y³z‰pDÉHè4‡=+Ø•[€'Zð%{ù°ò •qÐ;оG>4.†&ujqÌ^c8vYH£uß\q?J“Ãé˜ Œsõ¢ªNr¦Ft´Xß·W&!ÌI¦!Ï uŸI‹­ÀΉt¿üHß[¹„ʃ‡áIÇãÑ!ÜŽ½ñ¶Õ7[yƒÌµ, n0 ?†Ÿ±;‚ ¹¼¾?ÈŽ¹+XI´íÌ»!Û`m=CXYâRޣѱ¯›#U[ÏäªÀJþ“gqÌC׈\U㸃t…¢9¬›¹»{ʯ>Šâ ró ‚Ðòfîµ}B32<ÒÍ<„Û‚>oÚÛBÍL8pFA±¢óŽÈL‘‡äå²°Šº_•!gv•ظVÔw®"¸7•= j7„¸†ÑÍ00ØÔŠ"ºüLDO"?å1D2Dp–‘ÉÈý‹ö7Ñ!(î endstream endobj 421 0 obj << /Type /Page /Contents 422 0 R /Resources 420 0 R /MediaBox [0 0 612 792] /Parent 415 0 R >> endobj 423 0 obj << /D [421 0 R /XYZ 121.4 736.262 null] >> endobj 420 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 426 0 obj << /Length 2356 /Filter /FlateDecode >> stream xÚ­YK“Û¸¾Ï¯PÍ!KUÍhù&µ®Æ•uj¶\vbkãƒãJA$4B™"µè™q*ÿ=ýâKòÉE@£Ñèþºz½»úñM¬¶›m¦«Ýa„á&^eaºÉ·ÑjW®>{[ç‘§[S©uà¹õmà5Ðh×·Q{Ñ&Ïâõ—Ý/?¾‰ü Ÿ0ô7ñ6YùÌ#ôaïûÞÏ>¬ÃÜ{ÿá#®¼»wbFŸÖAxwÞÝówþˆ<¯~Þ]ýv ¢E›ÀÏVÅéêóUÂÐ/+móÕ#M<­¢4ۄЪV¯þzõÏn_œ1ÍóMe,߯ïÞÿeÇǘ©#Œ7[?]ÝÉfóÔO¨ÕÖäö3Ï•ãVÙi!5üµÍI(ES[×v…»~zÍ™ôhà¨'ó]9ÓÔ<±9ô\ieîÙóú6Ì<]˜¿ûQ¬KáljUÉ’–¿û ¶Õ¨ß¯xPÁml¶IÂ’Ë:/UûJ—›õmÇÞh$å®=6]Ur{Oìûy•Vµ–‘îÌwH‡¾9ÛÅø¶W´nS#Å™“Þ Žª½ƒß«´µÜjöÄÅ4 eµ øëŽFÆP›Ò|<êš[Š?'ÖMÙU²ÜÀ1•£œ–u øÓ0ÁvûÉR‹ Rï¾¶¦Ô3§|‚ù|8x{w7ü. Ú÷ü¡Áo}î7UJMœ¾F}ÒÐñ*¦¾Ÿ/l:+A¬,à­ùJú~4V÷|eë¹X ¶ñúílÛïùÓë5Cá„Äò2©äƽ ]L$ŒÃ˜.hb©Í™»úÉXg/ØáÅe‘8&Qè^TKV„2ÕKy4ª*ʽVÛ®rÜ6èWQæÝÝsÿü¹#,â6›wãŽÜ-ØyaÍwl›÷ø~`ÂCÃ_× ÛÞÔÊ5­Q"»e†n™y_­ˆÃ7;ßvá0æwؠ٭2>š"d‰Ÿ0Èo—̹•ygC¶q:Â$µ_„h¤šº¨º öÐzšX¥ëù͹«Ø'«O#N³x³Þ_ȇ[ºDœyb7^2ä!PÇl"±¿…–æÆYµÎ] œ"©³êAFQ…¸PqwâKÂç"t–LÝ#»i*KÁ×Xe~>É,–€®Ï3¶á$Ï€NlûTú”jÀ—Œ¾ÓT#ãEà ]=túWx‚y`§õ0fgû9§[^þähڒ“ …£ñêÆZ³¯t´’\mäiâåÚêÁÍsqóExøµ®$¾Ãüt+& ‘QªÌ}>Ë{ir7E× AøÄЬµ« s$LhcÂ…ƒ^†iSiЈ)eZrô¥ ŽB@È^YX@D¸(ÐÈ YnÐ,SÅSÉúpd}”!c©A‰£ŒqˆóÁ·ŠÖŒÐ[2¹«K:4{ÅÀ²’O¿,tÝ0ª39àÒ\ÿO{úªÑ–SÁ;ë-ì|‡Kv<‚ÚŽ1ãÇèW2­¿~¤WÍêÉ y¼¨þÁñ8xû iÁIÙCSÒNøfð°.ø/¹Õ3û)XØÙÑP¬?rW²<—؈š2¼B·à¯5DV¶kس½Ý*cê÷”´ÂXÏ|{ àÑE4ZLÚH(Šét,”„ÜqãÎþ$¥f0 .Q°‰²Ü•õY `&Þçð'ÿ 7ŸøóGþüóésC7Ëæàþaê½Z^·KH†ø˜68}Ò¬6&ÕZ ’µ èHª€‘)€ˆ©M"©MÉ$ ÇDJ^paUŽ1»M@u ~Xkª~–”ðýÚʉ®—ÔÝêß:P²ŠCïúé OˆÖBþNòA/â=zE&ØãaŒ²Œqóh™Š V¥1ŔٱÚÅðpwÏúôñ?@ &*Ó“GRêOƒõæxÈ‘ óœÕÕAзYâyý½hIœ.Ì“Dã²» ô.¡÷Ä*Õ%£¤d¡8ÚgqóP4“1‰@ö\q2OòDñ\9S(3¹¶0è+7)ô%«ýߪAxáS¸ øÕíSeÒ «†¾¢|5ÙÂÚ|ãè tS¡c§\×k%|xú3Á-Pâk,—ÃÈ»«@ÍP¬É F~Tpšr9Ä,=¤¸Á~þpdj$ÔÞïVÞ‚c¨>Ù/Û^uÐéU7ñ‚Qu° 'Oo®Aºë%»þd¨`Ž·½!Æù\‚Ùˆ²hv°Œ1÷Ð¥ 3m§”Ï À’Ç¥ì‰1»-P¶>&šV6´M»˜eRuLUdUûÜŽFÁ+nõÅíÈ;LæâµeªkUi0²QE͹è¢Q5s˜„Ħ%h—Œ(2-2m!½ß5"A½Ø;ŒI ÇðH€B\DR)eŸ‹jñn7V¬Öõe!T-¦+ˆ¢±âƒ”a'X¥ÜqR±ê¦d‡z˜²ŠìôÜ'e,À¡q2¯ÄV‹éwG¯a~:ØÈ¡ÿ kÍOÕü†æz0,yüÀ¯:`1ªfÊ‹'’äe€'‹¦j$¡ªéN½a̓xƒˆ.•¼fK¬Âê6S>FR¢Ì¹:dĔㅓÆ$¬G¼E°º5TeB›J7œ0œ"£S mþ<Œ=YJuÃT–0#+ÜQC_-ÊÞ‡¡ñmÁpå%·9/»ðaBSzù²Ñeµ£ÉÝ %«!aE›¨æE&Š$Ñ& bF„ Y¸$ëÿBø7÷a†Ù endstream endobj 425 0 obj << /Type /Page /Contents 426 0 R /Resources 424 0 R /MediaBox [0 0 612 792] /Parent 415 0 R >> endobj 427 0 obj << /D [425 0 R /XYZ 121.4 736.262 null] >> endobj 424 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 430 0 obj << /Length 2470 /Filter /FlateDecode >> stream xÚYësÛ6ÿî¿BãWªcÑ|€¯ËÝ÷’´éuÜží´i:ˆ‚dN(’±ÝÎýï·€”¦wé'‹°ØÇow©¯îÎ._‡É¢ð‹4JwÛEE¾XdQêçE¼¸Û,~ñ~\æ±§tUËeèõËUèµ0ÐËU /öóL,½ûöòuœE/ŠdðQû‚ ð^ÝÜ,£Üûþæ÷ÇÞÕõK>è§e†ÞÕÍõ8üúë[<óìÕÝÙ¿ÏB8$X„£h±٢ܟýòk°ØÀÒ·‹À‹|ñHŒûEœf~£zq{ö¯³¯>~£Èü8Hižû"ÎX»‚d‰÷öúûî^w…¯¾CRê=¢ÈR7U³cž½DÊ3¯ÊÚ´L^/W@¶çlÅë½]-ë–ÖKÜûžiª‘ëZ™ ˜å©WmTƒ‹}õ.ˆ…Úðþ­n÷¨ xÑ* ý"IXâ%˜Butp«{Ü#ŠÀëdÿÀ‹»–¤Æaÿ Ûa÷À’i§BÑÙÛ=Wªºö—«"Ì@ ‘–É(ß“;UHâÀŒ‰s"ßvϯgGØ«^ò¨l÷{«v—0èx%;^èU0°ÚÞð.ÉÓ÷}XF™§üQ‚Ä/Ä•£\œZI¸ËY £•£<±VF²}B9h»ïAi{j;ôÝÐÞAv#²dš^ŸºFZ»e–ºÝUå‘ÊR–XâÙ£ÙX;«†4Ò ¼=j>Þzè™Í^AÒñ6þeo‘{;’5;6½Ò0m}d!´|M–gy:²2öz6¼½fÆð•ikÙ«{iLµkœyͱéšFË[?ë›RWhìüÆvbÇðV¸Ø ŠâŒU4­@ªìê@>r‰ fa­ÁbÛõUÛX  .,|ЀºwA”@x«ÔÄÁ‹-&$·Ð)þj+,À½<œòcS%¡/ÂÜí0 :Ýú#SEE Y¥8ŽÞ}«•sã^Vµ™óÓ7»¦Õœ[€£ŠGG€D6/ŒÚ¦~æ‘©ÉÐ@¦ÚãlC_0OÕŸî'¾Œø”C]­á]p, ‘Ï:ˆŠ¬"á5WàðEdíùöú‡e‘‚ãÈûÇ?_½œÑݸmzðObð0ã^,­€CÓÉ{¿<ˆvÓë¡t`ÁþOëÄHtZnZ{¥‹¡ë )1þÍ‹Üi^ä' _d¨^Ž#R pì%‹È³©Dê)œ`G¯½ŠÎµlüAÛ©´·Ñ›s÷f´8ãÙ3Iaª?@™(MæY%ŒÒà ô±kX¯ÄJ#Všgœ±¹™õ«ð¾V›ÏðŒÛ7__ÿ i`=B¤!¼#{`2çB ržèäX †Ã‚dÆ¡Á4C€D@6LvƒâE‰÷ 2Ý]œ{8eeª¬D•™6¾ÏÆc* Ô“„#ëôüg«‹ÃôòÈAËßfÔ×iá8‚óÓXžÒxFiiLc|éÁŽ TiX˜Ÿ-2xüx™ðÁ ­‰ÂÓ`‰ÒÈ ŽŽ‚…$ަpd !ß· &Pf]¹TdvxÅÑp¡›’Ú=pHe÷v¹îÝþýé3|õííŸÁ.”œ±+rQ$c«´rªâ‘ ú•5IëÀÒ`ÇŪv\…ÈeBP,‹CdµÊ^½••¦,ãÚHz¼£™Äšñ×ÁÈÆTw¥¬K‡ /¸tã²(à0 ¢Q~wú®JJøÅÇëPÀÉžPüa<Ë¢LÅËJ«zêæäz$Áù—Õ‡Èúå9PBl VÖü+Ë<‰±Éœ qp‰‚IZX SU«ƒÞ"ÇNN¿7f>¿¼¬ –S”hoÔVµMVÒ§~A˜f‡cWd‹"—é0×=” /þ0ççŸÈù6ZNä¿Bwˆ¹åB_åÖlCÀŠ)e§{‚Є.Â]·YöFaÇQe˜±oyÞQ÷‚šè™`ënA@ ¼ï13!ÊFää)†ß¨¢Y€ÞCY\¦–œn±yÛÖ¶Ž þu®Ì|è>@9ý0òH’D‰w?4è÷Tð¿ç–èï¼ô—ßC$~±.H¬0~€š=î¡t¹¨lƒäÅ'’Ì1Û³êï×øi% ¼ËK¾ñ®åßµn[=Áf¼7¡þóböV!> endobj 431 0 obj << /D [429 0 R /XYZ 121.4 736.262 null] >> endobj 428 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F32 175 0 R /F29 144 0 R /F11 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 434 0 obj << /Length 1938 /Filter /FlateDecode >> stream xÚÅXϓ㴾Ï_‘ÚË8ÅÄX–î‡awÙ¢Þì<8 [”k¶d›0Püï¯[Ýr’y^X¸0‡‘,µZ­OÝ_·òùÝŧ_ˆtQ†eg‹»‡…ˆã0Yäq¥\ÜÕ‹ûà»e!euS-E0,W"0б˕”I Ã"O–ïïÞ|ú…ŒNôÄq&eºˆHGÁº(Ђ׷·Ë¸¾¹}‡ëepýö)ú~)„®oßÞ€ò·_¾C¯ï.~¾ $ZˆÉ4Š(_lÚ‹û÷Ñ¢†©7‹(”e±88Áv!³<Œ¡×,Þ]üçâóÿ?c’‡2ÊYQ„‰ÌÉ®u·[â2vŠ:ã~¿\¹ÊÒ÷/Ë4 *««uÃÖ´Ô[“¤󽞣Ø`΄X{¯êð‡(ËU’ÈàVuU«Î,(pÇô|GPÐÀñVB„eš’ùÕÒ Çy`Ђš@ݘîaìµéìÃNqÏªŠ ´™óò Vá´Ef9oñJ÷hEM‹Ö¸á#­«ÕC56MT½×ª{šFƒ¸[ќۨ€uôÙNYßó‘Ið²¨ìê%I¡°«úZW=BçI€pc{à›€¨Ù‘ճе]‰‹.³½BP²ÀqÀ†E÷îZ”­ºšWïŽ÷­Hu­ˆ¤TnfoA=ìúpÎaŽQ=ËQ°UìÑ4îVE°©:êhR9Ò-ï/ aÚÖ°ÐØW[ÕSφí)ýÁ¨óèN8ÒG¿3cSw—Ü©Bd“(wa”Dà8äŠ<è ‡[Õ£4Ü蟖k85íæ–9h¼·Ò€ò2 Žï­ÙÚªWY–_N𙑙p±Þ÷ »ýtß a­î‡Šì"@ä)'÷J$ªð޽78Ï7Í8@H÷ÏÏ‚”}ô¡Ïsˆ˜Ëžzry†T[w¨m ‘ˆæÁÖIVÆÔ®õÀ#Î7@üÖ\t¤GšnÔ¹ÁngjG‡£ó@ ¹å*ÍSv:ÊÂñ¹ßÌ¥£½ºV–Ùä7eùüŽJª5óJ7Ñ‘¤=©‹®ƒ»ÏÐÙKÓm€<º‰@šSNÄýúsÖž3Ó—Š´ãN &Wìê°Ä‡aâ A:µâ ò— 9ø]<&®äúMÕf’æÇõ”¸Ò”peLD¡x\Òµx¾Y®çr0œ dxH”"ÿ` grŠN:éI C`Š«x>$çT_3«_+HsjJ–3/k‘w˜ž(ºvàÈÅ&“mÕxÊL£`Úî¸$&ê[W̆ƶôø0£Y[µû ªtC:î·×·gÇ/æ¼ããÑsúDpíÇ#H©#J|ENΨ뀋8“÷Ò\9E‰s2ê ^ð Ò虎/wâ‚…-"*Q0ÀëúÉJ_à˜á=]Ñ®èá·šóH‚Tø¶AË;í©;®æ-ؤ“+´÷R¤“}L0(MöÞ¾âX¨l_ឨuåõœ¥Î†ß¿E¾¸¾¥Í¯Àij?žQ41µŒÃ4IŸdúÓ4†j6ªrððDPêcѦ}1ðäÝØ¸,„CÆ= ÔFPÖëÝù,mDl†/\»%°œ·sqÖ¿Æ¥•8¦C¸7@цX’•Gn‚áNQÊSD8›ÍhiïØö²[% G+δ—sËô«Ê6Úë>y¾ö¼l¶ÂeKeZú‡ b–EO0‚‘4î÷öNý¯Ðáç V×±¤Ú¤qšKl–«,w:C"þ­’–§µïÿ'æúGK?®[zNoúõ¸õ¿-Ð&Æ].ü·ëÝo-à°LÕÏáDB!üý-°Èã*ðåZû䆟œ:Åéã>oXò|£æ< |¯tÛѽ1‘zÜ£Ê=r­ä¶™~p6ð¯"ôgß·ÎÅhø;Ž¥ûÆP8'}àùä^ iðN©'O¯5\’«h8)QUàI–A¤2ÌE—R†EÁI%-ýoÿâ¥87 endstream endobj 433 0 obj << /Type /Page /Contents 434 0 R /Resources 432 0 R /MediaBox [0 0 612 792] /Parent 415 0 R >> endobj 435 0 obj << /D [433 0 R /XYZ 121.4 736.262 null] >> endobj 432 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 438 0 obj << /Length 2144 /Filter /FlateDecode >> stream xÚXY“Û6~Ÿ_ÁòK¨ŠEó9)WvlÏ8‡=±=²·Rqj ’ e’P@ÒŠò°¿}û¢F3Y¿ˆ@7Ðht}@ÏæOn¢Ì+ƒ2so¾ö¢8RoçAQ&Þ|åý昉¯©Ô$ò»É4ò- Üdš$©ŸÅ,ü>ÿéÉMžÊÉ ,"/dqûÂ0ôo&QùW“¸ðß>¹ywýöýõíüžð+ Lü«»Ÿ¯_ðxwó¹½Cù×ó‹?.P`èEG5“ gÞ²¾øí÷Ð[ë'/ ’²ðö´°ö’|Ä0ª¼»‹·Ïð¾qùÅ}ó¢Òd6Ü·Ìù¾^& [máû+]ñ|eVÍ7—¶™ï3þh·ÑlŒ3£ÆiP†¹7² Lµ³hÊ(õ[[k´°©uË”­’Agù«?O²ÌWUª1e ;l=‰gþÂ4(Ë(Ô1JüÊnÌ’Õhî¾êÌ®’mtÈc£íUUPo0Ô4Š‚2ËXKål߀ Òœ:€˜•Æiâï·Úiæ(þ¼¿ýåÍüæÕÕ¤Hý9“öx°ri6§„–'¦m{½-²°ô}ÇÔ•iÕ¢Ò«`2-òâÀD#Úé?U 7ºøEgð À§Þ4‹‡‚cUíÕŽÎâÌÿ>†Y¨à‡Ð™…þâéÕw£†ß»8Ù«ž.F\?Ódo*RŽÝlÈ'0^[þûhÇÕ¬dÕ–ˆ`(r˜Éý§F÷÷’Ø ÆÂ¹?`c>#8ô H÷ÎÀ ^ŽÞ ·:a¢sGÚ‚hÚÝ1Q5ü5ÍÇ0IC0MŒ» Ž"1"9Ç`°è~ÐL/ú »­AŒf0\ß -ǸIOâ—í Ø‡˜Ã8Û9‹GWzº\÷ͲEÍBÿ ÈüZ}ƒàÌ6ÃQšEl0í¦£(à„D>¨gü"àéôðáÕ^\?{ÿò(¦‰?ßꆗ/9–Ÿ$½º¼„“éöˆ¬ˆ‘…ëMë(Öö£N©•i‚åîyź`F†,Òtè[ÍD­–èÀ-Ïx¬‚,¤Ã®øÃù’Ì¢’íøî,»³õeZµÑhˆå[­œìÚÊöã¢ë ‰Üë€êØþÔ;Íg~‹X× ô4/ÄoÀ8ÍN0¥ÐÁÁ¹ÂH鶪“=h„ö À,­6)eŸÄ' ÑN9Ölœ:W8ˆÈ…î#j,=¥QP$‰$…˜w>ÿáêöåõ%'—µ©.‘¯j|¾Œ„¼;òŸ6ÆBV¬D\xQ$iSnÊó`–”àªýì¤RG\©ã*5 ï´R—UjðæP©Á2g•úA… éšE(h|Á¥”blk¤ŠR€ãê ç¿Ôÿ·iVËê¾ýþëªê¯P˜4⬄„Iu'??lö!à>(~'9ãù¶ïvX€pLÛÚó)±cHÿ¡[^³Ä¨ÞÎEk¾6Kg[»i –×1l?ÿö[NŽ’Zc%{Îøc¥Çjôžsóc¦S©ÄAÇ‘`)eJc–n%YÁzŒËðE2²ê»­uÁˆÃ¦GÃ-”UâŸ:Äö<@ ÞǬ4» ›g0>ÿ¿Ë¢ñNG·¯â(Êr_›S’lú¼{óšëaÿzª¿»~ÌSj!ôÊ:õ˜‘Ë…8; VÍí,8]íD´;‰°ö–¬ÛѶ@G•W¶ÑLY ò‡Ós¬ëÀËÌ=ªP«ãºÂo+³¡ZßU²³Rf±ã2L>¦VNØÐ,uÎ ;†zèÿ¸>npzLiÓRéOÄ:·P¼v`Ò¢7ÕŠ‡dOäKvL>= šÆ-¸bÏ«)b¥êÎvóæV •ì„”~÷ýdšC–~SiÕŽj,J§–ÝŠSA±€ŸýØn[ÐQ5K=Vo-v%iî·Ô#[pé¿Sì:ô=ÄóÚÌ ±ýmxèr`š¢†8Bp¹ëÅs¸¦ˆTjFÁ¤ æ,æÔg˜g(É8Ê\3ÿªR”Ü Ý«ƒ(AXò+nÛêjÇ é¡p‡j™‰%Yš±ˆÅóuÏ¢ì©çpŸð*c¥gHaƒžÒýIVBû7¤¡¡q”µòÑqŸ]Ÿ%Æ/_ž‘ÿÕ‰ë® òV²—Û,FL\+ˆtÇcèd)vc TÓ)¨:mMâzJVØ¢}eaz©¡§¤WHÄ  ‡>¾„^1FsµÁùN¹ŽGdˆ2¾_Jxä:…˜ì ÔGAÉãphEK,Y/:‘ðÂa­šÇ(ºWŠËß@Rê[|³Šá˜§š.x4ÖÚ¿¶?1tàöZ»%½Oqަ¤g)š²eÎLú&¦ |ü.$SÓäˆ »9Ê*ÖážÂ£W+~wâyX *’VÎ1»:wÍñl&âþ¡C­rÀ<5ŽrítÖÌ}Y˜sõ¢M–¿N[ÇM.—µßŸD<ÕЛ…o³Fw¤·)+Ç ×îFß,ÎÌ_ 1ÓJû°ßšcÇÉÒI.•=Òjò…åúAÆÝÀK£=²¬_;[§Úf:øf‰z–P°µâ×g\¦'ŽEÞë8ó]q?G…‡¸ößV·ä›29vâ$J Ò" pö^é9(…t¯/N%·‹?B!P&÷7A">E™Ì•¾L¿htJI”ÀZV¶ÕBcqéó)_»®=VЙ¯ µSR–Ñ-­eŸ }brì6ò,ç·Ó±©DОTpºîº#•k ×>ÆTfi%Œ¢, fQêMá[²~y8ü÷?žXî endstream endobj 437 0 obj << /Type /Page /Contents 438 0 R /Resources 436 0 R /MediaBox [0 0 612 792] /Parent 440 0 R >> endobj 439 0 obj << /D [437 0 R /XYZ 121.4 736.262 null] >> endobj 82 0 obj << /D [437 0 R /XYZ 122.4 440.302 null] >> endobj 436 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R /F28 142 0 R >> /ProcSet [ /PDF /Text ] >> endobj 443 0 obj << /Length 2696 /Filter /FlateDecode >> stream xÚYësÛÆÿ®¿‚U;cP1a¼ ØÓt,ÅV쨖])ÎdâŒ$b<”ÌöŸïîþî †w÷wû~œN¯ž¼tÃIb'‘M®—×óì`2÷";NüÉõbò›õ~û–jò"ºV7¹VM@3ù~`ùv<¦¿_¿~òÒw†ç„ŽÄîÄÁžKß9Žc½œº®k=Ÿz±õîÉËÿ¼x÷ó‹7×|ï| o=¿úéÅiíêúÕå›+>ÿèÅõÑŸG| 3q{6}Ûu擬<úíwg² ¥×Çö“xr/ˉÍm bruôîè”åõ’ÏäâØü9xý%/ b€Xz?M"HÞÕ Hõ¶Ûl;À*Ó¼¼­J¶V9õ=k§·3|O{B’½È3Uµê_PמڽÀNœh2sC; ÀƯ¢öö14¬¼{ÔÍ­?¶-ßEtÞÇ©7·°m›W+€çggØ[W ìx_½m€mšzÕ¤eû ín†©*½-ä›À„ÊÞ™pZ„¯€Ø» ÁÚNd¦8J¬k>úžÿ¨;ùÛˆ8Î Yõëaðƒ:`!Œ‡_ªH"]LÒÑF¤º*v %Ö1+’†ty܂ԟ¥F£-B‰c¥•&·5¾z°ÓFñæòzŒåFý¹Í>™3dW# 7Š9Q)Çãie¢×¤,‚—œ¾›º¶çvÝAbÖü˜ŒX0Ç~‘ß²¬xPDrêMÇYDOŒpå_“œâðaë[®ö¼éò¶csó&mnN~IBÉ(G¼hFV:íFÖ"w ™ª–Dé¥12px¬Zk‘cVìë•S¯°\ë…•ªT'arï$$öc$G11oÕ*£]iQÀgÛþ®yÏ™qÄÔ¥>8_î8ÈÂ/b"Qg&Žo¾§SMÅy)ÛV¸Ï»uTEª#u79e.±Œg¢‘þfö\–“‰:Î8?K² ­Óñ¨Ú•’‡e5¸‘‹´sÞ¦bÌCöµ[ÐrÆB•%ëg[åHêñÍ˪¶2ïJy R·N»‘àÊÒJ|‚L"²"µ¸èKí†ã©I e©š,—:ó9fcÊ€û°þÚÙ•‚MJÓ¨CÓÛ¬3ÖËêf#Äšœ¬·ÍA^;°¦äêÏíh25›;ã¨4žú-Éz?¸Øõœë`슢ù·íÄ×ÉÓá‰T±À̺„4ªz%8^¸P·ÛÕû´-«r'Ì{4ÓSóö# ^MÃ=¥”:A¥¿æQa%Òá:¯Ì¶ްIWÄ q^BÚ<ãÍ1Rt»½Ó€°»ŽÉ ‰Åõ®Û ˆ(ž~%lÜ@´Kè>Cn ³½,Á& !ÈEÙš~üÙI߉ ´7ºÜŠÃ! f·æòt³¡äŠàéòÄŒ^ìWºé倞‡©ÂCp†‚óÓǺlHý$Rj £q÷ü*£‹ª\ó)GwRꕇ¹³ØÄJV‹oÎ\?" !5-jü¾B†2Ý&ˆ÷¼1å?wüGQ×WêL'ÃLC…¯Å´"YP¿<œ}÷Ý7¾:ÈÉò©C¶–üŒÊ£DmR>]ªã7òÞ«¥òò DÓOª±CÞ‚<Ef‚Šb‰7‘hKfFÆÙ[yÿžOñèxzÀ¢M’~¢dMøt àÑ‘²Iô ?};/§Q©Br|¸ë‹éV-ž>–_èVù²‚M¶2?RÌç±u½æN(B––Àb2º)šºh©…³ÅöÖäªadý¡²ŽkôÜH„˜¶ôï=#ñ‚þ  p+0¼‹>Õ’RÄ‹7ƒ‹fÚ{ÜáÓ™O§º¾yâû~ÄÁæöáL:¤Fó ¦+0…&] ²™?ªÊryÈ£uŽ­ à?ØŒïº9¿¸<}~qsyúú TΩñûÀ%cÿNQa¡ñG£¯,‰îl·…Ì$ÞõÚv ³äºû]Ô•:È«O>ù·oI‚‡ }XXiÓ'ûú'Ópú8aº³ý›šó îdD¦à ÉÀÖX %‰í¹É7ÇÎï|® ÄQ  ©«ÜzåàYN6s0‡’—Z|¦§ÍHû;mZ*,â¤'"Væ_£æ=ÝË;#F#] õpGfK»tÿ£Ðme Ká ’‚¥ý'¹×ó3ƒnü¡F=‡R,ñ둱ýÿ˜¿ë\R‚ZÇw<ÝÌt¥¸¹“ð[EmÛ£µ«êpgŽ…ž@£Oj fâ¸iÃX`0rBËwý2–BëäDUwˆFÿ'7ŠÑ×¹ÑaóÞØú)ßa êa1}6&Hÿé{þ”êå xè–ÿÄO¥î<|@›ŸwÅ›Íì{fBKÏŒÈ(»Ühñ“¤gêðÿitZS¢ö= 7o‘kþ£õ -> endobj 444 0 obj << /D [442 0 R /XYZ 121.4 736.262 null] >> endobj 441 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F11 176 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 447 0 obj << /Length 1984 /Filter /FlateDecode >> stream xÚÅXmoÛ6þž_á¥C'§µ"‰’,¥[‡æ­k›5èâe(ÚÂP$Úf#‰®DÅ͆ý÷Ýñ(ÙÔ·aÀ¾XÇ#y<ÞëCNvöOÝ`Ûqè…ƒÉlàzžíÆ^hG1L²Áër1‹W"O†®¥†#×’@TÃc¾ÅìhìßMžïŸ2gSNàØqä’á¹°Ïqët躮õdèEÖ«ýÓßN^ý~òrr†'¼FÌzrñâä˜H˜»˜<;yòwN&;vP 3p;5™í:ãAZì¼yç 2˜z>plGƒ•^X X8¶= òÁÅΫC¼/s7õŒbÛeñ Œ"ÛgcÒVÍ–£ÇrÉËá(ðë­8»/~õ~š‰j_MU•¤|ÊËdš"?ݯEñѾI³]Xì>B…áБëÚqPÛ¶ûØ«…Èùúœ:*Q L>­UR,‘‰2iÉôÓp™Ùwÿ>}¿»Ô^R<Ãýs©NE)êE+c-ç/­Š>rÇÛú‰(7d?ø‰¾÷¶ïn*kŠåú¸×2ÖÆõõwŸA´Ì4—5G1­ê›RÂ)û§^¼áÖ‘Ø‘Ç`C`ÇŽ ä_äyÖ ‚ Â-“ô}†ßšó’W`:b®pa‚?7øÃg²*jšB…´÷k²&òðÆ÷Åm­xqô3)´•Wžz â Oêè$ÈÀW,[jÁ‰xëx–OÃz%TŠ f¤ï:)•¬/dVRa¨~oq£lªvë’ˆœßàÏixdNJ§ä;¤pŒ7¶2nD‹rÔç«4o2PÔcc0¬çX(§š‘fÓ:µöp仞5Y`Jáê4És¢6.³ƒ}õÒ¯:/ÉÚ¤;B"+­8z¬'.ÐÚײýN¶>(Í.Rœ -y> ­÷‡»‹²4ú¬•DHj.‘ñ> endobj 448 0 obj << /D [446 0 R /XYZ 121.4 736.262 null] >> endobj 445 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F31 162 0 R /F29 144 0 R /F11 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 451 0 obj << /Length 2303 /Filter /FlateDecode >> stream xÚ­]sã¶ñÝ¿B㙎©ŒE“)Q½éÜ8wöÕiz7wv¯“I26,AbŠT(¶ÿ}÷‹´$3¹>ôE\,‹Å~¯¾¿9:»L‹Á4žŽ³ñàf1H³,Γl—S5¸™~޾Kg+=L£0¥Q€Ž”Ê#—“|øëÍg—*ÙåS$ñ´L óÈR8—$It9LÓ4:feôùìòËÅç]|¼ùoø ªèüú뛫O¯‘ÿÑÅÍÑŽa2H;1Uœ&“Ál}ôó¯É`[? ’XMËÁ#®j<‰3€ªÁõÑç£ï_¿7ŸÄ*ÆeçjÂÒ~4Oát8ÊA=ŸæÑÙw¿£Ð¤‡Ð8Dª(8T‡ž>l½¼m~I”ú†itçž)\´¤EbLÚ¾Ð_1+¶J;ñ½rR†‡´U%‘Òp,„••€áœ¦ºÌ“£ô¤–/h.•«Ý)È ¥ʸç}+ts‹¥Ë8$h‹ã™ÐÖx4ØDEº­ùˆ•3g4%­œ3|ªféÏ:¯žˆ÷mª>•°Uû\ó|Ðñ³,CϬYѰÀBæ¯,Û}?bƒñÁ£Gçž#ß¾Ž3¤G½ã×<™Ù‚ U”ûæ¼Ý} ÷E\j–½…42GÝm-+rÑÉëpAµ+bÈ ùSáż]”’ €Šµ-ÌuÝ~ë&hN °ô  ª%?Ž‘Âú€ŠÜzÌBûGé]’…íN+bvêäÂ&h{Xþ$»`Ò¤>ªÌH_5ƒæIc‘Æ"Fš ¡ó2N(òQã´DÞ0™>ÜtÀÞAvÆ=¨AÁÙû-æ!º¨¤RßW׉KRÐ ·~v†¶BLÞ…Æ3òÏCšüà̆é)T‘ ó¹gœÚ~¬8å ÉÉ_Nä’FáÇ•Œb6=Õµ•ÅV€SHmÈZ7nÇr{ÁøÍ+^ñï•qR1)AÁ—]º¤¦¤ö ’ី­¶ë5xë[Ô8ûrW£  ¸(ç\£ç²nZþºe=ŠÛÎÂÛ6ñýYuf)oP?­4ØÓO¡›;©pµG¯©ï…µ$9TiI0—=3F3Å=¶HعÑ8$ŒÇQ{Ú†ŒörŒl ˜•~É0¼³¶¾· ¯uàËA ͸†J|ÚÆ³ ¥ äµtõIà·­XÕÈ}ÒVÔ+,¦Åª#÷ Ýˤ‚ðo[/g7àÔNšãýaŽØ5._Ò ÄD‘—Ñ÷•ÔeNx(€¡ŒÉ•,®hÜ4xñʹÇȳaÍ-nùrí1Ôâ«Ï15ß|úrÜÛšÊѽbÚ U§Òp6ü•÷+ì¼µ4÷|™ÚOJª¨RœtáÞßWÏ ƒˆuf ùæ¯2,§{Ãr ó'EY’ç,ì]Ài8ZdE$oŽð6z™ì¿ïºYh`Eʯ]…zo}eŒC'G}GïL=‡Æ¥'òó$.¦¹È¦ÚÈǰ}îm­—&ðúx[›'Täô ÀÞÍ›“cIÿ½„˜ îî!š„Ò8׸ÿ¹ßPXpuf!8gÂÖÕ² `¢ŒÀÁ L+s*³ˆ*%)À^Ýð> endobj 452 0 obj << /D [450 0 R /XYZ 121.4 736.262 null] >> endobj 449 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 455 0 obj << /Length 2671 /Filter /FlateDecode >> stream xÚÅYmoÛFþî_!>„B"šï’úå8Në6“XMQ´…&W6Ï|Q¹dãpÿýæ™RRª^\ûbÍÎîÎÎÎÎ<3C¿X¾òãÉÒ]&A2Y­'~¸Ñd$îbNVùägçÃt:¦-Êtê;Ýtæ; ít†‘º‹y4ýuõíé«ÐÛ•{îráO<‘ø´Ïó<çÕÔ÷}çù4X8ïN_½?÷Ãù›Õkœð†Îó«ïÎ_ IsW«‹Ë7Wt¾:úí½‰?ªº¾7ŸdÕÑÏ¿z“œ¦¾xn¸\Lxa5 “¹UN®ŽÞ½À}ƒåïî›,nÎE×oši8¤i•7ò{ŸÈÙ´æ#fM¿ÌU …N­5mW4µ•ñºm*¡~ñ¨-êÛé,&;ä½Ð˜i5Ýßň{DîÒK&3?v£Dµ;KËr: –s}y ß)ˆ(ÓÎä_}%:\Ö¿x±·NKkˆðeÏ ý,³nZ#ŒG¼DÓË€U´ ²ñ îNW oÏMùŒ4÷"ÌÔº¦o•*tÿMšAö=îE0ó}wÇr‰†ÖFIâ¤ëδ c1‚;-¢À¹èd:ÇíÖ¸\¯Q­Lwþ¶½á¾ó#+&_œÔŒ–K‡o‚Cv_‹2R„tìÚ¦,M.¼piý‹Ä"Aü3…yaÓhfrWžqÏÇfã;.Üå|!Â~¼ÛñšÏ¼ìÖ¨g÷unð*5´_Y›ÖÔ™‘a§ÿa³ë®¨ÌµíÒjƒ‡Ç›?9þR¯º «…dù³§O…€ˆºQîÕ£íLu&nF68‚ G' 6¬+Q¬ýWPî\ÕÊ€·¯³Y05œj›aCÚ ”ʰE5;ôB=E@ÃÈ㑼ºjVX²Ÿ^.ë[2"?½ÎíÈ…¢(r®Œ.ÒÕs|vùæÍùÙêâÍ×ÂX]Ê ²Ö±PpÔOƒ£V›ÒØÿ—#|x}ýþù›—×ïϯÎW×On`”8ZÒôt™ÌÅ|£>;6Tq]÷°ûxûžóPož¾=(ŽMú-‹ú^(u’VFYSmŠrX½M1ÝÀÚq1 ÓÛ´¨M,üN¹!sØçf›°a¨ÒruC†¤E¹€"ðT32ÄpŸãLæEk2r©G6kY:î!Å#U&뾌ͽÄYÝVöÉ/\[åviËoû¹"T>A(~øîúë×—/ž¿¾¾|ñí•âÒsªôžM £Ó˜0®-Œú¡î †á;Ya̅Ö\ ƒMʨ¶”;†ËÝ÷÷{=hvaï'VbAžTÛ—æÏã`©¤SÂŽˆ·¯5 l‡¥ iHG€ìŸ¢Z""/ëqÏ K*ó@8B/û‰ó=ç?žØˆ²—@Î{Ä“"¿%ƒ.´ŒÜµb\"šôšöN'h‡ò„ÒÀ†Š¤Yu+ã„Ö6<Û3ªxb»fƒ•–'@!¦cçä¡-:5„ä’˜ :ÒêøÝ€Cø ~Ã'ë rJ±¥ÅÝ—Ñ6`±>Kk=£d¸¥½5Û‡8ðØÇE%6Ãkb†ÎË·Ç †DƈnnejmRªŒì`tˆB­10}¦Œ¨BÎBÖY"A‡EìÐéFjb¤âÊŒõbDˆ{HûÕiß õW½:åñ²¨Š!Ñsax{¡+³ÌXÝŧßMSRˆ1m‹Ûš¤mÞͰk ña5gócðeÓ!žǎJRÊÄ%U\г4ŸÈ=â'1òcb;å‰eª5ËëÒ:OÛ\&àŒ2Z]6ÞÉçñB]$^"én$ž(£Ž5';i¼Ü… IÚÕâ”´«mú®¨¶æu¢2dM]<Ú4°‡Âó úkR*¦wóƒŽõý‡aî¡èú:™DšÓŒ˜_E0æ`IÁÑS‘“­S¶5Mï*^D¢ O°#õœyÑ3øõñ¿ôäëìéSÔm9FŽü÷ñè¿_RAü·† ýŠF¹ü E'w0 ãkNx=Ä~ª•JdH)ÒJ‰T+Ò”Pð%‘óOÊ“_Zmn!ˆn«õ"îÍZP@äƒá—#ÛGº¢'Å1û«uA9õ™`ŒðS]9FII÷XZ–µLÆ>…ÕB Òî“ìÐòé”åáA¥š‘)|ÕK„AeK‘k–ÝÏ©°%l\‰°9ñc “L‘FÝukn©+²§Ýiwm>u¦Î¯³2åà %’tí!å(Ësü |qü¢Fý”BdÀYž~÷V˜–7C\Ø¿Ä Ç:vZFmÐ7}Q鋟ýRïyAÂXg=·{^ì|}v&DèzBpŽ¡*,té±C”CÙMéÕ–HÊ%…¬Ý´ ™\ÚúSH2èa¹-›íÁ­J¤'½•%ÅZ~Gåcè5+ð°È_¨îD4 ±á’ ö½¹Ð„PÑO8súH„Û´'œÁÈ oúñã@Ž ¡vx…xà[4²HÒƒ‘N§3b-ƒ¨Á•ÈÃ"Šz biãˆI•%ň)eTÉW;M´N@ž¦†{Pz,r™éø=Þ5äM”Åq/ÐvÖjݘp›~¨Ô"øßôÝŒj´‚ûÉÄi6ŒÐ=Õƒ¸Úe&úÐ7Ì©sh?›Î2½‹Q TÿuY&“£´"3€˜JF›á£ õ[cÖ([ÁÀò‰!ÊÞ¡Ø/@´=L, ÉvŽùNp` áÔE–’…2•Ï ¨ì7âIº3ÍÚÆZ¡s”È¡çÃ.ÝZþ³Sgò‡–”?ËÌÕé5#8ÔМñ÷À³oÎ…c†Üû±h›ºulÛmqv¿íK¶*›Œt@ˇ6ÝhÙßþ}úP4Wi½3;@34¿íéÔRn…"‘sR«¢¥ä¿mº–ºæKá‘m™K}ú> ¡B°6B UæZ´ -kêk' ¶}¬ D«êRgÅäL6²nÛAs¼UŽ)aòyaŠ5ôFöð÷@þÂH8úb¡(1W¯nJ™ï´µ )òS+ %Ñc–nÒ—•AQËo@Þ4 U<—– ðO. t—õR@Ö€Ã!ŒÆãÁ\;˜skíŠ>kîk÷öФëPÌ<§ ì“Ézœ§|J‚Bù½èß„0&Ðvƒ \)ÊI†\Y˜E}ö¤…à¯^ûh®Ç­ —Er¡¶(´ÓªoÍ_SŒÅ=J¾cŸv©½Wf¡íèÙ—¶ø? ÔƒD­ b¯Æ2S/ùkŽÐo‘êӪ⻂q!0#å>\8¶†Ú‘ƒLåçwàN³C0¼ò‚{8§î‡.-n˜*jJP§’§¬°0%_;ÙW¥ÝøA›¥Ê/¶%³÷K>¯‘-Xù´ÏÏ?û£–+jÃÒö^(-®‰ž£9Ç$¸©î@ÙÚJ|ì¬E„D MÝÉPÂñ’;m’3¶øC+ÞÊ‚¢Þî8 j%WîÓRnâÇ¡;÷#rÔ¥»X¨ƒ&Ñðÿ¤ÿç£7 endstream endobj 454 0 obj << /Type /Page /Contents 455 0 R /Resources 453 0 R /MediaBox [0 0 612 792] /Parent 440 0 R >> endobj 456 0 obj << /D [454 0 R /XYZ 121.4 736.262 null] >> endobj 453 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R >> /ProcSet [ /PDF /Text ] >> endobj 459 0 obj << /Length 2507 /Filter /FlateDecode >> stream xÚÙrÛÈñ]_Ár zM7@{kS¶WJ¼Iœ8äºjËq¹FÀPÄ ‡hî×§¯@ ªò 1ÓÓÓÓÓwßn/.¯Ýp±¶×‘-¶»…ëyv°ˆ½ÈNÖþb›->[Ÿ–‰oé&/ÔÒµºåʵj4Ë•ï–o'q°ü²ýåòÚw¦tBÇ^'îÂaž ûDZ®—®ëZo–^b}¼¼þïÕÇ_¯>lÿ‰'ü†}ëÍæW?óÖ6Û÷ÿþ°AúWÛ‹?. ³p6}ÛuâEZ^|þâ,2XúeáØþ:Y ±\øQl{0*›‹oñ¾ÞúÑ}£$±?f^ÿ^/}Ï:ÀUVó÷=~K¥©n[µùm¥ ™äßý•…q&T/°×N´X¹¡½øí^ó%o–+…n;–g·Ï«[^É[þŠÈi\ª;fdÅÀÍ©ít‰2U¤ªú–1žiPÕ7$p€sb«n䜟ÿó^¨«öîÃê†A»¾J»¼® GªÃ;W®k¯ÃoÀ¢ÐÈä:a,ÅV‹§åp,Jçår¸À¨`eºM›\®œ1>IŽ(h0k0Hñª{uètÃFGÔRUˆÓ«‚çªÊF3­‹º²çxo'Ó=¤<ƒæ”ó‰èákߨv`½ûᆀ¬H‹3H –L Œî[÷Ë0ëìeZדּtQÎZüÑ¥Œ¨GžÙ¬t‰É“  *±¢ÔdW"(/‘¥ÀÑÀÏMÍej£joˆšì†0hK°: ‰8ëà7YÝä’ÈРAùN`¹Ñ¸Òt¼à[¾7.€rnÍÉ`“(Îl8-`ˆs2 °?vM¸ƒÑÿ?è( ;FãËÐúFŠ×\Q„˜0Œ­¿éJ7äb¸‘·Ä(°SU1ɾ•ý¿÷­Ý‹åøÞ×îy;ÇñŽBzâÙ|}¿Ar–TìYó¾0d£àkǰy2>ˆŽç2#cx€NuÈ -Ø•qthjqƒ®?Ã|X¥5±r13™É^l bmâ±y—ëÙÀ6[àz¨܇CÐaÅ#¼~¸a»lš¸ÒBÄÀ„…c%¤ÌnÕp<ñŽ_cz8>×è>=o÷‘gGŽ×ÆÑa„2ÆQbùî+¥½vÆr$6áó³óŬU²“µwF"ò_ùÞÓ4Ü/hžÀ⯜^[=›‹„^ƒ„ŽIdéoªñºÀÄ—êVó\œ7ÈÆQ¦g›8Á²sÓJ fmßR¤YÈ×*Efïx†ìµŒ@EÎôÌ~TÍ}ôÙ™›¤`ª«¬/ˆºÀ‰ Ý0itÛ8P%¡ÚÞêTqlÕ¡~ä ‰ ¶krC ,cJ…\÷dl0gÉiúÜɶ#d 9 Ÿ-%ESE®Y˦ðÝCráQÍ~/–Ó¾ªtŠQ¡¥’S5Dm2™ò¦ˆJÕŒ›~ƒí›-Ž®þÃwLy´`¬¢äŠˆ€½—RŸïø;L8Ù+)Îr)Ÿ1Óô$6F÷8x%ý’;m ]rãÅÊŽi¼òêЃ5…^5À ŠáV èŽhª˜×s½¼d¤u§yD" }…J5TW †â±cú-60˜p­É:IÂU|[Ý -Cs¨ ‹—34C¸5à*rêxg’ˆÔ­è%LØcSÄoU7¥¢Ž(û\‚® ‘W€Õ—XÊ¡×ýížQ@O;80IŠ'tj¨ªçÝH*fRÑ$ dŒ|Cù…Ç"º'B0q”‰Á›ÆZ¶<§¬±á–¤ŠÑ5’l|_B4—2^+VÃKÀ<9lcZBp6Ål&}ÏÊz b µŠ0×üˆaÞ*>-¡*^ á31 ßû”±©K -Eí„¢Eû$ ™+í L i@’º·q±¤(ÿ ÄS¶#m€yÔD޽>À÷j Í“óB‹ì¾ÎS~²Ô Ð[°nKâIÿ “c“cÔ¤õN¾/ ­?JÔS‚HÏæÙ•t'yÙA˜.ZÍ{ÄrÇ•?zjÒB/š¼ ͸)wè Ý0 XààOGî7aô(££ƒhASdˆ°ê®P"?2Þ†xî¦F‘CŸ[Hð¸“íïvíshfövÏy×çiS\ƒ”P¨¡"0a)j^r;- L&6N‚ÑèéËØ»©ÓG2ÔT„[yˆPüj¦tx#­®8uo*~b ÒU!­ñÙ‰¦Í…Ìã F©m†×œÁ†f¹ÁÖļ7ìZ#ÿ†G:÷źÒ"àÊÀ5N„kJ4¸&²×ƒ¸ž™}ÁZóãÁ«‰JUU-ÑPÜþ¼ô3<Õ¯ ©‹Q\&•RÄá5–.?Gbéõ¨.tGí‚‘Ÿk׉vaI´ £q|$¸e˜Q²“#ßv’Æ£’‡æB^DUðû3Þæ[ªòڛȣs°S%Ó">Œ´É7ì½<6]¢½·’&]uzö}© Šâ¤£»×ZsÒÂ%.|ÀkSEmKLí‰ÀêJ)Þ&¶,‰×&ÎÔ2„³ v‹gÌçó/CrçsÓÖÙ£( o°]>t&qúgþ¶/&}æóx±äö²Ö‹™7á‚ÍÍØ¹¡oÇn°Xø÷ŽÇ¼G¡ù{åÿ©A¾/ endstream endobj 458 0 obj << /Type /Page /Contents 459 0 R /Resources 457 0 R /MediaBox [0 0 612 792] /Parent 440 0 R >> endobj 460 0 obj << /D [458 0 R /XYZ 121.4 736.262 null] >> endobj 457 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F29 144 0 R /F31 162 0 R >> /ProcSet [ /PDF /Text ] >> endobj 463 0 obj << /Length 1679 /Filter /FlateDecode >> stream xÚÅ]“Û4ðý~…gàÁ™!Ž¿?Ê m¹ƒv޶\ÃS:ÇVbqŽåÊrÒÌðãÙÕʉ“ÚòÂK¼Ú•ö[»«ë9IœX.ñð8纮ýã³×Ë—w³4´ÇSW×Ë«÷Wls-ï(T|ÅUgØìÀ÷èk`r½CUÀÖ±7b²f¥ub Ü:$Žd¹2nÈM¾h­ÐAƒ‹TÒ;É6’uÝB®ä²FÈÁGš“ɧõpëZ`jî»Gæ&z£¼ö]pw Éí;±g’»G~4–ˆ¼º©-훯Z¨w׿=þéÕí5žqÚú„‡«…ëÿÀe‡èÊ‹a´›¸¤ó)k–“¨²XQIÛ K´ª(¤°A4ô­ÆqO >ðÝK®Ìùœ0Ê3“mD¢"•f”'”’S~Hí:ùŠ~k.ˆ®F^Åé"Oz,7ùaÒj¨!ìˆ&û–}Ó@Ýùdø£óð}}÷ìö1äwè÷»—/—X¦ÃÌþŠ6¼`ˆgå(8h*’„䮫®JÞ)ÉW=Ù†˜®¦¬:eœN¸n.3îÒù1×5å3# U <à¹ã죵 o×;N5WìC¾mkö-®ÒF$r¼G¡Ão®wP•vâ•÷ï‘J{Œ(nÐÍàØB±rm&£}*hAœáI©•KûÏ^WŒ“úafRV]/ Ä ]2•sÝmˆ…Ùj×.ês¤i{sJú qíFJ#;¨xQäÛ/è¦`íIRÍuBýµÐ5öÛ_W‰¾.©Ô­smú—–§ÿ!??«2šz?Î9ÏÜA«»ÞÈdÝëé‰F'9y+FœèèH=Ÿà,°á຅6®#`¸œ8à…0'5ú<]vx èÎ]ÿ‘*9} ±Ý’ˆ‚Þïø¶ÿy>ý×|Îwð³©Ê ÿÞò¶ç;—/ðÎŒä!”Ù}AÁRí> FõœÖyQà|Ò"oÝQ`wN$}ÿû-þš‚-‰.Ö´A´Çé ¦ßQí95Þr)…­í¶¹n;€ºÇ1zH€)×’Hœ\`†¹Á„Ü‚0Ê-¨RÐJ¶ã¢ï š&•cJ7À*GµwCŒ±V·%XÊÞ0¥Vé,ÜPa@Ùz.-©+µf¡u“,u<3/¡“ÆÔÑ¥fÖ¢~j…ê—áy¿L/ú%m¹hÚHljû4ÛÒ¼bEÓ%Î0ÌWf6€bðé7r¨Ò-”`Fˆù†F‡P}YÓë¢Ãq†ßéã=Jæ:W0 ˜lˆÌ•)±É¸Ä‚:q6<Å*¥ÚG‹Å~¿w ñòö8à@G«mÜ,v&¯ôrây¡ë$a80%Ë¡{„ðà ϳby¤:ôLÑ(Š ³§íW5/ê­v\ìØqÜZVé÷B÷oàfâs¡U˜[Ø«¢oŠƒX—SZÕ8 „f,&ÔÅÚwÍ¡dò;ø"O„!7.Ê2'ˆ‚3]>SçfÏ< 8õFoeïôVÎ|z+ÿû{õŸ_é¡gF}¯a¾MÁLÊ—„Ò |½, :Þ8ýJŸÆŠŠ”_Q´aÎ䊾¦Š¸öS! t+6PÏ4ø<¸ÚóßCƒVùäkáú}ÏÛa`†ÝnŒ\‡håCU "“\@?C±!Äx¢‚%½ñ7Bg$ä K[s*hRi‡ànAä§´<;†6„†F·h€—¤ÄÞ°Nš¦dEqü ©†› endstream endobj 462 0 obj << /Type /Page /Contents 463 0 R /Resources 461 0 R /MediaBox [0 0 612 792] /Parent 465 0 R >> endobj 464 0 obj << /D [462 0 R /XYZ 121.4 736.262 null] >> endobj 86 0 obj << /D [462 0 R /XYZ 122.4 698.4 null] >> endobj 90 0 obj << /D [462 0 R /XYZ 122.4 167.004 null] >> endobj 461 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F31 162 0 R /F37 406 0 R >> /ProcSet [ /PDF /Text ] >> endobj 468 0 obj << /Length 2103 /Filter /FlateDecode >> stream xÚX[sÛ¶~÷¯Ð#5µhÞ/gÎtN,§‰Ý$uc¥>3m –PS¤’‘Ý_ß½‘–j¦/°»X{ùvÁËÅÙÅO~<ÉÝ< ’ÉâaâMÒ q³<œ,V“ßߦYèhkJ5õv:óv: ÃÈ Ý,¦.n.~ ½=A¹‘ŸL<ÖİÎóßá²³·‹³¯g>ÈyØ=t}/Û³ßÿô&+`ÝL<7̳ɞ·“0IÝFåäîì׳Ë×H²Ì”°7íf:‹²ÈQü7ç¿¥jô ‡±3¿ý´m=©³Ò%Ïëh7š oÊÝFÔì, gN¡Á* š§©­lT­xИíDºRµZH¦:8L||° ÜmæûnÇ|z]¡‚oÆÖÕ–Ç-; Pe £ZœÎç®Ý^Ø1÷yý5n—{ŽŸç1n•¸µ¥ó³i•åÂdI&ЦZó¼kzŽ*›šG|ÓÜùØ•­Ùê•Q"R‰ì'Ýâa÷øSÛG&Þ&kÐV‡×Mø¸+ý Wè²Þ\7ŽÁlYi_™µiUéNg±ï9Wª„ñN•KÃÖwªyZ“§x1ËU´†÷âù‰Š»EƒÝÎÇ|E—ÒÔQ«•–a#j­*™°£si &ܪ ‚¨ ¸yƒ“~çî y•—‘!U#J[SŠº%«ƒH ‡!‰Fçy _Z¸Ñey2L‚Ã$;‡aÂ"[wë Ó)ý) `¢ÿð°¶mÃSJ$?8… Ì®ÞÎnD×V™ª|û+ =ö—ˆˆSYfmÕlÌÂ…©»†Åp»µÕš0FwGqæX]jH%!ndÐÔ-d\p`¬4˜8óç/öîðv˜Üü—.Úcƒša)O«ZÅ|u˜[ÝÔåj4DöS '7˜µ¡cIæz»S­/.ñ(”ØÌaôBY:Þ}úƒÛnY‚:0…®íÂuü#ÿ:8ÍÀóüsLœÔ¹Çý ¥ <çŽBïy¥-Ï2 zΣiIAÒÜGñºú™è{nZ½óêmoº£¥À@Ӳдc&;Y†|'À4‰"g±aC†/i‚¶,ñÙ¦åÉN‘§kÆO ØR‚èdžd>š1è͈'94¥O¦LSúNÖ} ð!8dÚ’¬Ïc«÷ÖH*±xtˆØ@z°õ–GMaUÛÇ ÀŒXqþïŒõ0…W(’ýqVïÔÍß‘u…)Œ´g£Ë gŠc¾î¤)&³øIìùÌ!u 8àž ORàyùy$°oâüU[žs<¡å{ÔkÙ½’k\Ý^ó TÕºïò¬év|­!NR‰“í0æíyg­ 2€ì|ŽZR($;Áq5>ØÁü\ÝðLªBü/‘_YÍ‹†R’š'Ö#® Ã$Ç“5KH‡¯Ë=òÉÿ©Æ%š&Šë>{æá ?(0»eZ GS$Â4'ÔŸ\9DÚÈÄI;è—ÄéŒ[m ƒ…<ùÒPÕ¶q¹ ²‰¹a”Ø‚Î(‚.6“4‚ü„Ôy3 }çËâ½4 ¯GX†nšF¼ê~£«Ã@®›Æ,K-¡¹“"C^Á-•Ä¡BáQ¸A{×­%ÖU¹iN»Öõ}‡`ÜŠfÿ@s’¸iâ÷Šÿ;²wê¦QÞ ì›¡˜üÆŒ†nm×#ÊóØ…Èè×þ8¢|æ'9<8ò£;|T\°kÛQÈ£]+†^àÙ-e{'1t¡ ­Ä}‰µU:HD…JZëóRŽÿßý«˜‹%æ^¿zN]Ø_è„.j6&ÀÃ#@쑞E,÷µfÕ? —a¾ðXtHbÁý¡[{Aæ¾ÏˆŽ«Í(X/¨®&þ1Dü¨møPì˜F/£o]?CÀ]uòª¢?’ ]—’€ÿrE®=°´1ëÊ`I/ÔÐ§Óæ<³fÙQá6A|´À™oñ?tºjÕ0ÉTEÙ­ôw“0wØâóyóÃûŠ'è9;Êt[»® ·ga£÷••½¬îû™¡ÃA7¢º‘“}r^{ûµ3ð\iʱ©ãÇ‚Jð– SšÕ¢n¶,ý¡¥€qA‰¾7…Úîx®ºp®‡È£{œù£ÛJA nØõFŸóÇ„wšœ”ˆ+t/Áà§™ Å0ØÍsù—¤ý§¿qú]} endstream endobj 467 0 obj << /Type /Page /Contents 468 0 R /Resources 466 0 R /MediaBox [0 0 612 792] /Parent 465 0 R >> endobj 469 0 obj << /D [467 0 R /XYZ 121.4 736.262 null] >> endobj 94 0 obj << /D [467 0 R /XYZ 122.4 420.432 null] >> endobj 98 0 obj << /D [467 0 R /XYZ 122.4 293.941 null] >> endobj 466 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F37 406 0 R /F11 176 0 R >> /ProcSet [ /PDF /Text ] >> endobj 472 0 obj << /Length 3038 /Filter /FlateDecode >> stream xÚuYKsÛ8¾ûWè¶tU¬P$%г'¿âÄv˜_<™ ³§ÓYœOêƒ?ÿŠ'%@—“xšËÉ 1Ö“t‘Oø²“»ƒœüb‹årš¥9« šUN£Skþ§©óòû+®ÏÙÇ)êcÁôÅŒ…î\­+†5?òß®"Bm’e¤ÝÖ ÇKåø£R‡€<ãm½#’)uÉøR-²bðñ¨5ll¹R‡Im„è<Ï·;†ŽI0Hó`ûRÿvx”Áèÿ=\f8ké6,e6›ó9¯å³ê*£ûwÈGgJ4‚Ÿq㯲4­k„áÆlçsÐN!Ç2:nTÛ©Ö(`zÇ3~TMË )§šÀ‰Jt8â m‚—½ C3wÛ »W­:úNãkܘ­²Ê€Tº,¢K³¥9JÔD[Fw•òªdê‰ZûÀ{Ü”^¿º/[«_qR»ÐM`À½îº0K ~ë´´Þš~tO¶,M@A¯k\ú+üž%щn83ûlp3*¥m€}­A÷1Ó”¿„ÓèÄ*l#3Ÿ©ÆÀ°c ºFã*æItáõz Ÿ¬ìÌõdf°%1Ì¢ÓÊ›¶sÛJ{as}­×É7¼‚Mé€-ïÀ'¯Þ5‚Á¡ìí8Œ}â_q60‘1%=0Ïaõ§ ”5à;Yž¨Ÿ„~­šèȤܦìÒUÍCÍ«u57Á}[9…ñˆÑëæÆ]Øñ® 'ÂÂF”½'?D›KÑ©ª·+Ð|ÎZ\*ŒGÛঔ –kÕÃTñ–} EÎ\£lZܸ,迵‡í£1N+ÝÈp·nÅnå;=žŽé{j•G;Iã,:¶4)@KGjój½b+–‹¾ÁMéÐL«qÞto¼ ¤­£ï|O+Øt£0°7Q•lÅi<ØpPñõ3Ý'–Äg™fP=ëÉP}©Œ…QÍvÀ½\áÙ`®h'Và[Ì_S¶Ò3£ß¹—½l~‚pÄ©iÖ£vñéùp¾ ˜àäO¤!š?á&<ã§4Y,@Ë¢± Ìxü%›¢ÇV¤·l?$$VÌ@× üà/Mf>_‹Aún˜Œ×6¦õ¹±¿`ÚªÖ`ѹ=ú¬ªÚõƒ_"Ãw‡l(Cø$ãG–ó~{8€šO¼Ó‚³ÄÊ›7ãöÙ<˜`i‚"Íј®Òä9Ë84ˆ¯d¤ÕêuÉÉ.-r‰l·.´5ވ܅¥S7»0«•!±4œÿ|À8¹ ¦jǪrTSˆ¢äPó8ŽkÃåR–C v`L` h0œV¦³}‰98°yEQ*^D7ÚXÆ>ªÚX>v¼ì›'¶2µ£½@™ûÊÕj4c}䘷1 eñEñ]nÉ`(ý"E`w#€#:[(S=ŒÝ‚°K¥Ô¶b@>!»ò%Ö‘\âÐD#ÁàÊ¿½¶oÕ\0žR½ÝÐA€©|Ž„™¯Œ0jGj ø ä)U嘘9Be¨]­[á†P!1xïe¿€Z±ý‘]dSÍ!w@•I‹†[æër*»Rë¹RÊ4ä¿«@¾è_Ž1å—Ar/„w5ËÁY ¿ŒèöuRÄEr±8î­åR"‰£[eÙ¯µPϸxCb÷&´;gw´z€c×ÀoêÚp‘C"«j<Ç_Y2“gŒI˸ ‡ÂU]ñÙîÒñÌa0v…fŸm;*ì$ÏÄ(¯ù@ŒÌr‚…ÝO“8H÷ÂÀµ?øÌ­]Õ­Ùˆ”hH5B:70jˆ`¢å0€#}m˜k¯ÈÏæ(Îñ§ˆÅþ{€^Ø¡V€lÄD¶,6˜« #ú®B;éýÀ‡GPØÍGZ4"}ùbÂŒgã&Ý·­áSZ,†¬„¿bhÆ„|Ö{Eæ0/€Xš† P¶²o+Åõ%¦sÕR£<|î-»6"_M-té5 )hGcŸ1ö"‹îúš?>sôœC_§i¥D”„¤‚J­Á—À¾‚ÔÕiÓ(§LßVìRÙ|k†¦C¸^¹CWóÌ@lájväFÙ•bS¥£$u2˜÷Ëèë—µ44žÂzXtèOiœuϳҾåó=‹!¼QÉ_¤z È7d®M«ÆT¾q»Ö,ÍãpŒ‹ÚH8b-0]ü»u­¤#ÀN¸¯€µ£j’‹)/,ûÁùÀÖÂÐg®6 l6#¶oF=_Š3.—û&г}á˜vÄ‘UxnÍ$ßI g` +>Q-аW+nþ 9@†ƒdY¡yƒ²Â†,—²“hîcy®·Ï»ý@Ç÷ª£+JÈ0 ÷¡'ƒÎþS';Á+µ§ÍB\ÿÝ“9ãÇXcE¯cŽ3ìà‰•;àûÝêµÐÂ)†®q! ¦EŠ… ª1ƒ¢k¼t‰H_”[€ï ¤ƒRpRF°;eë |Wi³©z,L(cyâv3tåÀ|«Õø½zµ¡Ž–îqÈ)²¹ô!^SGªTŽ(BaõÍâ•2^ð!U5[ÕÉ=  'žKtj9# 5–#Ò¹ïÄ CyšÌ3¬!f‘…b¸kÌ®†||ØÈ[§êF·­Ðyçè7Yᜠö6\~Rã^F͹,¹ #ãŠì$W![Úшw^C,¤Šú»N]ªú$Ãk+LåŒ@­) §€·ºY«€‚‰{øAw= KŽ7„)ôíºÃ2é.CŽˆl)­’Cðóc¡ƒ¯AšuÛyÎÛ8AÈI2‡Ä€[ p¡ðƒÉØ™ùJC ª}+-p–ï™1 q¼]æzÞg¡Jî½ùGg×t©ý<§¾Pêa2 WXËAÿŸµRq% …ÚœD¾eÚçæÂkžÓ]_X0ÐQ†#HZ³fvãÙzi\^‘3ç~¡…•á~¼.¤pÓ–W&,ךŒ©ÀâÀW1ÖßÊ9Ƥêp‡CFíyse‘›ˆ±ÂúJîP³{(¹+Âv§€]2TÉ"ôÝ-|1náIê0vH/[ˆ ÞÁ0ö£(ƵŠá­!½P°ŸÑºrÏ×ÿäê­äÊb¥6U[}ÿ o÷x%в¥¨gºJÓUtšîÞÀf„©r­æÏŠ!ÿÊt Õºcá‹|^ŽÀçìä$§üÄ’,'³l Ýi‚ _–M—E¾÷Æ2ycùámÄÒtšçYX–(¡J9þæY}k(²pyÚÀ8ûÊŠì£wµ¼åûÏ0óù´X.Ã+PÕuÛßÞ¿yy™>CÂÝÊ*©'³SZ®_¿QyçÓ8OÂ8|<`Ói¼øî½æÔm©äôf;Á!’8N’x6çŸ+éÓ0î| WsVÂnN9pˆâS~ùáéÅp?÷Ñk ÉCrxÄÝë‡òúŸ˜ Ž_®gÁ%³áEH‘8Ôº+0ô1ƒ5_e™½§÷ø®C­ñøÊ~œ*¨ÞÍö‹€døU/hmˤ›È$¡˜®_à¯6]õßÅÍü=^ûCŠ•1]y%Îð¥_Y*±àûÚ<è&¸†lîÎÔRþãüàb2‡R76¡?˜…ÅïFL¦1›Ì,_NÁw 7³LXËÅ2¼Cþ½„ j endstream endobj 471 0 obj << /Type /Page /Contents 472 0 R /Resources 470 0 R /MediaBox [0 0 612 792] /Parent 465 0 R >> endobj 473 0 obj << /D [471 0 R /XYZ 121.4 736.262 null] >> endobj 102 0 obj << /D [471 0 R /XYZ 122.4 205.239 null] >> endobj 470 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F37 406 0 R >> /ProcSet [ /PDF /Text ] >> endobj 476 0 obj << /Length 393 /Filter /FlateDecode >> stream xÚ}’[Oƒ@…ßùó¸$²Ý[÷ò¨I}0&Æ”ø¢A BlAéÖúó.ÅÖ O ËœïœYæ*f×|Ž:-4ÄkàBPFhj„8ƒGòZIò¦Ü$!'>Œ8©±hÂHJE$µF…«øfv-Ù G8ƒ¬gƒ:ÆY.­P’ËÛå]« qðpldÀG{I93nƒÇƒ ?Ý£ÒY8t[ÚPÕ–Á}pÕÎ!,pE¥Òâgm-UÒœ„àc­ÇÞœ„g€©1ª×}vÃû:–4ÏiïÉkÞëÎ.ϪƑ/&Àš2kŽ çØ÷îQ¯Óõ¾J§ØX2ù.þ‚o“·©„x)Ò¹ÿ"FÜq긆‚ãQûÿ÷ÄļÈ7ï&Mìhr(Ê´Õ½®Üõ‹ã‹¼?ØÕû&êu=Ð}qìËê0†¤ûm^…Xø.4DƒÉiʤʪ5ôyS%›õ_¾Gáñì²rç›òeï˺¢–Kq¢¹Â ”W»ã¢~íÆš endstream endobj 475 0 obj << /Type /Page /Contents 476 0 R /Resources 474 0 R /MediaBox [0 0 612 792] /Parent 465 0 R >> endobj 477 0 obj << /D [475 0 R /XYZ 121.4 736.262 null] >> endobj 106 0 obj << /D [475 0 R /XYZ 122.4 698.4 null] >> endobj 474 0 obj << /Font << /F15 117 0 R /F30 141 0 R /F28 142 0 R /F37 406 0 R /F32 175 0 R >> /ProcSet [ /PDF /Text ] >> endobj 478 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ52T2u ÍR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ(ª+¨ endstream endobj 479 0 obj << /Length 85 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3s…C®B.ˆMÎåròäÒW0çÒ÷ž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ €ËÕ“+ hz¯ endstream endobj 480 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ô35R0P0UÐ52T06W03RH1ä*ä26Š(XC¥’s¹œ<¹ôÃŒ ¹ô=€â\úž¾ %E¥©\úNÎ @Q…h ¦X.O ¶CÂu@\Å€ø3‚ðfáÌ ˜„ X„ Øžrãih4…ƃqs¹zrræŠH endstream endobj 481 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3cs…C®B.ˆOÎåròäÒW0çÒ÷ ré{ú*”•¦ré;8+ré»(D*Äryº(üƒì*ËåêÉÈžã: endstream endobj 482 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 483 0 obj << /Length 91 /Filter /FlateDecode >> stream xÚ31Ô35R0B###S…C®B.C° )D"9—ËÉ“K?\ÁÄKßCÁ”KßÓW¡¤¨4•Kß)ÀY(è¢ ÔËåé¢ðp‘\®ž\\Fb,ÿ endstream endobj 484 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚ]Ð1N„@ÆqÈ“¼fŽ0ïnÆXI²®‰&ZY+µ´Øvæh…#PRÅ÷>ÔÌ:„üLÂ^g› .ù\î°ápɯí)”¬—<ꇗwÚ6TÅ÷¹¦ùê˜/ ¼%‚NhWd·¦-²þÈ•áF~-MfV™€4Ùè9ì ¤Éõ@jŽ@Ò|Êò æ¶DÐÅvƒîzºi辆œ€ endstream endobj 485 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚuν Â@ ð”B–>‚y¯¥VÝ ~€ÄIõÑú(}Ç¥ñ’£¶î¹»$ÿ$Å ijOQ2£s„7Ƕ¥”‡Óçš=c4k{‹&ÛÐãþ¼ ™o¡YÒ!¢ðˆÙ’˜ù `-ÕZµWb ¬–b *ѯEO'«¯?rûÓuùU;ÍMNu—ìm2Ôl ¿T~7U7O“á-¦yëÐYˆÁÝë0ï÷ê4E_çºëUižR-ú™ \e¸Ã/-©J endstream endobj 486 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚ­=nA F=¢@r³GX_f–ÝE¢BâGÊH¡J¥ ” ¨wŽÆQæ”hÛ‰(!]š'Ùã±ü½ººšÕ4Q5¡±£M{¬Jn:ÒËçg Ú7ªJ´/ÜFÛ¬èx8mÑÎ^çT ]Ð{Aî›ô¢€<^™1FÃ> stream xÚ31×3²P0P0bS …C®B.c3 ßÄI$çr9yré‡+›qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÁÜКì=,'Lp¹zrr˜‹r endstream endobj 488 0 obj << /Length 232 /Filter /FlateDecode >> stream xÚбnÂ0àC –ná¸(Nhš*€Ô •Ú©CÅŒ  vNÍÂ#xd@÷'@iÕ©Ë'û,ŸÏž'’H.cÉ™$²JyËYfEÛŽ»“å†ËŠý»dûg+³¯^äs÷µf_¾N%e?“T’W3!êkCD…LÕ ªœ¹§Akq"³Ž4 „#³¡^è©]yêÛ"wlEtF8Ü[„ßÖÍߢñ¿,4ÞkÝî%w¯ÿ^ÅäæºÎ#ÄO]į]D0@KÆ´”lÄb›^¼$i©ê-a¤ÍóŠßø ˜´ŒÉ endstream endobj 489 0 obj << /Length 132 /Filter /FlateDecode >> stream xÚ3¶Ô32T0P0VÐ5R06R0µPH1ä*ä2² (˜Ae’s¹œ<¹ôÃŒ,¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. Ñ@ƒb¹<]ø? },Âìq ÃÿÿŸÿoøÿŒìÿÿaàÿÿƒ(ÌÀåêÉÈÖZ endstream endobj 490 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚMÉ1‚PPÉ6=ˆ$¿#AL¤0ÑÊÂX©¥…F[à&^…›È()Ȳš¿Å¼dfb½Ð¨§Ä!Æ/!ÜaI[@•Žó ÒÔ—¨Í´‚Ê·ø|¼® ÒÝ CPC Ng86–å×?[agza!,g¶"}¡W Òe[Òa;Òf{Òba)L*£_=¶!]¶%¶#m¶'-i!,göMúBïctG£#´ÿÂ:‡=|xb¬Â endstream endobj 491 0 obj << /Length 168 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bKS …C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿÿÿ?ÀÀ$€Éÿ²L>`q?€Hù ’ýˆd“Œÿ@$„ü&ë!d‚´ÇA"«©G2áÂdˆ-!¶ƒ\qÜ…H.ù‚a0‘\®ž\\\Lƒš endstream endobj 492 0 obj << /Length 247 /Filter /FlateDecode >> stream xÚ}=JA…K&h¨dŽ0uíùc6lYWpA#YÔpƒ¡ûhs”9„,S¾qÃM>êïU½î¶»ª)¥•ËZÚZºRÞ*Þs³B±”®þë¼îxݳ’fÅþeöý½|~|½³_?ÜHÅ~#Ï•”[î7B™Q¡QÔ™.T5eÀà ùL:)ŒäRH”¥˜ˆR„ˆÌg¡§9“Q€0ŽËYä¹"Ä5ìVÍÁ:+²Ž ÑFhrÌ 7¶(?Áþ‘…›® /†ohǬq% 8 I™¦ˆçÃäf®–‚S|Ûó#ÿï·|ï endstream endobj 493 0 obj << /Length 168 /Filter /FlateDecode >> stream xÚåŒ1 Â@E¿X¦ñ;ÐÝ„ÄhˆÜBÐÊ"X©¥…¢õæh9ŠG°L!´ò ÂðÞüùY>qsvœó8áÌq6ãcLJ•ާßËáL¥'»ã4!»RMÖ¯ùv½ŸÈ–›Çd+®cv{ò Óþ3ƒ²hBóË¢>4 Ç色Ãð…HG—F¥´A"¢áBDßôZI§DPMKO[zü…„Õ endstream endobj 494 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚuŒ± ÂP ES:²ÔÑAh~@_¯K§B­`A'qRGEçöÓü”úBcZÜD.gÉÍ=.¥“£©%—Kéhñ‚.¦>É·9œ1/ÑlÉÅh–zFS®èv½ŸÐäë9Y4í,Å{, ‚¨_B‘:yDÂvA;ÿ5R`Àãÿd¬V«‹£Îã¬ñ¸ªýé~ðY”ª¹j2ÎúͰ}s Oö:\”¸Á5y\, endstream endobj 495 0 obj << /Length 180 /Filter /FlateDecode >> stream xÚ½Ž½ Â0€¯8·ô¼Ð4¦N…ZÁ ‚N⤎ŠÎí£õQú;”œJÝ\Ìð…ûÿÒùlI -hª)•?¡‹Æ;#I u_9ß0·¨d ª¤QÙ-=¯+ª|·"‰ :jJNh ò ïˆ:AÌ‚ŒkðÌ 0³vY \Õ¨iôah@ù‰¬ú_ xØùþZ·ŽÛàâ‚UüD²ä ü$ø‹àÚâßu} endstream endobj 496 0 obj << /Length 179 /Filter /FlateDecode >> stream xÚ36Ó³4T0P0VÐ5T06U0¶TH1ä*ä2 (˜@e’s¹œ<¹ôÃŒ ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæ òÿ0ÔÿÀðÿÿÆÿÿÿ0!û†þ ò8€˜Á¾‚븈ÿ‘õÀ̱?ÀÀ4— h‡û†:ö?Ìÿ˜ÿÿÿtà[>€ÝÄþ‡ËÕ“+ ßrDª endstream endobj 497 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚ½Ž1Â0 E]u¨ä¥GÀ€$1E*E"L ˆ @077£Gé; š4°ÀÆÂò$ûÿÑp0!IšúŠô˜2I{…'ÔÚ‹’2õÚ쎘[kÒÅÜË(ì‚.çëE¾œ’Ÿ Ú(’[´€qÿCZ{˜‡³qóÍÅÌì’6a—6»^ ”ÎTþ¢³»2>ÐþŒ¯á³GùJ ¹é=~w‰»jQW¸í\Mh€3‹+|'bo endstream endobj 498 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚmŽ1‚@E?RL!G`. +¬šØH‚šHa¢•…±RK v8Gá”d×!R:Ékþäý=/BžpÄ£õŒõ‚¯!=HGNxÚo.wJRRGÖ©­Ä¤Ò¿žï©d¿âÔšORt¦tÍð 0@n ÇÚÒµ¶òZ¿ök·ñ+§ J´AO\ ‹e.d?:+°¦Ðaz²qw"–B…_c(/,]ã¹oÐé¹­¥¹„k@›”ô ÍUH endstream endobj 499 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ32Õ36W0P0b# 3C…C®B.#3 ßÄI$çr9yré‡+™qé{E¹ô=}JŠJS¹ôœ€|…h ÊX.O†ÿ Ìÿ0ð±<Ûq}ㆠ Aø3“ÿÿÿƒ™É4‹Z˜ËÕ“+ Û[þ endstream endobj 500 0 obj << /Length 234 /Filter /FlateDecode >> stream xÚ}±J1†ÿåŠÀ4y„Ì h6ç\·pžà‚Vr•ZZ(Úš> stream xÚ31Ò³T0P0bcs3…C®B.c4ƒH$çr9yré‡+pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ100Ð3þaøÇÿ¿áŸüÿÿêÿ?ø÷ÿÿ‡ÿ?äüÀþãÿæÿ˜ÿüo`üóŸÿÑs¹zrr¦…{ endstream endobj 502 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bCSs…C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þC¨'p¹zrr4ö+³ endstream endobj 503 0 obj << /Length 89 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bC3…C®B.s ×ĉ'çr9yré‡+˜sé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þQ¸\=¹¹6VLÖ endstream endobj 504 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚÕL;‚@\BAòŽÀ; ! V$ˆ‰[˜hea¬ÐÒB£µ{´= GX;ÌŽ‹–žÀb2¿Ì”Åd>å”Ë)ç3>ft¡"÷þcÇ¢=S­Hî¸ÈI®|JR­ùv½ŸHÖ›g$ÞgœH5,‚—{ábèÂ%0´{ ŒžðªO[YtÑ`b BG:„ˆzè~¸rßï!Z*ÚÒK=Ù endstream endobj 505 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ31Ò³T0P0bcsc …C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.OÆ? ÿøÿ7ü“ÿà_ýÿÿþÿÿðÿ‡üÿØü?ÀüãóŸÿ Œþ3 ð?:`.WO®@.²dG endstream endobj 506 0 obj << /Length 190 /Filter /FlateDecode >> stream xÚ1‚PDÇPlÃØ èç †X‘ &R˜hea¬ÔÒB£­p4ŽÂ()Œëw-hm^1“™Mìd6刧<¶œDÏùdéJqêÄ諨s¼P^’Ùqœ’Y9™L¹æûíq&“olɼ·¨,Þ@ 5I ˆô‰¼œî¿‡ èPÕA‹¬„MV#hü¶rèOÀë\š×ÿ‹áV1$kQè*-×:H§éHTÒ¡4ÐhYÒ–>Yñ]] endstream endobj 507 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ­Î;‚@à!$Óp纋‹D+ÄD ­,Œ•ZZh´†£qŽ@IAvœ5cibóóü£ÉxNšb…1EšÌŒN!^Ñ©jšF}ëxÁ4Gµ#cP­¤Ž*_Óýö8£J7 Qe´I0ϼÀ,$\e®™à&i«@(0<+À vJ!ù…âû¿/Ë×7.ý®OÐ$KU»|²àìÐû­ÛË·øfswo endstream endobj 508 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ð36W0P0b#sc …C®B.#rAɹ\Nž\úá F\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O†Ø?üáÿðÇþßúþøûŸáï†ÿþ?`øŒþ3@Ñ?Š—«'W Ì“C¥ endstream endobj 509 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚMÍ; Â@à ir„Ìt³‰­"1‚)­,DÔÒBQ°r÷h{”!¥…dc¾æŸW¢£„"Š©¯)‰(ÓAããTˆ†]g¼Dµ¦8E5—U¹ ëåvD•/§¤Q´Ñm±,L¿Àg¶³ Eö)ðmž}À?Óɬ¨[¹† ½Ñ@€ÛP&ØÉ„ª/ÿg"vâk tìŒeÙ3²¶wžòÈÎJ\ánONØ endstream endobj 510 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0TÐ5T0²P01WH1ä*ä22 (˜X@d’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒˆÁÿÿÿÇÀÄê¥ÿch`üÇØÀðŸýÐR®ÿÏÀ`””ÀÀåêÉÈ|Q  endstream endobj 511 0 obj << /Length 127 /Filter /FlateDecode >> stream xÚ31Ò³T0P0SÐ5T06¡C®B.c4¶€È$çr9yré‡+pé{…¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ10þ¡/f†bö?ÿäÿÔ7Ôÿ©ÿÿÿýÿŸ@üñÿÿƒ˜ÿ00p¹zrrÁja‚ endstream endobj 512 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚMÌ; Â@à?¤X˜&GØ=k ¢VÁ-­,ÄJ--m“ÜÄ›hŽ’#¤L¢³ ÂÂÌóŒæ£ÉBUÈÍlœCºQ4åºïØÁéJ‰!½WÑ”ôš»¤ÍF=îÏ éd»T!éTxóH&U_ ¨r@–ˆ‹’‘%rô2K7 j¯uð¿qðZ¿fD ´¢º>D”@ÞÃoËâÏ‹‘¸oKLjօV†vôg9Hã endstream endobj 513 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚEαNÃ0à‹> stream xÚµÐ1‚@ÐO(L¦áÌtYqV$ˆ‰&ZY+µ´Ðh+£pJ ú,ÄÞæ³™ìü?“5å€CO9\²šóEÒBe†«E÷r¾Qœ’8p¨Hl̘Dºåçãu%ïV,I$|”œ(Mn À׆L€Ö%­+¸WcT»x•ÓÀ+ÑÀ/ÁÏ!2äf;Ï EÏð4†òü|Þ38²¥»¾Å†±±l@Õ†¶ñ»"l%m9´NiO_¼ìvü endstream endobj 515 0 obj << /Length 118 /Filter /FlateDecode >> stream xÚ31Ô35R0P0bc3S3…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]0001;Ëñÿ ÿѱ> stream xÚu1nÂP †ÿ(C$/é âð’& &"•š¡R™:T€‘R‡Šäh9JŽ1µ#ÑU’Ÿ?ûÙY2>r̩؇#^%´¥4Ó<¶Ô Ë M roœfäžõ•\ñÂûÝaMnú:ã„ܜߎ?¨˜3Â@)€'RÃiˆ´E:DmtBTgäZÇÕ—öT' ¯:ç¢b¨ÿ`À5ò_T”=4p¾ÀÓ‘ðm£ U„ÍOÿ{¯õßôsÍ8ÌðÌðÍš¿Z)zð¿ §‚ô уe endstream endobj 517 0 obj << /Length 248 /Filter /FlateDecode >> stream xÚuÏ1NÄ0ÐoE"Ò4>‚çàdCT‘–E"T[ *vK ´$7á*¾Wð H™"Ê0D@AóÆ[ãùÇåQ½â‚+>\quÆõ ïJz¤ªÖfÁõé×Íý­[ò[®jò—Ú&ß^ñóÓËžüúúœKò¾-¹¸£vÃÈ&N”N aDd"#ò)Ÿ`3ÁEÌp¯hzt‰F‹Ö×ÏJøƒý!þƒ‹Ýoš˜&'º¨¿)í)“ýˆ¹È{ÐÕÞ‚‘9=”´Ò. :í›yÁ¤¬Ùˆäš nÐåº+šÜ‰ôéä¢ÏŒ¦×A:—.Zº¡OÌæzc endstream endobj 406 0 obj << /Type /Font /Subtype /Type3 /Name /F37 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 0 -21 60 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 119 /Widths 518 0 R /Encoding 519 0 R /CharProcs 520 0 R >> endobj 518 0 obj [41.52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 27.68 23.07 41.52 41.52 41.52 41.52 0 0 0 0 0 0 41.52 23.07 0 0 0 0 0 0 55.36 55.36 53.05 0 0 47.28 55.36 0 0 39.21 0 0 0 58.82 0 53.05 0 0 46.13 0 57.09 0 0 0 0 0 0 0 0 0 64.58 0 39.9 42.9 36.91 42.9 36.91 25.37 41.52 42.9 19.84 0 0 19.84 65.97 42.9 41.52 42.9 0 28.37 31.83 29.99 42.9 38.29 56.74 ] endobj 519 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 45/a45/a46/a47/a48/a49/a50 51/.notdef 57/a57/a58 59/.notdef 65/a65/a66/a67 68/.notdef 70/a70/a71 72/.notdef 74/a74 75/.notdef 78/a78 79/.notdef 80/a80 81/.notdef 83/a83 84/.notdef 85/a85 86/.notdef 95/a95 96/.notdef 97/a97/a98/a99/a100/a101/a102/a103/a104/a105 106/.notdef 108/a108/a109/a110/a111/a112 113/.notdef 114/a114/a115/a116/a117/a118/a119] >> endobj 520 0 obj << /a21 483 0 R /a45 482 0 R /a46 479 0 R /a47 480 0 R /a48 514 0 R /a49 515 0 R /a50 516 0 R /a57 517 0 R /a58 481 0 R /a65 484 0 R /a66 485 0 R /a67 486 0 R /a70 487 0 R /a71 488 0 R /a74 489 0 R /a78 490 0 R /a80 491 0 R /a83 492 0 R /a85 493 0 R /a95 478 0 R /a97 494 0 R /a98 495 0 R /a99 496 0 R /a100 497 0 R /a101 498 0 R /a102 499 0 R /a103 500 0 R /a104 501 0 R /a105 502 0 R /a108 503 0 R /a109 504 0 R /a110 505 0 R /a111 506 0 R /a112 507 0 R /a114 508 0 R /a115 509 0 R /a116 510 0 R /a117 511 0 R /a118 512 0 R /a119 513 0 R >> endobj 521 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚMÎ=jÃ@à*^³GØw¯„,Cªÿ@T’*EH§Lã@*KK_I9It•*–}y2$¤ù`fšYV‹ú† . e¹âjÅû’Þ©ªyn4^——7Z7乪ÉßjM¾¹ããáã•üú~Ã%ù-?•\> stream xÚEϱJÄ@Ð;¤xM>aÞèlHv‰ ÖL!he!Vº¥…¢`µÉ§åSò )§2¾·ÓœâÎÌåNU^n¯xÃ[¾(j®*.wüVЕµ¤’WG¯ï´oÉ?qY“¿“œ|{Ï_ŸßGòû‡.Èø¹àÍ µìÀÅ ›#LJ™bc‘O.Ây€l@Ó „“¾›¹9™3v\ÈÇìÌ„|Xpÿ4ýB§$Á$˜ Ñ&`vBJ³ŒRÅÅY×F™ Ŭ„…leµÎ;É $ùƒÐ H&õR¼¶m\"ÐmKô  íw% endstream endobj 523 0 obj << /Length 191 /Filter /FlateDecode >> stream xڅο Â0ð¯t(ÜÒGè=iª:üvtrAPGEW«o¦o¢oà˜¡ï1ð ä._rv+/8ekeëXÎ3^YÚR¦ÅTïÎrCÝŠÌ”³‚ÌPÊdªïw‡5™î¸Ç–LŸgrsNUŸ@rÊË7­iïÏ*…¿ ôD"öÉÝ¡¼Š³C8Å3thšHÝ+ýêCÇPX  ~„%Ô$Bfôþ„ÚõS²îý& *šÐ ÆàMc endstream endobj 524 0 obj << /Length 206 /Filter /FlateDecode >> stream xÚEʱjÃ0€á3·xͦ{‚ÊÆ©!Ki õPH§!SÛ1CBºÚz4?ŠA¥‹!õ®2Ü÷ß­»»û 5Ôó¬{êzúhñŒ´FV9¼Ÿp; }£nƒö™+Úá…®—¯O´Ûý#µhwth©9â°£*è:šuš2˜\ ¸RŠw.&?º ,Ì4Ÿ…4yþ÷ÁÁ*Á$ŒÿD®*BZ £ ÕqÔLÖAŤ„ïT3‘ù õ¬ S•E˜kÅk€À§_ñÏsc‹ endstream endobj 525 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚUͽ 1 ðB–>Âå lϯ©p*ØAÐÉAœÔÑAQpê铸*>Ê=‚ã ¥±N‘$ùCòn§7"EƒÐùº}ÚexÄ\Q¬0ÆÃö€…A¹¢\¡œ…-J3§óé²GY,Æ”¡œÐ:#µA3¡¤¾µ}‹+Á‚ë”ìRföúÁw¯…k…ƒÒŠ´é+ çøˆsú Wè[C ؈ÿâ’uCëÇëŸ*Fâœ\âëLv endstream endobj 526 0 obj << /Length 202 /Filter /FlateDecode >> stream xÚ]Œ= Â@…Ÿl˜ÂaçÆ`TqÁ0… •…X©¥…¢]ˆ{3÷(Á2Epb!û±ïÍì&­F»ÇMîÊIzÜêð6¦%±äæ+¾›= SŠ–œÄM¥¥(ñéxÞQ4œXÚ1¯äÉšÒ1÷¡lÊi\làŒ5»Ài¹…Ûk±Ì !ùgmü¥1ÌÛù—ìòKQQÞ¾WV…º£T¥º! Êà†<|„cñWo¡½ö€Ô@Ö €&)-è ²:Yâ endstream endobj 397 0 obj << /Type /Font /Subtype /Type3 /Name /F36 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 5 -18 49 52 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 97 /LastChar 119 /Widths 527 0 R /Encoding 528 0 R /CharProcs 529 0 R >> endobj 527 0 obj [43.59 0 0 0 0 0 43.59 0 43.59 0 0 0 0 43.59 0 0 0 43.59 0 0 0 0 43.59 ] endobj 528 0 obj << /Type /Encoding /Differences [97/a97 98/.notdef 103/a103 104/.notdef 105/a105 106/.notdef 110/a110 111/.notdef 114/a114 115/.notdef 119/a119] >> endobj 529 0 obj << /a97 521 0 R /a103 522 0 R /a105 523 0 R /a110 524 0 R /a114 525 0 R /a119 526 0 R >> endobj 530 0 obj [500] endobj 531 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚ‘=nÂ@…ÇraiÁs°þ‰q:K`$\ %E”*PR$JZðÑ|ŽàÒ…̳Y¬¤¡øš}³«7ß>'“t*¡D¡<Å©$/’¥²‰ø‹ãLÜÂÏÏJ6k‰36K$lÊ•ü|ÿnÙÌ^ç±)ä=’ðƒËBˆœ#‘«ø5QPåD´W:·%ò#J c9Ðуr¦ç4àvh|Ð }*q¨ÿæl©äzÿ¿÷Ç=ÐÍö´½ýö¾×Ý÷´{[½¸#¸‚3¸ƒC¸„S¸íÃ5œÃ=þÀ9ò¢ä7¾áÄÚ endstream endobj 532 0 obj << /Length 224 /Filter /FlateDecode >> stream xÚ‘1‚@E—PLØ 芔$Љ&ZY+µ´Ðh+£pJ "θLŒ&4¯Ù¿³™ÿv<Fôq‚ƒ0ÂÑãœ!ŒéÔÇÀ—l‚izƒa zÁèl‰×Ëízºša:Åm€þ²+¥TM܉„ðJ¹…RNIPhSh50O"gèRÂÐE¯4¸•Á©;hÀhÐZƒzóø&/z( ÉŸÈ|ßû¿{´Ÿ=eoî }¸›ô”Þâ°v”wÎã]²SvËŽÙuÒ¹ç?à¿€ykxBÐ{ endstream endobj 533 0 obj << /Length 173 /Filter /FlateDecode >> stream xÚ35Ó30T0P0SÐ52U05P07UH1ä*ä21Š(Àä’s¹œ<¹ôÃLŒ¹ô=@\úž¾ %E¥©\úNÎ †\ú. Ñ@Ãb¹<]@àˆ`|"™‘I°8;É߀D‚µÊ#‘vH¤ ˜¬A" HÆH$†µÈ²7 [‹l¡†µÈVÐÊZ¢ýÉðÝZº/~ki¼kÀ$—«'W R6N` endstream endobj 534 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×36Q0P0T0´P06T02WH1ä*ä2² (XB$’s¹œ<¹ôÃŒ,¹ô=€„§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ÂÿÿÿÂ\®ž\\Ï5^ endstream endobj 535 0 obj << /Length 383 /Filter /FlateDecode >> stream xÚ…Ò±NÃ0`G,yñ`¿$ªÒ¡Š¥R$2 ÁÄ€˜€‘R‡JñÆc‘7àÂdô帳Âèô9qï¿;e]ŸT§ºÔ+}\éu¥ëR?TâYÔ+|Xêº oîŸÄ¶Å®W¢¸ÀÇ¢h/õëËÛ£(¶WgÏ;}[éòN´;ÍëXüåÐGI¢ŒQæËEuvìÛÄ"ó/5A|bGKþ§&i“tHŠ½È™¹EÙ¸(ñÅ)9H»HÑô84‡&iŠÊÁ%ITŽ*…¥qK; g2Iù Q+G~C¤Æ¯™=ø\ÒÞ/ÓüêcÆËt×UšàßPÙ¤À†ØI’0Œ;Ž-P¬D >V9j•Â̘aÈ&‰b»‘aœ ê¶ðº¿-”‚÷>HÂgØ à's8É•QÿÙ@ó€ïºÃ³EÔu>Ð<{å=ÍTe±ÞÄ”ÅoÎ8 Ú0Œ°P†ê%½gøŽŠ9:´Išk‰óV\‹oØæf endstream endobj 536 0 obj << /Length 291 /Filter /FlateDecode >> stream xÚÑ1jÃ0€a ‚·øÒ jR'YbHS¨‡B;u(™ÚŽZڭؾI®â£ä=˜¼JïIq‰ÁT`ø$/ÿ“V‹«ëµIÍÂ~«ÌäkóšÁ,s»OÝÖýxy‡m É“YæÜÙSHÊ{óõùýÉöáÆdìÌsfÒ=”;#ìÒðkTÑNUç„ÝDö3’8L¤ð4£1è¤裵>+*bôùT)ôÑ?£dÐ C~yE}ˆŽºQÂKZq¾<Šš¥¬8ZµT°b+Ρ1ܼÏ×nÎ N”¿q÷Aªœ(ºF».äÀùgE¤žã…¸$ <†àAéÄñ‚óGÅ.!Ñ šÕP¼Ï/X-Å{Uü°­«£wÅî¿‚ÛáÆÁÊ’ endstream endobj 537 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚ¥ÒÁ ‚@à‘Â\zç ZÑ< f‡ N¢SuìPÔ¹ÍGñ> stream xÚÅ’=NÄ@ …MÉÍ!¾$)Èf«‘–E"Tˆ (‘AKr®’£äS¦XÅØ“Ù,=S$_> stream xÚÅÒ½ Â0ð‡Â-}„Þ˜ìÇV¨ì èä Nêè èl­ÒGpìPz&±M„ˆÐÉ@á—„$åÓ$BgüK|Œ<p8äs9‡3d°-Æ!°%_V¬ðv½Ÿ€eë9ÀrÜèï¡È‘ä°øxë©Ô)Q©TóÅ”ïxÔô²©íe¥4ÈG¤ªzMÄa)[¼"ei=šAikÊëL¹ôM¥!çCÕhÕ×ø.TC×Ê#³¦igÖ^w†£o¶êªî´î¾J„-ã$äŠKH…­We¦N'Q<‹6ð¯?K endstream endobj 540 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚÒ½ Â0à„…[úæžÀ´[' µ‚ÄI'õÑ|£ƒìµÐ´Ö@ໄ\þ.ôû]Ô=ô0âÖƒa»:Ô›=Ä)È%!Èi> 2áéxÞŒçcô@&¸òÐ]Cš ú¶ŒuãŘPŒq‹Á"p3q%ŒÚÑ«áÒ§™ÎÐN°¢€¾ðß(WUyxû¦9ø³8¡ ëÑVÁ6q¯Ã1 D„=¸¢$Ø¡¨•D‰÷/À$…|®±ßd endstream endobj 541 0 obj << /Length 173 /Filter /FlateDecode >> stream xÚ37Ð31R0P0b3S3 …C®B.3rAɹ\Nž\úá f\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O…ÿÐ@€>À`ÿAJ3Bi†z(m¥å¡4?”f‡Ñ 43š+ÍøF3| @3€hf4;”æ‡Òõ`è+¢h˜z„~vö1’HƒiP¤~ ‚ærõä äœÏ endstream endobj 542 0 obj << /Length 300 /Filter /FlateDecode >> stream xÚÍÒ½N„@ðÝP\2 pó ÄX‘œg"…‰Væ*µ4Q£5÷&÷*< °åÆ™`¹øQ{ù±,ìÜÌ¿,OÓsL1Ç“ Ë3Ì/ð)ƒ7(r^L±ž<¾Àª†ä‹’k^†¤¾Á÷ÏgHV·—˜A²Æ‡ Ó Ôk4ü#gÌ«`Id ßKD-XûHT±ú…HžQìd[Ïë;'Ûøë¥n—ü1‰ªÞ“ÕÆi/jœ®óÇ{;_…ã÷ƒZŸÓöX\‹?b.®´ ê¿«QÙ_äËó%þ5Üt×õIÿ¥ôs&µüAÚÉciÇUÝ h’NËN SµÓ¤#þvPHDH‰&‡4MÎÒnL˜Ï•OÝ!“è|&%­Ig]‚«îà ê¤ùr endstream endobj 543 0 obj << /Length 121 /Filter /FlateDecode >> stream xÚ³0×3µT0P0b 3 …C®B.s˜ˆ ’HÎåròäÒW0·äÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(ü‚f ñXƒý? øÿƒaä±þƒ)¬‘VøX¤§:.WO®@.Ö 4n endstream endobj 544 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ô37R0P0aK3 …C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÁlƒü†Q3è¸\=¹¹‹iƒ% endstream endobj 545 0 obj << /Length 290 /Filter /FlateDecode >> stream xÚÒ=N…@ð%[l2 G`O h„ŽäùL¤0ÑÊÂX©¥…F[àh…#PRlwgvÆö‘@~ËÇvvéÚ‹¶ñÏîÒ_wþ­Oh»8>¤azðúÇê'ßvPßÅ»P÷þûëçêãÃo >ùçóÃÉceõF4ª‚ˆBHn¥ú, !QiADõITŸÄ!I•Þ›ô=ܲ •EÉs¸g•ˆY}/+̳ òLq+qa­N´XäŽp¶\$F¨ÿkÚU¨ý¢¬_¥*©KÖÙ¡¬½UqO,Ý-ê‰4©¨§,Ùiê‰Tª¨§¬Uö<áÿ Šÿ¦x ç nx„?¡«ÿº endstream endobj 546 0 obj << /Length 149 /Filter /FlateDecode >> stream xÚ33×36T0P0b3#3 …C®B.Ss ßÄI$çr9yré‡+˜šsé{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü‚ „hû £4š½?Í£ðÓò8h{4ºþ¡¡43”f‡ÒòPºB3ÿÿŽ×ÿÿÿ¤¹\=¹¹¯½¢a endstream endobj 547 0 obj << /Length 278 /Filter /FlateDecode >> stream xÚÓMJÄ0Àñ”. o“ H›˜dŽÕÂ8‚]ãÊ…ÌjtéBQ讽‰WéM캜Å0ϼøW:…Ðþ(üyÄšüt–+£Îܲf¦òsõhás·aˆt²}†eú^-æ oÜ.èêV½½¾?^®¯”½RV™ T+…xþi[Dü2hé; Ê_Ð.°#ÄŸ ì ÉGˆf È,D¹#¤ ²½ð¯ H_W3H|ÝÀ ¦ ¨gQPÜMAP]Òr :)8P]Ê‚‚ŠiP]Í‚ê®.êY¸ ¸cá‚’ö4ƒ<Ê]:‚l_Œ@êcà0‚˜æÀÂÏŽ… áðáù»%Ãåœü®+¸ƒ/]zœ endstream endobj 548 0 obj << /Length 277 /Filter /FlateDecode >> stream xÚmÒ1N„PÆñ!$ÓpæÉ*l¢!Y×D ­,6Vji¡Ñd;<Úe`Iaö93o,(H~<Âÿ+ mÎÎ×TÑŠ¯vE-½ÔøŽœUr+žßpÓcùHÍË[>Ų¿£Ï¯W,7÷×Tc¹¥]MÕö[ !@‰õí:,è]øáW`¬Ñt~]'Óå¬!LêdDUHZ•KZ•i:j4¥®DGD i•¦Uš6L…KGT:¢Ò´JÓ*M›Â¤Á%#Q’Ž’t”¤'¦Ô%#Q2bâ´‰Ó&N»Ž¦ÜÅ#&N›8mâ´+L\úÉT…+we®tA‰ f ®ÎU,(we#Ä¿RWâ‚Yû›ðXMÑ× endstream endobj 549 0 obj << /Length 286 /Filter /FlateDecode >> stream xÚ½’±NÄ0 †sb¨äå!~èU ë1U:‰H01 ›€‘sîÑú(}„Žª;¶RÐ!F:$_þØŽk{sqVã ×xZa½Áõ%>WðuÅâ k»yz…m åÖ”7,CÙÞâÇûç ”Û»+du‡ì³‡v‡Î¹‚:—>¢˜ö‚H%Ï0„èhâ}ÁGOÉäàNÄhI¢öl+÷­›Ñé"‡$§>ªx$O‰‘Aâ9Ñ3Hà:ƒ7¼¦ICc0C0˜Â” üdÿæ4rªGðËZƹ3h醥AŸ¡°:wß*¯½8,´;$Á¥qQRrº¤WEö¤½g‡Ž½{ !“Љ̳A:>6@ ÃøcòhÙ°Áu ÷ðž¤ö} endstream endobj 550 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚ37Ó35V0PasC3 …C®B.3s ßÄI$çr9yré‡+˜™sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ„ñÆøcüo€100ÈUòƒŒÿ@ õ  ûPˆ3øúÑ v,ŒÔf [Í=èn†ûæ/¸O¡~0”ñÆ85 †)šˆcp¹zrrÚõÏ\ endstream endobj 551 0 obj << /Length 251 /Filter /FlateDecode >> stream xÚ­Ñ1nƒ0€á‡: ½…”wÖ 4ÈYŠD©†Hí”!ê”d̪™áh9 GÈÈ`ñj°1RaKd}22²äây™PD zŠI¾P"éãeDÝ“¬Ì›ý ³Å–d„b­—Qúù¾Qdo£ÈiSô…ENÜôèÅW§Æ©uâJ3d€”k«¾YA¿¥W©¥í ù©² fuýM¿<7'MÕäž»¥ïnžÚÝ€ASýwMRàö \S¿ošÖ'ðæŠß%u—«vªrChë2<š>úï¿\+#_ç2ò˜o¶cibBרÂ÷?ñi h endstream endobj 552 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚm‘½JÄP…OØ"p›¼€yÍf‰‘aa]Á‚Vb¥–Šv É£åQò)#\î83w‰.x›Ìï9“zu¶ªhI5–t^S½¦—Ò½»j-Á%]2Ïon۸⪵+n$ìŠæ–>?¾^]±½»¢Ò;z,iùäš<àH9àØ0w{‰1‰àÛcÁ]Ω<² h=òQŠ=6 zh¾,ÝŒ$üûýd˜ˆà1bŠðÐ׆«ا¨#X«êéÉA}Éëă¼ÞiMËÖ©¥S¬Ñ-d§ÚpíAÜiÈÌ$ r¢ñÉ0cúðGÖÝ‘»Ò"Øyäž*\ެŠå'¨ªÍ5 ‰Ðš?ŸÛ)¦ÔœhVVQ¥»nܽû÷ó× endstream endobj 553 0 obj << /Length 162 /Filter /FlateDecode >> stream xÚ37׳4T0P0bs3s…C®B.3K ßÄI$çr9yré‡+˜Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(Øÿ‡€D1þ1ðÿo`þÿ þˆÁ`ÿ¡þ˜!ÿ¡žÌ`G0ê æ5#F„Á€ñÊøñʨ †Áe0Œ2¨É`'â\®ž\\TÒË. endstream endobj 554 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚí’= Â@…G,Óä™ è&"ù©þ€)­,ÄJ--mMŽæQ> stream xÚнJÄ@Àñ )Ûän^@“øqäš œ'˜BÐê ±RK E»ã.÷f‘{‘tצÜ"dœÙÙUCPœÀò#»,6?;>ŸA 'p”A~ Ó3ý¢óø›ÎdçáY/J¬ OurE¿uR^ÃÛëû“N7éd w¤÷º\Ò(¥Pæ?RE¯x:¥ ôšˆ «"¤XÔ²êBR$jX´¨ˆ–PT³èˆŠI¨b™&|=v,åU°¶¬¹§nX6zm…ñY‰6^çs²D‡VÍÉý­ÈŠ£9^[q>'K´M¦T#É6ºQôÜ©ÿ¡ˆò×N(ÉöÍ×Î)Æ]ëõñ¥½S„ûÆëàâ¡öB§±ú] Q´íÇ*º¿41cÅíXQ3”¾,õ­þhñÀî endstream endobj 556 0 obj << /Length 232 /Filter /FlateDecode >> stream xÚ}ϽNÃ0ð«J¡l¬ü¹³;Ta?ùìûpÛœ7k©äBÎjiÑÃkÍïÜVb»¹Ì7/;Þô¥­8Üj˜C'Ÿ_o6÷×RsØÊS-Õ3÷[¡&Òå±0’Æ`Q·Ð0‘|T*õM *pŠÓŒ_¬°·ÃÅ2ô $ŠL‡o1ÔJc4|îÐåÝœŽä~82ý;á eSz™ñéºÒ)<Æ8`¯ÍŠN9y{ƒÑ2Êhà›žøål¡— endstream endobj 557 0 obj << /Length 229 /Filter /FlateDecode >> stream xÚÅ‘; Â@†7¤¦É2ÐM4ñÑ(øSZYˆ•ZZ(Ú ñhà̶Ü"8ÎÆP+q›æ±óÿ3Íz­ ‡ ¬ú¶±ÙÁµ;MÐÃV‘Ym¡œc€sd4ÁÃþ¸ÙŸÐ9Ä…Þ¢!Š8üˆ¾Â~Âúƒè̸¥Œ+‘fÜ’^Æ áÜke˜ÄÙ"eš,®”æŸˆÕ tŽÞGd?ÀË„bú›$UÊ5â“ÒŠflì$*lóÞÍMgnó ´C¦JÙæhVÊ·3Ë®FÌàiÔp endstream endobj 558 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚ­1 Â@E'l˜&GÈ\@7‘E±1#˜BÐÊB¬ÔÒBQ°’£í‘R¦gEì…áv>ÿ¯™'SŠÈÐ &3!3¦cŒ4#£Nq›ÃÓõ–ÌõRdÔùŠn×û uºžSŒ:£]LÑóŒ’> stream xÚÅÐ1 Â0à”…·äyдÒ*N­`A'qRGEçx¯ä ¼‚7бCéó=q(8‰òÁ ÿŸv«ÙŠ1Ä&]lwqÁ†Øy,ÖÐËÁN1‰Áy 6án»_íûÍpa8‡•‚&:2)Ñ™¡BztòŸÊU™«ÇUN­ËÇ+æIZÔà^Ü>¡àj©‹$qÍ©ÂÆIMîMRÚ'*ùmseÿ c¨ÒL@… ÜI 9Làwn¶i endstream endobj 560 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚu=nÂ@…gåb¥i|Ï’eÅÒYâGŠ‹H¡¢@T’Djûh>а¥ äÉÛX ÉŸVï½yšyñÏÞËD¦òä%¼J˜ÉÁó™C€8‘0Ï/*v[ ÝdvÕ»\/_Gv‹¥xv+Ù¡hÏÕJˆÊžˆ2Õ†(Wí ¨F¢ºO†¶öFF›l@²Ä&¿%`Ý}b —ÝÈzdüeL,¢>2½¿Ýÿ°~dgygL[41Ƕ¦³Š» ÚÖhKy“êJ BaûsµQø óºâ îDŠ endstream endobj 561 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ36Ñ32V0Pacs…C®B.cK ßÄI$çr9yré‡+[ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ700ðÿÀÀPÿÿãÿÿ?˜ÿ÷ÿaàÿÇÿAþ<ø$ìADýÁÿ‡áÿ0ÁüH0 ¤ÿA6b#È4oˆúÿ@ÁåêÉÈèü®  endstream endobj 562 0 obj << /Length 281 /Filter /FlateDecode >> stream xÚ•‘=NÄ0…ÚÂ’!sH›´––E"Tˆ ()@Ðß`¯ä£ä)·ˆ<ÌØ‹Å$Å'ÏÏ{ÏIן5-5tA§ç-ukZwôÜÚ7Û5¤oßZO¯v3ØúžºÆÖ×R·õpCïŸ/¶ÞÜ^Rkë-=ˆÔ£¶ð„/ÀqZq€gÞ XŸxÂqdWŒjï£Ip‹nIU¨ì¤iÿÀ+ÂÿñW%KK"5²-CiÖKìŒ #;–A˜ 58©E,˜ æ½k΢SvàYlK³ S^`‰%*#ÃGÝÅ4dP€ãã”ɲ€1ê:¼^.ei³À¥üiþ‘C–¨žÌ%ý>+éÁ^ öÎ~ÝèÈñ endstream endobj 563 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ33Ò32Q0Pa3 ²TH1ä*ä25òÁ\Dr.—“'—~¸‚©)—¾P”KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓE¡þüÿOb†PŒF±ÿSöÿ@Ôÿÿ€ÔÁÿÿ©ãìÿ©ó ò ê>ÿ? uBýP?Øÿ©(ÔlÔ¡Dýÿÿ¿ùÿÿø(.WO®@.Jå×m endstream endobj 564 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ36Ô34R0P0b#Ks…C®B.#ßÄ1’s¹œ<¹ôÃŒL¸ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. 5 Œÿ˜ÿ7°ÿ?Düÿ #ˆ P¨¨’¨?Pÿ1ÿ?ÀH{ôp¹zrrÙðD endstream endobj 565 0 obj << /Length 220 /Filter /FlateDecode >> stream xÚÅϱnÂ0à  H·ärO€“¢´bB*‘©L ˆ‰22´*+ö£¥êÀc¾c"û¿… F,YŸÏ²ÿ³‹A/áŒû~oü:àÏœ¾¨uʰXoiT’YpÑ'3õ»dÊÿ|ï6dFcÎÉLx™s¶¢r‘­"?D+§c¥~DRãdZ¡ÞÛ+-ˆЭARÔ«.à·Z”£§T7œ™ÿrBŠ ‘³Ê°U. (]Ÿ«],ᮣD> 4À¶À§ù®±Hsz/iNW^`ص endstream endobj 566 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ36Ô34R0P0bc3K…C®B.#S ÌI$çr9yré‡+™ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ê0üÿ‰™˜qàÿÿÿ7 c.WO®@.„S—œ endstream endobj 567 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚíÑ? ÂP ðˆC!Ë;Bs_ëZA,T;:9ˆ“::( n>'Go qèQz„ŽJcªƒ¸îß—dûÚZ£E5eÚuj¶héâ}O²SÆò°Xc¡ž’ï¡Êu4¢Ýv¿BŽ{ä¢îÓÌ%gŽQŸàh¬@åÌ&àŽlJ2§æDxbΪ…çÔÎUdÂK¬ ÛØ9TùŠ»`Pá+XÜUò.<¼˜ÉS*ñ“©0y1Æß ÍŸoò³–^Š_ˆƒ'øøïü# endstream endobj 568 0 obj << /Length 162 /Filter /FlateDecode >> stream xÚ33Ò32Q0Pa3 eªbÈUÈej 䃹 ‰ä\.'O.ýpSS.} (—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹C}û?†ÿÿìÿ7€¨ÿÿ©Æÿÿ©öö€Tƒüæÿóøÿ10þŸ¡ö@¨ ìÿÔê6êÀP¢þÿÿßüÿÿ?|—«'W ã[« endstream endobj 569 0 obj << /Length 213 /Filter /FlateDecode >> stream xÚ¥1 ÂP †#B–¡¹€¾[¥S¡Vð ‚N⤎ŠÎõh=JбC1&¶ÕE\|>øóó’?ádäùäј†>…c &tðñŒA$¢GÁ´éìO˜X4 "4 ‘ÑØ%]/·#šd5#MJ[ùh‡6%·y=æ\0`..³ªYå°€óßAK<ý@\À@Q‚#6·§-WQwˆu©;Sðwð ÷?ñkB·KƒnÏú•¾ÍÐ&jÑ×´…„–ìùû1³´Áa®>7k.ˆs‹k|]Åf endstream endobj 570 0 obj << /Length 227 /Filter /FlateDecode >> stream xڵѱjAàY,„i|çtïôN´Œ‚Wbe!V&eŠˆÖç£-ø>B|„-¯Xÿ•D„ÄT±X>ØÙeçŸíuÚLéJ+HÞ—,—×”?8»‰ô²¯ÒêGÛ¹äÛ)öÙϲYoߨŽ^ž$e;–E*É’‹±P鑪SݽêT+ðé†(5OTÓ@u%ƒBMwF=p§±ŒºoHý-euŸaø~ÏÿììÒnlÞ]£Tȇ`1æ)†6AâÆ¯bXiú DAãŸü O žñ¥ÜÆ endstream endobj 571 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ31Õ37U0P0bcS…C®B.cK ßÄI$çr9yré‡+[ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êêþÿoüÿàÿÿæÿþÿïÿÿHôÿùÿ¾ü?æÿûäÿ1þß"~À‰`‚ÿãÿì?€ã ÁÀ€L 7ñÿ?Ðbl—«'W n endstream endobj 572 0 obj << /Length 223 /Filter /FlateDecode >> stream xÚE1NÄ@ E?šb%79Âø0;Úì"ª‘–E"Tˆ (·AKÜq­%GH™"б´4o4ßßþv]_ä+^sÍç™k{wüšé6[í{¹T^Ž´o(=òfKéÖdJÍ~|½QÚß_s¦tà§ÌëgjŒ8êU•ʇ R:EZ Ê·cªV¢ÿG@­‚V‡•ŠjçU'Øø„3r¸Ø¹Ó–½µ—£å:ªÓ ¾Fg ñ¾©u·Ð1Ìv¥Mª#†bj¿2;Ý4ô@¿* endstream endobj 573 0 obj << /Length 173 /Filter /FlateDecode >> stream xÚ31Ö35S0P0RÐ5T0¶P03VH1ä*ä26 (˜™@d’s¹œ<¹ôÃŒM¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Œ°ÌXv8Á'äá„=ˆ¨ÿ3ˆàÿÿÿÃ,X  wˆ'€þüÿùC=„`?À`ÿƒ¿Aþ<Ø7@ïÿÿ ¡ÿ? ærõä ä ,t endstream endobj 574 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚÕÊ+Â@ài*6Ó#0€í6ÝÚ&¥$¬ … (ŠD@@/G[Ç5ê°8¤Ã‚¨Á£¾ü"e9¥”ÓÐP!Zj îÑZ)%Ÿe³ÃÊ¡^’µ¨§R£v3:N[ÔÕ|LuM+Cé]MàD Ì!æßÄ a9PIÒcУd€/-x>ƒo£;wàê*”Ì!aVBÌÝð7õœ8\à ¦ä¤d endstream endobj 575 0 obj << /Length 216 /Filter /FlateDecode >> stream xÚ}Í=jÃ` `-¾A¬䳋M)˜òõPH§ !SÚ±CC ÉÑ|”Á£'ꫯ¡¸’oþ4J$ëüQ²LÞSþâ<ÜØh‡õ'+v É3v/ز«^e»ùþ`7žO$e7•e*ÉŠ«©¨*…ÚÝ#ÐÑ3‘Q€Æs;Ðþ*ÑØ— ø‰/‚Ô@iàh#2ê+1@îð„[|áiöÆ¡ÙyÚÖ(ÛÆsöÄç“G=‘Ö· ·G¨Ô#¸ô¡î–ʳŠßøà•pH endstream endobj 576 0 obj << /Length 276 /Filter /FlateDecode >> stream xÚÐÍJÃ@ð 9æ’70û&‘ÒXµ‚9zò žl… …¬oè‹ì­×=¦3þwÛR<,û›Øù¸ÌÎg¹ÊÔN1S“‰ZæüÆÅqæB—xyåyÅé£*¦œÞâ•ÓêN}¼®8ß_«œÓ…zÂ7Ï\-”HŸˆèDìHC¥!Ú—%ZCÆ«%‚\Ä:Pm)î(0#µ”tB%ÔSØ@•=ER¥P¤GêéK(†b'$´GWP$d¥9óÒG…òmêæj9h m @¶Mi×^»£Hv:±vP{*ì½jÔÿ1ƒÄËuŒEü!7£è±blEèDna^ÔŸ(ôûö¯n ¾©ø™¶… endstream endobj 577 0 obj << /Length 234 /Filter /FlateDecode >> stream xÚ}±NÃ0†ÿ(C¤[ú¾'¨”±4R[$2 ÁÄ€˜€‘¡lU›GKß$/à Çù¼0Õ²õéì»Oþ››euÅ%ÇÓ\s]ó[E;jj­ËXƇ×Zw䟸©Éßé-ùîž?÷_ïä×®Èoù¹âò…º-‹ü¢•p ÐÀiB1íŒE¸ mQ,GE!ýA‘Ë0)29÷Nò3Dœ¤hœIƒ¤AÒ iþ¡1µ„„Éæô7ºVÎpHšÉ4Y0Ml¾3ÃEˆg¡°²P1€jDßEæK ÛŽé(kЉ endstream endobj 578 0 obj << /Length 267 /Filter /FlateDecode >> stream xÚ}ϽJÄ@àRn“7pî h~˜(Âb`]Á‚Vb¥–ŠB !y´ø&û)Sdw<óƒd„>¸ÃÌ™SŸ¥äRÊq™Ku&ZËsÁo\iLs9Õáèé•× g÷Riή1笹‘÷ÏÎÖ·—Rp¶‘‡BòGn6bŒ¡ØÌÿ™-Ñ‘eFGZ0ý‚Ucc^ÏpGí))€¡$ ·ô)ˆY†€È=ò ÜÆ¯ã—¥[Ç4Yêitìj·uGj†¿ wAlhA´_Bóí“gô6U¹ÊT÷¶2uƒ­Œ¶2H¾–òø’ƒo÷í^î_Ë„>áë>ƈ¯¾ã ø‹ endstream endobj 579 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚm±ŠA †±XH³0ywGAnÁSp‹­,Äê´´PÎÚy4eáJ 1&ñ´20$Ã÷g&{C.¹¯'8FÞT´§Xi_Zk?;7T,9VTÌtJEóÍ¿‡ã–Šñü‹u:á•*kj&D+½áAZÔ7„³3á¤C@.¨Ñ‘?|þ³+­2“3FÈ%½¨JU•ªj=¨p®>i05K¦¾¨™ïΓ©9´€ÜÕàê“¶»öÝ'ß-Æ®øão°Ï½#MZÐ'´}Õ endstream endobj 580 0 obj << /Length 211 /Filter /FlateDecode >> stream xÚÅ‘±‚@ †kLºðôôÀŽ$ˆ‰ &:9'utÐè Æ£ðŒ „Ú£ º¸š\¾Üý½4×ï¢xîäSH³€¢Å]¼c¸”Ч8ÖÊù†iŽæ@áÍFb4ù–ž×Mº[Q€&££4:až@ÒÀ„Yè2×0KT4^ÀÕ´—¢]N/ÇrÚ¡”ŠÊµ¬]¹œÔže£´“vd൅e÷›lÙÿ‹¿ßö5ÑÀÏyÕ€ÚP3jɱÞJY²Q“£U5¬¶æôpãß³ÛÀ endstream endobj 581 0 obj << /Length 126 /Filter /FlateDecode >> stream xÚ35Ó30T0P°b 3S…C®B.c ßÄI$çr9yré‡+[pé{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(000````ò ¢H0ÿö@âÿ,Äáÿ0%#Œzÿÿl—«'W ØšŸ endstream endobj 582 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚmбNÃ0à‹Åöï³Ïãú¢|ïGý¿ýÓÀ/¼Òq¯CýyÜófâîίFî®0ËÝtíß^ߟ¹ÛÜlýÀÝÎߣÌO;O$™ˆ9Á 1!˜rðHõâ°Ðdš…Úˆõ4›f¢&˜ç‚p–B•l9{„ôŸÈÃÕ6©8ù,Ö´Â/õvîK¤qb´ûÒ·í¢+tÍÙŠ%+ ¿N»C7¶É"­EB´8Ñè¤V‹êP Í#R¨I*š‡h~ jÁ:¹Rᕤè[I®ÍÆlÍ`Φü˜þÊ—ßò'‰Ä& endstream endobj 583 0 obj << /Length 258 /Filter /FlateDecode >> stream xÚ…±N…` …{Ã@Òåú $÷g%¹^Ltr0NzGÎðh< ÀÈ@¨=…ãâò íééicu]”RH”«Rb)U”·’?ø­XHU­×w>5œ?É1r~geΛ{ùúü¾p~z¸‘’ó³<›Ñ 7g!Ò‘ˆRUc¦ÚµŠ’R;Q2Q½P:X Ja2m0{´þ£ëûtÆ”yíl[ÀJ8ƒ XÏ í¥-ÖAvH¸xÎiO›zÚM¹Í÷YýSgâ¢ÄV6ë•Óo†¬GÐbìÔùÇÉÆï2ޏ´ÀºC’lÄLñUú‡[ÏŸù]~(ß6üÈ?údµ£ endstream endobj 584 0 obj << /Length 216 /Filter /FlateDecode >> stream xڭбjÂPà„ ³ärž 7ÁDpI *˜¡ÐNJ'utPÚ-4Ù|-7_ÃÍÕ­…ôæÿmzàÞs/üœ{ÓñCk¤#»Ò‘ŽS]Ų•dbû¨k»‹åFŠRÌ‹&1 {*¦|Ô÷ÝÇZLñ4ÕXÌL_mÌ›”3ulåŽó‡š´Ø]â ðI@B’¨I Ü/àßsÁ„ÌÌÈ'©È¸à€ßsABN–‘jÀ¸à€AOB¾/#ù&-ª¹Çï¿ü'5£o#óRžåŒÔ‘ endstream endobj 585 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ¥Ð1NÅ0 `?uˆä¥Gx¾¤‘^:éñè€bF¬4G Ç GÈØ¡j°]&`£ª>EIcÿµï;Gy:räõžî>áÎófG}¿žÜ=â~@{M;öœ·Ñôòüú€vyJín¸Ð-2ЀÉL]_~ÔEÕI-jV£¸€8«Yåz&Á? …}—Bæ£Öæs훃$–SéÂhjääMM|wSSYNñ-ðµŸN¿m£²8±®NZôTÜÔ2fé5J÷ü’äD 2ЏMÐrà[μ©Ñ‚΂̿˜51ÿ=ž x…_‚²¶d endstream endobj 586 0 obj << /Length 264 /Filter /FlateDecode >> stream xÚ}пJÄ@ð9®LsoàÎ è&p›6pž` A+ ±RK EëÝGÛGÉ#¤Œîs&åüƒ~Ålvfö õIYI)AŽ+ •ÔAî+~âuÐb)u½?¹{äMËþZÖý¹–Ù·òòüúÀ~sy*û­Üh£[n·B´@""‡^­H1Ñj$—¨éÉeŠÅLЯÓ; tËY½Ñ;su ÓVÈfLæ5*}:˜ñ›…ý;8ÝCD§á­×ëxÏ:H:n2Áæfìfu«Y›ÛÿrÐVÿµùißL=Ý’½züÊ! å´äŽmNû@¢½Hö´ h––ö”‡ø¬å+þy×- endstream endobj 587 0 obj << /Length 290 /Filter /FlateDecode >> stream xÚU±NÄ0D7JÉ?!þH"]ÒZ:‰HPQ * ¤AíHüX>ÅmJ–—Ù=N:š'y¼ž™õ8]öƒëÝè.7nÝË`ÞÍn„Ø»i:Þ<¿™ýlº·MwÙtó­ûüøz5ÝþîÊ ¦;¸G=™ùàˆÂFD53h™W"Ï ),m¦*S]¨NT1Õ™š(WB¿X^lÁöÄxÆM™”E'YÞ¶HB’b3œ-—ªPÃü…?IJqD´¶bmN £¶MʬJÑÆ<K“e›àÑAñzó‘VDlaAD‰ƒ!I„W¶J{Ææ?1߈íx’^¶Ž~ÓM“ü•-ò{ ÊÝ(kÏM;¯Ú†$‚¹žÍ½ù«C¾ endstream endobj 275 0 obj << /Type /Font /Subtype /Type3 /Name /F35 /FontMatrix [0.01004 0 0 0.01004 0 0] /FontBBox [ 1 -25 102 75 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 38 /LastChar 122 /Widths 588 0 R /Encoding 589 0 R /CharProcs 590 0 R >> endobj 588 0 obj [87.13 0 43.56 43.56 0 0 0 37.34 0 56.01 56.01 56.01 56.01 56.01 56.01 56.01 56.01 0 56.01 0 0 0 0 0 0 0 0 84.59 79.64 80.91 85.86 73.53 70.42 88.05 87.59 41.72 0 87.71 67.31 106.26 87.59 84.13 76.53 0 83.56 62.24 77.91 86.09 84.59 0 0 0 0 0 0 0 0 0 0 54.46 62.24 49.79 62.24 51.11 34.23 56.01 62.24 31.12 0 59.12 31.12 93.35 62.24 56.01 62.24 0 45.75 44.19 43.56 62.24 59.12 80.91 59.12 59.12 49.79 ] endobj 589 0 obj << /Type /Encoding /Differences [38/a38 39/.notdef 40/a40/a41 42/.notdef 45/a45 46/.notdef 47/a47/a48/a49/a50/a51/a52/a53/a54 55/.notdef 56/a56 57/.notdef 65/a65/a66/a67/a68/a69/a70/a71/a72/a73 74/.notdef 75/a75/a76/a77/a78/a79/a80 81/.notdef 82/a82/a83/a84/a85/a86 87/.notdef 97/a97/a98/a99/a100/a101/a102/a103/a104/a105 106/.notdef 107/a107/a108/a109/a110/a111/a112 113/.notdef 114/a114/a115/a116/a117/a118/a119/a120/a121/a122] >> endobj 590 0 obj << /a38 535 0 R /a40 531 0 R /a41 532 0 R /a45 534 0 R /a47 533 0 R /a48 580 0 R /a49 581 0 R /a50 582 0 R /a51 583 0 R /a52 584 0 R /a53 585 0 R /a54 586 0 R /a56 587 0 R /a65 536 0 R /a66 537 0 R /a67 538 0 R /a68 539 0 R /a69 540 0 R /a70 541 0 R /a71 542 0 R /a72 543 0 R /a73 544 0 R /a75 545 0 R /a76 546 0 R /a77 547 0 R /a78 548 0 R /a79 549 0 R /a80 550 0 R /a82 551 0 R /a83 552 0 R /a84 553 0 R /a85 554 0 R /a86 555 0 R /a97 556 0 R /a98 557 0 R /a99 558 0 R /a100 559 0 R /a101 560 0 R /a102 561 0 R /a103 562 0 R /a104 563 0 R /a105 564 0 R /a107 565 0 R /a108 566 0 R /a109 567 0 R /a110 568 0 R /a111 569 0 R /a112 570 0 R /a114 571 0 R /a115 572 0 R /a116 573 0 R /a117 574 0 R /a118 575 0 R /a119 576 0 R /a120 577 0 R /a121 578 0 R /a122 579 0 R >> endobj 591 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚ³0Ö30Q0P0bss#…C®B.sC ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. `ÀÏÀ€‹ÁÞ€“Á|ƒñÊ`„3>À ‚3*`ŒÃƇ[· nô‡úÿðJÿÿgÀ¥àŠÑµÃ ”ǰ´ÃaÐ÷܃˜~ÇPXƒ—ËÕ“+ »IŠ endstream endobj 237 0 obj << /Type /Font /Subtype /Type3 /Name /F34 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 5 0 77 42 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 25 /LastChar 25 /Widths 592 0 R /Encoding 593 0 R /CharProcs 594 0 R >> endobj 592 0 obj [83.04 ] endobj 593 0 obj << /Type /Encoding /Differences [25/a25] >> endobj 594 0 obj << /a25 591 0 R >> endobj 595 0 obj << /Length 100 /Filter /FlateDecode >> stream xÚ36Ñ31T0P°P04U06R02VH1ä*äÒ`a°Dr.—“'—~8PšKßCÁ‚KßÓW¡¤¨4•Kß)ÀYÁKßE!hL,—§‹‚ýÿõ0ôŠþÔÿÿÃåêÉÈ&Ï endstream endobj 596 0 obj << /Length 294 /Filter /FlateDecode >> stream xÚ}Ò±NÃ0`W,Ýâ7À~”dh+,•"‘ &ÄT@°’H Œ<BÞ€GÀ±CÔã.·IA$–¾(>Ÿã_™Î\æss7=âq›ÃÝóYœ[Ýâ€ôŠ* =£ H‹s÷ôø|éââÄå.Ýuî²(–NÑe±fbË$ˆÈšµ*+žÊp¯•$½,YŒÒ 'C©>Ùìä>ì•ëM·™Òíÿšèz¤§¯Cn¹g÷ž—ØFZ 4Qná£a«6Hgôñø¿•j~”XöÄhÅñ¯Ab'øÖ«ë­ÉPSq|;m¯•8Ëc‰Í·"Ÿ‡Õaç8Fã|o:Ë/¿£aìGÿ|V¢—ví‹XöÛØ~-Ëœp ?ÌyÁU endstream endobj 597 0 obj << /Length 302 /Filter /FlateDecode >> stream xÚmбNÃ0`G,Ý’Gˆ_’ÒÂd©‰ H01TLÀÈ‚Gâx„> y“uèH$–QÌù.Nª¨Nä/Ší»_ÎÎŽO3•¨£ß™šž¨ì\=¦ðø™à3›úµ‡g˜çßá&ˆ¯pâüZ½½¾?A<¿¹P)Ä µLUrùB ºq³¬ýlQiíÆÕòÏ©Ki¦­Ûi‹ˆd°ïNˆI;øËÊ‹%±¼·ÔÞj0ôâYã-…¶n”ÂŒäÿ×ô êÅV½o»§ñ–™lˆ½C¾ŠxÈÈ[ ÊÕ;êíÕÞoM™Hì­7Þª—®qËÙÂ-g‘XÛéÎR¶†¯Ñ Ê2vꯚ4kÖ®«‘%»êü.XÍåšÖtmt×Fòv—9ÜÂ?Ò"Øs endstream endobj 598 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚUÏ; Â@à‘ir„ èæ%$ >À‚Vb¥–ŠÖ›Îkå(9BÊ‹ëÄMŠÀÏ·ðÏ3i> 3 )§iDó˜’Œ®>0¹ )ÉÝärÇeòHiŒrË5ÊbG¯çû†r¹_Q„rM§ˆÂ3kPLlÃúÖð#mºZ±¶†‡ð¾ƒ-ø¦3p¶ \š>j£Ùt=’cÙ l5²OùϧœôÎÒ©KÏ Ö·‚— þ*»Qõ¢;Eu›7¼ð§pSàêÆw¿ endstream endobj 599 0 obj << /Length 222 /Filter /FlateDecode >> stream xÚeбNÃ@ `W"yÉ#Ä/—S/R;TŠD$˜02Á|~´ãMò;„—èX¾Á–ìßvîÒî¨%ÛÒ…%×Q·¥‹GÜ8­¶ÔíæÖóî{4´qhn´Ž¦¿¥÷ÏW4û»+²hôh©}Âþ@Ð µüB\Ϭþ3ë´Pe> stream xÚmÎ=jÃ@à'T¦QënçÎj‘V%°ˆŠ@R¥®œ”.lìz÷hs”=‚J›±R%¸ù˜˜yuýäZ.¹å•ãºájÍ_ŽŽT5:,¹j7ûm²\5d_tLvxåóéòMvó¶eG¶çOÇ历žb& OI»« èb!ðb)t’%­ó’,&¥˜¹*F f„G7byð3ñiFþ“%°ˆJ;ų›ÆÓ÷T¿¤û £¹éy wú×\é endstream endobj 601 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚmÏ¿jÃ0ð  ·èt/ÐÊâ%‚4…z(´S‡Ò)í˜!!å-c^ÉÐñ#ºd0VïâFN¡â㇬?è³-o³9eTÒMN…¥bNï9nÑZ^̨(Çõ—š²Í/£©i¿ûü@³|º£ÍŠ^sÊÞ°ZðP“†ÿ×Núk›Épmý¢‰è¾‚|òR`uçY׸A®ë^«’a2íAd"ž@Çtw‘ãG[)å„ÑFŠG§ÔÍÅٯdzªõu4›ÍeÕY ÛÁ/øWz'Í;n|¨¼¯ðC—® endstream endobj 602 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚmÎ1NÄ0Ð¥ˆ4à¹8ViSYZ‰HPQ * ¤Xµ}4ÅGp™"Z3¢yÍHÿÏ8^Û™{žùÊò8ñpà7Kg&Yö<Ì¿—×:.džx˜ÈÜÉšÌrÏ_ŸßïdŽ7lÉœøÙrÿBˉ•” Ж Vá’Šð¡K(èRsÚJ· jg…JZˆ.CW|p¹)ðÙmð¥äŠ„È€’jCü‡ð—&ø€6 ]òQ:\”x$^ï¬Rß–=µFè  Û…é£`Ï endstream endobj 603 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚUбNÃ0à‹è#ÔT–4)¨þIäŠAƒãAˆLù¨-" b&DÊ:ê!§ò×b¹ “ˆo:~à7$Œy endstream endobj 604 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚmбJÄ@€á‘ Óä2/ ›Èï@ œ'˜BÐê ±ò®´P´NÀÂÇðUrø"ël™"dœM4›áçƒÝ-vvÍò$]PJgtœQ~Jù‚¶>£1²™R¾OŸpU¢Þ1¨¯euyC¯/o;Ô«ÛKÊP¯é>£ôË5AÔÀÿ/Äm0™ë‚Å\¬æ6Aݳ÷ïø“ÜØ«VlU'ºÈkň›¨ëAð©©î xª=(™r¡bÌþi¡úvÞ½“ÁùkðÝÊà“20«æ×8®½ ˆÕÈ£ŠúáŸÎ”¼*ñÚ“Š endstream endobj 605 0 obj << /Length 207 /Filter /FlateDecode >> stream xڕαŠÂ@à_,¦ÙGȼ€n‰"HêÁ¥88+‹ã*µT´ ˜Îײó5|„½.E07»¬øš˜áÇý$æGÜ‹x0àdÌëˆö'†<|nV[šæd–'d>%&“ññpÚ™~Ï8"3矈Ã_Êç LœNã”èzh=$«e¿Ã[“‰æ*/îP7 }©¨Vª[…8µ¨2+ww©â\[SzïU«ûÐ¥rêÀvªL¤¢€¶”­ þ¬ïá¥}ä´ _R’ endstream endobj 606 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚ32Ñ33V0P°PÐ5T06P0µPH1ä*ä22 ¹–™ä\.'O.ýp#C.} 0—¾§¯BIQi*—¾S€³PÔE!¨'–ËÓEýóbÿBöô„ê!èý‡  b„" b†  ÄA@ˆ‚~€<á2þð úDÇüo?Bý@ÔDõóìèÈ(æ \®ž\\{Ud endstream endobj 607 0 obj << /Length 280 /Filter /FlateDecode >> stream xÚeÐ1JÄ@à?¤L3G˜wMb„ÄfÖL!he±X©¥…¢ÝBÆ“Øx…t–N9B˜ø&‰»¨ð¾÷ç…dRV‡ÇG”QI9U9ÝåâQ”—'ÓÛ±¬EzMe!Òs®EZ_ÐóÓ˽H——§”‹tE뜲Q¯(rÒ‰Gã¡= ‡×a0È·­m¶V·PêÝèVwX¨êÓ¨ 0°t0Xl´ƒê'Y(·Ó˜žŸçãÖ×´³ðK¼ÀÁ0©e™±þ+^àD³ kªMŠ‚€x/êxf–Å ‰W&™Ô+¾Âê?ñBâ{¹±v›Ü¬øË†Ÿœ8~MÙ!±ã¹bþl>¡ÄY-®Ä7†©ñ endstream endobj 608 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚ]Ï?JÄ@ð/¤¼fŽ0ï: Ù%¦ÙÀº‚)­,+Ýr E»…Ä“ð^!GH9B˜ñÍ&âŸbø=¾˜ï-óÓ²à” >ÉxYp~Æ=Ò¢”0弜nî÷´®ÉÜò¢$s)1™úŠŸŸ^vdÖ×眑Ùð6ãôŽê Gj‡ÆÊ¿zßB½½M­?ÚªÇJ{è€;RЕ~1Êk™l#ôBÀ’Ãwa‚üòÉ£@+`&úˆgœLª ¸#‰Ó­”OF-ç?v5c…Ä ÄŸCX<ò=ÔÔ*–@5ÝÐuóy% endstream endobj 609 0 obj << /Length 203 /Filter /FlateDecode >> stream xÚMαjÃ@ àßÜ`ÐâG°^ ½3q!žÒâ!ÐNJ§¤c†„d¶ÍâGðèÁœ"Ÿ -œ„¤¿¬^܆W¼*øÕñzÃç‚®T:žßºZ:§ mk²Ÿ\:²-“­|¿=~Ènß߸ »ã¯‚Ý7Õ;²€`D:ýå|ŸŽh:3AZAL@"é¤d‘QÉ#ƒâ1ÒDú¤"JÐÝdÓB»3ƒâ#}Óêù™Öwø. È{=ãÅ 1²´¯éƒž‚j endstream endobj 610 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚMбNÃ0à³2DºÅÐ{°)-S¤R$2 ÁÔ1ÑŽ ‘»ñ¼J$^$ˆ0›+Ç¥ ÄÒ¯o¸;ùN.Ïí’,ÐQqFsK§KÚø„åBª–æåØzxÄUfCåÍ•ÔÑÔ×ôòüºC³º¹ Íšî ²÷X¯ t“E€ÊkÞƒ‹·ðÖuÚCàØgQy–!õ#vÙïŸù÷ÁÏÁN“§‰“:‚”„ÉY€Ù ÄViÚ>®u-ô7{Å ÊBpA6G9˜¹?¤ ü” O¿Yj7™§Æ^'ŸÓ?ìû ^Öx‹¿–Ó endstream endobj 611 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚUÍ1‚@Ð%$ÓpæºlÜ 6 &na¢•…±RK v&p¯Bç5¼[Rlai “¼âÿüŒÓ(Âç8(cœÅxpbw³Eßœ®)à{”!ðuW|ÜŸàÙv‰xŽáTŽÌ°¢tÉ!íчŒÿþUMàK¿a”øÆ¡$°Ô.½= 1©vL~™f-¬§°T#ÈRqzØ×ÒŒð,fLÝ¡»Y÷ V vð4…SŽ endstream endobj 612 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚ=α Â0à …[|„Þ hR[P§@­`A'qRGE7ióh}”>BÇ%çY‹äþ„»$fšÄdhN“ˆCñ‚.Þ1žI(íòws¾aš£>P> stream xÚeÎ1‚@Ð1$Ópæº, j# b"…‰VÆJ--4Úåh…Ä PRqÖeµ0™×üIæO_öÆCòhD]Iý€‚í%žÐ9ô(ôfwÄ8E±&?D1çEº Ëùz@/§$Q$´‘äm1M °*[©œêÇ5J-2 í¡5M“±¼•Òù‚Ëxi¶Q·ÕÆ_½+Qé(YT¸ ¿0awˆò¸Eγ§)¸ƒûù.ÎR\á´a`¾ endstream endobj 614 0 obj << /Length 229 /Filter /FlateDecode >> stream xÚEϱNÃ0à‹2DºÅà{p¬4 ,µTŠD$˜02´j·* êÀkYâE²±1à!ª97U¸áþ“þÓ•ú¼,(§ŠÎ4•%ô¢q…³ŠÃœŠËqóü†‹ÕÍ*T7£ªoi³Þ¾¢ZÜ]‘Fµ¤GMùÖKq‚ip möåÁX±÷ÐZñ•ÙÀÎÙp²l·>*}ºA:ÖGÌhŸN¶}z`íhvˆvÜ7É­ÉI~>)}stuÿçG!@ûí¸!°íþ÷§>ãSá=t Ð^×xðÞz¦ endstream endobj 615 0 obj << /Length 211 /Filter /FlateDecode >> stream xÚE̱NÃ0ÐkyˆôÿAý~«‘Z–F*E":TL´cl ¿Õßð'xôÙ8.U—ó¤{õn]ßš;®xÆ7†ëOç¼3ôFÓ1¬8ܼhÙR¹I•Ùö‰?Þ?÷T.ŸïÙP¹â­áê…Úã ŠØK/£-†âשAý8´Êxÿ¨ÐiWŒÈÐ5N„¡±üŽ™Ó˜é3§yáDÄie&œ)NTA#1X }t@Ls8~; ‰Pi¬A-­éd" endstream endobj 616 0 obj << /Length 260 /Filter /FlateDecode >> stream xÚuбNÄ0 PW*yÉÿ´Õ©Wº\¤ãè€Ó ˆ @°U4ˆß ’µl‘ˆ0.w=1@†<Ù‘-ÇóÙA]QA5í—4¯ivH×%ÞaÕH² Y³y¹ºÅe‹ùšªóIcÞžÒÃýã æË³#*1_ÑEIÅ%¶+röØÉÝÛ”0–]ö$b§^ð3{õºQgñÇE“ÀþIö¾SA4¾Ó!eÐ>ê!ýåÂV0“>›Œ ¬”nu“*‚¶2—  e>û‡¶:ÀB=ììþ1üÖ É }Fýد©(Ÿ™0oŸQÆÍ̲¢Œ]Ç]1()ÃãÏñí’ endstream endobj 617 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ]Ï1J1à·¤xÍ;BÞt&ìÌ¢u§´²X¬ÔÒBÑNf{,³x¯#¤œ"Ì3K¬¶ùŠÿ‡þvuÚuÜðŠO w†—güdðÛ6‡ /ÏKóø‚ëë{n[¬¯sŒuÃïoÏX¯o/Ù`½á­áæû C5Á  g%FÙ‰_$ý» *’¨Xš)’§YGr”tÔ@ÉF 4Ùxñ¯žl wþ3Kçbl1;ý±Rt”UÁúƒã^\ä Ïüh'_¤ ‘¸ƒþÞO`EKª<§â"_Ä«ïðìpa endstream endobj 618 0 obj << /Length 259 /Filter /FlateDecode >> stream xÚ]бNÃ0à‹2DºÅà{HR’– K¥Hd@‚‰1ÑŽ ؉Ô×ò£tc͘!ªù/n¥Š ß`ßýwN5?ŸWRÈBÎÊ…Ô…\\ʺä7®f8-¤®W/¯¼l8”jÆù-Î9oîäãýsÃùòþZJÎWòTJñÌÍJÈ‘~Á“¡4ôd}ö;óf;PëÍj³^Áí¾úeÕIèFÛ'†IrÑ]ݵQÍö:Ih?©ˆB*ÚOµÑþ¿.ºC/&hB€íVuo"3™Œ­?¼Rí(õª™Ö<®¬«Õu\á7=ôV#©íPïQŽ`”L,&ñMÃüå"‘£ endstream endobj 619 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚ}Ž;jÃ@†áB0ްsdWHyU ~€UìÊ…I•¤LacwBøb:ŠŽ r áÉlb·f˜¯˜ù˜ùK÷øR°ã'~ȹ|æâ•¿rÚQé8Vñö¿ùü¡iEvÃ¥#»Ô1Ùêûã7ÙéjÆ9Ù9osvTÍa0E&­‡‘®—¾ÆI C¢è“€¬K˜€×F1jë ˜ Š´W˜îŽ‘ý×u4êhŒj$A4¤ñevCoÎ"×m£aÔö—; Äo´¨hM¿.GYé endstream endobj 620 0 obj << /Length 294 /Filter /FlateDecode >> stream xÚMÁJÃ@Eo˜E`Δf~@“Ú+UÁ,]¹WêÒ…¢à¢4óiù” Ë,BŸ÷M 3òÞ}™{ßâü¤Zùʯüñ©_ò,ýË̾ÛÅœÅÊ/Ïç7»ilùàs[Þ°lËæÖ~|½Úrswég¶¼ò3_=ÙæÊ^äÉB²5{ ´azH@Ѹm‡" îPO”»)êˆímÄx¤”ÙýSH4ýÒ™¸N\%~gÊ>“`~¢‘ Ÿ|QBÎ××p£Ú*Ôê^ÙªCŽYò¬6÷_ò×ÌÓ¼Kå"MÖ!I A8é#’ŒÈPŒH‹*`ŸÙ ÚÞ“"{Ôäˆ 'ÜÏΈôØB¸±-ý TÒñ¯ƒ.öº±÷ö* †ƒ endstream endobj 177 0 obj << /Type /Font /Subtype /Type3 /Name /F33 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -1 -17 81 59 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 28 /LastChar 122 /Widths 621 0 R /Encoding 622 0 R /CharProcs 623 0 R >> endobj 621 0 obj [56 58.45 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 34.41 0 0 0 0 49.08 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49.08 44.19 44.19 49.08 44.19 0 44.19 49.08 29.52 0 0 24.63 78.42 53.97 49.08 49.08 0 41.66 40.43 31.97 51.53 44.19 63.75 46.55 46.64 40.73 ] endobj 622 0 obj << /Type /Encoding /Differences [28/a28/a29 30/.notdef 45/a45 46/.notdef 50/a50 51/.notdef 97/a97/a98/a99/a100/a101 102/.notdef 103/a103/a104/a105 106/.notdef 108/a108/a109/a110/a111/a112 113/.notdef 114/a114/a115/a116/a117/a118/a119/a120/a121/a122] >> endobj 623 0 obj << /a28 596 0 R /a29 597 0 R /a45 595 0 R /a50 620 0 R /a97 598 0 R /a98 599 0 R /a99 600 0 R /a100 601 0 R /a101 602 0 R /a103 603 0 R /a104 604 0 R /a105 605 0 R /a108 606 0 R /a109 607 0 R /a110 608 0 R /a111 609 0 R /a112 610 0 R /a114 611 0 R /a115 612 0 R /a116 613 0 R /a117 614 0 R /a118 615 0 R /a119 616 0 R /a120 617 0 R /a121 618 0 R /a122 619 0 R >> endobj 624 0 obj [777.8 500 777.8] endobj 625 0 obj << /Length 219 /Filter /FlateDecode >> stream xÚUнŠÂ@à]¶X˜"yp7Oà&B¼tþ€)­,ÄJ-…xœ`—¼¯äÜ+ä ÎÒBX³3wf>f¦˜Q6øbйËG)î38Aîf©kÝbw„q fù̼›‚)øûs>€/'˜™â&Ãt åEòæªPš‰>{Zâ; f,óOÈž?B]}tì1LÂU|÷hµ‡¼ª§!´ð‰’€‚©­õ°L+ôƒ^¤Þ¨†Ð=‚ˆ™ˆI æÂTÌB?…KkÙÝ Y +xir§ endstream endobj 626 0 obj << /Length 212 /Filter /FlateDecode >> stream xÚMÎ?ŠÂ@ðoH1ðš\@È»€Nbj£àº°)´²+µ´P´ $`‘No°g‰7ñ)S„dgFA›ï/ê÷¢ˆ}q7`Âo:PhŠ>‡Ãgg³§iLjÉaDêG—IÅ¿|:žw¤¦ó/HÍx°¿¦xÆ@@6/ïcGÇÄP‰Âà”¨!×Rˆ^!ª'“ÌâTH3=™â,ÑšÅæ×R˜;÷â…g¹X²Kž%Hs$h%Æ¢uõg·+> stream xÚMÏ¿ŠÂ@Çñ‘-¦Ù70óÞ&a…ÀÀ‚VWˆÕ¥…rWšGË£lgé–[„è¬QsŧùMó¾yK)¦!õêúJp©á1¦Á°¹|îpœ£þ Ô žóŒ:_Ð÷ág‹z¼œP‚zJë„â æS‚ º¶àÄŽÿÔ¬jußkÉÀzçäEª’¥òÌ «¬°Q)Ü]ÑÈx’îÄŽ/ÊÕ¬eQPú»¬xÏÑžc=þrÔ_ÇÁ»°0’%t£ÿÀà,ÇÞ!_‰ endstream endobj 628 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚUαN„@àÙPLÃ#0/  ¼æHÎ3‘ÂD+ c¥–íH ± Ó7ðY0¾ˆ@IAXÿÝcCl¾bvæß?;9Î2Id#G©d¹¬Oå!åg^å&²Þ^îŸxW²¾‘UÎúcÖ奼¾¼=²Þ]IÊz/·©$w\î…ˆÔÌGï ~=ÑBç‰Oá \N nk¢m`ˆª`Â\MèðÕd³G :5"ìÀ€šÕ»>ƒfÆâ®g¢ä|w3±ãÇòÞŒT8Ú¦¢º¥ŠLH[e"4ûü 8 ¿Ð6IõÔŸ—|ͬÁkÞ endstream endobj 629 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚmÎ=‚@à!$¯á¼ èòS $Љ&ZY+µ´Ðh²…‘åfx“=%-l,¾f&™LCö9áQÀQÂÑ„)LLès›ý‰¦‰ ‡ ‰…‰IK¾^nGÓÕŒ9oöwTä ”€Ý×pŸ< ÑAZ-¤Ý@:ÒÔh½M¦,ÃÑ™òTYõ(ûÖPà zãõG÷ãߨ IaévíÁU.R8Uk®èÏÍ ZÓ¢ B endstream endobj 630 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚEοJ1ðY¶L“2/ Ù¸{ºÀy‚[Z]!Vz¥…¢ ({ûh_$°¹"¬Î,»ÚüŠI曯^ŸSE º5Žê=:|ÆzÉÓŠÍôôð„›íŽê%Ú+ž£m¯éõåmvssAí–îU÷Øn @ð‰ÉëE2 ÊȨ èž1½JàAE8èƒA‡b„räÈßg|¯FÆí‰Ã„äÌ d¾]¥ 2÷ÑG€d˜÷Æ3úKê–‚ú'Îè‘'BÇ¥„žx`:!s\ÁIŸ²`~zNx /[¼Å_¨TdW endstream endobj 631 0 obj << /Length 229 /Filter /FlateDecode >> stream xÚUϱJÄ@Ð7¤^“ò~@gãfa„ÅuSne!Vj)¬¢`•̧åS"þ@Ê-ÂÆûFaæ0Üa.wª³Óª’™,䤜NžJ~å¹Cˆøü÷æñ…W5Û;™;¶×ˆÙÖ7òþöñÌvu{)%۵ܗ2{àz-” DfJ £HŸGº„"|„Z¥ÑÖ¦ÁçÑԠÛ)ä€ò`ötfTvhÌ"Ã?|@‘×QZ×計VШó@0ã1ØE–Îã×¶-eý¶ƒÒƒ¯nOæ;`ëDŽhI|Uó†´éd" endstream endobj 632 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚ…Í1 Â@ÐR,Lá^@ܹ€nŒ¦¢‚)­,ÄJ-m5âÅâMö)Sq79€3¯øÌ?ŠÃ<æ~ÈQÂq̇.ì6µŸý‰ÒŒô†£€ôžIgK¾]ïGÒéjÊ!éoCv”Í^a JH˸ìçø;%ü¢‡ŽB·‘Xœ[O”ë ÔŽgUð[¥kM•4FF~ŒúêÕxçÊÏ•€ÓìBTð hžÑš~; 9õ endstream endobj 633 0 obj << /Length 248 /Filter /FlateDecode >> stream xÚUαJÄ@àY¶X˜âòr™ÐM.ÞA\8O0… •…X©¥ ¢íeå _ë|“XÙFlR,‰3…m¾â˜ÿ/ʽe4§Ýœög4/é6ÇG,r|ð{¹¹Çe…ö’ŠÚSŽÑVgôüôr‡vy~L9Ú]å”]cµ"Ð-€"ÀŒ4ÉÈ6"ñn"ja ‰g\ô ôê½… ßÃ}abZvL£ºRÈ´WÝ€î¸Wq‘þæÏz=Aè…æ³ã=AF­…Zp2Ǥ>}Ýþ±áÄm¼§ÿ1¾fxÔ‘0Sè!9„¦ƒTxRáþé^ñ endstream endobj 634 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚ}Ì1 Â@…á‹ÀæbæºÙ…è ‚#˜BÐÊB¬ÔRPQH!š£å(9‚eŠÝÙµ¾êð”(E!¨/I )ÒtxA©M )»eÂ8E±!©Q,LF‘.év½QÄ«I m%…;L¿ð>?9›:À^ÖÓj¬šµœŠµ7óœ’ùNÁ‚ÿ÷Ö=¨»Öj •‘Av†G ¹Êç)®ñ ®E‡ endstream endobj 635 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚUÏAJÄ0à?dQÈÂ^`0¹€v:B[¡LaÁ.]¹WêR¨¢ÐU'GËQ2x€‹É¢t|MUÆÕG^Âÿ¿dùéyªæ*W'©Êçê,WO©xÙ‚†t,¦›Ç±ªEr§²…H®h,’úZ½¿}<‹dus¡R‘¬Õ==ˆz­˜Å€È!ò|¯e£2ŽL»Äñ²ä[+1“-ÿ2R•c;“–íë¶2l ›IÓTšõAp©ÝfÒvàî@tc[¥§Ö èÙÿư`æ)ôÏaTzÄCY?›ô£´‰/C ÷EåîPÚÌ5¡„Û&„së~´¡„o eŸôs*ÁP%Äe-nÅ7ã7x` endstream endobj 636 0 obj << /Length 225 /Filter /FlateDecode >> stream xÚUϱjÂPà?ÜáÂâ ˆ9/Pc0$Bj¡;u(ÚŽ…V2H¼à‹åQî#dtí¹É`]¾á¿çÿáÆÉ8ÉxÂ)?DÏxšògD¿GNxšõ/ß4/)|å8¢ðYb Ëo7»/ çëKºä7é¼S¹dÏâ蓺øù@7=æÊbTªEV´žÓŠUш?âI4›öà´õMÔÐâÚç;žØ@ê½A¯êmQSuj#Síêõ}7µ÷ÝÈ~Ô9ìÌÜ`^¹©ÀBË× è©¤ú’tUž endstream endobj 637 0 obj << /Length 190 /Filter /FlateDecode >> stream xÚ=ο ‚PðO„³ÜGð¼@]ÿAµ(˜AAM ÑT Em¢B/foâ#ÜÑA´«BÃßóÀ›;¼â™ËÇþ‚¯.=È÷tè°¿œ6—;Å)É#ûÉ­ŽI¦;~=ß7’ñ~Í.É„O.;gJ Àì+ˆ¯‚92´È =™ ¡¥Y5"¡ÙÕ$*GE1À_ßkÐMŒAÛŽÌfb)­n!ê ¢Êa—!"„ºt¨5¾}€6)è•GÏ endstream endobj 638 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚUÍ1 Â0à_:ÿ`/PìMC”v(j3:9ˆ“: U:ˆÍÑz”¡£ƒˆIÄ!Ë7¼ï‰é8âQL#NN"¦#Ç ¡ÃˆDòkgÌ%²- l©cdrE·ëý„,_ω#+h§‡ö( ò¯¿ ß0¬R‚GéC:k3•d¦V™ª4PÖ`  {@û1¼ÿ€¡gy9x–Ρoi|KãZ”Cf1.$nð ñÿ> stream xÚ=ͱjÂ`à2î’7hî èŸäÇ6]ˆ fìÔ¡tÒŽ…*:H|±é(V;Qû¬›X¶’¤\FjÓÛeý%E)æM“TÌ‚k1åRvûO1Åjª±˜™¾Ç}H9S Ü Á¹B†4øÅ7Z4^ë7^󝿬üð;r<×ÿŽÌȇ0È)¤ Êèz§»!ËB–e,; eá£__ß=Fʼ”W¹|/Hd endstream endobj 640 0 obj << /Length 178 /Filter /FlateDecode >> stream xÚ]Ì1 Â@Ð )Óì„Ìt“MBÄ…Á-­,ÄJ-+³GËQr„”Bt ñóªÿá«|(¢œú1%Š2EûϨR.#Ê’ï²;baP®I¥(ç\£4 º^n”ÅrJ1Ê’61E[4%o!¨Aü™u4§x@ÕuŒ/øòØÓñYë¬qDówßûk;Ôp×pÒÐjh´WOü: ¬ðm 83¸Â7Ä¡B endstream endobj 641 0 obj << /Length 216 /Filter /FlateDecode >> stream xÚ5É1JÄ@†áo˜"ð;ÉMB¢™……uS,he!Vj)¬¢°•›x¥9ÊaÊ)Bp’ÍS¼oÓ\^]sÉ-_TÜ´\·üZÑÕëK®õù¼¼Ó¶£â‘ë5w1SÑíùëóûŠíý WTìø©âò™º##„M~!ÝJõ‰Ë&Ò ­zåt9FìaÆô¹õ¹u‘Þ"øYa€áÌ b&ÄõÏ9ã1¬ÄM¤‘J·°‘^-}´ð‰?Ÿ°9:o,”U ÛŽè;¢VF endstream endobj 642 0 obj << /Length 238 /Filter /FlateDecode >> stream xÚUϱJÄ@à?l±0Åí ·óš,GHŠ`à<Á‚Vb¥–Â) r—GÛGÙGØ2ENÜS8¦ø`vfv¦,Ï]ÅW|測y]ñ³£7* žc]§—§WÚt”ßsYP~-iÊ»þxÿ|¡|s{ÉŽò-?8.©Û2" 5Bõ¶×+hßú……–‰&Q[Xo}ÝÂöÆïfô?´BÜÏôAqaú#ÐGØÏ L0P3 ¨(E§È>QZ–ÐAj4‰ú„¯ÄNq1 ‚2!šQydqõ-«`l.ŒÜÝvL¿@WÝÑaÔ endstream endobj 643 0 obj << /Length 216 /Filter /FlateDecode >> stream xÚEͱJÄ@…áR Ü"y¹/ Iv"f!XW0… Õb¥–B…KœG›G™G¸eŠŒ,Ææ+þSS_l8ç’Ï .K6—üRÐ;™ís6Õiy~£]KÙÍ–²Û%SÖÞñçÇ×+e»ûk.(ÛócÁùµ{†òÊAzD¬jÈUW>õsèô‚ÕnVÐnŠ¡í-t‹ ¬ß+Ãʼ2ýü3¢;Ž_| üJà%Ár,¡cQvŽ$FŸŒ)úêX£‘F \ì@7-=ÐsºJÅ endstream endobj 644 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚUпJÄ@ð/l˜Â¼€¸óšÄäHŠƒƒóSge!Vj)DÑN.>Z:_ca;S„à·Q9m~ ³ó)³“âT3­ô8¯´,´¨ô>—')Œfº(¾îeÝHz­ÅBÒ Æ%m.õåùõAÒõöLsI7z“kv+ÍFá˜QÁ¸‹Ø–Ú"qõ Ißîé`{¿ƒ}w3ÁˆÕ ¢™á›fÀÆÿaBì™»=ÑÌð3ã ÓKˆ·žM;tŸÄ~®è±='sŸ.ìC˜Ë±ä |G ew´†UuÌ‚%s‘LáárÞÈ•|–ob3 endstream endobj 175 0 obj << /Type /Font /Subtype /Type3 /Name /F32 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 4 -17 70 60 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 65 /LastChar 121 /Widths 645 0 R /Encoding 646 0 R /CharProcs 647 0 R >> endobj 645 0 obj [61.72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 42.44 38.2 0 42.44 38.2 0 38.2 42.44 25.46 0 38.2 21.22 67.91 46.68 42.44 0 0 35.01 33.95 27.59 44.56 0 55.17 38.52 40.32 ] endobj 646 0 obj << /Type /Encoding /Differences [65/a65 66/.notdef 97/a97/a98 99/.notdef 100/a100/a101 102/.notdef 103/a103/a104/a105 106/.notdef 107/a107/a108/a109/a110/a111 112/.notdef 114/a114/a115/a116/a117 118/.notdef 119/a119/a120/a121] >> endobj 647 0 obj << /a65 625 0 R /a97 626 0 R /a98 627 0 R /a100 628 0 R /a101 629 0 R /a103 630 0 R /a104 631 0 R /a105 632 0 R /a107 633 0 R /a108 634 0 R /a109 635 0 R /a110 636 0 R /a111 637 0 R /a114 638 0 R /a115 639 0 R /a116 640 0 R /a117 641 0 R /a119 642 0 R /a120 643 0 R /a121 644 0 R >> endobj 648 0 obj << /Length 132 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0S01T0¶P05TH1ä*ä26 (Be’s¹œ<¹ôÃŒ ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.OÆ 2ìÿìøÿ7ÔÉÿ?ðÏþÿç?õóÿÿøÇþÿÃæÿ~0ü?PÀ`ÏÀåêÉÈG(Ç endstream endobj 649 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚ…Ž1‚PD‡PlÃØ èÄŠ1‘ÂD+ c¥–m…£q@IAˆû;“WÍÎÎL0›† vÙ xólÎaÌgnäû¢ºEãét¥4'µgß'µT¾áÇýy!•n—ì‘Êøà±{¤> stream xÚ…O; ÂP±lãÜ è{IüÄ* L!he!Vj)¨h-GÉ,-$q̃´ÂT;ß…ÃñL­NuihuéÉ—›V'Ç/2OÅì4Ĭx“®õqžÅÌ7 õÅ$º÷Õ$Mô |€ ¨,G\ WÂ{¡ûFÇ9úé^Ù€"J[|š¼ ¬µÐîrè’YÁ"Ö±4nT?…”pGrjݬc_e*[ù«ËM* endstream endobj 651 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0U0Q0¶T01SH1ä*ä26Š(˜%’s¹œ<¹ôÃŒ¹ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. L@ÌÀß$äAD=ˆø$˜ÿÄÿ€Ä?€Ä ‹³ÃÅíáâÿáâ?Å@âP¢&VVÌŒ.ó.ó.S—áG—;ì&.WO®@.n=Þ endstream endobj 652 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0´TÐ5W02S0µPH1ä*ä2 (˜™Be’s¹œ<¹ôÃ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. (\®ž\\&Q# endstream endobj 653 0 obj << /Length 162 /Filter /FlateDecode >> stream xÚ]± Â0†‡Â->‚ÿ˜ÄK…N…ZÁ ‚N⤎ŠÎú¨>‚c‡bMN8¤>È÷] çy’°ÈáÁü GGbŽÎÂO%ÎT2[0“YFK&¬p»ÞOdªõŽLƒÝS¨AZZFý¢HW 2"ÃòL}¦¾Tß©oþýï»­® ËÐ"І¾Öº?¦ endstream endobj 654 0 obj << /Length 114 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04WÐ5W01T0µPH1ä*ä22Š(˜™B¥’s¹œ<¹ôÃŒŒ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ†þüa`üè?’›îçrõä ä—5ez endstream endobj 655 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0VÐ5W02W0µPH1ä*ä22 (˜™Bd’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ‚êÿÿc`¨ü¨æ`°›ÿp¹zrrléI endstream endobj 656 0 obj << /Length 152 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UÐ5W0¶T0µPH1ä*ä26 (˜™Bd’s¹œ<¹ôÃŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  @ðNü5 ¢DØ{! €?˜8$ØÁÄ Á &> F0ßTt£Ÿ©¸ƒa*ˆ`gàrõä äW:Õ endstream endobj 657 0 obj << /Length 175 /Filter /FlateDecode >> stream xÚµ± Â0DQXúKä'2Ò† á * D” ¨Ãh%#¤¤Âü#6HáWÜYòóMíÄÈà0žÃp œsº‘µf˜¹Øœ®Tz2{XKfÍ1¿Áãþ¼)·Käd*rdGò”R/¥RA-œ%¡a|¸½ݠЂ´V$‘Q¬ùµñžî†·êÞoÄ×e«ú¿U¿ïG+O;ú‚a endstream endobj 658 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚµ± Â0EQ Ýù €miCp¢ ” ¨“Ñ…(©0¾ó i~ñϧ{~37õ <& ¸ ~‰³¥9—Jƒ¹Ï“öJu }€s¤7©&¶xÜŸÒõnKºÁÑœ(4è^J©øåøqÄ^©.JùNQrŒ?)F#ŒPäëQ1H¢)3RŸ;™Ê;Ù˜J~.؆xCÙˆ?ZÚÓOYbÍ endstream endobj 659 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UеP0¶TÐ5RH1ä*ä26 (˜A$’s¹œ<¹ôÃŒ¹ô≠ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿÏÄÿа—«'W *› endstream endobj 660 0 obj << /Length 113 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F ¦F )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêü€ÖÀ åPº‰õìä¸\=¹¹AQ@ endstream endobj 661 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04U02R06P05TH1ä*ä24Š(YB¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü òì?Ô¨ÿ„êÿØÿ‘ÿÃÿ‡¡ ÿ0ü`øÁøƒñóöìøØ7Ô7ügø.`àrõä äj'.ç endstream endobj 662 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0S0W0¶P01VH1ä*ä26Š(›%’s¹œ<¹ôÃŒ ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h –X.OæöX±ûŽììþ±ø÷Ÿýà¿ÿÇÿûÿüü?ûÿÿðÿÿÿ€ùÿÿÆÿÿêÿ€1ˆ ÉÔ€Ô‚õõ‚Ì™2—} ·p¹zrr«xSº endstream endobj 663 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V0S01T01QH1ä*ä26ŠE-Àɹ\Nž\úá Ææ\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O† øA-Âþÿÿÿ€øÿ4‚Šv@  Ã¹\=¹¹emH™ endstream endobj 664 0 obj << /Length 136 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04UÐ54R0² R ¹ ¹ M€Â FÆ0¹ä\.'O.ýpC.} —¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒüûõ?€ðÚÿ‘ÿÃÿ‡áÆŒ?˜?°PààP—«'W ŸÒ,5 endstream endobj 665 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F †† )†\…\@Ú$l‘IÎåròäÒ pé{€IO_…’¢ÒT.}§g ßE!¨'–ËÓEAžÁ¾¡þÀÿ0XÀ¾AžËÕ“+ ‰;“ endstream endobj 666 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UÐ5W0¶T0µPH1ä*ä26 (˜™Bd’s¹œ<¹ôÃŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ì@ÌÀß#äÁHÌD؈:Q'þ€ˆ@Ì&> f0ñd˜82î>3Ñ dfâ ¸™¢Dp¹zrr@Ä:Õ endstream endobj 667 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F Æf )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêüƒõìäðì:¸\=¹¹{-= endstream endobj 668 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04UÐ54R06P06SH1ä*ä24 (˜XÀä’s¹œ<¹ôà M¸ô=€\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü òìÔ€Aûòøð Žöêá´ÿ#ÿ‡ÿÆ ?0`ÿ ÿ þÀÿ†ÿ@¡.WO®@.…8 endstream endobj 669 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V04S01T06QH1ä*ä26 (Z@d’s¹œ<¹ôÌ͹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿÿÿÄÿ °‘§\®ž\\ºâAŠ endstream endobj 670 0 obj << /Length 145 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04Q0²P0²T05WH1ä*ä !P"•œËåäÉ¥äré{Źô=}JŠJS¹ôœ ¹ô]¢  b¹<],jÿ0ÿaÿÁþÿ€|ƒ|ƒ=ƒCC þaø†ÿüðÿÃÿÿÔ¡ýûòØp¹zrrÇà/° endstream endobj 671 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 672 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 673 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W01T06W05TH1ä*ä2 (Be’s¹œ<¹ôÃŒ,¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ? ˜ÿ1üàÿÏøCþûûÿç?ÔÏÿÿà?ÿÿØÿ7üJq¹zrr)}(Ë endstream endobj 674 0 obj << /Length 117 /Filter /FlateDecode >> stream xÚ31Ö3µT0P°T02W06U05RH1ä*ä22 ()°Lr.—“'—~8P€KßLzú*”•¦ré;8+ré»(D*Äryº(Ø0È1Ôá†úl¸ž;¬c°ÇŠí Èl ärõä äÇ\+ß endstream endobj 675 0 obj << /Length 168 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.cs ßÄI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.Ovþ;¢ù†: ÁPƒNØÿÿÿÿÿÿF0Ø1ü`€uŒ@¢†ñQÄf ñƒù„Àf2ØJÆìó~ ñ€¿‚ñ;—«'W ÇžsË endstream endobj 676 0 obj << /Length 251 /Filter /FlateDecode >> stream xÚ…±JA†'\!Ls­ÝÎ èÞ±žšÆ…Á+­,ÄJ--íÄ;ðÅy‘µ²4åB–[çO"h£ÍWì¿üßÌì¹Ýf,•4²s n,Í¡ÜÖüÀÎéc%ûÍ:¹¹çIËöRœc{ªÏlÛ3yz|¾c;9?–šíT®j©®¹ fDT„¿P&E—{åh+ç•9G2ËÏD~þ>/BG¯Eðô$E7è~ }§ø¬€ŸK…ÑvmV›:¶¼«$ê,HŠ@•%¡j»}¦W”}þa³ÂzHõ‘ ¦OØ#b£¼A=ðb2ñßãà~|Òò0Ž endstream endobj 677 0 obj << /Length 247 /Filter /FlateDecode >> stream xÚ5ϱNÄ0 `G"yÉ#Ô/iÕ+…)ÒqHt@‚‰1#¶Ó¥ÖGé#dL¥ª‡ãÐåÇ¿½k.Ûª¨¡‹Žv5µ×ô^ã6+ºjóËÛ'î{´ÏÔth﹌¶ Ÿïß´ûÇ[ªÑ襦êûé4”˜)Á pŒàaYàñ˜Y £„¸QDî+ÿ`|ÔÂ.;™1£‡ràÆ °á§ÄšX6”7 !0Z˜6Œ Ós„I¸1Â{ãá8bþgU3/­BF ‘)„™Ó)sàˆ9rá'Aóì±ÀÞõø„·³…Š endstream endobj 678 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ1NÄ0Dg•"Òo|û$Q6ÍZZ‰HPQ *–’‚ÕÒ!ì£ýp!eŠUÌ8âi¾ý=o¶ýÕpíZ·-§uCçŽ|H?Я¶\¼¾Ë~”æÉõƒ4wœJ3Þ»óéóMšýã?¸çε/2"På˜<>Ïå uÁfA@5ãž`cÌO4ês´1dµ1gõÊ®šƒîêɧï:ÙôeÔPø~•KÙœ-ª˺QvõOÔhù9–ŒXÒÀÜ…H$%Ë RM ŸÒZÉlémb– „d·Ùr)}ÙA!·£<Ê/}L~ü endstream endobj 679 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚuνJÄ@ðYR¦‰oyMr¹ÀÙÜÂy‚)­,ÄJ--í–$baé#ø*Ä€…íÙbÉ8ëGió+þó9/wª]ÊiFÛÍ ªftQà5– sªÊŸÊù®jÌN¨\`v 1fõ!ÝÞÜ]b¶:Ú£³5”Ÿa½&HzЃÐZ]À(°&ÐDv) ÿZðÚEÖµ^mŸV­vjRPÜkYß-ÿ™›À€òB4‡x1+É›²>ß[ÐOBò:@|ÓƒFA:änKã¡ýe’Ì4ÒbÚˆå¯Çqã4¿³Kù…mÂÛ˜¡íåxÚá~ÇøÚ⃌ endstream endobj 680 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚŒ1 Â@EGR¦É2'pÖa!F0… •…X©¥…¢­ÉÑr”!¥EÈ8 I¥ ûàÏû33;MRŠ(‘oSJb:ÅxEk%GU/˜hvd-š•LÑkºßg4ÙfA’sÚÇ°È \à1×0·2wà˜{(Ÿ¡`‚« ÃUOÂ\+rBZt‚ð%p ¬á#'*=•žJ@« šŸðõÒ¿Ï«F»a;ÂWh—nñ ³ƒI endstream endobj 681 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚmÉ=‚` à’.žÀ߉1‘ÁD'㤎]…Ä‹‘8p n #¡~ $(}úö­ëL<ŸL²å¸6y6í-<¡Óvf{¶ÝÃÅšÅ\¶(â]Î׊p9% ED‹Ì-Æ4 ð•Óžgö&ëÉ{ô¼øâ!1îå¥qƒú?µ\ÀÜ P˜ùCÁµ#ýA“dZz–4Àu ×,iºÔu8‹q…/ÂaoM endstream endobj 682 0 obj << /Length 190 /Filter /FlateDecode >> stream xÚ}±‚0†K:˜ÜÂ#pO`iÀ‰1±ƒ‰NÆI4º æ£ðõ®ØîKÿëÝùÓd¹Ê0FM•j\i¼jx@½˜%\îPPGL2P[ê‚2;|=ß7PÅ~¤K<ÑäL‰•s ´Â9×óËy|¥9#l K#‚vÓœ_ó[¹Z²½äC„N Ò_‹¦C£•èFôŒÏ,úa8è—‘[NÔøXT®®þQ­€ü÷âŠÝ endstream endobj 683 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚÏ1NÃ@й°4¹¬—QY AÂTˆ (‘A‹ÃÍrÁå 3AzšWÌJÿ_¤ãæ”kN|y¹9á‡H/”–v¬¹Iû—û'Zun8-)\Ø™BwÉo¯ïVWg)¬ù6r}GÝšÅ3J•~ ZýôªýT™Mè¥Øa.åˆÊ)¥œ- ™oö̤Å/½ó`t™œÝÿ˜þRôø27ÈäVÖ¯½ifðöƒíh·¾hãÛ`+-·Rû¡ÔÑÒìNç]Ódvg9 endstream endobj 684 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.c ßÄI$çr9yré‡+[pé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿþÿÿD|?€bØ0ÿ ÿAD}°ò€ÿÁ&> f0ñH0b!þO ¶ƒn%Ørv¸ƒÀî³?sóˆ?À>û æË `Ÿs¹zrríÇG endstream endobj 685 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿÿÿÿÄÿ Øæ Œ„ † ‚ƒ`|$€lthv›bˆ)ØŒ‡6 ¢Žä£ÿQ Ø.WO®@.ÌŒ‡r endstream endobj 686 0 obj << /Length 145 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.c ßÄI$çr9yré‡+[pé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿÿÿâÿHìó"ˆ Á€ƒø$`@±ØCLÁmQDýÿ ÿ!Ä( ,ÆåêÉÈæxô endstream endobj 687 0 obj << /Length 227 /Filter /FlateDecode >> stream xÚÐ=NÃ@à±\¬4๬¥PY AÂT(PR$‚ÖÞŽkÍ ¸7eŠU†ÙI"QÒ|Åìß{;—Ý5袥ùŒº½´¸Á°ÐaC]8®<¿ár@ÿHaþVÇè‡;zß~¼¢_Þ_S‹~EO-5kVE*#TòÉPËŽaa¥'\¦BÙƒ°û‰«oè¹Ò\Qéõ4÷pf<á¢`2éß”²Oà$‡Ì˜gãßëíµúD> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿþÿùÿŸñÿ?cÀÀ€êÄÿÿÿ±4± Nàô%—«'W žˆ‡ä endstream endobj 689 0 obj << /Length 108 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bc SC…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§g ßE!ÚPÁ –ËÓE¡þÿÿÿÿÿÿà >ÿ†Áޱ¹›ËÕ“+ H¨X~ endstream endobj 690 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚEÏ=nÂ@àE.,MÃvN€m M,ñ#ÅE¤P¥ˆR%)S€B‹9QPr„ø.]¬lÞÛÈ¢ØOš·ÒüLÒÑt¦±Žñ&c&ú•ÈFRf1K~|þÈ<—èMÓ™DÏH%Ê_ôw»û–hþºPÔK}O4þ|©…3EÓµ¦s|–Æ@F öÄAÖ¤ÃØÈHaÀž8pnÀ…\]Ï­GЈ-8¶j<ì\  8hP÷Ãýÿø­žHF¬é–=a…‹,oËÚ>“U.k¹9‰s endstream endobj 691 0 obj << /Length 123 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.cs ßÄI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿþÿÿ€L€Å˜ŒÁN|Œ?ˆ êÿÿÿÿã?*ûÀåêÉÈé f’ endstream endobj 692 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õøÿüÿÀ ÿBü`°ÿW$þð‰ü{ª1ˆy Ÿ‘‰ùŒ0¢Ÿñ1Œh†í͇ÄqÑ|¼F¼‡ï™aÄ Ñ𕨠‚l¢è·?`¿!°—«'W ±,ˆ endstream endobj 693 0 obj << /Length 194 /Filter /FlateDecode >> stream xÚUÏ-Â@à%ˆ&c¸Ì 迨¤”„ P‚$ޤu½Ö’[GEÓev›¶ æKÞ1Çî»hÑ8º&nL؃-;CF¹XïÀA_ í>¡ôpŠÇÃi º?!å—&+ŒRå"c¢(ɉ(§N+˜ÆµGÍSroˆ‰›‚W\¯Š‹"­àЬæüÏ ¦+éÕtI…–ðߣmÅ›h5|Ö ¸üˆ‹¢dXB]/†qsøº‰| endstream endobj 694 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚÅ1 Â@ERÓx„Ìt³Ž)R-Än!he!VÆÒBÑÖä¨9‚¥EØq™Š†Wüßü7sžæe”ÓÄ”Ϩ¶xAæƘ‡æxÆÒ£Ù3šUŒÑø5Ý®÷šr³ ‹¦¢½¥ì€¾"h é`,ò‚T¤'ÀuID ˆ§x¸/„ˆ¶Hÿ ¡øÙ÷®î9 ƒ›Zª¯šëpéq‹o¡lª endstream endobj 695 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bSC…C®B.cs ÌI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿ0üÿÿÿˆø"þ3Åþ70`øH؃þ@‚ýŒ`?€#^¬„ùŠ^°Q`Cƃ-YÉ ²œä fƒ€² Ô$êÿ700€ F"Àb\®ž\\æ„wN endstream endobj 696 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚÅÐ1nÂ0Æñ/Ê€ô–!ïÔ &HYj‰‚Ô •Ú©CÕ @°Æ9j1CäÇ‹KªÞ ’õìåû{iËŠs.y^,ØV\.x_Љ¬ÕÛœWËûÓîHëšÌ[KæEïÉÔ¯|9_dÖoÏ\ÙðgÁùÕ† ùƃHLd€ pÝLià¡'ÒîAi û?’NIû¬ iïÚ&tZÁéà0÷^gú±È…Ÿ¶X{c¹þ‚Y7‘öÉ01ÖÞñ¿<¶5½Ó ¯ endstream endobj 697 0 obj << /Length 197 /Filter /FlateDecode >> stream xڕСÂ0à›jrfÐ{Ø::"#a‚‚ ‰€€îÞ e0‰XvtmC‚ùÄßöîOõh˜Ž)¦„Š´¦TÑ^á µ²aLiâOvGÌ ŒÖ¤FscT,èr¾0Ê–S²iNûf‹EN†`æÒY9†»Q‰¶3p‚qNÊNÙ3¼ÿ¶ßO0ïÉn‹ßè¶ ×ÄZ¿’J4½&}þ5tÊò›¦y+™A²ý ½-ؼ+Ô€³Wø2>z endstream endobj 698 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚu1NÄ@ E½Ú"’›a|˜„$ÕHË"‘ * D”H»$*â£å\!GØ2HQÌw€‰æÉãÿmÿ©«ãæT ©å¨”ºæDJÞsÕ ‰gõ­Ü?ñ¦åx#UÃñmŽí¥¼<¿>rÜ\IÉq+·¥wÜn…˜™åº2ûÐÌÌ4w„C0Mý€¤LúNÔéL”túAø ¨9ÁçÒ„Éa=tC¹6”8y€ÇF¢Ì›Ôa¥OÚ2éý/òaÁ<Ãô&ÄØùE>oùš¿åxv endstream endobj 699 0 obj << /Length 124 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿÿÿÿÄÿÿ¡êêð@†H0 zÂþÿ(Qÿÿ—ËÕ“+ +òT¬ endstream endobj 700 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚÕË1‚@…áG(L¦áÌtYY +ÄD ­,Œ•ZZh´†£qŽ@IaGhôf'_ñϬ‹gÉ‚#}SËÎqbùléF.b27§+e™=»˜ÌZ3™bÃûóB&Û.Ù’Éù`9:R‘s)U*µH]JóíØý^‡¿w˜ŸøÂ¤Ôè¨%ÂH«´RQCôª/ê‰~ú´*hGo8‚˜ endstream endobj 701 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚeÌ;‚@€á!$Ópæº,‚Š1q ­,Œ•ZZh´.FÇ5¸”\5šo’2ã¹s? ›šqòò98^Ñ}G›|ç»9^0ÈväÈV2#kºßgdÑfAYL{NöELi iÛwÐw?>Í,À¨Ì Ìʰ ]’ xB˜i ¿´LHäÊ›1VÞL0óJRþa”…¢Vèu¦èZ À¥À-¾òVi endstream endobj 702 0 obj << /Length 197 /Filter /FlateDecode >> stream xÚϯ ÂPð#†Á)>‚çt»ºËÂœà‚ É &5mÂ.øb_CY°N wíztøo,È¿ðNøìvÓéE‚‚ì69‚æWh .-rZùe¶D/@sL¶@³Ï5šÁ€6ëíMoØ%n}šðÏŸÂ :ƒš–ßæ}v%Ö$@ö—F•´T÷iX°zÒûÓ[õñ¬¿VÎÉ!zyMŽì-¹ß+_ªX=”Ey>JÍ3CN™.°àï{ŒK endstream endobj 703 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚEÎ1nÂ@б\ MÃ<'ˆm ÕJ„Hq”T)"* L‘(i½–RøZt)¹G L±Úá±EáçÝïÝñŸW‹¥2Ã3ŸÉ¢”}ÉŸ\YVØÖ>ì>xUsþ&Õ’óg¤œ×ùþú9p¾zyì×ò^J±åz-NS={èÅkg`ÕgÉ?EJ €E£AJ>.½€dÝœÀôt &Ú¤JI¡0rÏî熻ÇqžMÎþ û›û5¬·.M_Íf…[݆{ÂG¨èZµ>’¯‰±_õ?ÕüÊW®Kq{ endstream endobj 704 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚ­Í= Â@à )Ó䙘ÿ"U F0… •…X©¥…¢mñb ¯a—Ò”)®³‹¨pØùà½)6 GqB¼Q@±O[ªÎSQ6{Ì t—&èN¹E·˜ÑéxÞ¡›ÍÇÄ9§•OÞ‹œªªA â‹î¬ì†q“©ÍÒÚÐð@# ~8 ©¡¸ôŽæÚØ7űÚdzm˜'cÈúðh„¢ü/–ämÙý¢:œ¸À“^[Õ endstream endobj 705 0 obj << /Length 182 /Filter /FlateDecode >> stream xڥϱ Â@ €á”Y|„æ ¼–¶ƒ j;:9ˆ“::(º¶}´{”{„ŽÒ3‘ÞÒÕ!äŽH–ÎóÅ”ÉÄ”'tIðŽiÎûo•ó ËõÒõ†_Q×[z>^WÔånE¼WtL(>a]Qáœ3-c'4‘aŠÎÓÓ|` ÁBAõž™I=E’zNGþKCö ¬8e  œŽpª¬“‹&È•×5îñ ûÚlÎ endstream endobj 706 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚmÌ= Â@à Óx„¸ ‰‚Õ‚?` A+ ±RK E[“›™£ä)S,;Îh%Xìûfæùh<¥” }å:exÅ\³T¿:8^pV¢ÝQ>E»’m¹¦ûíqF;ÛÌ)C» }FéËEÜ$ s­´àXBט^H”ȃ©ÁÃ@ž?|be¨®ŸàzY©E—ƒâÿðTZ_Õq×-`öRÅ!a~…ˆƒ„®K<.KÜâj/\ endstream endobj 707 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚŽ= Â@…g°¦ñ™˜„Ä"•#¸… •…X©¥…¢­ÉÑr”aË€!ãN;±˜æï½GÓY‡®âg!ŸBºR¤³@[]/”òw%ä¯Ü”|³æûíq&?Ý,ØõïÝåLƹ©¿+ðx•ƒ“À—´€"Ò¡@±y‰Rx Œ-¶0ª±éþ~Ð*ž?¢uîmÖ½rç!0±ƒe¥æ] ÔEÓ`ç%ÐÒЖÞ*Åsz endstream endobj 708 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚŽ1 Â@E¿¤¦Ik—9›°° Än!he!Vji¡h›äh%G°L2ΦÐÖ…}ðgÙ?of§óÇœêÅlS>'t#k5Ñ?œ®”;2{¶–ÌZ§d܆÷ç…L¾]rB¦àCÂñ‘\Á¤"iJzŒDˆÆ=á[5/”ÈjLAOåQ~Ñý‰ß¡@«B_ÕZ¯h4èÊJ—â5¡Î«µ^RMuZ9ÚѲuEJ endstream endobj 709 0 obj << /Length 193 /Filter /FlateDecode >> stream xڕα‚@ à’.<} L— &Þ`¢“ƒqRG®â›á£øŒ—;[pqÓᾤ½´ý 5)+ÊHñ+•9ís<¡’^&¥|ìŽXLפ*LçÜÅÔ,èr¾0­—S⺡MNÙMC±€Ä  ÿ$z1Ú1Þwxï!"Ëûâ>ô<æôZ™iá&³N°?â>cíH ãRa¸ÊÉHŽ'c Ë:ÇÑ´m™¸O,Î ®ð —ºYK endstream endobj 710 0 obj << /Length 201 /Filter /FlateDecode >> stream xÚmޱŠÂPEï’âÁ4ù„ÌìKˆ¬® ›BÐÊB¬Ôr‹mM>í}ÊûËâì}VÌ™;ܹ“ú³™i©“Ô¥ÖS=Tò'uÃù9&aÿ+óNüFëFü·â»¥žO—£øùêK+ñ ÝVZî¤[(²€ÂÐÛ f#2³;܃J>ÂPD´Cˆv@Z }•ˆ„‹÷c½C  ¤7¸¾Ð'Ð* 4u‘ö.æ7ú¹mp Ìb2ræcÀòÝÉZþI÷_þ endstream endobj 711 0 obj << /Length 154 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0asSC…C®B.cßÄ1’s¹œ<¹ôÃŒ¹ô=€¢\úž¾ %E¥©\úNÎ @¾‹B´¡‚A,—§‹ÿû@âÿÆÿÿ˜AûŸz ñHð?°*;&põÿÿÿš4A€Åðk£aÿÿÿ[~ `1.WO®@.òÅ^£ endstream endobj 712 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿ#E`š}!óšÄä”k.pž` A+ ±RK E»#›ÎÇðUò(y„”[,g‚²ìǰóÿÿÌÖÕÉzßòq¹áºâꜟJz¥º`;볟Öã íZÊï¸.(¿ÒwÊÛk~ûx¦|wsÁ%å{¾/¹x vÏ’€4¸ˆlnfxYé•DdöItÁ§S¶n\Å#7@efd=º`’El6X4jB*²`„éá¾fÀ}E_éh0‡íb•ôj“1SLÍ€,xÝ>v*‹Å!*:MÃö–Æ¢ó½:²?-y‰%Û§F‚Í@—-ÝÒ7ãè‚> endstream endobj 713 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcSC…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @¾‹B4Pe,—§‹Bý øÿ¬“Œ‘ò@dý ùóÿ? ùûÿ ùB~°o’äAdƒü ÉÀ$ÿÉ?Häz“õÿøÿÿÇÿÿIˆ8—«'W ƒzú endstream endobj 714 0 obj << /Length 132 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcKS#…C®B.cC ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ì ò ØþÃÄ@òx@ýÿ@ü€á?×C1;}pýÿÿþÿÿÿ†A|.WO®@.üØO) endstream endobj 715 0 obj << /Length 169 /Filter /FlateDecode >> stream xÚÍ= Â@…_°¦Ð#d. ›ÍŸ B Fp !Vb¥–жnŽ–£xK q\‘`eïÀW¼ïñЉ£~2â€cîé!Gš“·š¦ÎO¤j‰Ô .»m÷Oñë1üêâþdXˆ÷„ÈVîŽ|¹¢-M -è§úX endstream endobj 716 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚÌ;‚@à%$Ópçò.¨H)L´²0Vji¡ÑV¸‰Wá(xŒ…[Æ_­Å~Éü³ó‡Á0ŠÑEŸ_ècäáÆƒ=’¹2Êb½ƒ4gA ΄Spò)§-8él„ôŒs˜ÃQ¹yÀ endstream endobj 717 0 obj << /Length 115 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b e¨bÈUÈel䃹 ‰ä\.'O.ýpc.} (—¾§¯BIQi*—¾S€³ï¢m¨`Ëåé¢PÿÿÃÿÿ‰zÁÀ<Œˆúÿÿÿ7ñÿ,ÆåêÉÈî{\W endstream endobj 718 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚ½Š= Â@…·[˜&GÈ\@7!Q°1#¸… •…X©¥…¢õ^,7ðæ[n±ì8šÎȃ÷WÃÑ3ä‚r„Å9œAl&’ø]ö'¨-˜\À,¤c—x½ÜŽ`êÕ s0 nå¹Û =œî=Cê¿bq䙣Ò1 S¥e¬”ö‰K•vI'ì’ö‡mrÿ/)Tžòì8R`ßû¾‡¹…5¼ízfÊ endstream endobj 719 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úòþÿ¨ÿ$þÿ$ÿÿÏÀPÿD2þÿ`ß$ȃÈù@’Hþ“Èô&ëÿ?:ñÿÿÿÿ7 “q.WO®@.‹£ll endstream endobj 720 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ}Ž=‚@…‡XLÃvNàBL¬H·0ÑÊÂX©¥…F[Ù£íQ8¥…a†‚Îb^2ï}¹™KJ)*%³ K†w4÷Ò‹ó +‹ú@¦@½á)j»¥çãuE]íV”¡®é˜QzB[Ä_P¥ ¢:˜…ðá9o’.êAµ@9(¡dq%Ÿ»7@â'a¸ý/=ßµÓGÃ.^¬ÄTyhÆ ‰”pÁ A!\\[Üã>P: endstream endobj 721 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚ¥= Â@…g°¦ñ™ èfI"¦üSZYˆ•ZZ(ښͣä[.(w“€–‚S|Åæ½7q4HRYs_8Ö ù éL‘WCNâvµ?Ñ$#µá(%µp:©lÉ×ËíHj²š²&5ã­æpGÙŒs” V,ÈS*7;(& A‰]ƒt,¾à -À•ÇýGTÎÀµ@Û8×=ÓF–>¼®á ¡¯†¾$Úñ¼Ë_È¥÷ªùF­Ñ<£5½Þ¯ì endstream endobj 722 0 obj << /Length 211 /Filter /FlateDecode >> stream xÚ­Ï= Â@à‘ ÓäÎ4 ÙˆVÀ‚Vb¥–ж&7ðJ{¯à Lig³ Z 6_ñBÞ¼Õq;éQH1µ¢.é„â­#Ü¡Ž$ )ѯO«-ö3 æ¤# Æ’cMè°?n0èO$éòÓ³!W© É¾Èùb Á|3à1³õP¢_6Äæ¬ri©Ölxz+=Õ>jO=®Ù]qÝu¿ôìªÊç÷B·V–ŸÅ´~…º[ëÎÿ)×DÅ\|kse8Ã'á·vG endstream endobj 723 0 obj << /Length 158 /Filter /FlateDecode >> stream xÚ­É1 Â@ПJø—ðŸÀÝu£Äj!Fp A+ ±RKAEëõh9J¼AÊÁqc!Ú[̃™Ií`4-ØԈËÞð™m»îjw쎜{Vk±«y\Yù…\/·«|9ê½e_Hx’+5ÐCôÑ8´äÂ#‚$ÒRC®¡¹šˆ\õ¡ì¸ÿBÿ"¨¿xo<ó¼âõõIw endstream endobj 724 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚMË1 Â@ЋÀ4!s7q5Æ@T0… •…X©¥EÁÊÍÑrr‹ñ,,Þ2³óÿÔŽg©D’€MÅ&rŽùÆv‚=ê×þpºr^°Ù‹°Yã—M±‘Çýya“o³YÊ!–èÈÅRÈùr¨êGB®ù7 }Kïÿ´D#"×eZS¨¡W¡ÿ!§ˆ("P÷B Ca÷£}­¢9ª6A«ª=> stream xÚ31Ö3µT0P0bc 3…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€Àž¢þÿÿÿ @ü¿A€ÅH2…‚ù`€hàÀ ß €AþAý~ [@óÿ Œÿ€LxÀÀåêÉÈþ:B„ endstream endobj 726 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úÌÿþÿ`ÿ…¬ÿÁ $0ð()DÚÉ? õþÜÆðêdƒ=˜”ÿH2ÿcÿÏÀåêÉÈÄ£d> endstream endobj 727 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ5Í= Â0ÀñW:oéúN`ú¥ÐÅB­`A'qRGE7©…^Ì­×è êØ¡4¾Ø”É? ‰Âé,&žQ@áœÎ>Þ0ÔÍÓ[}pºb*Qì)ŒQ¬¹¢zÜŸévI>ŠŒ>yG”½•¥:ÅôJ•^ý›]ƒS |Á-,ZHZX:È^<rœ[CÂ×Á准’qÊz¤b&Õg¤aì¦QŒ¥À½†¿À•Äþ$›Lã endstream endobj 728 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úÿ `Ôðÿ?ÃÙaCÄÙ00~ @2?ÀDv`²N2~¨+þߎ ¿#Èß``’ ?Ÿ‡“¿¿G#«¾g``¨?øA6 Hû†@Rž¡†ËÕ“+ Ém¢ endstream endobj 729 0 obj << /Length 202 /Filter /FlateDecode >> stream xÚEŒ; ÂPEoH!Lãœø£‚UÀ˜BÐÊB¬ÔÒBÑN!…Û²³t î@Ë!ãL@,ÞaæÌ»·µ{¸£¯Ûá¨ÏÛ™ lµÃfOÄܒ£¹©ZrÉŒOÇóŽÜp>âܘW!kJÆ‹/ŸLnRüQ;”H¡(Ô+€Øû­Üp{Íçh¼¯€/ O ¨.†êçê«oŸk> ¹¶´¬4¶ú…¥4Wè¬&F&ž”™äRŠ¢ª§ÚÑ$¡}¨xY& endstream endobj 730 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚEαjÃ@ àßdˆ‚ÁzöìØ)ÍCšB=Ò©CÉ”dÌÐÒnÆvÈÐ×jé‹:tÍ&É=Žûîî$%ñÍpÄ!ø:ºãdÀñ-¯"z¥X£!—Znh’‘yæxDæQâd²¿¿}¬ÉLæ÷‘™òKÄႲ)—Ö³µ[{²v§È­õöð+ïðOPy5À‘ Æ@®²äÌ©¤äUíð·-Gÿ[ùÙ;z¿Êßàµ[*ö‚l”ãŽBÉ;¥v\ɼHer”;åSú¾H‹R §Z88 ¾~íKôÑßÍa{ endstream endobj 731 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ}Ž1 ÂP †S2Y<‚9¯Å*B¡Vð ‚N⤎Š®­Gó(ï¤Ï¤c‡|?!?É'ãéœSžèä3>gt#Í”»Õ§+•žÜ^wrëŽ~ÃûóB®Ü.9#Wñ!ãôH¾â"Æ…ôPŒ‚¢x+š—"B I À/ >Š¡€i`˜¦$fà_£…$hŠ¡¨†¢Šj(ª¡D{£{-ÐÊÓŽ~æêb° endstream endobj 732 0 obj << /Length 203 /Filter /FlateDecode >> stream xÚ= Â@…_°L“#8ÐMLRØðL!he!Vji¡h'š£å({„”!qœ-–6ß²ó`ö}›ÄÃtÌ!'<ˆ8 9ñ1¢ Å© å»äp¦iNfËqJf)c2ùŠo×û‰Ìt=ãˆÌœw‡{ÊçŒÞ@в¶^m ´­…ו„û•W÷¨”x:ô däTLdOñ”€_Öû'¤X`–*ºw]!WÒ¢qµ½z¨‘º9KõUóïÐ"§ }}dà endstream endobj 733 0 obj << /Length 141 /Filter /FlateDecode >> stream xÚ31Ö3µT0Pac S#…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]Øø XŠí¸ˆÿ7001;×ñ¾Äójä‘Ô®ÿÿÿÁÿÿÿ?À0ˆÏåêÉÈÅFJÜ endstream endobj 734 0 obj << /Length 222 /Filter /FlateDecode >> stream xÚe1N1Eÿ*…¥i|„Ì ð.›-V Ab $¨(U ¤A›Ý£ù(>BÊÑóÓ„,?kÆÿWíEw¥µ®¸kí.õµ‘i;¯O%/¶ï²$=iÛIºó®¤á^¿>¿ß$­n´‘´ÑçFë6Šx0ڄʬ ˜íÍŽX⌾T†~ÂèËϰœfGvÄlŽâgØ×ÎOÈ —˜À<|žðHTGÇ‚+î©¥µ§Ë‡D5ÿWôTŒL3ü*Ù¡¸=·‡2šÿÐþ‚½,·ƒ<Ê8hñ endstream endobj 735 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚEнNÄ0 ðÿé†J^òñ @ZÚHH•îC¢L ˆ @°Ò>ZåáÆ§úl·ÀŸDZãTåe}Í9W|Qp•s}ů}PYkP·å|òòN›–Ò#—5¥[ SjïøëóûÒæ~Ë¥?œ?S»c„€Nz¬DÈDF‘â˜Mˆ&4=:4§WâLì• «hLºVÆÚšÄQ—5Aýâ1;Í,òw×Ki üs°Ä™ãÇ…à Îdw;«Ò-¯—y"ŸÍ§\Û¼>¹ÿí[z 3áVc4 endstream endobj 736 0 obj << /Length 181 /Filter /FlateDecode >> stream xÚ•Ï=‚@à!$Ópæ.¿ bâ&ZY+µ´Ðh £pJŠëL±hë$ó%ó^5YºÌ Š(áÍʺÄxÇT²HN)Î7¬4ª¥ª §¨ô–ž×Uµ[QŒª¦cLÑ uMþÁÄ„B9ÓÌÆ›‹‘ñGÐ3aç(if ãMŽÅ( Œ/½#ì˜`Ëc„÷—V2öOZË¿Z;ý®5îñÜþtý endstream endobj 737 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚ¥Î= Â@à‹À4{„Ìt³&)!à˜BÐÊB¬ÔÒBÑÖ,x¯’£xË’qFEÐÖæƒÙ}o“¸v)¢„ZŽ’ˆRGk‡;ŒSʱóÚ¬¶ØÏÑÎ)NÑŽeŒ6ŸÐaÜ íOäÐiá(Zb>$Ã\CÈÌßÈÌüǹ.ì5ïªTʺ)ñ7¢ ½œùPÐ €ù\è)'…ߘ'å-,e›ù$9óÒ‘• i«ÌŒþ `¾AƒYÒ Öš G9Îð-²c— endstream endobj 738 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚmŽ1NÄ0E”"Ò4¹ž @’T––E"Th+ ¤Ø´±æ£ø)S„ ãÍ“ü=3ÿuíEÅ5w|ÞpWsÉ/ ©í5ÔgûýóüF»ªGn{ªn5¦j¸ã÷ÓÇ+U»ûkn¨ÚóSÃõ†=6™Ì@! `dÕHpÑë³Îç³¢˜¢¢Œ°0g0º°¿p ã†\ÏF<'Ÿ"D´MÖbLz[‚Îë€õZj6]*7DEñã?°?(£j”A…LP5ãË GÕÔ¡˜µ(O•Y*GÒ@BRƒæ ›è þ5pI endstream endobj 739 0 obj << /Length 183 /Filter /FlateDecode >> stream xڕͽ Â0à+Â-¾Þ hÓ NB­`A'qRGEÁÉöÑú(}„ޤzW©Eqñ _Èå~3°#ò) ¾¦À';¤Æ#ËI~š×Ïö€¡Cµ"cQÍ8ÊÍé|ºìQ…‹ iT­5ùt]ãÁ‘ Ù'é`œ010%p1ßà ­‚içBÆt*R¦—€t 2;nB)¼û½¢¦•×4㪙_T+~Ѭý‹.œ:\âãM† endstream endobj 740 0 obj << /Length 213 /Filter /FlateDecode >> stream xÚ}O» Â@œ`q°M>!ûz‰I «€0… •…X©¥…¢­É§åSü„”Áõ²W؈p w»3s3Y:Ê'sÆÃ„³˜ó1ºPš»¡{¦~s8Ó´$»å4'»tc²åŠo×û‰ìt=ã„ìœw Ç{*ç Ó(¤Džˆ¼`D:„y#jAÔ BQ»SQ]9h@ø”¢9…׆mðÆ 3/"-PIÿoÓ™n•§ ÕªË×ÙñÍó?|ÉR3{¿¾‡6ÒnÚRûúæ}Z”´¡ëån endstream endobj 741 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚm1NÄ@ EmÉÍa|HB’b«‘–E"Tˆj¡¤`í&G›ŽkøéHÅü 4ÒÓØ£ñnêóv+¥4rVISJ{!O¿rÝ¢‰²þ~9¼ð®ãâ^ê–‹k´¹ènäíøþÌÅîöR*.öòPIùÈÝ^(Ÿ‰(`)3SÚ˜èç¹1›É+-:%ô8p'?, ó\üú‡%ᔀ^Ê‚úH½"È4Ÿ)ÂM¡ñ©úP¨9%7¹Hiè/üŠ!©¯ Gó«dLºâ!n&{„ÁÈë•|ÚÒöÍ J™MøÞc_u|Ç_ž!r· endstream endobj 162 0 obj << /Type /Font /Subtype /Type3 /Name /F31 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -1 -19 45 58 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 3 /LastChar 126 /Widths 742 0 R /Encoding 743 0 R /CharProcs 744 0 R >> endobj 742 0 obj [43.59 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 43.59 0 0 0 0 0 0 0 0 0 0 0 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 ] endobj 743 0 obj << /Type /Encoding /Differences [3/a3 4/.notdef 21/a21 22/.notdef 33/a33/a34/a35/a36/a37/a38/a39/a40/a41/a42/a43/a44/a45/a46/a47/a48/a49/a50/a51/a52/a53/a54/a55/a56/a57/a58/a59/a60/a61/a62/a63/a64/a65/a66/a67/a68/a69/a70/a71/a72/a73 74/.notdef 75/a75/a76/a77/a78/a79/a80/a81/a82/a83/a84/a85/a86/a87/a88/a89/a90/a91/a92/a93 94/.notdef 95/a95/a96/a97/a98/a99/a100/a101/a102/a103/a104/a105/a106/a107/a108/a109/a110/a111/a112/a113/a114/a115/a116/a117/a118/a119/a120/a121/a122/a123/a124/a125/a126] >> endobj 744 0 obj << /a3 673 0 R /a21 672 0 R /a33 660 0 R /a34 674 0 R /a35 675 0 R /a36 676 0 R /a37 677 0 R /a38 679 0 R /a39 661 0 R /a40 649 0 R /a41 650 0 R /a42 662 0 R /a43 663 0 R /a44 664 0 R /a45 671 0 R /a46 665 0 R /a47 666 0 R /a48 732 0 R /a49 733 0 R /a50 734 0 R /a51 735 0 R /a52 736 0 R /a53 737 0 R /a54 738 0 R /a55 739 0 R /a56 740 0 R /a57 741 0 R /a58 667 0 R /a59 668 0 R /a60 651 0 R /a61 669 0 R /a62 653 0 R /a63 680 0 R /a64 678 0 R /a65 681 0 R /a66 682 0 R /a67 683 0 R /a68 684 0 R /a69 685 0 R /a70 686 0 R /a71 687 0 R /a72 688 0 R /a73 689 0 R /a75 690 0 R /a76 691 0 R /a77 692 0 R /a78 693 0 R /a79 694 0 R /a80 695 0 R /a81 696 0 R /a82 697 0 R /a83 698 0 R /a84 699 0 R /a85 700 0 R /a86 701 0 R /a87 702 0 R /a88 703 0 R /a89 704 0 R /a90 705 0 R /a91 654 0 R /a92 656 0 R /a93 655 0 R /a95 659 0 R /a96 670 0 R /a97 706 0 R /a98 707 0 R /a99 708 0 R /a100 709 0 R /a101 710 0 R /a102 711 0 R /a103 712 0 R /a104 713 0 R /a105 714 0 R /a106 715 0 R /a107 716 0 R /a108 717 0 R /a109 718 0 R /a110 719 0 R /a111 720 0 R /a112 721 0 R /a113 722 0 R /a114 723 0 R /a115 724 0 R /a116 725 0 R /a117 726 0 R /a118 727 0 R /a119 728 0 R /a120 729 0 R /a121 730 0 R /a122 731 0 R /a123 657 0 R /a124 652 0 R /a125 658 0 R /a126 648 0 R >> endobj 745 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚ•; ÂPEo°L“ ™ èË{? bSZYˆ•ZZ(ÚÆ,-KÉR¦uò)ÔN8Õ ÌœãúzÀO¸g4û†‡†šÎdŒL=ûíj¢0&µacH-dN*^òõr;’ W3Ö¤"ÞjövG t)PÂ*ÐÉaçp2¸)\ à <` %:5vQá9܆ Á÷ô‹×ÿü\ø<.¿š§òÝ)Z™FL ÅSl+ç¤ö— i‘"é’:i”Òª·Kó˜Öôï*c¸ endstream endobj 746 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ•= Â@F¿`˜&GÈ\@7»þ¥RðÜBÐÊB¬ÔÒBÑ.ÄÍ£ìR¦⸠j)¼jfÞk÷[ºÃ w¹i4›”{†wšŽdŒLNÛïÕö@#KjÅÆšÉœ”óùtÙ“-ƬIMx­9Ù°J @,ˆnB‰ BPÂÈ«gXxnˆ÷$ÊaõKý?¿¾GîýT¾‹ÃKæ%–{Ïúé,æâ/Ò"EÒûÆÌ÷J5M--é7Z£ endstream endobj 747 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32Ó35V0P0WÐ52T02U03RH1ä*ä24Š(XC¥’s¹œ<¹ôà ͹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿ7@ц`þårõä ä.§á endstream endobj 748 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ó35V0P0RÐ52T02P03RH1ä*ä24Š(XC¥’s¹œ<¹ôà ͹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿ7@ãÈ@pÿr¹zrrßb”ß endstream endobj 749 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ31×37U0P0SÐ52T01R03RH1ä*ä2‰(XC¥’s¹œ<¹ôÃŒM¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ö˜ÿ yQÿ(b0þ?o@!v0ño`~0r™<˜ø$ê?@ÊrãŠÿ`!°.X¢¬¬l ÿ¿ô 8$™!D4œ¡N{î?,>€1ÃåêÉÈ” vÙ endstream endobj 750 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ31×37U0P0SÐ52T01R03RH1ä*ä2‰(XC¥’s¹œ<¹ôÃŒM¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ000üÿ"þ700°ÿb~ö?€„> stream xÚ37Ñ32W0P°PÐ52S03R† )†\…\¦ aS¨Tr.—“'—~¸‚©9—¾‡‚)—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹Bý0`€PÿÐi˜<—«'W ¦5° endstream endobj 752 0 obj << /Length 141 /Filter /FlateDecode >> stream xÚ32Ó35V0P0W0²T02R0µPH1ä*ä24 €Á2ɹ\Nž\úá †&\ú@.}O_…’¢ÒT.}§gC.}…hCƒX.Oþûõê?üÿ„@°íÿðÏaa°a°Ã ††Œ0`oàgJI0p¹zrrz +¹ endstream endobj 753 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚ]Ž=‚@…—PLܸü4&$ˆ‰[˜hea¬ÔÒB£­p4¼ÉzˆÍšGvÑBšÉÌ›™ï½Q2L"ô0Æ ÂQ€q€;ŽjÑÃ0é6Ûdø Ãø¬•‹9žO—=ðl1AxŽk½ ˆ™U3Ælõ+ÎëoÔel+§¼ÚÊ­ÈVI·ºt¯IRÓ,žªR"*]¢7³ˆZ`Jå¥;£™­¹3æ·£ž&ãÖKÐO¥3ÃTÀ>7i endstream endobj 754 0 obj << /Length 112 /Filter /FlateDecode >> stream xÚ37Ñ32W0P0UÐ54R0³T05VH1ä*ä23Š(˜™B¥’s¹œ<¹ôÃÌŒ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Ì `0¢èÿð©áÁåêÉÈÇ‚J# endstream endobj 755 0 obj << /Length 143 /Filter /FlateDecode >> stream xÚ32Ó35V0P0WÐ54S02R04VH1ä*ä24Š(YB¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü öê?Ôøÿÿ€`=ÚÿáŸÃ Ã`Ã`†  0>`>ÀÞÀÏ ”’`àrõä 䦇, endstream endobj 756 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚ32Ó35V0P0b#CCc…C®B.C˜ˆ ’HÎåròäÒò¹ô=À¤§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒýƒúõþÿ€AÏþ—«'W !‘$‡ endstream endobj 757 0 obj << /Length 168 /Filter /FlateDecode >> stream xÚ31×37U0P0UÐ52T01V03RH1ä*ä26Š(XC¥’s¹œ<¹ôÌ͹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. @ ",@Dˆ(€@Ä f€3˜h€ì`¤ŒDð9!'l°˜7§éƒqšŽ0x`LGŒÓt„Á8MÇä‚ËÕ“+ :Ì6Ù endstream endobj 758 0 obj << /Length 111 /Filter /FlateDecode >> stream xÚ32Ó35V0P0b#Ccs…C®B.C˜ˆ ’HÎåròäÒW04æÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(ð7Ø?¨ÿPÿáÿñìð70`¸Õs¹zrrD7„ endstream endobj 759 0 obj << /Length 153 /Filter /FlateDecode >> stream xÚ32Ó35V0P0WÐ54S02R06WH1ä*ä24Š(%!Rɹ\Nž\úá †&\ú@q.}O_…’¢ÒT.}§gC.}…hCƒX.Oþûõê?üÿƒ žýþ¬Eý¬Bû?üsdl,À°‚¡€áãÆÌØøäR \®ž\\FÊ>í endstream endobj 760 0 obj << /Length 109 /Filter /FlateDecode >> stream xÚ37Ñ32W0P0U°T0³T06RH1ä*ä23Š(ƒ%’s¹œ<¹ôÃÌŒ¹ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÁà„úÿF3 €î.˜{¹\=¹¹X@ endstream endobj 761 0 obj << /Length 141 /Filter /FlateDecode >> stream xÚ32Ó35V0P0S0²T02T0µPH1ä*ä24 €Á2ɹ\Nž\úá †&\ú@.}O_…’¢ÒT.}§gC.}…hCƒX.O††Ì˜°7ð3È¡ ƒCC~`xÀðüÀÿÿá¬Bûö?ä?°àrõä ä<.œ endstream endobj 762 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ}É+€0DQ?«˜ðúÚ4TóI¨ … (@" àÙy!Á#®9×i •êisZÇE±Ãú Ã7æ E„ ´Ò0@bËó¸VHÑ•THÅQi&ÄŠ)¥û/Ô=–Þ-˜ endstream endobj 763 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ31×37U0B#C #…C®B.s° 1D"9—ËÉ“K?\ÁÄœKßCÁ˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEá?üC&¹\=¹¹J®# endstream endobj 764 0 obj << /Length 138 /Filter /FlateDecode >> stream xÚ31×37U0P°T06P0¶T03PH1ä*ä2² €Á2ɹ\Nž\úá F–\ú@.}O_…’¢ÒT.}§gC.}…hCƒX.OFûþõä?ü`ÿÉ£cûò@zѱ|ÿyv ÌÏÀÞÀÇÀ Æ\®ž\\ýIM endstream endobj 765 0 obj << /Length 269 /Filter /FlateDecode >> stream xÚeÐÍJÄ0ðY*rÉ#d^@ÛÚíöfa]Á=íA<©GŠÂbóhy”> stream xÚ­Q½JÄ@žbaš¼A²O`Ï˲pž` A+ ±RK E!Åaòhû(ñ ¶Lqdœ¬Åõ.,óÿÍ7›‹³ó.ôšu©×[ýRâ;V+¶ oúÀóîZÌtµÂü†½˜··úóãëóÝÝ•.1ßëÇROØî5ôGð/!=¢‰!¢!&Fņ±æ¯8Áøû¾}.Wú\h r3ˆ¥G2( Ùʪè±eG3H¦lˆ\ ÆqŽk ¹fª¡·Ü£«¸Âv‡HðÐEL‚lÝŧ8-Ø85{Lÿ Cß´;ÅúGàUž[áÍ|eFÙ‹F'{ÒÏ({ZtHhÑ%šƒNtƒ #]aIyÝÁLr2^î$ã»ÍRÓûsáu‹÷ø ÊØ¿g endstream endobj 767 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚÕ1 A Eÿ²]¯8;êÀvë N!he!Vji¡h«{´9ŠG°´ãd±QÄÞ<~~ „¸~·p\p/•³ìJ^[ÚÑ L}¡­V[ª™9J2ãä’ >ì2ÕtÈ–LÍ ËÅ’BÍ@.ÀY®*åtÀßà“}4˜I“½¨™kÆ\Ðê7B <µÄ/z‰¢ñ…íž¿aúš×³?I£@3zóպà endstream endobj 768 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚÕѱ‚@ à’.<‚}#èF‚˜xƒ‰NÆI4:ãñ(÷72(µeqbÑÉK._þÞµ7\šŽgÓDv6¥tN§¯˜%’czp¼`a0ÚQ–`´’*FfM÷ÛãŒQ±YTKÚKËMI>×A»Šk‰üb¶2p:È[àvä ²; ¯zªUë^_mT™ÐŒœè} ä2H«¾öÜ/;è¯óÿEægÎòMCâÒàßλáR endstream endobj 769 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bSCS …C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜ÿ?ÀÀPÿÿÿ Dòÿg’ö?dýf ùÿd„’ Ì „d`D"H'ÿƒ’<ÓŠüÿÿ=ÈÙè$—«'W b8Ë£ endstream endobj 770 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚÝÍ1 ÂP à<ܲôÍ |­PZ'¡V°ƒ “ƒ8©£ƒ¢ósóZ=JàØ¡ø›ªC]téäƒÀ—?/$ö£Dhʼn¨·!8Ž´š¶löœæl—Gl§š²Ígr:žwlÓùXB¶™¬B ÖœgBÔCA®ªˆÈ¡ò•îî)š–¾JËF*Wj]!Baô“Ê´t1¸5굤qÙìªèCþK®Cáý~©ë»ÿ' ö+P~Or^ðóu endstream endobj 771 0 obj << /Length 328 /Filter /FlateDecode >> stream xÚmÑAJÄ0àW²d“LríTÆ:q»tåB\©KŠ‚‹öh=J¼AÀ…KŸÒº-„¯4ÍÿþÒåbÿ`içva÷ [®ìáÊÞêQ• <œÛrÚ¹}P›JåW¶\¨ü U^Ûç§—{•o.Nl¡ò­½.ìüFU[K$¥Ëõ£õÈ“½NÊN6É0ªƒl£Æ‹u”?6¿ c¾ fr6y4ùš4ÝØÓ|zÌd¾ÚQn&)©c}ÓLÒ("%öi=¹‹b<¢5£V‡Wa†Çì)óØâ@·DsêŽÐX†º'øà†o¼b¬ó(€Æµ×Ü좒[IJü¢¿û(ñG›¬cèb#LAÚ,Xc*iLxg溴·6=Îõ´Ó,رè%s¯™;|zÀB:NÕñ$~§HVêR}zP° endstream endobj 772 0 obj << /Length 194 /Filter /FlateDecode >> stream xڕͱ Â@ Ð!K?¡ù¯¥t*hotr'utPt¾~Z?å>Á±CiL Ö© y!—ä.›Nâ9Å4•È$Íèœà ÓLê®ÔÆéŠ ‹fOi†f-·hì†÷çÍb»¤MA‡„â#Ú‚ jfcæB¶ÃˆÁ ¥+.¹ ¸b?€Ón^Êp¤ ï@ØQ-ä^p•"­¢Í îy #ßSýÁg¬s‘þ‘×\3Àw¤ÛÐ]\YÜáæE`_ endstream endobj 773 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚ}бNÃ0€á‹ó[ñòŽ«í#•Ú[wж¾£¯Ïï7´«ûkÊÑ®é)§ìë5€Ú‚,ÝÇH‡Y˜1Fu˜EÃ1˜Û$Ì`„Ú³$ª] ½ciÕÝiÇ’˜¶MÓ6Òj T§Ä%˜0Òú©`t‰è)ßšô »µýÚ£Éî§ûì0„R7¡ ŒÇ’A¢«Ó\—þt‚‡dèC@ëf;„wÛ€75>à/G°ž% endstream endobj 774 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚÑ= Â0àJ‡Â[rß LK©¥S¡V0ƒ “ƒ8©£ƒ¢s{4Ò#tìP“ö¥qj |ä‡÷Ã[Æ‹$Dõ^†Åx àQ¢Î¾>ê‡ó 2ü€Q|£n‹->¯+ðl·ÂxŽÇýˆ¥^oÇémIiTEí¸²êud=X4ƒi;87v¶LNó7މoò™üTÏŒêd²T}Xö÷_õ§—QOË^Wþo5Q;ŽG2Ê7öOõ×Ò<êq.ÖœÔWX ØÃuRÖä endstream endobj 775 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚ½‘=NÄ@ …¥ÉÍ!¾L"±ËnC¤e‘H¢J ´$GóQr„-·­ñŒ7qF}#[ãŸ÷–«Óõ9Õ´ “†–g´XÑsƒo¨¬Sxm™§WÜtî5áZúúxÿ|Á°¹½¤Öª±Û´ (E¸TV";§‘èYäepšÒ{ðJý¥9†~P(eÔRÂé™XföìdH-Ø ÌXq*óKÏíÄ8§ãþ/÷ü§~ÖbyœoƃÑöq?´}Ý`ôƒéáÁô©ÀôºÓïëØ0fW Ø';´¬jœô÷#˜©†úcŠÍªþyÄ< ^ux‡ß³ = endstream endobj 776 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ37Ö32V0Pa3 Ss…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ@˜þ¥ÿÃè õ?ØÿÓp,ÿBóÿ‡ÐÌ@@4#P2Íðÿ„®ÿ€JÛÿ@£ÿ@hytúú?iBöÿAu?œ†ú«þª¿aá¥aá ?öÿ¨á[ÿþ°ø@‰Ÿ?P\®ž\\2oÉ™ endstream endobj 777 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ}б Â0à+Â-}½'0­Út µ‚ÄI‡‚¯ì˜¡Û¤…¦VÇÇår~>ÅS hR(Šéâ#^ô¦-Ç &ÙŽ"ŽlUÜ"“kºßgdÉfA!²”ö!”)isÞÀKT •¡oéY<py~# ³ˆ?@Iæz­S=©Z¿ˆ¿‹Ah1s–Ì!oâ9)ù–¹ÁÓʦ«:#Ç¥Ä-~·Ê endstream endobj 778 0 obj << /Length 159 /Filter /FlateDecode >> stream xÚ33Ð3°T0P0bS3Ss…C®B.S# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÁ¬CýfÅPÿLÉC(~ÅŽB1£PŒX© ª‚Å€Dý@¦!;˜úÿ7UÓ€j š ø(ÚP °ÅEq¹zrrco©· endstream endobj 779 0 obj << /Length 262 /Filter /FlateDecode >> stream xڽѱNÃ0à«2Dº%à{p<¸-“¥R$2 ÁÄ€˜€‘súh~”> stream xÚ37Ñ37V0Pas#Ss…C®B.3 ßÄI$çr9yré‡+˜Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÿ‡H|ÀÃ`¨ÿÁÀÀøÿÃÐdüŒ!íAœ b"—ËÕ“+ ¸0Õ endstream endobj 781 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ36Ó32T0P0aSs…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…h 1±\ž. ÿÿÿÿƒŒê0 uŒî'.WO®@.•õy9 endstream endobj 782 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚÝÐ;Â0 €a#†J^r|HSRS¥R$2 ÁÄ€˜€‘ss´¥GÈÈ€0±Xz–oø-{°ÆJÉÐе”OédðŠ6‹1¥|ö/X:Ô;²êŲݚî·Çu¹YA]ÑÞPz@W(fn:„·ð¯*/­X‡Ÿü첉öÅ Ö!awxõP¡x$ÌA®Ëï@àÒá?/™F endstream endobj 783 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚ}ѱNÃ0`W"Ý’GˆŸ'‚6Ý"•"‘ &ÄT¨`mòhåM"ñÙ"Ê‘³ÿƒ­ƒ¥Ï¶ìÿ|./ÎÖK—»óy”…[–î© WZ•ó<—©lì^hS“¿w«’üõ¼J¾¾qoû÷gò›ÛKWߺ‡ÂåTo3Æ2OÀ4ƒ1&ë Е&`1¶’H@ÕŒ@8-§iHd€D#` Ñ•t2*Æ= ð-¯ü|qÌâOŽéü¡h96Ž¥ŽbÔ£ˆR3· <9QXF7Ü+´chFm”vµb S„ŒÐ^¹:¿cÿÑ›ðƒ swtUÓýQ~Ö( endstream endobj 784 0 obj << /Length 138 /Filter /FlateDecode >> stream xÚ35×31V0PaScSs…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þVŠ¡þÃ0¤ØRüPŠ %BÙ£Põê?˜b„PÌŠÿ˜ªÿÝÿ8(.WO®@.‹† endstream endobj 785 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}Ò±jÃ0à·è ì{‚ʦIëBÀ¦P…vÊP:µ;´´ÒÁ~°~?‚Æ &×S !HÁßIËwWÅÙÅœ :—[U4¿¤—ß±šI_„6|<¿á²A·¦j†îV^Ñ5wôùñõŠnyM%º=–T> stream xÚeѽJÄ@ÀñYR¦É#džÀMü¸\·pž` A+ ±RK EA±ˆ¾™¾I|ƒ³Sˆgwv/'W,üfþÅn³¿ÓìQEþ4»tÐÐuw8›Ë\ùÑ/®nqÑ¢=§Ùí±Ü¢mOèáþñíâôj´Kº¨©ºÄvIÌ@ƼÚÀ˜À èøU´Á;€é=zÅ‹¬ž'|+ž|1 #G”R (¤ø¹¤2))€RT¸58BÒ )*¤¨¢BŠ ˜0Dtc„㈒ß(rþTd¾†À¿á±<\B¹…"!OÈL¬ÑmÁ%”‚Á£è!ü)ä Y‚Ùµx†n«Äº endstream endobj 787 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚµ‘1NÃ@EQ Mã#ì\Ì*Š •¥$\D‚*J(SAíÍGñ\º°2üñÈ "JË»Ïþ£ïÿÍã]>‘{™Êm”,—éƒ|DÞr!B~ôÊzó’Ó¥d‘ÓÈœ– ùþúùätöú$Pçòϊ˹‘vdW¢º3Vª-p¥uèÁµ›/ˆ «Æ—=›:Ô`Nzº¸wÏèʼn¬8røöØ,œÍVÃpÚž£¯Ý¥xèçóœðdnÿ¿&8둉ç°;æb9©•ßÞ³µ0ÔrEÓªõUXîЂyjóÖA‡^ªýŸó:œŸŸ'?—üÆ¿°ÛÈI endstream endobj 788 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚ33Õ3²P0P0b3Ss…C®B.S3 ÌI$çr9yré‡+˜šqé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ˜ú¡þA¨ÿ õ?øÿQŒÿ€( Ä Êþ2%ÿ…úO&…b ª Pk!Ž€: ì@ˆ'@Ôõ¬q%vŠËÕ“+ 0¾ª( endstream endobj 789 0 obj << /Length 317 /Filter /FlateDecode >> stream xÚµ’ÏJÃ@Æ'ô ì%/ î¼€¦©6éAX¨ÌAГñ¤=(z6>™ }‘‚/ðaé8³ÛÔéÑìæOæÛo·ÌË#âò‹ Ž'xŸ«'UŒ8:Äòx•º{TÓJe×XŒTvÎq•Uøòüú ²éå)æ*›áMŽÃ[UͨyR¢Zh‰FB ã™;$/€ör†«iÁeü.”˜ncŽkò“t{º^^8’ì¨#öa–3¾7³GÙØ ò/£xjÿ‹Ûævº¶é^ïoEÞ·v¼o¶Â6ÑjyÐ{óÆÉ„æn_Ì y²Ÿ`?ëôƒý5_ÜÃ^kéu⥠žòìà]<¯Ýp~-쉸oÉN©ö‘¿l7h×l6hD@Z„„+nL> stream xڥѽ Â0ð‡Â->Bï4bÛ­àØAÐÉAAëækù(>BG‡Ð3͇‚uP=¤òAYý‡Ú¯K]¹k̵ÚpÍ&ŽËœÛÈ…MšÊgd ŸÎoç°Úk|x–¯pÿ +‡Â@Zä/0ƒ´d73(Mº\5|¢³3¿WU =e0ƒ>¬ß endstream endobj 791 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚeϱNÃ@ à?êÉyƒÆ/iJ"•¥‘J‘È€D'ÄŒ X{÷hy”^åc¡¯êŠ™D5‡=îþÙü:þé§“ÎÇ|ñ_.þ(Ø_’ IŸ˜4B±±ÌCjÑz8½–nZ:Ð7¡6 endstream endobj 792 0 obj << /Length 152 /Filter /FlateDecode >> stream xÚ33Ó31V0Pa3cS3…C®B.SK ßÄI$çr9yré‡+˜Zré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿƒANúÃÿÌÿêi†úõ Zþ@ˆæ‡Ó5`šNW€ifœôýà˜fÄI3€i0™4?(pÓ\®ž\\wG³æ endstream endobj 793 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚíÑ1‚P Ð’.^@?'ILtr0Nêè ÑÍGã(ÑP[ˆ‰““£Cû_Û´Ë‚Á0$êûy4Šhïã CmJ9î&»#&š5…!š¹´Ñd ºœ¯4ÉrJ>š”6>y[ÌRbæ\æò €[B§øãgpq ‰¸þD¬…b¢ ¤û7 ›%é¸ÇXzÂ’¯²+pîC‘7 M=$¿©¯¬qÓ˜«ŽÀY†+|œ¼T endstream endobj 794 0 obj << /Length 271 /Filter /FlateDecode >> stream xÚ}нNÃ0ÀqG"Ý’GȽ8‰DÃÔH¥Hd@‚‰uFlU›GË£¸o©‹‡¨ÇÝÅ|4RâülK§¿\•ç%æXâYUŽ>ð³Šy{9Þ<½Â¢û€³ ì ƒmnñãýóìâî °K|,0_A³D"êMLäþá¿1 /äΘ­¢c Œô/jEË802F¦x©åZ0WðýFf ÖÇàa2+x…3‘ ô .Hbìþ‰‚[¥TS'J &f N”@MüA­àÖy@»Qpâ: œèÜ7v#"Úõû†ö.€¶ÔBMíúŠGH'‘ SÄ~ }J× ÜÃ2ÿš` endstream endobj 795 0 obj << /Length 345 /Filter /FlateDecode >> stream xÚÑÁJÃ@à 9ö’7èî hšÒÒZÁ=yOêу¢ÐC1yŸÄCÄYðrkKÆ™ÝMEÛƒ·YþÙ?[Ï'j¬&ê(UÙ\Íæê."›Òp¬f ÷rû –¥H®T6ÉERž«ç§—{‘,/NT*’•ºNÕøF”+…ˆZ"(ÐüǶ…€Wëžœ;ËÁ÷ b#yí6ì sû"¶ßÇü¾ô£s¨Ý>‰Âæ·yGA¡¢Ú9ß¹±ŽÉ!yCacp^Wƒµµ$ä–ެÛéà ¥°¹·–ƒ;ë »êBú9>׺‰vݱ Õ°µî,û˜ü¡½)”7²?­c”䝯yD¿‘·Ö¾S¨míL?h:ƒ3E©öX÷ÞCÛà›7ÞÜÈWìΛÛ9à‚i÷-ÙÚ›CyÛvø,qZŠKñ ydõ• endstream endobj 796 0 obj << /Length 297 /Filter /FlateDecode >> stream xÚ}‘1NÄ0E'rišÁ>ImVT‘–E"Tˆj¡¤A»öM¸JŽ’#„.HQ†ñxD³‘,?ÛŠ_þÏfu¶r•;çÑ\¸õÆ=ÕøŠÍš×U\ƃý n;,ï]³Æòšw±ìnÜûÛÇ3–ÛÛKWc¹sµ«±Û9O4pÀ/Å-1 6B/À†‚zhy†ü†8$aŽÑ” Ô`6£€_òA ]Š–Äá3D2³ã–†ÒÅÑ‘þ@$‡:Ž ÷HÝQðÔëë4ü‡ì›Ò7›/u˜Qùà½Êl¯l‚–sˆã ¥ñ³p¹z–ÒØ0Iiñb ”(¶$ŽXŽ8býâhCú1àC D\WEáàU‡wøßHµG endstream endobj 797 0 obj << /Length 220 /Filter /FlateDecode >> stream xÚÕÑ=ÊÂ@€á )„i¦ž§u‚;ì{¹ÛU«-2tsê{tyE—ýÑaÜ L‡” Ñ"¡x‰Ùˆ˜ù sñÀOh_ΊV!xéË eA”Ëáü©ŽYæ'ý@V4Сn.— B)€Æ´`š²˜¬QCS;¤QãiùV¾¿ñ°”ĸ¨pnp©r^!z£Íðkˆä'~Ž3œá?jz”ó endstream endobj 798 0 obj << /Length 246 /Filter /FlateDecode >> stream xÚmÐ1JÄ@Æñ/l!¼&7ˆs“°c•uSZYˆ•ZZ( ËfŽ–£ìRn1d|ßc„˜Ì üyLsu±¼t•k¸—®iÝk-²jõ\ñȇ—wY÷R>ºU+å­ÞJÙß¹¯Ïï7)×÷×®–rãžjW=K¿q>éšO0Dtð2uT'°H{œ¥ý@ǧ ž§°¥PýL‡?j¤é fG'€XÆÁ ÕŒ©À›šet%Ê þ2Ó¿LaTf ËœIe¦³LÇ™ÐY¦³ÌÎfÚÚ41?Ef‘™<2ã£f²ùU§”›^äÖ¥Ê endstream endobj 799 0 obj << /Length 199 /Filter /FlateDecode >> stream xÚuν Â0ð+„[ò¹'0­~€ÄIí›™Gé#tì =猪‹!ùAþ¹—úù€RÊÉG4Ó!Ã3vYªW}ØŸpR ßP>@¿}±¤ëåvD?YM)C?£mFé‹AhÀ0W–¹pµ•(Ô†Å&áRŽ_ïÕGW«¶RM©Êú1|šŠw5áFò—ú«ýö ]Ÿ÷æ·ñ¯¬5IW¦†º'C»§{p´Ü:ކ«ƒV†#Î \ã 8.y endstream endobj 800 0 obj << /Length 191 /Filter /FlateDecode >> stream xڵϱ Â0ÐH†Â-ýï L«–ºj3:9ˆ“::(:·ŸÖOÉ'dìP{^ŠCEœÄ<¸Ü%¹$“Q”`„c^ Ïc¸À4å¸ }âp†Ì€Úâ4µä]Pf…·ëý*[Ï1•ã.Æh&GA‚}1è”t@%’c55lË)É1•’¬(*ÉÚúzí¼Ãºgã û¶?øqÛÛ[®ë„­Da_½=@ÖMÐ é4ÕBÚ3²ò'`a`Otí„€ endstream endobj 801 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ•Î; Â@à )ÓäBænbÄ*#¸… •…X©¥…¢­Ù£å(9BÊKÆY#X[Ìó‚?›M³ŒbJ]-(Ó9Á¦¹ô±kÝâtÅR£ÚSš£ZË•ÞÐãþ¼ *·KJPUtH(>¢®> stream xÚµ= Â@FR¦É2'p³$!vÁ-­,ÄJ--­o–£è ´‹dœ±ò¯æÁ·3ì<6{AŒ†\±Æ¸+ [ˆÎDi,7P3ŒP#¾eƸßÖ ²É5¨çƒ˜->E) ït´ÿD›ŽL®Ì”Z&U¼×!˧Òm,—J¯¿–yÿ"LŸXœÞI?ðåµ]ìÀ&^-Vìæ±gÇž·Zêø¿n$ù̴ɦ†¦p h¥Á endstream endobj 803 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚ]ν Â0àS:wÉ#ä>m©Ð± ì èä Nêè (¸¥à‹õQò3ã­ þ\È'›3ʇEÁ)çrFçï2:RÞߥ}ì¶×”¬$S2{ZÏù|ºì)/&œQRñ:ãtCuňCèà:DávG|‡iÊFy”­öÐV;¡tPo¼0ðáƒÌ7ÀæÙ÷âª{äKxÕNÄ. P¡5­ô €’’ÒÒ‚¦5-éQle€ endstream endobj 804 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ3²Ô3´P0P0a S …C®B.c ßÄI$çr9yré‡+›pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä?000þÿÃÀÀþÿ?÷£¾ÁþÁÿ†ÿÿŒÿ¡óFÁð¿FØ1 bˆÿ ÓÑbõÒøÿÿÁåêÉÈŽXo5 endstream endobj 805 0 obj << /Length 264 /Filter /FlateDecode >> stream xÚ…½NÄ0 Ç]1Dòropõ @ZµU™ˆt`b81#æô x¥lŒ¼B$€Ž7œbì´Bb"Š~±ì¿?â¶?é;ª¨¡ãº§¶§æ”j|ƶoE]·„îŸp3 ½¥¶A{)~´Ã½¾¼=¢Ý\ŸSvK»šª;¶rJ“€xþâP0ów4Éð{\í .c9ØNø]ÿ”"ÿßY¹pÒ&Zm­¬m¥1¬˜÷BÏ`­XëX Ï2ÝÌ1Ï2s–Pª)£Ö—àH˜²r”Á€—L¥5ø1ýÒýáU¥—Wôš[$ÜtUòÝ’ŒáYņ'¼ðr˜Ô endstream endobj 806 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#S …C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ3Á$;˜d¦%YH2ÿÿ$ùÿÿ’ò@Aæÿ6Œÿ˜ÿW€É òÃÿÌÿ ‘ H$Ã’ÿÿÿ±ÿÿ“ärõä ä WžH endstream endobj 807 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ32Ó35V0Pa#SSK…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒØÿ0ðÿ!ùÿ("”ªÁþ3Ô#!öÿ ÌÔFÿÿÿ€#.WO®@.Nq endstream endobj 808 0 obj << /Length 173 /Filter /FlateDecode >> stream xÚÍÎ1Â0 PwõÒ#Ô(i‚ í©‰ H01 &`dÁœJ\,Gér„I+: F,=þ°*G² ŒÒ ¥rBjLyI‰gTÝ9£i>dûVņTbfI×Ë툢ZÍH¢¨i+)Û¡© ë¸íEì¿ Yßëú¿Lì!æO`ý’@7Ú[§=·Û¾9nÙ…ÝØû4?ú×#nç×ø`9yÚ endstream endobj 809 0 obj << /Length 198 /Filter /FlateDecode >> stream xڵб Â0àJ†Â-}„Þ˜TZèV¨ì èä Nêè èj}´¾¯ÐGè˜!ỗƒ:Èw÷'„dfœ¢Á‰ßiŽYŽûNf¾6\ò`w„²½Æ4=÷]Ðõ/çët¹œbºÂM‚f u…~ÑCQýÓˆº¯*ÇSÕK¦cã;[È©›èXeÙ°c£–ÅF:Ô‹’!÷ö1HÞ¿B !ù›%ލõÔ‰=Ûˆ…ec'lô’ü_Ù‚ì§0«aOP‡Œ± endstream endobj 810 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32Ó35V0Pa#3S …C®B.## ßÄI$çr9yré‡+qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ3üGBìÿ˜úÿÿq¹zrrÊWù endstream endobj 811 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚÝÍ= Â` àˆC!‹GhNà×"Ú ‚ ì èä Nêè (¸µÒÁkyo =Â7:”¾¦ÅÉÁ8„<ù! úín(žt4BMl}>pÐÓº.«ÁfÏ£˜ÍR‚›©vÙÄ39Ï;6£ùX|6‘¬|ñÖGB%%9µ "” 4Dªrr•{Ef‡V5 ÜR×’S^r_Ô,µÿ¬¥»IQiâNÉë[)%ö[ôyü/ Èû[<‰yÁo¨Rµ€ endstream endobj 812 0 obj << /Length 151 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#cs…C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ1Ô`øÿùÿ Éÿÿ”gþ$mÿ7°ÿ«’Ìÿ>0Éÿþ`þ‰l@"üÿÿýÿÿ˜$—«'W Žá‰ endstream endobj 813 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ31×37U0P0bScs…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Œÿ000ðÿÿ$ëÿÿ’ÿþ700ÿc°ÀÀþ‡Aþÿ2 \ i$Á €Êêäò?ˆl •Ä4b>Ä.dÛ!îp!îdræ~ùÿ€$Ø_\®ž\\-in« endstream endobj 814 0 obj << /Length 193 /Filter /FlateDecode >> stream xڭп‚0ðš$·ðÞ h[I;˜èä`œÔÑA£3>Â#02Î+šhÔM‡þ†ûúçK£`¨#Ô8Âc¤1ˆqgàaÌSQðˆ¶H-¨†1¨ÏAÙ9žO—=¨t1A*õA½›¡ ]‘O›Pö±’JA…äy)Iˆ¼r&õÓ~ó®ßþàÇmý—·’ªkÂ]Ÿ{77”Ôx­Ü¿f}N$¹nýCâù&L-,á‹ endstream endobj 815 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚ­Î1 ÂP à‡B–¡¹€¾>ÚÚÍ‚V°ƒ “ƒ8©£ƒ¢›ðr4½I ›ƒ#Uuù†„?ùÓ¨•PD15m›RKqF ‹kL2F”ƯÕ|…ÝÍ„’ Í@çhÊ!m7»%šî¨GMASKÑ Ë‚Àð©†\.!ƒö97„;9ûwWð…ÃÚ è*¯=išÝ§ÕSùA÷uSyïÚA­û<»‰öÔÖìÉá& NÎj(GÕMÀ¿trÿû%Žñ¢‰› endstream endobj 816 0 obj << /Length 144 /Filter /FlateDecode >> stream xÚ3¶Ô36V0P0bcsJ1ä*ä26òÁ" ‰ä\.'O.ýpc.} (—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹Ã?æ ÿÿñÿöÿDM}Ãÿ?þ`ÿ÷áÿæÿ@Ä8ÑPß$쀈` 4'þÿÿ‡Ap¹zrr8WÖ endstream endobj 817 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚ%Œ= ÂP„7¤¶ñÙ˜„‡Æ.à˜BÐÊB¬ÔÒBQ°“£y”á•[„ŒûHñÁÎÌθb2+$˜Š+ä’ó]n: 2ç/*NârN7ærZmåùx]9]ì–bîJŽV9qµ*ý> stream xÚ36×34Q0P0bc#Sc…C®B.#K ßÄI$çr9yré‡+Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ø0°<¶‡âz þÁŒ@ÌÄòÿÿ?ø„™bTÂðÆÿ ÿ7~`øøƒýÿ@Ç400ÿcàrõä äÎpR endstream endobj 819 0 obj << /Length 149 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#cs…C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ30ØøÿŸÁþ?’ý?ãÿÌ@5J2"‘Ì0’ñ?;ˆlàÿÿ¨Ìèâúÿ€¤üÿÿA*þÿçrõä äðŒ endstream endobj 820 0 obj << /Length 199 /Filter /FlateDecode >> stream xÚe̱ŠÂ@Ð7¤¼&`Þ8Éš …(¨ ›BX+ ±RK EÁBÐɧ䦜"8ÞqaZÜ÷=¸yÒÎ$‘/$ëI§+ë”wœå良þ±Úò¨`=—,gýƒ+ëb*‡ýqÃzô;–”õD©$K.&âœQÎ~8¢˜¼-x¥)؇%‰à Vd‰.hUAëmPþ[‡0ªÃ+|D0|D] ×zy‡ÊÝ^Öœ}÷b‡Uc\6úù?ù»à?#Zh endstream endobj 821 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚuαJÄ@à9R,L³opÙ'p=…póSZYˆÕ¥…¢pE ûhû(û{]Ä#ãÌZ˜F˜ácfø«Ë³«Ú朻ªÍEmö%¾aµâ¹Q»WÜthMµB{Ë[´Ýùxÿ|A»¹¿6%Ú­y*MñŒÝÖ‰\Kÿ©&Ð#d!#P¬OIÇ*¿ —M «D // R2h‚``ÝRÌ“m\®ùÕ‹ãzð=@>6m8ˆ}F}:ä1Μ¢>²Šý ,EýÍfù¹œ‘]ˆîO Î sSq0€iî ›TxÓáþ¦‹j endstream endobj 822 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚeͱjÃ@ `-~„ÓôìÆ&lpˆ‡B2e™ÚŒZš-?šó&†¾ÀA–Œé– î㤻_*³—‚2z•S¼ÑbI_9þ`QJi©ŸßØthwT”h×ÒEÛ}Ðßï鈶ټS޶¥}NÙ»–˜a÷lÌ}ì!â!xHĢ µK{Ñ0S%¦ÓYLæIŒÙ±„4¬^½vA:ÓCžõÿ5ûÏ2?¹j,TÓkØ„pÂgÙ àe3D^63ÔìŸÅU‡[¼}l* endstream endobj 823 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚeϱJÄ@€áYR¦ÉÜÎ è&^¢‡óSZYˆ•ZZ( Wœ$/%ñEò[nnœYäÚ|Å,ü3[åû%åt@{Å!•Ç4?¢ûŸ°¬dšS5ÿ}º{ÄeƒîšÊ ݹÌÑ5ôòüú€nyyJºÝ”ßb³"fo8ü7a êLìàŒ¸{؈kq€ÐàEoÄÚ›A ª I¿sLÅlL;q›‰é6‘­˜ð,ú)þˆŽ"pøkë'ëaÒö“šß “6ª«jùTº…vûMtÕ%ü¥yþÖpû®É7«±šc%^–Æ ð¬Á+üš~oì endstream endobj 824 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚMÎ? Â0Çñ_ÉPxKŽÐwÓÚ‚bÁ?`A'qRGE¡ƒÐ-Gñ;ˆñ¥.ù@^ø’W EÁ)çáŒ9ñ)£+åa–†kx8^hV‘Ùq^YÉ”Lµæûíq&3ÛÌ9#³à}Æéª—Þ{÷G«¼-m,@{L¡?˜ y㉲§C¦|Ï uäj%@ª* éy RM§œT—rR)§~ØØI;Ýó¶Ri+&¶éPÚ¦¼•õþ¡eE[ú´åfN endstream endobj 825 0 obj << /Length 188 /Filter /FlateDecode >> stream xڵб Â0€á+Â-}„Þ hšP:j3:9ˆSutPt®à‹ù(}„ŽJc¼ quù†ËûO¥óTSLŠf’”"­è(ñ‚Iæ†1ií_ª3ÅŽ’ ÅÊQ˜5Ý®÷Šb³ ‰¢¤½¤ø€¦$,D¶¨m`ŸX˜ôP?¦䯰…¨a"GËä „ÝHíè¿°Žáüú’ñ[¹%=ãΡ‹i¸ˆÛ¸’{}9ßàs \Üâ#G— endstream endobj 826 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31×37U0P0bCS…C®B.cc ßÄI$çr9yré‡+sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€ÀDübvQ$þÿG%úAüȨÿÿÿÁåêÉÈB•\ endstream endobj 827 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚmÏÏJÄ0ð¯,Ì%ÐZ%c‹ã7¢â!¿02I†ñ|ÜøÖÛz¿ü¾“éGÆ­…Vx|–í,ÍïGi®˜•f¾ö‡×ã“4Û› ßI³ó÷odÞy¸A# ÕŒJõ—&E½8]&”ÃRj ©Ð¤ šÙõKXÿ™"9ãØß°öC¯ú"‚ãƒùÊÞáN¤¶¶šàžç‚ +–o¨q‘Ô ™€ï@æF2ŠÌÏh.ÊpFmLF IÿA.g¹•OÕ¬—´ endstream endobj 828 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿbaš> stream xڕϱ Â@ à– Yú6O`[¼Ò¥T¨¼AÐÉAœÔÑAQèP°ÖGé#tt«—ªtò $áB¢ÓyšpÄ :áDó%¦;騿‘¤Ò8ߨ0XÇnl•B³åçãu¥°Ø­ØVK>Ú/'2%;ŽãµÇÀ%|ÃAtG*èA0‡¬`/ºPu°½Fô19€9¬a{ÑíDíªb#úØj3XÃä5S¯øS… imhO_o`{ endstream endobj 830 0 obj << /Length 229 /Filter /FlateDecode >> stream xڅϱNÃ@ `G"yh_éüp’([+•"5:T #Ö^í%pcó»He``ùÛ÷û\·wm# iä¶”º’¦–ç’߸jQD¹ùéœ^yݱßKղߢ̾{”÷Ïöë§{)ÙoäPÊâÈÝFnˆ(ºžŠèF Ñ©j…Àd|ÉŒL@Àä6ììmБÜT /åˆõ¤sg`À|¸®Œ¿8c†Â¨Ò’5 MñÃÙâ—”i\Qn+ ¥yrŠevœEs¬á‡Žwü Ô4„s endstream endobj 831 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÏ=NÄ0à¥Mã#x.N´ŽV[YZ‰HPQ * ¤Aíp³%G0¢ÀE”a²» ÍgûYš¿<]6\±ç“š½çÆóCMÏ´XiXqÓì~îŸhÝ’»áÅŠÜ…ÆäÚK~}y{$·¾:ãšÜ†ok®î¨Ý0`2™€R¤Ó—é†r@ìŠI…ÀærBÈG£b¶dÅþ2lRÌ“V;äxFïò!#äSòÕI§gìµk4I±Yòžñ€;ý!þGøaÜbóžÝ¸óài^aÐeb_È»î+:‚¶‡ÑÚ(4¢ó–®é–•™ endstream endobj 832 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚϱ ‚`ðáÁ{2As‰3È!¨©!šª±¡(hˆôÑzÁñĺïŒt©¡~Ãÿ8îÎûa@ ¨ç‘R0¤‡Gô=9›Îö€qŠîŠ|ÝÇè¦s:Ÿ.{tãÅ„8MhÍ3L®±â“+ÿ"dL-V¢K±x{°pprm î%@%*­!š¥ÞiÉfúÈ£ú1ƒÖºÕh¬´fG«£Ý¨ZŸFéȶ> stream xÚEÐ;N1 `G)Fr“#Œ/³£Ñj«HË"1Tˆ ()@PgŽ–£ä)S„{Aló)Çù“iw¹›iC]Œ4M4Oô2â;n÷²¸¡yþÝy~ÃÂÃm÷8ÜÈ2Ë-}~|½âp¸»¢‡#=Ž´yÂåH`xpœv ú$¸ä"¸,t¹?“”¬¥JIÏRÜsTR/´°vÌ „ –å6£#`f€ÀÁ3G&û-Û]\\ò\´Eõ«åV>R®ô­tŠUÌ?p¦²"ÅFÏ ¶ø¿Ìò¢!ÚS‚S¯`% ^/x?}Ï“… endstream endobj 834 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚmÐ1NÃ@Ðo¹°4°s°­ØŠR­‚„ $¨(U ¤A½¾ WñMØ#¸ÜšapJ‘æ³Úù·]_®;®¹å‹†Û–»–Ÿz£ÕƆ5wÝádÿJÛžª^m¨º±1Uý-¼¾Pµ½»â†ª?6\?Q¿cä Ài‚&dš r¢˜†2!Œ.ÁG?pS8’ôÈ|9‡]ó'ø?‚XP‹T)æL%—ü[2Õ/±jNl¥›þ§”>9Û’¼5þ‰FX ü”éà¢=Ø … Œ–W¨UÊUG@—˜ºîéž~Uí–Ž endstream endobj 144 0 obj << /Type /Font /Subtype /Type3 /Name /F29 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -6 -26 97 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 125 /Widths 835 0 R /Encoding 836 0 R /CharProcs 837 0 R >> endobj 835 0 obj [47.75 0 0 0 0 0 55.7 53.05 53.05 0 79.58 0 0 47.75 0 47.75 0 74.27 26.53 37.14 37.14 47.75 74.27 26.53 31.83 26.53 47.75 47.75 47.75 47.75 47.75 47.75 47.75 47.75 47.75 47.75 47.75 26.53 26.53 0 74.27 0 45.09 74.27 72.2 67.93 68.97 73.23 62.74 60.09 75.08 74.73 36.21 49.36 74.85 57.43 90.65 74.73 71.73 65.28 71.73 71.62 53.05 66.43 73.46 72.2 98.72 72.2 72.2 58.36 26.53 0 26.53 0 74.27 26.53 46.42 53.05 42.44 53.05 43.77 29.18 47.75 53.05 26.53 29.18 50.4 26.53 79.58 53.05 47.75 53.05 50.4 39.33 37.67 37.14 53.05 50.4 68.97 50.4 50.4 42.44 47.75 0 47.75 ] endobj 836 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 27/a27/a28/a29 30/.notdef 31/a31 32/.notdef 34/a34 35/.notdef 36/a36 37/.notdef 38/a38/a39/a40/a41/a42/a43/a44/a45/a46/a47/a48/a49/a50/a51/a52/a53/a54/a55/a56/a57/a58/a59 60/.notdef 61/a61 62/.notdef 63/a63/a64/a65/a66/a67/a68/a69/a70/a71/a72/a73/a74/a75/a76/a77/a78/a79/a80/a81/a82/a83/a84/a85/a86/a87/a88/a89/a90/a91 92/.notdef 93/a93 94/.notdef 95/a95/a96/a97/a98/a99/a100/a101/a102/a103/a104/a105/a106/a107/a108/a109/a110/a111/a112/a113/a114/a115/a116/a117/a118/a119/a120/a121/a122/a123 124/.notdef 125/a125] >> endobj 837 0 obj << /a21 763 0 R /a27 768 0 R /a28 767 0 R /a29 769 0 R /a31 770 0 R /a34 764 0 R /a36 765 0 R /a38 771 0 R /a39 752 0 R /a40 745 0 R /a41 746 0 R /a42 753 0 R /a43 754 0 R /a44 755 0 R /a45 762 0 R /a46 756 0 R /a47 757 0 R /a48 825 0 R /a49 826 0 R /a50 827 0 R /a51 828 0 R /a52 829 0 R /a53 830 0 R /a54 831 0 R /a55 832 0 R /a56 833 0 R /a57 834 0 R /a58 758 0 R /a59 759 0 R /a61 760 0 R /a63 772 0 R /a64 766 0 R /a65 773 0 R /a66 774 0 R /a67 775 0 R /a68 776 0 R /a69 777 0 R /a70 778 0 R /a71 779 0 R /a72 780 0 R /a73 781 0 R /a74 782 0 R /a75 783 0 R /a76 784 0 R /a77 785 0 R /a78 786 0 R /a79 787 0 R /a80 788 0 R /a81 789 0 R /a82 790 0 R /a83 791 0 R /a84 792 0 R /a85 793 0 R /a86 794 0 R /a87 795 0 R /a88 796 0 R /a89 797 0 R /a90 798 0 R /a91 747 0 R /a93 748 0 R /a95 751 0 R /a96 761 0 R /a97 799 0 R /a98 800 0 R /a99 801 0 R /a100 802 0 R /a101 803 0 R /a102 804 0 R /a103 805 0 R /a104 806 0 R /a105 807 0 R /a106 808 0 R /a107 809 0 R /a108 810 0 R /a109 811 0 R /a110 812 0 R /a111 813 0 R /a112 814 0 R /a113 815 0 R /a114 816 0 R /a115 817 0 R /a116 818 0 R /a117 819 0 R /a118 820 0 R /a119 821 0 R /a120 822 0 R /a121 823 0 R /a122 824 0 R /a123 749 0 R /a125 750 0 R >> endobj 838 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚµ‘1nÂ@E¹°4o€çÄ^Lh°D@ÂT(U’2Q¨ÍÑ8JŽ@é"Âüo³ QR¼b53»;7´Ô\ßz™³ÁÀF©}:Ý*NiSp¾øñ­“B“µeN“9+š ûýÙ}i2Y¾ÎSÛ`î]‹©‰HŒÁ¿H§ Ž"áŸHâƒH¾)Q®Á -h @XµDh Ús‚‘’`¬né`”W„\]W·äžcKù<[?ÞûèMÿ'ÿÇû¿_ïÅ=ýÎÜ?¸ø ÞQã‹Þèé“^é×»¦wúgMÌ…ù0'æÅܘsdžM®]ºÒ3è’¤6 endstream endobj 839 0 obj << /Length 247 /Filter /FlateDecode >> stream xÚµ‘½ŠÂP…o°L“Gȼ€&×à.VÀ‚[m!Vj¹ÅжÆGË£ø–!zŽ×‹‹¸¥„¯¸Ì ™9_Ïv쇦ú©íÌjÖ×~ª++¿‚WŠÏví½¶ü‘A!É·fV’ ’SÝnvkI³¡â=Ò9ÆRŒôdŒ9ƒ=ÈA|0&ªÀјÅŠA IIДWŽ1#‚æ` EGpñ`ðFå(ÉñA~zâìˆ=õk"Ò¼úÿúüŽÏ»ÿ½«¬7ãþà†ËÄgļ˜ócŽÌ“¹2_Ÿ5s/ú ú¡'ú¢7úËï>é•~e\È—\ÄE“˜ endstream endobj 840 0 obj << /Length 123 /Filter /FlateDecode >> stream xÚ340Ò36T0P0WÐ54U°4U07QH1ä*ä²0Š(XXB¥’s¹œ<¹ôÃ,̹ô=€â\úž¾ %E¥©\úNÎ †\ú. Ñ@£b¹<]@@‚lF™C˜YÿþÀYÿÿagŽ†Ù°cBò1—«'W Z(Q½ endstream endobj 841 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ33Õ37W0P0WÐ56P0µT°4PH1ä*ä25Š(Áä’s¹œ<¹ôÃL ¹ô=@\úž¾ %E¥©\úNÎ @a…h ¶X.O08&€)fT "ÇŽBñ7 PCäQ(;ÊBÕ P?P¨7 P¨NAu{§ ºA›SPÝPÅ)¨nÀ*ã”A3ôrÊ Šh¨0$@(.WO®@.”ªYÍ endstream endobj 842 0 obj << /Length 466 /Filter /FlateDecode >> stream xÚ“½NÜ@€×rai›}ï Ÿ!‡¸†•‘rT(UB™"ºv”;‰‚×°”Èv,bñd~ní-Ê]qŸÆë™oföÚÅþ‡ƒÖ.ìÒîµvuh>Úï­þ©W Kߣ¥<ùöCŸ¬usiW Ý|Á°nÖgööæîZ7'çŸl«›S{…‰¾êõ©UJ•QMŸfî`›°—PM\ÅÂ'6¡S¯&v^m¦”ÃÛŒ•Žßàâ?¸|‡ï3Þd339û‰‡r˜¹Êy;³é'·¡žÇæ3ÞdL X¿€çXÁ‹Ÿ™Gžx›qÏ)z^çã>»‘y“1÷éøŒô¶c/LJ/k'–Þ×’Þ:v0ÌâSKq ×¸Ïò‰Ùñuø!阈I§þã¤Ó‹N‡I“`±^tŠ‘ïëT# ±ŽQtdƒ…Y§ŽÈA\Tæ±w7wÓ‰h=Š3ˆIüö‰;x;ø»M\Ë ÉYs²â’»4ÒàŽyC|~Çü¯ª{ž>uƒSdîhŒCt%¨â=ÖTõJ‰F¬ã• ˜¨¤¦F¼q|è,š¡½Þá>åM¡pàHOb1¬D"% èÏk}¡ÿ;4A endstream endobj 843 0 obj << /Length 327 /Filter /FlateDecode >> stream xÚ•Ó¿j„0Àq%C ‹`ž *½B]®W¨C¡:”NmÇ-ív¨–GÉ#dt—&æ—?RiDø¨ ~ýi]_\V´¤;½×WôzGß*òIê’šMš ¯dß‘â‰Ö%)îôYRt÷ôûëçû‡Z‘â@Ÿõm^Hw ‰YmVìaܶb«Nß4RbÕXM›Î”\u®N›n•ònbÁý |ä± –mˆœbçÞ©¶‹LEæ´]$â±±7æ!3äi»ÈlŒzçÚ.2Ob'Þzº>¸Ñƒtî!ò¸´—Æ9™7Ê ×˜CîÒ.Ík&) 7L³Èʬ ¦k–üÓùì“ËõÁóÇ Á͹!¾·!×Kk¹KÛøÌ!×#°€Ü¥m<æá“ÆÌþçÎFkó(­°¿4J@?û¯ÉmGÉ/ðc ¥ endstream endobj 844 0 obj << /Length 267 /Filter /FlateDecode >> stream xÚµ“=nƒ@…Ç¢@šfà9Al%"’C$SX²+V*;eŠDI£pJ ÄzÖ°òÚîÌŠÕ·üì›y^çOÏ‘=“Jftˆñ“ˆìॽ±ÿÂEŽzKI„zÉWQç+úýùûD½X¿QŒ:£]LÑæ™óÑ@G¦j…ÌQ¨P¦˜ÚϘº§‰iz‚ÿVÈ8Jy›Ž¦<_’â­oSÈr¡ûºãJ^CoC¿âÁàK(®¥vR“ਾB,á|.ÅÝÚWK¥uÅÉ¡Ë`DuO6®KNý™‡‘¯6‘_i JGãT+É­”´ ç¤KP±„û²¡J¨ðÿ~ ßsÜà uÍyë endstream endobj 845 0 obj << /Length 338 /Filter /FlateDecode >> stream xÚÍ“?N…@ÆgC±É6½€QãÚ¸Éó™Ha¢•…±RK vF8Þä%^€’‚0Îì ‘¼Z ø-;;3|óqvrX”ºÐ§ú ÔÆhs¤ŸJõªL¡ù6Ç~çñEm*•ßiS¨üŠ^«¼ºÖïoÏ*ßÜ\èRå[}O‰TµÕ@W‚€dªR‰ˆ;Ȉ,Q–ˆG¨9ÛCi ì7rXKËä0—Aà@$ˆs;’²º:ñ>GOÔ11PV¨GG’ª à{ ré(µëÜ‘  J}1*7S(»$;SheIÙLõ>âoúCø¨^¥f­i0Ó¤ÚÙIñ™Î§ÉÌô¬ð§ Cœ4ôqú¢ŽHºèG®¹‹nJÛè°¬‰®³œcÔC +{ç7ZÛÎÛ¶>»ƒ Úà¿¢‹*E!¼Õe¥nÕ/ÙÏíã endstream endobj 846 0 obj << /Length 258 /Filter /FlateDecode >> stream xÚÕÓ1nƒ0`£ ‘ÞÂx'¨¡b€ ‰¦R"5S†ªSÛ±C¢d†£õ(9BF†ˆcWæGµR¦Z}lÀþ_ÇYÂ1§æÈSÎù#¡=e¹éÇ}·¿ñþEeEzÇYNzm®’®6|<œ>I—/Oœ^ñ«™æª‹kªo?nÁ‚>ƒíCK¹(Iç¸ÖªoïÐv^سs`'rVr\wƒ Iã‚—ý˼ÏÞ‹‘/ÞÁÈí¤íýênp=g¹ÇÍ?ôÿ;³†¸ÎØ—¹=Å  13èr…Ù‹ “E7™ÛòŒ™ÇZ€1µÓŒk kmªgjÖ.=W´¥€Ms³ endstream endobj 847 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚ•Ò= ð×t y G('«Æv3ñ#±ƒ‰NÆI4:—£õ(ÁÑIÓ¾ú¤H~…þi¿ÕE[ôLK;¶nc<`’˜ïgØìq˜¡\Š$A95½(³™8Ï;”ÃùHÄ(Çbe–Yc6º,wh*àúÀ´.9)"1RH HP+wh ¾yÅ›(¸/*±†øPè#qRDÒ¥LùSõÜ×õ¸c_ÿÿ½Ÿè擽®²éPèÒå[Ì+^« —& ÊIº ¬)J¢¢t*Jl)sŪJ¶SàN2\àîÀU\ endstream endobj 848 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚ³0Ò33S0P0bs  #…C®B.sc ßÄI$çr9yré‡+˜sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þCÁbY ìÿ?00ðÿÿe1 Xòp?œÅg1ÃYŒp‚UgÕÃYöxYò¤³À,æ üD²p²Øñ²øá,y8ËÆbüe‰,„^$óìà'Ò}ÌTaAÀf“õRX\®ž\\1=# endstream endobj 849 0 obj << /Length 349 /Filter /FlateDecode >> stream xÚÕ“±NÄ0 †]u¨”¥P¿´U‘®"‡D$˜02€`ny³ãMNâ¸ñ†ªÆIÜ»´EÀJ÷“ã8vâ?ÏŠã¢Â x”cµÀ²Àû\=©Ò83,OÜÊÝ£ZÖ*½Æ²Ré9»UZ_àËóëƒJ——§˜«t…79f·ª^!ðÒ û5D±Åˆˆ6XÖÌ;Ж©‡Æí¤uH@†cýN.|ÍŽrá.m@µÎ³Û¯F|Ž=›Mb¶š Ö´`]ƒÃœb{)Ð$èÀU2¤ئç¿ô' ÄcW˜¾|–rƬÇ,eŽ9sóýÃôOx^cf¥u=þÌzÆ.‡–{6œü‡·›òðÖS–1´Œ¸;ôAýe&oVýögÛ›ù`¦_#œˆ7ÄŸ¢)ÒNG¼¼ èöÝYmv¢M£Ù­è×Üf !ˆ&\oê¬VWê ?¦! endstream endobj 850 0 obj << /Length 123 /Filter /FlateDecode >> stream xÚ340Ò³0Q0PaKK #…C®B.KßÄ1’s¹œ<¹ôÃ,M¸ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿA Dþ!•ÍÀþÿØÿo`e Èb†á gS’7¹\=¹¹üïb endstream endobj 851 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bS #…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿA ÉÀþÿÃ(9THü±ÉåêÉÈ’:Õ° endstream endobj 852 0 obj << /Length 344 /Filter /FlateDecode >> stream xÚ•Ó±N„@à%$ÛðìÜsT$ç™Ha¢•…±:--4Zãñ(<‰…„qÙøÙòH  ùwØòlwUܘÌ\Û³8˜ÃμåúS{{ŸÍ·óƒó‡>V:}6Å^§÷vT§Õƒùþúy×éññÖä:=™—Üd¯º:šF…öÚ]jQ¯ìÛÅÁ¨V‡÷pÒÁe × ž`)v‘⨇ãv‘âºI­æH6G²9’͑줅9’Í‘ÎÁK¤³D:K¤³D:—›ñ̈ÆÕ1aÞdã’P[=ï˜xªWÿŽ5-ßõ7”´|ï´¬µ1ÜÄ´¬©¥ˆÈN®­'ñ Ú¬¹Ákèû%Eðš{Æ^K¼_„Þ=£¤éÏ ú„Ї\;ñŒæ"¤=£ÿ¹éa7±ô¶oü;®ˆu¼Sò¯Í×áRë»J?é¤[¹ endstream endobj 853 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ3·Ô30T0P0bs #…C®B.3K ßÄI$çr9yré‡+˜Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü Ä0ø!Ô(c2~f0ÂH`0ãf°c0øáŒP†<Ãƨ‡1þCŒ0;ŒÁcÔCÌÀ¤ø Ãàrõä ä6n6 endstream endobj 854 0 obj << /Length 311 /Filter /FlateDecode >> stream xÚÔ±N„0Àñ’oé#´O ”\<'HÎ3‘ÁD'㤎ÝHàÉ ÆÁÑGð‘áBýú•Iû%)ð+,ÿ¦`ÊÕÑz­ ½ÂaJ£OJ}oà Œ9Æ™ÂÙ=º{„MùµÆyÈÏqòæB¿<¿>@¾¹<Õò­¾1º¸…f«­µ£ #q·8&ÏtáÞ3ûŸxž=%Ýüæ·õT]ˆ_¶'V1ü´± òÃîˆSï>8ƒ|º‹bGýx ²¦~Ù‡©¨_‰(Jê¯fÔß2L©Šcâ–# ןî8º~w‰¢[ÙstýJptýU,Ýr´,]ÿÄû±ž#öc},»=Ö3Ö³Tëc)íÛfôÑrLi‡G’vKA;+DEï ñß1¥]þ*Y÷‡¨ÄB8kà ~oˆ§L endstream endobj 855 0 obj << /Length 316 /Filter /FlateDecode >> stream xÚuÓ1NÃ0ÆqG"yÉâ¤êÐL–J‘È€bFÌé ¸Rc@n@G†*Æï9~ýÈðäßóò,×Õâdµ4•¡i³Z˜ûZ?é†öŠVÂÝ£^·º¼6ÍR—çþV—í…yy~}ÐåúòÔԺܘ›ÚT·ºÝçÜR*ñç<‚ÝV™s[¿(;(rOηì¼wþäpô(þàXð;¸áàŽÃуØr,¸çÎ8=ŠSpÂá`ÅáÉb æðdOæ°x§`Oæp4…ÄLáh }S8:S8šÂà^ìÃb öa±ƒb§`ûØx'îÜ·Ø‚ ~›à|Æ8'`5çlÁ8ŸqNÁ X‘‹½xúƒ> ¶àœÿµ>kõ•þJÔ@ endstream endobj 856 0 obj << /Length 325 /Filter /FlateDecode >> stream xÚÍ“±NÄ0 @ÝPÉK?¡þh H×›*‡D$˜02€`¾û´~J?¡c†ª&±ãrœNldH^âØŽ{U.+,p‰'%®Î°:ÇçÞ ºð‡ú…%O¯°n ¿÷_óÜÜàÇûç äëÛK,!ßàC‰Å#44~d´32DCÄšˆZAOÔ3%ä,F•¢b= _&gŒåË2‡½·dõÀ‚FL¤dtæ½Èêˆ^c;È“ºh†MZE=°p¡8È}ÃÚ‰âèÝ´1ª˜M¸Ótøµž°=Š[’l¥ÔýiÂþÿâìéñq<”3Mu;Ëúo˜ê†Ïš0Ñï÷q¯fUËȱ„±çšà:ëØ „Æåq’ñÌ×Ä·€•ZwÑ»¾$D#ÌB·HÜIè!iÐýh²Dåß W ÜÁxkD— endstream endobj 857 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ³°Ô³0U0P0b c #…C®B.s ßÄI$çr9yré‡+˜[pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÁëÿ8ëœõ¿ÎJóƒûÿ ,fn0‹¤ªÿcÙ5CXòÿ@Y ÂbGb}ÀÂúe1ceý¡ Ÿ½ìH,ln~÷å Ÿ#BBðPŒº`pÎb€±~ÀY 0SFYä± I—«'W TÛ4# endstream endobj 858 0 obj << /Length 422 /Filter /FlateDecode >> stream xÚÍ”ÍJÄ0ÇSz(äRß ymë²n÷ba]Á=yOêу¢°±_¬Rß Þ"”ޓɇ]XéÕ¦¿mæ#“ù'Ëü`‘ËT.äþáL.g2ŸÉ»Œ?ò|Ž_S™¥Gvîö¯Jž\É|Γ3=Á“ò\>?½Üóduq"3ž¬åu&Ó^®%ÃG@ÍÌô h "AG ``Æ©Ar,=CÆ  ÈØŒú?Fmq¬zæÌ´‹ÉY€Ìš2fä`œÁb‡auDzvQˆ¡Ã~ŒåÅ@ƶˆ-pŒÂc=B[ žÄÊc»…fã¿[&ª$ø…häß:_gVÚ9] ÊWAîàú8©ßC†^{dA˜Çe‘QI#ÜX<¸0å° =v£;¿t–'±µXíÄÂß ÝÍ!¶ÐnÄà0ò7 6J9 |^ŒÖ0~ZòKþï‰õ endstream endobj 859 0 obj << /Length 290 /Filter /FlateDecode >> stream xÚµÓ±NÄ `H‡&ÿÒGèÿJk×NMÎ3±ƒ‰NÆIMÔèÜ{4¥ÀØá"R ÜßÈ%)ù ~ø¡Ùœo®°ÀK<+±©±¾À×>¡©Lcuåz^ÞaÛxĦqkšAtwøýõób{%ˆ>•X> stream xÚ}ѱJÄ@à?¤l“v_@“pÞ] !pž` A+ ±RK E;!÷hñMÎ7H¹à’qfwO ¦ù`vv23»œ•µ)ÍÒVf±0õÌÜWêIÍ%Xšú8œÜ=ªU«Šk3¯UqÎaU´æåùõA«ËSS©bmn*SÞªvm€| 82"‡7@бï, }8$´þtHIR2>JØÜJ =°MT;4[6ÿ±ùR׳éÄÄ~“û íD©Ï}~k£.:Âíì£6ʃH«¬Ï±¥DÎJ†wðkñ©8ÊÌ1ÁÛ‡=Iszÿ‚‰6üÑWÎBðJIľ7ìl¢:šÇa²hJ½Ý7ùCÞ¦ûßÍ8‘ÂýðˆþÝÆðâÞ5,φýkV›Ôqœ<ò Òöè÷Ã/™„µXY×dã|…ËvRJµêJ}áI± endstream endobj 861 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ³4Ô31W0P0b 3 C…C®B. rAɹ\Nž\úá \ú@Q.}O_…’¢ÒT.}§g ßE!ÚPÁ –ËÓEÁþ?ü!žu€¡þ?3õ‡Äb°ÿSÿÂâÿWÿÂbÿWÂbþWßa1þ«g€°Xu0V6V ŒeG,ëŒeÿÆ’'Åc1Œ²†%‹’œÍârõä äãCì< endstream endobj 862 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚ퓱 Â@ †S:Y|„æô]ª‚ÄIÝÄöÑú(>BGñLÓZD''—|ü¹ÿr7œÑ¦©;¤©M CA‡º>­ î0ðYÔÔmÕÃ՜՘eTÑ„ûãU8A5¤…!½ÄhH–ãàpɾe¨Û ä§P±þóï¸Vrÿ…{ÂÙŸy¹%ŸÞرWáÛ K¶¹Žp,ìŠ+¾ç¹&ûÂuaÏJNE±IÞM ºœ4y0犉%®Þ­àØ^žÃù ŽâAlæH 4È—¬6eOæ†E8Ã`ò| endstream endobj 863 0 obj << /Length 347 /Filter /FlateDecode >> stream xÚ•Ò±JÄ0Àñ YúÉ h¯w v¹Ày‚ÄIÝŽkÁÁ×êæx¯Ð7ðÆ ‡Ÿù¾/ׄë¡Hû#MHYO =ÖS}TèòDŸNôC!Ÿe9q‹c}:å/÷Or^ÉüF—™_¸e™W—úõåíQæó«3]È|¡oÝAw²Zhpà !j€Í- ´GÝ ¡ #gM°rÎÜ>²6n¦Þ3²xåf[ò22>GÞ–üÑ_Þt2À¾r º NɆݲñ•‘»aw{VdS"Ø9ræm÷¼"sØ22Çq˜ æDŽä,‹xc'²SoŒäDŽÌ¼1’³8,¶òÆ0NdoŒœõ¶> c¬Ïâ°Ø[o ³Á»DŒÜeaXì¤w ï]ðGoŸm𺷂uüzg|UNùj ¼»–¿yö l»îþ¶i[5ËóJ^Ë÷ûø· endstream endobj 864 0 obj << /Length 459 /Filter /FlateDecode >> stream xÚ­Ó±nÛ0Æq pá#/8ŠÀ“$)PÚ©CÑ©íØ¡E³ ²ß,z=GPħ£íZ™êáðáçNþëõÝõæÎݸ[wU»zýÆmnÝ·ZÿÔõº¾q›u~ïë}¿Ó«OðCµ^½׫Ý{÷û×Ów½ºÿðà@Ýgø¥/z÷è"¼‚ØÃEwø lì…€;ÀiŸ€åi24> stream xÚ•“?N…@‡!$Ûp„Ýȃ—©6y>)L´²0Vji¡Ñ¸Wâ&¾#PR×ÙÙag šGÂðñoù2¿¡i.ö•Ù™=ìÍ¥¹ªÍk¥>TSÃùΟú/ïêЪòÑ4µ*oáª*Û;óõùý¦ÊÃýµ©Ty4O°Ì³jÆ:Ø’Ê’œËIæþ_OXÔ¤ó%œ87@]{7ÂÝ™9 lýÙ„¬ós1"žÕsÿu=0[Ä >$˜R@!R@‰le dR@ R@ -y  R@‰n‹SìY”˜7¹wSdì Klr!ÞÍÅú’CL¢+œ…˜Vy–(ë_–Ð?,a…P'$:!±0§3K@Q‚ˆ Aô«»¢=“»bEW:Ñ É wÅÏÂ*‘Ižâð†q$ œbœÂY bšã_P&‰…£ ã¸p1üÕ|ÎM粺iÕƒúà -Ì endstream endobj 866 0 obj << /Length 285 /Filter /FlateDecode >> stream xÚíÓ±NÃ0€a£ ‘nÉ#ÔO€›R iõ\/ÂfOõÙB?´ð vÎçñ4ÞØ<Áªs«íÌe¸ ¦»Ò¯/o`V×纳Öwa™{èÖÕR³pø©Ãn¯âpáЈ¯TMS¤]ôar%va;B,½‹~;1­°E_¸Sé)Ž\ ´0…ãíº§rC pPòArRSlœÌA”#Ac²Ÿã8‡ƒ²Éá8Îá ìQr8Žs8(%‡ß–äPPa?&oñcŸìð³ð×<+Ü ö…}r]¸’Ï‘ßPš†|Öÿ¹›ø¿õ¿0\tpß4­ endstream endobj 867 0 obj << /Length 322 /Filter /FlateDecode >> stream xÚÒMJÃ@Àñ²Ì&G˜9ITbݨÌBЕ‹âJ]ºPtw´¥GÈ2‹Ðñ} Å‚Ð@É/M;^2«úìâ:ÔáŠ?—auÞ÷éÚ–®k¾ä¯nÝ»ê9´­«îé[WõáûëçÝUëÇÛиj¶M¨_\¿ >ê'!‹|œ°'Œ¹Š¸€ß fð ¡dÐoéþ~ìÀï¡£Ã@k:$D§ ´jš2,Š"Sp#˜>S†QÁM98eÐs– )H)H)H)H)H)H)H)ø'…SÙ!µ?J‡Ô|”â' ÅhM†¤¨ˆM ¸PŽ–"hªDKÊM x*6ž`Tèxô’t*ŒY‚MQŸdQ›yDM IñÓ]‚š¢¦rZLRÁöãipw½{r¿q%˜ endstream endobj 868 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚ…¿J1‡gÙ"0M!óº·`D«Ày‚[ZYˆ•ZZ(Úºy´}”<•aÇ™¹ãôP1|ðå—?üâéáIO :¢ƒžâ1ÅH=>cT¹Pc;÷O¸°»¡Øcw!»á’^_Þ±[^‘ØÝÊ™;Và8ƒŒ‘?dm˜gPÇj·\R…q :“dÄ„*Á |…Vbn¶;ƒg³Eó çd˜ö1Öo( Ø÷aãhDBÿcü³!ýD[Áo˜¬1¿En¥ ¹±¦ä%iêÝînª6N:ó\ÒZÛ` æ]H›_ÙI<ð?yë­œ endstream endobj 869 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚíѱ‚@ à& &]xúÞÜHLtr0Nêè ÑUy´{ጃ „zwÀ¡Í×6ÿÔd4”’™JBG´ñ„qlfiG{Ø1+P¬)ŽQÌÍE± Ëùz@‘-§¢Èi’Üb‘¤‚˜µ©ÒÁc®|æÚ!P÷Æái à±®!`{èø.ÿT¼ÊV6ß¡ýAÓõ_°yÍÀ4Õ8+p…o âøš endstream endobj 870 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚµ‘±‚0†kHná¼Ђ±0’ &2˜èä`œÔÑA£3<šÂ#02Î^KL%!_sý{½þ¬æI‚!.qa¼@¥ðÁCT±Ý9ß +@P% 7º ²Øâóñº‚Ìv+Œ@æxŒ0> stream xÚ]Ð1NÃ@Ð¥°4¾;ÛŠBƒ¥$\ ‘ŠQ%Ú¬æ£ì\¦°v˜Y)¢yÒî·çÝT—ëk.¹æ‹Šë57 ¿UôIõJ/Kn®æäõƒ6O\¯¨¸×k*ºþþúy§bóxË[~®¸|¡nËXÊp8™ÎÙë…HDÑFä#ò°Ô々Ú~Àþ¨¨7ö'ÉQÈ”´^;LKZ+45qj@.dêtÜÇv“ù!¤¸Ç"iíÐÄÌôehÖ”ôÁjÛ]ˆÿdVçµ³½ÍSuž‡è ±ýõ?h©›ÓêgåcfKxýºëhG¿Á•¡Z endstream endobj 872 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ35Ô34S0P0RÐ5T01Q07SH1ä*ä21 (˜›Cd’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.O†ÀOþÁN2bÌH$;É&åÁ¤=˜¬“ÿA$3˜äÿÿÿÿ?†ÿ8H¨úANò7PJÊÃç‚”ÿÇ`$ÿƒHþÿ ÀØ`ÿð(Èþßÿ ýß E` q¹zrr:é“p endstream endobj 873 0 obj << /Length 229 /Filter /FlateDecode >> stream xÚÍ’1 Â@EG,„i<‚sÝl±F«@T0… •…X©¥…¢ur4â,-‚ëw3)–.düfÉÿ3tƒ8–Hœô­ ­Ä#Ù[>±s#‰ÇUewä4c³çØÌ!³Ér9_lÒåD,›©l¬D[ΦBÔöá$þ‰»å½:À¨ë[þŽRI9Šùƒz%”î 7t„ø | t}º½€GIÀ³¦ã%EPþðú_üþ+µM_*|u°69X~o ©hFš˜æW§©ÙjÒš»nîDµ!<ËxÅo†s endstream endobj 874 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ33Õ37W0P04¦æ æ )†\…\&f  ,“œËåäÉ¥®`bÆ¥ïæÒ÷ôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQ```c;0ùD0ƒI~0Y"ÙÿIæÿ ò?&ù¤æDå(I²ôÿÿà"¹\=¹¹VI¢” endstream endobj 875 0 obj << /Length 301 /Filter /FlateDecode >> stream xÚ}ÑMJÅ0à)Y²é’Ø–G_]x>Á.]¹WêÒ…¢ëôh=JŽe¥ãüˆ? Ú¯if¦“tߟ ChÞ¯6 §á±s/®ßÑ\¦¼ððì£knC¿sÍ%½uÍxÞ^ߟ\s¸>kŽá® í½Ào@£B,D¸'€DdZš"-š,-ÚB/6¨3"x‰š¢äç”™œ®—ÓÊ®k‰í ƒËpÞ7q|Ì$pãFúæš¿È »ùdíL™@ÚAvüZ´H¥ÙFÓ¬¦YM«5Þk|,ZdÖìI³eb4Ðj`Môä³g!@Tt¶«`[ÈBÍ».àA8ã²EþõËwÌ•b«ÔŠW¢’üÉü'îbt7î}tû” endstream endobj 876 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚ‘½N„@LJlA² À¼€ÅgErž‰&ZY+µ´ÐhÍ=Ú> @IA烋 á·ì|ýgf.ëK xQá®Âz¯•ÿð!ðe‰õ•Y^Þý¡õÅ#†à‹[¾öE{‡_Ÿßo¾8Ü_cå‹#>UX>ûöˆ)Eà§£‰¿ŽˆN£ÈGG#›"ˆqhfHøÔ8¾ÏéäfEÊAEIÅÈ=¿ÿ„Å-ˆÎ’%$©#쵂H\ÀÕWèfä¹  Íhg™…™cgݺi†¹8iZþG«`©s+´¤É,25×ô\iÜ`2[Ì[¸¨ÈE3)Dä/ˆþbZÁ1.8Gƒ ƒ•I¬³éUuužR¯áÍ:îXÔ&¼oÝ´í]Ö¯"MºÎÝß´þÁÿéýëo endstream endobj 877 0 obj << /Length 225 /Filter /FlateDecode >> stream xڽнjÃ0ð ‚[ôº'ˆìPÛt±!têP2µ;´4›qüh~?‚G‚$ÎýÅC»õ@ú¡Bw—&ó,㈮+]pöÈo1}R2æ¢ñ8^¼~в$ÿÌIF~{Í’/wüýu|'¿Ü¯8&¿æ—˜£•kžnûLMÔÐ@;ÑÁž&žEõD-twñ>‡5 pU/jh:ØŠ¶,PW+D5À^Ôh ma#:ôYÀVpÔ=ìDÓŠºb~9¬a€g‰æ/ÌÿŸuøÿwiSÒ]]Óq endstream endobj 878 0 obj << /Length 285 /Filter /FlateDecode >> stream xڭѽJÄ@ðY l“Gȼ€&áH¢ ç ¦´²+µ´P´N-²°`“b¹u>r‡"X?²ÙLæ¿Ó6']‡¶x\c[awŠOµ}µÍšéñLß<¾ØMoË;lÖ¶¼¢e[ö×øþöñlËÍÍÖ¶Üâ}Õƒí·hF8ˆs0;àÛ¤Ž¡+*³¯Lʨ€•Yñ ‘ iþŸŒk›àäï!%Nó¹4tíaà(.JÚ‚bÒî> stream xÚ’=NÄ0…'ÚÂ’›!sHRd ‘–E"Tˆ ()@ Qa-GÙ#¤Lyxcó´‘•Oòóx~ž×ÍaÛrÅ Ô¼®¹=âûÚ>Ù¦ÁfÅíqRîí¦·å57-ϱmËþ‚_ž_l¹¹<åÚ–[¾©¹ºµý–‰ÈÒOdÀ%2…È ¸9SQväTòÔy2ÙSÁ Tà» 2NXFvY òŒø_ȹèíC!š‹"Þˆº%R­î/ºQ‘‰(Œ¶"!×V$ÞMÀ x#$“0"»W ­ ÎˆPrÂ(¨ì$Ó7´Ày?â Âîßèö"^Ò\æ%òˆI‘Éd¾«^EÀ€AíÈRɯiP7ë@tÊê4F¦¾Ã}œÒ·  CÔGƒÉžõöÊ~†\ö endstream endobj 880 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­Ò±jÃ0`™[ü¾he…ÚÎTAš@=š)Cé”dÌÐnÁò£ùQü5˜8²þ@mp CoÐ'¸ÓJ“§,ã˜3~Tœ>óLñVÑ’Ô%cžMq³ÙÓ<'¹æ$%ùæÒ$ówþ>þìHÎ?^Y‘\ð§âø‹òGÂGT‚ ´%ð1Šîs °à< (G˜®Ï‹(ºnhÄÉõ<œA홀°OîÐÂS€ÆiüX+ÒÃé"¬]ö1¨Õö n\PrÀ䚇cDôÆÞ§ý+Á"ZlÎ`eºúý1´ÌiEWÂÁL endstream endobj 881 0 obj << /Length 339 /Filter /FlateDecode >> stream xÚU‘1NÄ0E'JÉMŽ`_²)²ÊÒ²H¤@‚ŠQ-” ¨£…›øéHayøcARäIñÿù?ûî¼ïÍÎtæ¬5ûÖôæ¹UoªëðqgúË|rzU‡A5¦ëTsƒÏªnÍÇûç‹jwW¦UÍÑ<¶f÷¤†£!*y"<–Þ3Dà‰ê@¼àȓơ©ŠD,#DQÄc!C<– S 1¹©úŸ`}½EØ fðŠQæjÙÀM5ÏA°˜øcÁ²¦Ç.%ó‚Í€€ %‚Æ ç œ9æd’QÿÅœrè™’t‘pI#xÙï$u_"E`—-5KˆfXÊz‘ qv, /&Áy¹6:)z…‹©veÒuFµA¹EøÅ”àVxXVˆ;Õ³]äß‘^KFƒùa9 ÔjcªG²ëÜY•ëAEJ˜¨ëAÝ«D© endstream endobj 882 0 obj << /Length 312 /Filter /FlateDecode >> stream xÚ’±JÄ@E_H10Íüy? ÙÙ(uSZY,Vji¡hý´|J>!eŠa®ïÍàÅsàN2sß½Y×'MÃ+®ù¸âuÅÍ)?VöÅÖµˆ+nÎÒÎóÝt¶¼ãº¶å•ȶì®ùíõýÉ–›› ®l¹å]Å«{Ûm™È`Oòô˜eÍ€@ªAÕ"dek¦v"ÂDÅLª8O92!~l@Ncï@ŠzÐÐ.1öaiÂŒßáÿðBÿÚ v?Qàƒàt>—p„ C 4‚s9¿ŸH]¶>Ÿ0BÁ/@ IL}~¦-&¾ÃÇ\²^+—™˜îèävq°€ÑÈpÚƒ Ä:ŠTNëµ&­ÐøXaž*ÌE——3ìµq}µˆNd”!ýÑ«ÌId/;{k?žnf endstream endobj 142 0 obj << /Type /Font /Subtype /Type3 /Name /F28 /FontMatrix [0.00836 0 0 0.00836 0 0] /FontBBox [ 2 -31 134 90 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 38 /LastChar 116 /Widths 883 0 R /Encoding 884 0 R /CharProcs 885 0 R >> endobj 883 0 obj [102.31 0 51.16 51.16 0 102.31 0 0 0 65.77 65.77 65.77 65.77 65.77 65.77 65.77 65.77 65.77 65.77 65.77 0 0 0 0 0 0 0 99.31 93.5 95.01 100.81 86.31 82.66 103.39 102.84 48.44 0 102.96 79.01 124.77 102.84 98.78 89.85 98.78 97.76 73.08 91.47 101.07 99.31 135.85 99.31 99.31 80.39 0 0 0 0 0 0 0 0 0 0 59.81 0 0 0 0 0 0 0 0 73.08 65.77 0 0 0 51.89 51.16 ] endobj 884 0 obj << /Type /Encoding /Differences [38/a38 39/.notdef 40/a40/a41 42/.notdef 43/a43 44/.notdef 47/a47/a48/a49/a50/a51/a52/a53/a54/a55/a56/a57 58/.notdef 65/a65/a66/a67/a68/a69/a70/a71/a72/a73 74/.notdef 75/a75/a76/a77/a78/a79/a80/a81/a82/a83/a84/a85/a86/a87/a88/a89/a90 91/.notdef 101/a101 102/.notdef 110/a110/a111 112/.notdef 115/a115/a116] >> endobj 885 0 obj << /a38 842 0 R /a40 838 0 R /a41 839 0 R /a43 840 0 R /a47 841 0 R /a48 873 0 R /a49 874 0 R /a50 875 0 R /a51 876 0 R /a52 877 0 R /a53 878 0 R /a54 879 0 R /a55 880 0 R /a56 881 0 R /a57 882 0 R /a65 843 0 R /a66 844 0 R /a67 845 0 R /a68 846 0 R /a69 847 0 R /a70 848 0 R /a71 849 0 R /a72 850 0 R /a73 851 0 R /a75 852 0 R /a76 853 0 R /a77 854 0 R /a78 855 0 R /a79 856 0 R /a80 857 0 R /a81 858 0 R /a82 859 0 R /a83 860 0 R /a84 861 0 R /a85 862 0 R /a86 863 0 R /a87 864 0 R /a88 865 0 R /a89 866 0 R /a90 867 0 R /a101 868 0 R /a110 869 0 R /a111 870 0 R /a115 871 0 R /a116 872 0 R >> endobj 886 0 obj << /Length 195 /Filter /FlateDecode >> stream xÚÏ¿ ‚PðÂY\›ô¼@Ý?‚HƒäÔÔMÕT88øh=JàØÐÐ/Ñðîý¾{áóõXOH’R4Ò’üM…Ô_K u›íO§(6¤ P¤Kº]ïGñjF EB[Er‡iBð0»pøè²ˆe¬äè `U±QñŒZÞT_M½}b>cNÑñ 3íÉ¿x7ßÿRþÁìg=‘Á5Tsm¨§[E½©Ú•3 Ùç)®ñz BÙ endstream endobj 887 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚб Â0à”‚…[|½Ð$'” Ò¡V0ƒ “ƒ8©£ ¢ÐÁ¡ÖGé#ttôÄS¾!w—F4¤1*Ô8 …”`L¸×pйª0!ÛÚ!3 ×H1È9×Aš^/·Èl9E 2ÇFµ“£è!"–B«ùа+XÂ&¬çéz¢òKõþ!ú¡ë”m}Ñ–zř‚æ/¬½ÕîI-µq ïš÷ÆÜÈë·¸%`f`Oo?b endstream endobj 888 0 obj << /Length 154 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P°PÐ5S03Q0±PH1ä*ä25 (˜š@d’s¹œ<¹ôÃLM¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Œ 3”b H±C(6„â!LÉ@( \Ô0ø¥€9|T„J L=€PRŒ°„±áÈåêÉÈ;.Q endstream endobj 889 0 obj << /Length 153 /Filter /FlateDecode >> stream xÚ31Ô35R0P0RÐ52T01W03RH1ä*ä21Š(XC¥’s¹œ<¹ôÃLL¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. `€D€É0ùLŒ`’¹L‚…ÙÁ$˜ä“<`RLJ€I b fl l<Í &ÆÝ43˜~! %¹\=¹¹ -y endstream endobj 890 0 obj << /Length 324 /Filter /FlateDecode >> stream xÚ]ÑOKÃ0ð7V²^= š/ Ý†«=˜ìa '"êQ¨¢àAh>Zü&ù/=ÌÆ'Øa…ò£IóöyßVg§«ZÎåJž,eu.«¹|^ˆ7Q-°8—Õ2î<½Šu#Ê;Y-DyeQ6[ùñþù"ÊõÍ¥ÄêFÞã̃h6’ˆ Š—3n£™±Á\? Š^ø}àîÀa¯M†úl`I®£E'Éir–¬“m2–c† 7s:HŽ¢#Zq!1Üþ™ú$Ž2èpÿdÄÖú$3¥É'¨¡OÐÂc±…!$á¶~J¹õår Q®ÐYïË*Êz_VuÄwÓðu¶›EÇ:¦¿¢®vA 24Ù뻲=B=êzë4ý¤ ÿÑ_a•vÜRîFRø££Èý:Æ ®q+þ(‚ endstream endobj 891 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÐÁjÂ@à ƒ4׊ÁSµ`B{êAA{,ØÒž“GË£ôrô ngvÜ]vù˜]Øaþb:™Î•QOt ·O9~ᬠڕüpüÄe‰ú]Í ÔºE]nÕÏ÷ïêåëJå¨×j—+³Çr­€Ö€Ç(àYXU€õ‰zj&®|’€aOÃd pèùcš1uÔŽ¸Æ-1H[7c(< ¤bÆgá Xk;®>É÷èN`$ŸŽ³„Ö:¢‹ -åomc)¾ŠZ¶ç†/%¾á?OFi° endstream endobj 892 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚ}бNÃ@ `W"yé#ÄOÀ% í©‰ Htb@LÀÈ@ÕÎÍ£åQînìåøí‹ e@Ê铳å³_^-¯¥’¿+ï5±÷ˆ+ õÇÛ'¯[vÏâ=»dÙµ²ß>Ø­Ÿî¤f·‘—ZªWn7BÇ”R$c̤Ž(õÔ„•Ñ(NHN͇ÌxÎì‡ÙÄø—ù%ƒ•ƒõCke2Mo胵ŭB/ç©•ð›Äpè·8Yi¹RN„L4pʉ`Eÿ¡ËÀMôÓ¢s‚Ñd޽~Fgû:5ЗêTúŒŽšHºi¬Ù só}Ë[þL[œæ endstream endobj 893 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚÐÁJÃ@àYh`Í ”f^@“[ …ZÁ zò ‚ …* =É£åQò9î!tÝ™¤‡âAO;»³Ìü¶8-Î)£‚NÎhaÉô’›wcm(f´È‡›ç7³*MzOÖšô&”MZnèóãëÕ¤«Û+ ç5=ä”=šrM¢“@åë) ¼oç\SÝ%´Ø}‡«³ØqÝKK䄸´ã‡PËFïF왎»m4â„øˆ¤cž´ÂRÀ1Uó'~¤þú@õ›h`"[bzÄ ÉOv˜ÙJ:Y³åœ ¨°»®‡8!áÎy¥»@ì4÷h? î%<$ü¹.ÍùD‰pj endstream endobj 894 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚѽnƒ0àC"ÝÂ#pOƒ(TLH ‘ÂP©:D™ÚŒZ53<Â#02 ßÙ$i¤(Aœ>l#ÝÓxñSHiLÉ+}GøƒIfÖ!/ùàë€ËÕ'%ªÙEU¾Ñßïqjù¾¢UAۈ–A¥µîÄÑ©kó¡~ÍF AkóæpÖ³Þ`…Ñ9EåÌkð&Çkkpk ³Éá9ç“\SþX¿·ù}iúžõÙÀõ,3ÐðO®ùZ®)g{I!9ÅÎê·VÓ®ÈQ5’Fb´)e¬<îþR‚gJàëàÛ‘)›gpò-áºÄ<[?—Ò endstream endobj 895 0 obj << /Length 230 /Filter /FlateDecode >> stream xÚmпJÄ@ð „´bæ ÜD؈ œ'˜B8+ µT´5y´> stream xڅн Â@ àÁB]ó^«=ì þ€ÄI¡}´>ŠàØ¡´&ZÚŠã#¹§N—,êñÑ.é>íl<¢v8·$•‹íGªiÕŒ«¨¼9O—=ªÑbL6ª ­m²6èMü”#Îi ÆÀx7.2>´Ê12¦VFS¨0•ªBÌ@‘ú3–ù`F²[ˆ…×cs4"#p}ãþ¢ýK¸—_†á_üŒà'Fújá¾À©‡K|ÒÐqj endstream endobj 897 0 obj << /Length 270 /Filter /FlateDecode >> stream xÚ…Ð?JÄPð/¤ b.°ìÎ4‰°‚XW0Å‚Vb¥–ŠÂ²ÉÑr”=BÊ!Ï™I\ˆ ¾æG&óþÌ—¥§IÆ1/ù䌳”Ós~NèR-Æœ%ß§WZÝsšQt#eŠŠ ¼¾P´º½bù^óCÂñ#kôð…ÜUà9·µæµs`Ñàâ(+Ìw€z;#h¿GØÈž‹½œÐ!¯ éW¤øñze«»e0Òá¹TV<%× ä‘Êú_ÜHõ'Ëèo@Ûííeõ7®²)Àˆ%pÀb9 czCr™&!j.Ç; w¶³‘¶uØùÍLÚœ«ô$ – ]tGßPÄ< endstream endobj 898 0 obj << /Length 217 /Filter /FlateDecode >> stream xڅѱ Â@ à YúÍx­ÒªSA+ØAÐÉAœÔÑAѹúf}ÁÑAŒI…C¹á~¾ä²Ü%ïvºJ¨''RÖ§mŠÌ3©-õb³ÇQ…vIy†v*]´ÕŒNÇóíh>¦mI«”’5V%AÍÜ0óåpFµ„6¦;˜—Â8HO?BEà >üˆ¡ƒDtWÈ£ød&VDñÍB;Hµ¢ph>?ìÃg_;ù# tXžymWú Ã,?‹“ øgÔ¬! endstream endobj 899 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0bc Ss…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿÿ!êAC=3Ø€õ`¢ñL0`'ÁÄ?3˜øƒƒ`?pü`âBL<ÀAØ£úA€=ÿÿÿñDp¹zrr¾aZ¡ endstream endobj 900 0 obj << /Length 274 /Filter /FlateDecode >> stream xÚ]ѽJÄ@à [¦0/p}“ — XÎL!he!Vj)Ä¿:y´õMâ\g„uf3›ãR óM–ag3ùùéºÐ©>£Ø¤z½ÑϾažSíJ>xzÅm…ɽÎsL®é+&Õþ|ÿzÁd{{©3Lvú!Óé#V; µ8í@Ê*bãAøxå@QxÔ@AÈ9 œ8ŒÒÍ(> stream xڅн Â0Àñ ‚…Côï LC[T?À ‚N⤎Š‚›>šÒGèØAŒEl ù‘Ëø'ªÙ¡"ÞIDI‹Ö wÛYh¯öaµÅ¾F9§¸ƒrÌS”zB‡ýqƒ²?B9¤…¢p‰zHp6&øÌÕžp¾|b¿-j8 endstream endobj 902 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚmÑ¿KÃ@ðxT³r¹X4íT¨Ì èä B :Š?Ð9'þ[·uô_ˆ®f’Áó½k›Úá¾|ÞÝÁ»Éá^¼/•ìÓôåA"¯c|ÀdHµâ’¦·8N1ºÉ£šÅ(=•OÏ7ÏŽdŒÑD^ÆR]a:‘[ Âþ’LK> "@ÎÚª(î ŠÖw­wVÞÒ¬¤˜nÐŒä5z+WñJ¥ð×ÕiÄ µì:yNÅR½ RN@WP!Ége¬Ë„¦­<½.#Òv­.©#ÍéFÝZ½ÊI»åÔ[Ê6È,,iÁ‡vR|Ÿ¶­¯•üŸZx¬ûZøsà!‰¥J¥“G*œh;‰¿ÜÚBamÅòi'> stream xÚeÑAK„@Àñ' Èk‡Àù©Úv¶ ò°P§KTÇ`‹:;}³‰û ó òèÁvzÏ]Å=èüFaü;“ON&S™ÈSºòs™ÉÇ_0Ïhžð”_<<ã¬ÄøVæÆWôãr!ß^ߟ0ž]_Èã¹\¦2¹Ãr.¡²„µjÀÊ5ƒn¡rh„߯á‡à3¾Û1¾ÖÒè}Z‡ÂCÑG¨tc‚P…ÙG¢zŒ°é1Ž Ú>#é ÖcxÖ,¬ ‹³ŠA•ºwÐÅÆ!2´EÕ *kíÐ8;´âAqÂ2¨À³jØGÅXmÁ Á'ñÎmA?N¼i¿ƒÞ/K¼Á¨‡xƒ endstream endobj 904 0 obj << /Length 262 /Filter /FlateDecode >> stream xÚ…‘1NÅ0 †]e¨ä%Gˆ/m©xS¤ÇC¢L ˆ ßð¬´GëQz„ŒªÛdè"Jò)ËþÓ^žû+ªiGgÔzò;zmð„Þ³XSÛüܼqßaõHÞcuË2VÝ}¼¾aµ¿¿&>è©¡ú»€]@ƺ¼›ÙN¢ff¹üÒYÌ*˜à('‰’ ü‚Q‚ BФùŠ Id“!Ù‹¥T$·pÓa“¨èÿ‡6U.ÃοÀÅ~‹I2FE?h+(¸QÊ©š[/¹UöB–€éÃÄ oÄ\öLrƒD’Š5éßÑð¦ÃüÖ¼ˆ„ endstream endobj 905 0 obj << /Length 207 /Filter /FlateDecode >> stream xڅϱ‚0à# $·ðÜX0)ÆÉD1‘ÁD'㤎áÑxÑP¯GIt0 Í—»¶×¿:è„bšòÒsÒ3º$xGrÛÒnœo¸ÌQH§¨6ÜE•oéùx]Q-w+JPetä1'Ì3‚ÂÓ€Ðõ˜ÀTPÔ\–6Bðæf ~ËxŽî3à9º:ð^vì@+ð{B#pˆ€‰*ɱpqä”íý‚>{È{ wƈõ( G5Já(ÿâ9Ò‡ýÂ6qã?¾}O endstream endobj 906 0 obj << /Length 318 /Filter /FlateDecode >> stream xÚ…ÑÁJÄ0Ð)AÈÉh[0ëî©°®`‚{ò BA= *z5ý3û)ù„€—JãÌ´ Š¥í+“iÚ™Yž¸µ-ìÆ—+»rÖmìC©^”s-ì™›—îŸÔ¶VùuNå—Wy}eß^ßU¾½>·¥Êwö¶´Åªwôt¤Ôâ]ô:P¬=RÐâŸÙÀL ÓL”>n!#x`ï—´‘ÄI£&²QGÆ, L8s‰ïþ…‹’Ãßèþ7¢'ÌL`ª™n¢¥bÁ·}ÈcX±š*6áè+Öa}€”¡ØŸ6IôÀ~eÈ'¾:4‚:ä2ò`æ¤D@õÕe\ÏL<« ™¨§É£HéY ý4ñÈøÀàLÕE­öêoâ© endstream endobj 907 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚнNÃ0`G,Ý@¡÷à8UÚ2E*E"L ¨tìPsüh~”> stream xÚuнNÃ0ðä¡Ò-YÙz/IÀTt!R)`b@LÀˆ&PãGó£øÌV¤¨æÎa¨øÈðS|gûîlg{Í×lywŸíœç|×ÐY+Ášg͘¹} EGÕ[KÕ™„©êÎùåùõžªÅÅ ËzÉ× ×7Ô-0j`šÜ#ЧQ æ#ÀD¼LÚ€Òc0u(e ‹+9í1ü´ _¬E—ÿÿrùŠ4ê²A)'RòÐvd/Ú”F½¶™¢”NI/ÏJB7™,ú|z’5[%°m_‰«¾}תŒ¦£G9Ð;}ŒÞ£tøŒúBq)[m0”:˜Ï}ÐiG—ôy?x endstream endobj 909 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ…ÐÍ ‚@àÂyõ 5OÐ*h&‚ä!¨S‡‚êØ¡¨³>šâ#tô°d»µDFäÀð1?00~8r(9ôÈhïâ }OÔŽ,å`wÄ8E¶"ßC6]déœ.çëY¼˜‹,¡µKÎÓ„ŒZÿ¢‚¬Ô¹Y@T7sɸ z‚l»õbô¤ãÔ x³ýÄR I´;Èø‡®à­ŠªSqk¥¯([‰Å²µ\ÑŧÅy£NS\âwpmõ endstream endobj 910 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚ}ÐÁJÃ@à ¸0HsõPè¼€nHLO…ZÁ=yBA= * ÞÌ£åQò9öP:Îvô 9}à 3Uœ5gœ|Zp5çòœsz¥²ÒnÆå<ŽžiÙ»ã²"w¥}rÍ5¿¿}<‘[Þ\pNnÅ÷9gkjV,"­ùVöFZે˜áÀ&²WŽG˜"‰ì”“jØÈVÉFxA”Í=f‘^éþÇtXD:¥ýƒ$‚ߨÀQ`¢uþõÓ@ ¤ºú3 çØF«d@âma5_³óÙjέ ñ"btÙÐ-}”^p endstream endobj 911 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚ]ÐÍJÃ@Àñ †@¯½9/ » ÄF„ZÁ„zò …Bõ(¨èMÌ>Ú>J¡Ç$ë~LµÙÃòcfØóê¬jHRYÒiE Iõ‚žJ|ÃÚmíxÁ§Ý .[T7(níE{GïŸÏ(–ëk*Q¬è±$¹ÁvEƌѱ©Q³y‰]CªÃœ*Ö>gY8U°³Î#å±`k½²ö¬&•³÷98ù7‹,¼ûàlïsÇJﯬËB>ø¬S}òŸƒ>éŸÙÔ±˜˜Œs¶aeÐø¬ý˜-«#ÕÔ¦~G~±—lÆÞ´x¿+%eÒ endstream endobj 912 0 obj << /Length 318 /Filter /FlateDecode >> stream xÚmÑAK„@ð'‚ ëU(p¾@©™äÒAØ6ÈCP§Õ1¨¨³³ßl– Sb?‚ÑEXqz㨛ëžüñÈûó&ŽÃcêÓ  GtÒè„>ä•Ħ>¦íèá™ÌRâÝÐ8 ÞæÄK/éûÛÇñfWgÓ9½ÅŸîH:§BTºÁ†4‘Ò ÜÀ-AÇ]˜+ÅÉ@kS]Ñ”„žÆNZC E$«ž6ÒÑEfŠ{œ"92gÖ=ƒ4¦x? vl¸ìÈ% É„k‹0QÔq£µá¾¢t6Œ®,¤¬ ®${Qtpc6¢äÛ,2Ȳ.Þ¹lÉ!ÿ„ŽIËÉ׈¿Øã[qÝÓÄÓ$eO·e%7ŽXÊJÛÔqèòžvKÚl'A‘8Q”ÒÈyJ®Éj㬠endstream endobj 913 0 obj << /Length 276 /Filter /FlateDecode >> stream xÚ]ѽJÄ@ð [†3iÏ*ûæã0^eà<Á‚VWÂZ §høf_$•¥¤LnœÝ™æ,–_f–ìþ™-‹³bi3[ð*K{~aŸr|ÅrÁuæJ·ñø‚«Ó-˜ÞpÓúÖ¾¿}o¨F`¦Î5@¦î5@/òÌ|ž™×øI¸ãÄÈOàRm\ŸÿáoC= þ‰þ‹×5Þãa“|Ú endstream endobj 914 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚÎÍJÃ@ð ƒØko™'p7…Øô¨ÌAГ ­GAEÏÙGÛGYñ ‚ôP2îÇH=沿ÝÿÎ s1;Ÿ5¤©Òþ˜kªç´­ðë…Ä?ãÏæ—ª{ª¨®}Œª»¡÷·'TËÛKªP­è¡"ýˆÝŠ˜ dwthÙåì g ïDŸõAs´ u<ñ–¾öTœŠw²ÐâÚ[l2 æd&™Cã8ÈÎÄ0Ö/b¦bí틸N:m?Å/-¿!ù“œ âAÜ'‹?w’ÕÉü±¦õ )§¾žÙŠæŸxÕáþZmà endstream endobj 915 0 obj << /Length 247 /Filter /FlateDecode >> stream xÚmпJÃPÇñ_È8KV·ž'ðÞ@B)ˆZÁ ‚NRÔQPQpó>Z¥ÐÑAÏŸ–1¾ÜÜäCÎmâñ¼æÈÞ 7s~¨è…ê…¬£.uãþ‰–…®.ä)…î’ß^ß),¯Î¸¢°âۊ㚺c6Ê•þf@6³¥MÈ P|§@ùœH¶À‡¼%y–íå³î$É"AoˆD‘]²d#‡¨Gàˆd°ä³°GÊí?Öùe99D­8™JæhwSõ:Ît*ý¡Ì‡Ë}*‰"EoH™,rˆ­*H!ý¨-؇Î;º¦ÃÓ|B endstream endobj 916 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚuÏ1 Â@ÐR¦É2ÐM41Á‚Vb¥–Šv¢9Ú%GH™BÔÉJ›·ÃÌÀìƒnÔcŸÜéqrñ& =õciúůÉzGiNjÁý˜ÔDÚ¤ò)§-©t6â€TÆË€ýånàz¬*íp GÃ]bØp–êy¬Ú`JÁyãt‹÷C»Nþq•óÕ?Ê‹|µ¼¡[¼…A–´ . g©%„Ák™&® nW²„G-$ qNszmh± endstream endobj 917 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚeÎ1 Â@ÐYRÓäÎ Üìj0] Fp A+ ±Š–ŠÖÉÑö(9BJ É:‹-üÿ«¿2‹ÜRF[®)ÏéjðVz&UBsÇÊ¡>‘-PïxEíöôz¾o¨«Ã† êšÎ†² ºšÀ$,e¥<„Ð)1–o“V@,°1¦Ä7–ˆOl&†X*úØ\ø?¾mÏ×Ã0éqëðˆ?oEQ{ endstream endobj 918 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚUαJÄ@Ð;L1ð óâ¾/pIÀB\XW0… Õ"j)¨(Øí|Ú|J>Á2EÈø®»æ0™{'/msÜh­-W§]§O¼I[+{eðø"«^âFÛZâ•Jì¯õãýóYâêæB‰k½k´¾—~­@5X£” ?,„T}ãaÄ!ü„S¸ ¯p3†˜1YÝöFù͆cÅø½~eOÿ°€M32![[à€cͳX«ØX0<' CÏ0d< ‚qD΀Œ/bav.ûŸB)%Udi`KÊžy‡\ör+?€¾f¿ endstream endobj 919 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚmÁJ1EïÐÅÀ[˜?°ï4N‡Ùˆµ‚³tåB\©ËB Ý%Ÿ–OÉ'ÌreâKBEÄEáææÝ›¬ªËfÉ nøbÉ«š›†ß*ú ºQä6Ÿ¼niÝ“~âº%}'2éþž¿>÷ï¤×7\‘ÞðsÅ‹ê7 ¨€™€"‹r˜;(«<Îe+”c†I°‚ð Ôˆë<+aî#œ K°1D޲Š1ÚÄ1“D?i˜pò¥ÝÏ€<ïRÐp&–Aì7N~ø +Õ¤«Äxv˜qˆ¯J½•“œ2~AbÇNè¶§Gúé«jp endstream endobj 920 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚeνŠÂ@à Ñ6…ûN²1’NðL!hµÅ"v·\6ŠÖæM|ßDÁÒBϱÐÂóÁ{¦—t³µÇ¤šõõ'‘•¤9æ˜#ß2,Ä~jš‹âVl1ÓÍzû+v8i"v¬_‰ÆK)Æjpª'gÄ#> N ý$"òOÜÝ#ð÷$ Ò$á 6&')Éx5ðÍ“éĤ47tGü4HÓxWtAN*²sÎ] î‚¿\ÌÁ‹ó;mçN/dRÈB\ endstream endobj 921 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚuϱJAà± ¢­•7/ {›Üy¸Dð A+ „ÄRPQ°òÖ7[ð|ûW¦8¼Ì$Ml¾…ÙÝf w\9ç>rQpYòÜÑ3*)æ\V››Ù#k²7<ªÈ^H™l}ɯ/odÇWvd§|ë8¿£zÊØKdiÐ"ëû¤D%(€ï;¥œ”Û<)÷ÿ‘”Ø_ŒïOIY Ó~0-Î`> stream xÚ]Ð1NÄ0Ð¥ˆ4à¹$Ù]C*,-‹D $¨¶@T@I‚aÍ7 ¥ â)]D˜I²H@᧑ǶþxUï›W|À{ ^6†ojº§e#››Ã¹s}Gë–Ê-/*Oe›ÊöŒžn©\ŸsMå†/k®®¨Ý0€$«HЩ"² òŠNjòÚ ‚Cñ52 ûëEÿƒšèÝYý‘:èÏa_ñ ûŽ#Ø7yÑFyÛö‚“APÁ¹9ãgô/þc'‚ûË‹Lã'Ü8—…¤Þ‘ME(/YUPA2KÈ,Ÿ‘†)4@'-]Ð70¥oÈ endstream endobj 923 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚuν Â0ð“…ìÚ¡Ð{MÒZɤàØAÐÉAA]ÅGë£ô:vjNLÄÁ ?È%÷¿ë©n–$¥¨“P&)ëÓ^áSmªæª?O»#Žr+J5Š™©£Èçt½Ü(F‹1)Z+’Ì'ä9þ›‚išæüPdžŠ)™"ðš›$@›‰` 2š9I*MX‹½‡Ðf"‡fNLÅ¿ …[†[&Ë0wÇÓÒrxµÅÿ%¨þ¿)-[§9.ñ†©O‡ endstream endobj 924 0 obj << /Length 260 /Filter /FlateDecode >> stream xÚm±JÄ@†ÿ°E`š}ƒd^@s¹\ˆ…8O0…àUb¥–Š‚ÅAòhû(û[¦7Î(‚,|Åìÿ;ì¦>m×¼â–OÖ¼i¸mù©¦Wj:ê¸û¹y|¡í@Õ7U×:¦j¸á÷·gª¶·—\SµãûšW4ìÈ€þ¨™à’ȃ‹ðÈ á˜q|êùEú‹Ù"³…«‘EȤ y€D?aœK`\TÖ‹&K‰€—  ˆ*2›yY€b5–2eɛ™"“  ‰ªèã…¶£z|.Îóü¾¡‘|2@kÞP@U”ú”Ê|„³/€Øg”Ú¡«öôé8p endstream endobj 925 0 obj << /Length 248 /Filter /FlateDecode >> stream xÚmнJÄ@ðØ"0;€°óšä.1åÂy‚)­,+µT´;LÞÄWÉø ûN™"dï r`óc™Ù-‹“jÁ9Ÿòñ‚Ë’«Šï z¦e­Áœ«zŸ¹{¤UCÙ /kÊ.4LYsɯ/o”­®Î¸ lÍ›‚ó[jÖ ¸ $N@*¾ƒímߥ=Z¤Œ$ãŒ`†t‡(ö·#üKúK¿ÇâmêÄxѦ­˜€/I$ù æ#`kõ¹›~jˆÞüÝL‹™ GÀ¨g:"#ŠÖŽº¡æ]§y<áØê^ðQµ¤Ñ¿7tMß_Ås‡ endstream endobj 141 0 obj << /Type /Font /Subtype /Type3 /Name /F30 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 1 -21 93 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 38 /LastChar 90 /Widths 926 0 R /Encoding 927 0 R /CharProcs 928 0 R >> endobj 926 0 obj [64.58 0 32.29 32.29 0 64.58 0 0 0 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 0 0 0 0 0 0 0 62.28 58.82 59.97 63.43 56.51 54.2 65.16 62.28 29.99 0 64.58 51.9 76.12 62.28 64.58 56.51 64.58 61.12 46.13 59.97 62.28 62.28 85.34 62.28 62.28 50.74 ] endobj 927 0 obj << /Type /Encoding /Differences [38/a38 39/.notdef 40/a40/a41 42/.notdef 43/a43 44/.notdef 47/a47/a48/a49/a50/a51/a52/a53/a54/a55/a56/a57 58/.notdef 65/a65/a66/a67/a68/a69/a70/a71/a72/a73 74/.notdef 75/a75/a76/a77/a78/a79/a80/a81/a82/a83/a84/a85/a86/a87/a88/a89/a90] >> endobj 928 0 obj << /a38 890 0 R /a40 886 0 R /a41 887 0 R /a43 888 0 R /a47 889 0 R /a48 916 0 R /a49 917 0 R /a50 918 0 R /a51 919 0 R /a52 920 0 R /a53 921 0 R /a54 922 0 R /a55 923 0 R /a56 924 0 R /a57 925 0 R /a65 891 0 R /a66 892 0 R /a67 893 0 R /a68 894 0 R /a69 895 0 R /a70 896 0 R /a71 897 0 R /a72 898 0 R /a73 899 0 R /a75 900 0 R /a76 901 0 R /a77 902 0 R /a78 903 0 R /a79 904 0 R /a80 905 0 R /a81 906 0 R /a82 907 0 R /a83 908 0 R /a84 909 0 R /a85 910 0 R /a86 911 0 R /a87 912 0 R /a88 913 0 R /a89 914 0 R /a90 915 0 R >> endobj 929 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ1 Â@E°L¡70sÝì ’@°ˆÜBÐÊB„€ZZ( 9ZŽ’#XZ:IV›t«þ 3ïOÌØÄrÄ#²‰xjø¨éBºN%7nt8SjImYǤ–’“²+¾]ï'RézΚTÆ;ÍážlÆ@TðJô ø@ ðhxÁ«jze/¨ š]aöåÙáýÝ;¿íÇÎAdDÉ/ak+ÚÎ?i¶¥”T“‚RSÊ"§…¥ }G«@ endstream endobj 930 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ1 Â@E¿¤L/ :ÐÍ®A"ˆEŒà‚Vb¥–‚Š‚…EŽ–£äÁÍ$±ÐNxÕÌgæý¡˜1‡qß„l">hº.§!Ǧ^íO”XRÖcR 7'e—|»Þ¤’ÕŒ5©”·šÃÙ”s Î@ t€h~//i¹ÝKxO`L®Ð“tIVãçßxÅ?üÞù¼¨>ö‡©(=C±uÚ•¿/ñ@ªÅRÓr•iniMoEËBs endstream endobj 931 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ52T02R03RH1ä*ä24Š(XC¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿüÿó‡a0C ¹\=¹¹¶ h endstream endobj 932 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚÍŽ;@PÕggÜwAí“x…„J!*” Âî%>‰EÈt3ÍØ00 •¾UjÌØrR¬Ð豆iø¥qAæ 5‚T‡¸šûv̬ɩ‚½Ò p¯ó:½_ó¢thq_þh endstream endobj 933 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Œ?øØ¾á„ËüýóƒðÚcyn€8£žáÐ@§Ô­ÿÏ¡A|8X¤¤^þ}ÜÇÿ& ð…(¼À…ã.WO®@.QåXÙ endstream endobj 934 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. þ```ÿÀÀÀâÔ±=700ȃ0P’ŸøÐ aþäy û]ɃÔÔƒôÑÃ} p…(\ìàN9~ ×r¹zrr°Wß endstream endobj 935 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 936 0 obj << /Length 109 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCs3…C®B.K ×ĉ'çr9yré‡+Xré{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]dêþ7 ÂzlÐ+”Á Ѫ-õ@>—«'W Êî/ä endstream endobj 937 0 obj << /Length 130 /Filter /FlateDecode >> stream xÚ-ɱ Â0…á gð 2œ'0¹-¥™k3:9ˆ TGAEçæÑòfÚ¢|Ûÿ—ÕÒ7ôlXUÔÀ:ð¢x@='eý;ý m„;P=ÜfÌpqË×ó}…kw+*\Ç£ÒŸ;Zä“Fy2d›åÏd“L*R!s™ÉB¬¹ËY°ŽØã ,P#Œ endstream endobj 938 0 obj << /Length 164 /Filter /FlateDecode >> stream xÚ31Ô35R0P0U02S06W03RH1ä*ä26 (›Ad’s¹œ<¹ôÃŒ ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæö8qsƒÍ憺Ì ÿê››ÿØnÿÁÿ¸ÿóïý ÿÿ10Øÿ``àÁ 6P $RR ÒÒ 2d>»@nárõä äT¶Dí endstream endobj 939 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 940 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ-É1 Â@EÑ?^á ¦xЙ‰‰mŒà‚V"ÑRPÑ:³´Ù™&Nwo¾\ø’ž%红V\ó¦xA=y1žö:À¨n×w¸°ççý½ÃÕ‡ ®áYé/ ­tò‹½4è’M22ÉD³˜ÉT&2+•<å*ØñBÛ#´ endstream endobj 941 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsK…C®B.K Ïȉ&çr9yré‡+Xré{€O_…’¢ÒT.}§gC.}…hCƒX.O†z†ÿ 0XÏ ÃÀåêÉÈ[\w endstream endobj 942 0 obj << /Length 153 /Filter /FlateDecode >> stream xڅ̽AÅñ ɉ¨ŠóÌ—eëµSH¨"‘ ” ôÍ£xw³ÓN¦ø5çæþgvZ8œ8K¿àÜñbñ€·²–>žÎ7TzOo¡×²C‡ _Ï÷ºÚ.)k̓<j*¥zÑP ¢±‰R˜è.NÑO|[ƧÕmÈÜÏdSéL6•Îeé\6•NdV;üxÔ*Æ endstream endobj 943 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsc3…C®B.K ×ĉ'çr9yré‡+Xré{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]dêþ7À`=ƒ 1S—«'W fp"¸ endstream endobj 944 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ54S0´P06SH1ä*ä24PAS#¨Tr.—“'—~¸‚¡—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEA†¡žá Ö3È0຀`ý™ PÈx€±±¹™¨Ò‚¡€!ËÕ“+ &,• endstream endobj 945 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0U04T03P06TH1ä*ä25 (Ae’s¹œ<¹ôÃLM¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿAà˜üÿ‡Îj-Ô\®ž\\~,Ü endstream endobj 946 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ32Ö30W0P0S06V04W0µPH1ä*ä24PA#SˆLr.—“'—~¸‚¡—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓE±¹A†A‚Á‚Á€¡€!0€Âs ÿþÁz ´oàcàrõä ä-#ª endstream endobj 947 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 948 0 obj << /Length 90 /Filter /FlateDecode >> stream xÚ31Ô35R0B#C##c…C®B.Cˆ D"9—ËÉ“K?\ÁÄKßCÁˆKßÓW¡¤¨4•Kß)ÀY(è¢ ÔËåé¢ð $—«'W Rˆ endstream endobj 949 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31Ô35R0P°T0²T06V0µTH1ä*ä22 (Ce’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. 5 5ÿþýg„" Õ1ü*Êl*,,0‘ƒ—«'W /¨67 endstream endobj 950 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚµ‘½ Â0ǯ,ÒÙÁá^@ÓH[ëZ+˜AÐÉAA…*:ÛGË£ø&õ-8d¨ —áIøpéd8¢ˆȔҘ’ŒÏÈŒøŒã÷Óþ„¹B±æ(æ|B-èz¹QäË)Im$E[T@¼ >Øß²>¸˜A`AÇÉBË+ºø`3šô4;V¬è ‡+-¢ƒq€{m§z¡Öß×l[·]ý&G“ëG5Á˜jCãàØîŸ·Œ3…+|¯rPË endstream endobj 951 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚUÏAJÃPà‘Y13Ð4i»j³tåBA] * ]”vB.{b yÐ ÜdÞsJDìâÛüÃ{ÿÌqt”ô¹Ç &yÐ燈^(Ž4ìñ`ØMîŸhœSxÍqDá¹ÆæüöúþHáøò”5ð¾¹¥|€ü`aaÇ9Áïeå­ ã—R(£L¥(û3”]µ7EÉÛ`±¥EiÕÔêN-6Vj-pâW©|gÁÓíªÀ9£Ãpã«\ª²,~‰UsퟻNöŸívI ÊìN=k¿jF(uŠE}€¥ññ£òÖŸÚg\ غ]ÑYNWô_Z endstream endobj 952 0 obj << /Length 351 /Filter /FlateDecode >> stream xÚ5‘ÁJÄ0Eo Xb·6? í ¶Vf`T° AW.DÔ¥ ¢àbÀúeü‘|B—]Æw“6‹Hšóî{-Oæ&7…9,Lylʹyšé7]Tr˜›ò$Ü<¾èu­³[ST:»”cÕWæãýóYgëë33ÓÙ¹¹›™ü^×çÈz@´%[Ä µH~, „p@ìp€/ ±Xb¤VöðÝÈó}§äí“íöòÕ$í—@‡)…»@?° ½§éc˜ŒlSŸT¤_2øz>:)zÉSQ/w9õ’÷•zæ§žýPÏþ¨g¿ÔS@=×Ê "mÃÍ¢"{tSøí_¶‘Û‡£\L:eÍR@5Rl#² L7‘¥^ Zê7û] gOª‘.P²y&#›àMYYê¬.IÅŸ«gÂØÏž¹ýp¤?éËGúTl]úfbÖÒµ¾Ñÿ&¨† endstream endobj 953 0 obj << /Length 295 /Filter /FlateDecode >> stream xÚ¥Q±JÄ@}a‹ÀîÚÁìh6± œ'˜B8+ j)DQlDîÓ⟠ø)-qf·ÑÚdáM^&/oÞlª“º±ÎÖö¸´ÁS{_ÒÕ•Î3úæî‘¶×¶®¨¸šŠîÒ¾<¿>P±ÝŸÙ’н)­»¥ng³@¯|a…Yn b Ä=Z F˜Á-µ;C4 ¬`Ú £ FŠhj…x‘†¹1føo8ý}}‹Èà¢IDœ3Ö솘sÓ{Hûõø ØC6æb‰“BKú¿à›i°”ªÁœSµÛr£æßØé(_Ó ƒ}NìÇ\F?t"@!„°Bzéï>a3û„óÉ'¼tíìס²¡é¼£+ú®E}d endstream endobj 954 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bSK…C®B.# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ø0Aý? Áøƒ½ýãù† ö@CÿùA2þ€’@5@’±D‚!™dþÀðPI¸ùÌCdþÃÀþƒ¡þÿƒÿÿ “\®ž\\^åˆÓ endstream endobj 955 0 obj << /Length 175 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bScSK…C®B.SßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.Oþ êÿ³ÿg``üÁ~¿ùûÆÿüäØÿÉ?`°gàÿ¤êàÔ õN}`o`üÁÀþ¤›™ÚÔøFÑ¢¢˜ÿ0°ÿÿƒÿÿ? Q\®ž\\à  endstream endobj 956 0 obj << /Length 154 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bSK…C®B.# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]øÿ0AýÿÆÌذIù~ iÏ"ëÈ?P¨†ñ3õÈÿ@€JR×|Z“ÌÀ0ù Çÿÿ@&¹\=¹¹)“ endstream endobj 957 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚåѱŠÂ@à?¤X˜f!ó·FHÄJð"˜BÐÊâ¸J--îÐÖ|1}_aaËÁu=ÎÒÎe¿Ùýg›Mû]îp,+íqÒçeL?”&Òwš¶¹X¬i˜“™sšË)™|›ßíŠÌpúÉ1™Œ¿$ùMyÆ€vˆ¤Š3|-{Pé½ÓeƒÓ!,¨„GpPghÁºFdPCWTíÓ-”k¦¡Cˆðj( ­g¸f"{¿!ªý—Â[ïÞ—ÿA£œftàùËC endstream endobj 958 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ3³Ô3R0P0b3sSK…C®B.3S ßÄI$çr9yré‡+˜™ré{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ø0Èÿ`‚úÿ ÿÿ=```üÁÞüÈ`Àxþ?!ßÀþŸAȰgàÿfÔ1ðÿAeücu1þ``ÿ4Ä`¦ã?`cÐÓƒ–Áü‡;€‘ýàÿÿƒÿÿ7`2¸\=¹¹UEÖ¾ endstream endobj 959 0 obj << /Length 330 /Filter /FlateDecode >> stream xÚeÐ1KÄ0ð WbV‡“ä hÛÓëUw'ØAÐÉAA…Stp±7?S>ˆC>BÇGë{I<»üšòþÿ”‡ûÓJåê@íMTY¨2W÷âÓn檜„“»G>¯yv¥¦3žá6ÏêsõòüúÀ³ùÅB<[ªëBå7¼^* ák¬‡µÎ›Ø[ojW^ar¯„*ºóG½áÉ¿ý*šo¸ŠºhÈ¡YP~˜hˆ)?£_Ño`Ã`@tÑ6Š×éó£¯J[êL©žmS/t Ý]ŒÑ#”¯zð‰ŠI™m€’&Å+S£ % -%• -3_¸ÄP}ÑÒ˜w4ò&ë!Y½¬¯¼ðkC1 RÛ ¤u㛥ÞFt(×X@;xë1¸lYÛÀ1NNÛ|1`×'ÿ1:?­ù%ÿ©£rú endstream endobj 960 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚÌ1 Â@…á· LàœÀMŒÀBŒà‚Vb¥–‚Šv¢9ZŽ’#¤L!êÄ‚ºËWÌü0aÔíìs_„D¼hO¡Ïõ—±«-%–ôœCŸôX¶¤í„‡Ó†t2r@:å…œY’M¦€zÜáæ&óÐÎc¸¥§ÜÁ©ÎPÕêöøp±t¼¸e£] 0.â,$+IJ’“‹¬áâ­õ§_ÏFn_óoõ^:,Íè Àv;r endstream endobj 961 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚmÐÁj1à é^=;OÐd-‘õ$¨…îAhO=”‚ÐöX¨ÒÞ„Í£í£ø{ô°˜N"¸Q6>fB&?™Nî'izàmf4Õô™ãáZûÒ||ã¢DõJÆ zâ.ªrM¿»¿/T‹ç%å¨Vô–“~ÇrEP@X×ìû8õ \²²IU{ó˜»ùÁ3ÌbÆYã¥1Ezôè$æ'i=SË©†LÂB„p6Pu Ž–8ç:R†£ ²Ž÷›[4ß9Þ²áéí…ÃŽ&ÎÈ&üZÚú'­ãXήÁÇ_ð%°m¼ endstream endobj 962 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ•±‚0†0Üâ#pO`Amd3ALd0ÑÉÁ8©£ƒFgúh< ÀÈ@¨…«Ú´_®íÝýýe4fÐÜ,¹ ¹¤kˆ”µÓ„íÅåŽqŠâH2@±5§(Ò½žïŠx¿¦EB§‚3¦ i3 €5C8ZA–›À/:LÊ^ÕÁ­ûpšôXpžÛôkÚF¶­±bIF°Ü2ÕéqžËUœNÐC¨™E>ª_…ñ÷c‹ð+v·d¯ó¯åínÔâ&Å~VŸP endstream endobj 963 0 obj << /Length 260 /Filter /FlateDecode >> stream xڭѱJÄ@à? LaZ áæ4‰Üª[-œ'˜BÐÊB¬ÔRPÑÖÌ›ø*¾‰yË+Äuv²g!–Bà#“ÍÌî¿ÎïúnÙñÎ;ÇÎóMG4÷Zly¿›¾\ßÑ¢§æ‚çžš-SÓŸòÓãó-5‹³#Ö÷%_vÜ^Q¿d ˆRPDZT†¸R´öR ÊOÔµ þ@ù*˜(ÞAWEÁ],øR‚º˜IµRê5ú7P­Ñ&?”2oÆ(~#FLØàgÈü5=dF#ïzv¢L;mf–Ä&,—mXJ[°Ìa Þ#å }Rº:%e-vÁvS½•Ô=U:î霾šes– endstream endobj 964 0 obj << /Length 194 /Filter /FlateDecode >> stream xÚ33Ö31V0PaS Ss…C®B.S ßÄI$çr9yré‡+˜špé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÁõBýc``üßD@.ƒý0ÅÿL1ÿSŒÀÃ?UBÙ7@¨`JJ=SüPêŠýê (<ö¡9ÅñP¯@=ómrüC%h˜ACž  !@ y`> stream xÚuб Â0Ð  ·ô¼/0­ µ‚Dª£ƒ¢³ý4?Å/iLsqˆð’»INÍÆª œ&vª)©9 ¼¢‹åý¶O4¬4Ê©åÊFQê5Ýo3Êj³ ­ioK¨k2ýè D˜ÒÀ€§dFLƤ1’(­C8^Qˆ€„ÉÆDð¹ïɰ|pÃ1ÆÛ½Ó.þ"bøÿyÒ€Œ)™gëºk¸×¿àRã?UŸ’~ endstream endobj 966 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚ35Ñ3R0P0bSCSs…C®B.s ßÄI$çr9yré‡+˜˜sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÀd’ñƒü†ÿ Œ`’ᘬ“6`R‰äÁAòI68ÉØ€L2`%™‘Hv0)"ÿÿG'!âP5Ⱥ‰ A€J$ãÿ `G@%¹\=¹¹Mÿx× endstream endobj 967 0 obj << /Length 254 /Filter /FlateDecode >> stream xڭѱJÄ@à?l˜&yM"&`µpž` A+ ±:--­7`ákMgé+ä ¼òŠãÖÙÍ& XšæKf’Íì¿]{Üt\ó)p×p{Æ =SŠu¨ÄÎæ‰V=U·ÜvT]j™ªþŠ__Þ©Z]Ÿ³>¯ù®áúžú5ð(ü6S¬ßü`À쑊-Ì— oÕ¶¸áÖë¥d‡ˆ¾¯ I¾Sòý03a‘™LlB".€¿Ñ!1ÍúOx½&ÂpcÄJÂ&ÆHù‹¸£…¸Û…˜„rI)¥ÌÜ” _ò,v0Ÿšõù{lØtéT–‰é¢§úî”Û endstream endobj 968 0 obj << /Length 125 /Filter /FlateDecode >> stream xÚ33Ò3²P0P0bSKSs…C®B.SS ßÄI$çr9yré‡+˜šré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÏøÿÿ?TŠñó bü78) À¤¯s‘)hèb y.WO®@.!»¥7 endstream endobj 969 0 obj << /Length 106 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0aKSs…C®B.#3 ßÄI$çr9yré‡+™qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿ†€ˆ¡¾aècWüÅåêÉÈ3v\‚ endstream endobj 970 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚ31Ò33W0P0VÐ5R0¶T05WH1ä*ä26 (˜ZBd’s¹œ<¹ôÃŒM¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. öÿÿ?@"äÿ000°ÿâ„=ˆ¨oÿ`#ø?0üoõ ü ä0X0È`a°o`àŠ2°7Ãñÿ qõ \®ž\\ŸÎ`¬ endstream endobj 971 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚ]ÑÍJÃ@ðYrÌ¡¾@ û&A[sjsìɃxj= QôjöÑò(y„=HÇíÌÿДeöDzÌÌ~,¯/•/üUŒeé7~_òG‹8"ÇÝ;¯Οãšó›GÿõùýÆùúéΗœoüKé‹Wn6^DÈÅ8×I êF"!¢:˜+2oa[8˜®7“`¦dÎ`+ØÂÁÔôhLM‹fp ˜&byiguf0«­~5Õ¿jŸþ©RrÀyd* îÕõSkÜ_ Ÿ¨ NÔÇ÷9LÕxoéá ÿádÔÿ™‹„sù¾á-ÿ5Š•P endstream endobj 972 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ35Ô³T0P0bKSs…C®B.S ßÄI$çr9yré‡+˜˜ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÿ€™dü€þ3 eR/i& 0È ò‚d“Ì`’LÊ?`üßÀðÿÁ@!¹\=¹¹Afl÷ endstream endobj 973 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚuÑ?kÂPð{<0p² Þ'ð%œÿ€ ur(Ávt°ÔÙ€«ê•]ÝÌGÈè|½¨X#yîøÝ=8. [~›< 8¢€:½û¸Ä°ËµW”ÅÇ|ýÕ”Â.ª1wQÅÏôõ¹ú@ÕjH¯>yoÉà瘣1 ýƒ¸ 8hFãx‡]Ê*ñ›1æ•øá8§¾yºØTBŸ¤,a P³ —À“M õ2Ü< œ fepÒˆ\$ÀIÂÖ5+zÛG4÷V¸Y5D NZ@fWðí¤'c´ÔÒÇýoÊÀQŒü¦Â! endstream endobj 974 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚUпJÄ@ð/.0…ûfŸÀMNÖ?óSge!Vji¡hkRù\AKÁTÖ©$EØuwöŠM1üøf`Šï`¹·<’…Üw£¥>”w%=’Ö.>úÃí­jRWRkRçnKª¾ÏO/÷¤V›SY’ZËëR7T¯¥µ@fµm óÀ¦‡í¼ÅÏ0 à{d¾¦˜üۘÎ=õ4]LÕ3ùȦ€aÒ@b·´liº@ÏT|`Ä“MLjbËÀ¾Å4ŸLõ“ÿ1ÂÄdtFÀœW$®Gœ á*Ã.|ר™±ÕtIÿ6D†c endstream endobj 975 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­‘±‚0†Ï8˜ÜÂ#ô^@D'ÔDŒ“::htGáxWÚœmš~éÝßöú_LÂyÒxJsNgoô(ò»ÌéŠIŠîžÂÝ5‡ÑM7ô¸?/è&Ûñ~IŸ¼#¦K¶ Cµ¥ Ô¼*x1F%¨À)dBœÃè ñ‘Š…¬ªA«ÑŸ8çEÅjGîU…Ò(ßNk¼ûÈ4ª,— ~ÐjÔ…}Á<ÛC¿2[|Žþfa?­-ÈÖžÆ3ë ñ“­oŒ×œÈ¾}°]Ñ=ÂUŠ;ü”K‰É endstream endobj 976 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ35Ó35T0P0bS#Ss…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü‚ ê„úÏÀÀø¿,ÊÀ ÿLñSÌ? Ô0Åø™adªT Y;ªÑPû ¶CÝuP7ÈÙÿÀÔˆ ƒ™….ĵ˜—«'W ŽK€¿ endstream endobj 977 0 obj << /Length 221 /Filter /FlateDecode >> stream xڕѽ Â0ð–‚ì#x/ i*Uœ ~€ÄIí£ù(}„ŽJãÙK Í"&…äHrÿt¢F*ÄÇ8 q¢0šâYÁ È€f4ãÊé óäžê ×´ 2Ùàãþ¼€œo¨@.ñ 08B²D­uåÐ uf,HW§‚ ô¥lüfëç¬(ºz¥eõ§Ö~ûüæÞ¦Øô§¹_Qš@™ñÍëõ6Ò+L®6ŸñeålóZ¹šÿ«›v,X¿ÕKéP~ï‡ÞEÔºe¯Ö©úN=â’¹«vð™<›Â endstream endobj 978 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚUϱNÄ0 à¿Ê)K¡~h{=îÄB¤ãè€Ó ˆ @°!ZÞ̉èF%Psw ²|Jì8¶ç‹Ãª¦’æt0£ùŒŽŽé®r®^j°¤EµËÜ>¸U㊠ÕKWœkØÍ=?½Ü»buyJz_ÓuEåkÖ?€ÆŒ!òÎf°l#>Ù3ZÎ;@Î'€ç7Àîx ïÉ&Œ&È–Nm9ƒR0—!¡G/aEïFD+E$½ÑŒµ²MX‰¿„^É>a‡-úÆü‘Mˆÿèû=¦×:upÇ´–¤-µiÞ}õèGŒˆA§Š^{s¦ywÖ¸+÷=Ÿ†# endstream endobj 979 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ3µÔ³4W0P0bSsJ1ä*ä2ñÁ" Fr.—“'—~¸‚©1—¾P”KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÁþ?<@£0ÿg`ÇÀøùA ˆbüP¢>€©T*L`¥€)‹`J+ŦF Åþ¿Hʃ‚ârõä äWÎr° endstream endobj 980 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚåÐ= Â@àÑÖBÈ\@7‰¬ÆJðL!he!Vj)¨h«9šGÉ,SˆëlÅ3X,ßòf˜âu¢VsÀmnFlzlº¼ é@ÆH¸¤˜¬w4HH/ØÒ‰I'S>Ï[ÒƒÙCÒ#^†¬(±µÊ>ñl \3X~ZPCAù©J'BEH?4€þ—ºôuâ7{©-'¿ROrï%ËxºVÝ™‹Ã·¹CÙ ï qBszØxaº endstream endobj 981 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚmÐ1jÃ0Æñg1> stream xÚuÑ1KÄ0àW „ãºv8ÈûÚôÎb ç vtrá@ÿ…?'â)ΤC¹ø’£âMHøH^ÂK^Yì/Pá÷æX.°8ÄÛ\<ˆR¡ëÅÑvçæ^,k‘]b©DvJË"«ÏðéñùNdËócÌE¶Â«Õµ¨WhíÀ­í"kÿ·ä@öŒæ¤àmDâ$f~¤#; Hl ¿¥½8@£ÁŠwdFUšì¨%[pù¤^q(é`J7)¯Iˆ’›ÑMk¯T¢äRÙñRI JN%}¤½Ö<=“Dt2l¥IÜ©yÑÑ&ôFš:Uï; ôAš9ÉOŠ} ô5*¡¿­ºÿÄÿ‰°­ ÄœŒE'"'íEÑ<´¾¦®_g'µ¸ßÑÆ©Ñ endstream endobj 983 0 obj << /Length 279 /Filter /FlateDecode >> stream xÚ]ÑAJÄ0àC»…МÀ¦Ç.„Â8‚]ãÊ…êÒ…¢ëöÁ«ô&æuW°ôù’<3‹ôãÑ¿ù».OËÊXSÒZ[svnž ýªIkÂè_<¾èM£ó;šu~žÍyûxÖùfwi oÍ}aìƒn¶¦E„'8p…@ë@Òµ1Ù±=™Ž h¨ $«3,ØÄ+N¼€ÝŠ­‚moƒµÛ³.˜ }0ý颿Q…£’x(`ÜO‡b<¾£âkˆç|ŽÑ4ºPS0á€%»â€ ¢–ƒöàØÞW¾œÌÈCeàË  »ä›PIÂ{Á7™½]øоiՈݱúªÑ·úR}Ý endstream endobj 984 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚÍαJAàYÈÁL›"y÷.p1©b¯L•BAS¦P´Î=’p²2EÈ8»n@ô,†ofgÙ§“ËÉŒK®´¦×WüRÑ+ÕsË8ÆÅó– ¹5×sr·zJ®¹ã÷· ¹Åý5Wä–ü 7©Y²È ð~k%…öÒvìT²Z^{ÓcÝÙ³ ÷ÃâôU«o²CÕ0Ë–*¤ÅSTB¶‹ú`ζÑñÞ&‡í%‹ãE¶Ÿ´§QÒÈ0›b4è3¾Ýe}÷¿Íÿô"Ý_馡}Èl® endstream endobj 985 0 obj << /Length 204 /Filter /FlateDecode >> stream xÚmÌ; Â@à . ´Vf. ›´1àL!he!Vji¡(X›£å({„”Á8ë£—åø‡ùÝéÅQ—Úš’˜º}Úi<"ÏÈŃ÷f{ÀQ†jÅ{T3ŽQes:Ÿ.{T£Å˜4ª ­5EÌ&¡€º6äü¥…°%/_x÷/PAP02gøýÁ0Ò¦–yp&îî¬dBw›:Œ+0ðÁüâ}¨AT¾yóMÞ6Ó¢5lö–¢.Ë5²Ài†K|¤øT£ endstream endobj 986 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01V0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃT‚D0S$ê00|`ÇÀü¹A¾ù;ÿæ ì˜ÿå˜00þ* àÄ?8Q"êI&êPMÊøbÛ½`Ëßœq ä ã ò Ìê˜þÿ:]þ—«'W ÈckA endstream endobj 987 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚÎA ‚`à'?( ‘œ ”ýüºÌ A­ZD«jXÔ.Ì£yàÒ…Tcu€ßæ 7f: 5ÙðP³™° ø éL¦ %¿—ý‰â”ü MþBbòÓ%_/·#ùñjÆ’&¼•ÎŽÒ„¡ZÀ{ÈUe5ÈTÆ©¬Ö-Õ‡W¨6êÀj@-ÐÉÅóOù¯Ó‰;*`{ú^‰ž[bàTd7“ý w§”§ÍSZÓ»= endstream endobj 988 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0VÐ5T01Q0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÿó‚ÁþT‚zó !ÿHÔ±÷`øÁøþó†ú쀶¤ „|P±=˜i«‡u âÉDª)öph‘<„ÚkrF=ÈAï?0þ`<ÿŸ¡†½ÿ?ƒü?þÿ ì@‡s¹zrroXhI endstream endobj 989 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ]Î1 Â@Ð\˜B/ 8ÐM²(ÚЦ´²+µT´“èÑr”!åbI qáÁ23ü;èö9änÀ¶ÏvÈû€ÎdC)úlGUgw¤IBfÍ6$3—2™dÁ×Ëí@f²œr@&æm)‰Ú¸·2Ï©\^¡sϵ2¸Î÷¯HÅøQ‰RñþQÖOþø—Ö5ÉQÑJrµìhè M£íÂá„TårL¼@³„Vô½£@ endstream endobj 990 0 obj << /Length 141 /Filter /FlateDecode >> stream xÚ32Õ36W0P0bcSK…C®B.# ÌI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ê˜ÿ70ð|À ßþ€ÁžÿCÿ`ÆÌ00ŠÿÿÿÇäè§3ÿa`¨ÿÿ޹\=¹¹¢&[ endstream endobj 991 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ¿J1Æ¿00…ñ v^@³9ïäŠÃ…ó·´²+µT´[¸}´> stream xÚ31Ó34V0P0bS …C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ì€à?É&™iN‚ìaþ`ÿD~°’È700nà?ÀÀüDþ“ØÀÈä‡$Ù€‚ëÿÿƒÿÿ7 “\®ž\\y endstream endobj 993 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS3…C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜ø0È@A@ 8~Àüá? ±q©ŽØ0üÿ‚¸\=¹¹(CE` endstream endobj 994 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ32Õ36W0PÐ5QÐ54W0´P05SH1ä*ä22 (˜Ãä’s¹œ<¹ôÃŒ ¹ô=€\úž¾ %E¥©\úNÎ @Q…h ®X.OÆ ìø   P?`üÁð†Ø€¸ôE6Œ?êügüðŸ‚üc?PÃ~À†Ÿÿó.WO®@.ÿ§Wõ endstream endobj 995 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚµÍ1 Â@Еir3'p.#˜BÐÊB¬ÔRPQ°ÍÑr±0EÈ:? êdÙ³3ó7èuÂ.{Œô¸òʧãH‰ÆrCqJzÆGz$¯¤Ó1öÇ5éx2`ŸtÂsŸ½¥ […RÊüâë?´LõºæÝ3Ø‚ærÁÊkm‚¨„;xÔÂ3êH†Kv¤Ø@%¯â.êýoÔ nn—**ŒÉù@Ô¦ôDr endstream endobj 996 0 obj << /Length 108 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS …C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?0ü‡!þ ̃±ÿ`øÿÿq¹zrrÆ‚Q. endstream endobj 997 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ3³Ô3R0Pa3scs…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?ð`Àðÿƒý†ú@úƒ=ãƒ:†ÿÈ77Ø3ðnà?Î ßÀüÿˆþÇÀDÿa`ÿÁÀNÿ``ÿ€þÀÀþ`Ð O€âÿÿƒÿÿ7ÿÿNs¹zrr#߈ endstream endobj 998 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bcs…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ìø?00üÿ`ÿD~°’È70ðnà?ÀÀüDþ“ØÀÈä‡$Ù0½ñÿÿÁÿÿI.WO®@.‡e% endstream endobj 999 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚŽ1‚@E¿¡ ™†#0Ðeƒ6 &na¢•…±RK v9Gá”Tâd)H¬ÌN^fþîþù‘žÌ¦ð”Çš£€Ã9Ÿ5Ý(ŒE”qÑßœ®”R{cRk‘I™ ?îÏ ©l»dM*çƒæàH&g8^W‰S­œQƒdHàVðá•R¾ ò!J*¨- Ài~ nNû/†ooñkg»Íîõ$AéÖHåŠ> éáwlzZÚÑIKÚ endstream endobj 1000 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚα Â@ àH†B¡y½ž­uj;:9ˆ“::(ºÚ>Z¥p"ØŠç]qÐQ |CB’?Šû2ä€Ü“1G!‡#ÞI:R°«aøm”d$V$f¶O"›óùtÙ“H–$R^K6”¥ŒÊ¯À¨\ƒ¹UW0÷Â/¼º%>Á«°T¨5*è´4hy~“ÿÌ÷ö²¥ý¦Ýß> stream xÚ31Ö³0R0P0VÐ54S01Q06WH1ä*ä21PASc¨Tr.—“'—~¸‚‰—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃùŒêØ0üa<|€ùÃãìÊð?`0?À€Áþ€> stream xÚ36Ò35R0PacCcs…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ØÈ3üPàÿÃÇþ?nÿÀÿœýó3 ~Äo˜0ÿah`þÁÀ€‚?P³Íüÿÿs¹zrrjÙF„ endstream endobj 1003 0 obj << /Length 195 /Filter /FlateDecode >> stream xÚ=αJÄ@à¶X˜fßÀÌ x{›`TñSwÕ‡•Z * Wî£í£ÄÊ6`“"8Î%GŠ™ùÿfŠ|q~ÆK.ø4p¡ó‚½R^j¨çåÔ<> stream xÚ36Ò3²T0P0TÐ5T0²P05TH1ä*ä22 (˜Ad’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  Ø W á Œ@Ì Äì@,ÿÿ?Ã(f„ÊQ „þ0‚pC sC3ƒ=;ÿ?°f.WO®@.uH– endstream endobj 1005 0 obj << /Length 153 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01Q06WH1ä*ä21 ([@d’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæ ìþ`üJò`À‘p’ƒºBþ`°ÀÀðƒ¡üÆçÿì™Iùÿí@’ùÐ.WO®@.1c endstream endobj 1006 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚU̱ ‚PÆñ#‘k[çêªWJ'Á rjjˆ ¨Æ†¢¶ˆûh>Š`›Ph—º—jù ÿ¾@ BŸ\ò©ïQà“ÒÎÃ#ŠHE—Äè³l˜dÈ—$"äS•‘g3:Ÿ.{äÉ|Lò”V¹kÌRj×_œ œÒ.Á.X ,g0i)à <¡¥©¡pƒ¶&†®A†=éjœ|c(v‘kØ]þb=ÀÐ(Ô¿áúO¨ÁI† |F£?ê endstream endobj 1007 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÎ=KÃPÅñs Xx³v(æùzËíËb ­`A' ÖQ|A7©‘|±€Ð~Lïx‡`¼7UÓN?8gù«áá°Ï!ñAÄjÀÝÏ"z$¥ìr·¿~nîh”¼d¥HžÚ™drÆÏO/·$GçcŽHNø*âðš’ WUPñ÷6¾Aß´4æðŠ5¹§q ‘þ" bxØ%âtÇq¿Á_ù®cùGˆÅ²h;²š÷L€ Ëtè5Â<þfúOk…2·|âµÁ+ñ–ZlECÝdÑ ±ï(°ç˜ÂÑIBô¥Y_™ endstream endobj 1008 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚMν Â@ ð)(¡«ƒÐ> stream xÚUÎÁjÂ@àYi® Î èn²Zõ$¨sÚSE¨GÁ½‰æÑöQ|„x ‰³²Iéå;üÃüü=ÝF¤(¢N8 ^DúÖ!þ qª¨¯ÝiµÅIŒò‹ôåœs”ñ‚ö¿‡ ÊÉÇ”B”3úI-1žQY¦ãâàAægà//7ˆœŽ4gËZŽvª*Ì 0‰Ã¿˜Š+ã]S‡¸CEÉ@QsüϰFÕì,IqSn/¼'¶’gCþbŸ^m‘mjg`ç1øã'>ÚŸKø endstream endobj 1010 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ%Î1 Â@„á‘@„‡$|'0‰+AA¢‚)­,D¨¥ ¢æQ<‚eŠ`œÅ_ìì·°&î# µÇL_M¬‡H.bìÚ£½ØŸ$I%ب‰$Xp• ]êíz?J¬¦Êu¦[>ÙI:ÓIU•uO§Ã)Fh~ðß!;£ó:còÌÛዬQÖ‘‚ôŸÿ)HÿåpIëH]R·YÀ#õH[¤mé(œ²âl2Oe-?uàC endstream endobj 1011 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚµ1 Â@EH!L“#d. ›ÍºˆBŒ` A+ ±RK EÁBb޶GÉR¦R×l´6¯˜˜ÿþPtÌ+îǬƬ5$Ii;ŒXÜf¢$#±a¥I,ì˜D¶äëåv$‘¬f,I¤¼•í(K~ |[äj¿„W¢‚opGÏà ÀÄ!´—S‹¢E¦ /‹òèzù´ÌO¾6x+Ó¸YÛ~åÕÎÜuдñí…æ­éÂÕ`ú endstream endobj 1012 0 obj << /Length 121 /Filter /FlateDecode >> stream xÚ31Ô35R0P0bc3SS…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]0001;Ëñÿ ÿaX*6T°ý†úÿÿ?À0—«'W ¾NÚ endstream endobj 1013 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚmαJÄ@ÆñoÙ"0M^ป'p÷WóSZYˆ ¨¥ ¢`eòh>JáÊ+ŽŒóé5‚E~°;ÿY²¬šc­té_^iÓèC-/’³Ÿ+9¸’u'éZs–tî·’º }{}”´¾<ÕZÒFoj­n¥Û(Ê-€~‚Ù€8¶#J^ÎQì0CÜc…0áùîÈDÌ_úŸžÓÁïø:ßsöNüaçü™r$_΂[-> ³À,°ˆ, %‡s„'äƒlÏ"³ÈÌñ¥™aAZÒ›M°¿ÈY'Wò TŸc| endstream endobj 1014 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÐ1NÄ0ЉRXšß`3', ZiY$R AE¨€ ´ØGóQr„”[¬0¼„‰"OÊŒóÇ“ãîÈ/¥•^—ÒŸ‰÷òØñ+÷ÅVüɾóðÌëÝ­ôžÝ%Êì†+yûxb·¾>—ŽÝFî:iïyØ™-­2È9QµµÕ EëPõE6‚f¤LÍôV»&‘ÆàðÌÔb&e6‚€§Ñf“õÕŽó‘òY (yâ/ifU ý°Å_ cBüÔ¨M>Õ‹ý‚¸Ÿ™°y¥ÿ€‚޵¸2_ |ÃßÇ›jh endstream endobj 1015 0 obj << /Length 188 /Filter /FlateDecode >> stream xڕν Â@ ð+ At-(˜'ð®¶µkotr¡P?ÁQðÅ_ÄÇè èý‹­³ù‘äIàõÃ+FŠÃ!¯=Ú“™º,ñ‘o)Ñ$ìG$'¦KROùt8oH&³{$S^z¬V¤SBĢ⊠ØÀ©iƒèA«äf°1ë€h‚.p;»Áö`¯Z  \2ðoóŠß›ÿÂy™³54Ö4§òý`ö endstream endobj 1016 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚ•Ï¿jAðïnaÜ ˆÎ ˜½s=b!j W¦J!‚`R ìnÍG¹G°´8ÜÌœEH:›_1;ödÏyŸSp¯ÏnÈyΟíÉ9)¦œ¿Ü_6[šd?Ø9²oR&[Ìùð}ü";YL9#;ãeÆéŠŠÇÀŒÇæÒºÂ„ÐpQ*Å+j .+xsº7á”xÄ•‘Íç–Üð‘\ƒ }µrÓþ† ”¿ø´•R þ/:tK­¬uéîNTc¨'Û¼‰Ä'ò¡jìiT”2ƒ®D¥×‚Þé+XÑ endstream endobj 1017 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚm½JÄ@…OØ"p›¼ÁÎ}d³ƒÚXW0… •… j)¨hëäÑò(ó)S„ÏD…m>†{çüÜuuìVZj­G+­ÏÔ9}ªäMjÇa©îägóø"›VìÖNìÇbÛkýxÿ|»¹¹ÐJìVï+-¤Ý*Ðô@ P„sŽºø‚&¾³¾[ D>#E@ƒ¢Ç†r˜Iõ~2û> stream xڕα Â@ àHÁB}Ѽ€Þ]õ¤“…ª`A'uª(¸ÙGóQî|ƒšTZèàà‘û†?$w#3°i²ÔhdÈŽéhð‚CË!Çá·s8cœ ÚÐТZpŒ*YÒíz?¡ŠWS2¨f´5¤w˜ÌHŸP˜Qžç®ÎëY’ 4aÐ:B@à ¸Ç8 ‚—1¾ìn -¡SQ¼üRá-8­ð d“_Ñ®Ó+ÈJ¢_<ÿ!’¯tùâ<Á5~lúQ- endstream endobj 1019 0 obj << /Length 265 /Filter /FlateDecode >> stream xÚMÁJÃ@Eo˜ÅÀ[8мÐ$A„ÒB­`B]¹WêÒ…¢ÐEÁù´ù” ;#Ç›*ÖÍyóî{wæÎquÔLµÔZ§ZŸjÓè}%OR7KmN~&w²l¥¸Öº‘₲í¥¾<¿>H±\Ÿi%ÅJo*-o¥])L OÄ[ À`;d1ëa¶°3X`LpÀM6{ä{xÖSÏœ˜°Hpžî|tO¥0£1l¹6Ì ùi4ÈþÓ,ìÀe3zŸÓáw™gRÒô¦SÅß@v伕+ùÿcå endstream endobj 1020 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚuÏ1NÄ0бRDšÆ@ò\œlÖBT––E"Tˆ ¶¤AKr®â›ì!eŠ3³ ˆšgiÿ_×'aE5t¼¢æŒB ÇŸ± 2¬(œÎ_žpÓ¢¿¥& ¿”1úöŠ^_Þvè7×çT£ßÒ]MÕ=¶[‚b—….'0SÉ2*(ÙŒ`&p ÞÁõBì!Ît ç¼àÒð_èÝ_èR¥c§Ø™%Éž 6{6Cñ!I¬cˆ“Ä)A×ô?€Ö«ÌÁ“ôXZ1IÁØËN+éOVë”ùÀäqY‰-Þàú m9 endstream endobj 117 0 obj << /Type /Font /Subtype /Type3 /Name /F15 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -4 -21 83 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 125 /Widths 1021 0 R /Encoding 1022 0 R /CharProcs 1023 0 R >> endobj 1021 0 obj [41.52 0 0 0 0 0 48.44 46.13 46.13 69.2 69.2 0 23.07 41.52 69.2 41.52 69.2 64.58 23.07 32.29 32.29 41.52 64.58 23.07 27.68 23.07 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 23.07 23.07 0 64.58 0 39.21 64.58 62.28 58.82 59.97 63.43 56.51 54.2 65.16 62.28 29.99 42.67 64.58 51.9 76.12 62.28 64.58 56.51 0 61.12 46.13 59.97 62.28 62.28 85.34 62.28 62.28 0 23.07 0 23.07 0 64.58 23.07 41.52 46.13 36.91 46.13 36.91 25.37 41.52 46.13 23.07 25.37 43.82 23.07 69.2 46.13 41.52 46.13 43.82 32.52 32.75 32.29 46.13 43.82 59.97 43.82 43.82 36.91 41.52 0 41.52 ] endobj 1022 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 27/a27/a28/a29/a30/a31 32/.notdef 33/a33/a34/a35/a36/a37/a38/a39/a40/a41/a42/a43/a44/a45/a46/a47/a48/a49/a50/a51/a52/a53/a54/a55/a56/a57/a58/a59 60/.notdef 61/a61 62/.notdef 63/a63/a64/a65/a66/a67/a68/a69/a70/a71/a72/a73/a74/a75/a76/a77/a78/a79/a80 81/.notdef 82/a82/a83/a84/a85/a86/a87/a88/a89 90/.notdef 91/a91 92/.notdef 93/a93 94/.notdef 95/a95/a96/a97/a98/a99/a100/a101/a102/a103/a104/a105/a106/a107/a108/a109/a110/a111/a112/a113/a114/a115/a116/a117/a118/a119/a120/a121/a122/a123 124/.notdef 125/a125] >> endobj 1023 0 obj << /a21 948 0 R /a27 955 0 R /a28 954 0 R /a29 956 0 R /a30 957 0 R /a31 958 0 R /a33 936 0 R /a34 949 0 R /a35 950 0 R /a36 951 0 R /a37 952 0 R /a38 959 0 R /a39 937 0 R /a40 929 0 R /a41 930 0 R /a42 938 0 R /a43 939 0 R /a44 940 0 R /a45 947 0 R /a46 941 0 R /a47 942 0 R /a48 1011 0 R /a49 1012 0 R /a50 1013 0 R /a51 1014 0 R /a52 1015 0 R /a53 1016 0 R /a54 1017 0 R /a55 1018 0 R /a56 1019 0 R /a57 1020 0 R /a58 943 0 R /a59 944 0 R /a61 945 0 R /a63 960 0 R /a64 953 0 R /a65 961 0 R /a66 962 0 R /a67 963 0 R /a68 964 0 R /a69 965 0 R /a70 966 0 R /a71 967 0 R /a72 968 0 R /a73 969 0 R /a74 970 0 R /a75 971 0 R /a76 972 0 R /a77 973 0 R /a78 974 0 R /a79 975 0 R /a80 976 0 R /a82 977 0 R /a83 978 0 R /a84 979 0 R /a85 980 0 R /a86 981 0 R /a87 982 0 R /a88 983 0 R /a89 984 0 R /a91 931 0 R /a93 932 0 R /a95 935 0 R /a96 946 0 R /a97 985 0 R /a98 986 0 R /a99 987 0 R /a100 988 0 R /a101 989 0 R /a102 990 0 R /a103 991 0 R /a104 992 0 R /a105 993 0 R /a106 994 0 R /a107 995 0 R /a108 996 0 R /a109 997 0 R /a110 998 0 R /a111 999 0 R /a112 1000 0 R /a113 1001 0 R /a114 1002 0 R /a115 1003 0 R /a116 1004 0 R /a117 1005 0 R /a118 1006 0 R /a119 1007 0 R /a120 1008 0 R /a121 1009 0 R /a122 1010 0 R /a123 933 0 R /a125 934 0 R >> endobj 1024 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ32×3°P0PaCKC…C®B. ‚†‰ä\.'O.ýp ŸKßLzú*”•¦ré;8+ré»(D*Äryº(È1Ô7Ô7ü? ¶—«'W Ë endstream endobj 1025 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚ3±Ð37U0P0UÐ52U01QòR ¹ ¹Œ-€¢ †0¹ä\.'O.ýpc .}—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ðÀ !',@„ˆ( pâˆ8#ÁD` 0‚D°Á >\–!ì¡…e8=…×2„=ø-ã#2Ñ,Ãå)êX†7¸\=¹¹(o0› endstream endobj 1026 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32×3°P0PaCKc…C®B.CrAɹ\Nž\úá †\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O9†ú†ú†ÿ Ä–c `3ËÕ“+ ö…( endstream endobj 1027 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ36Ò3U0P0T0´P0"…C®B.#3  ‚D"9—ËÉ“K?\ÁÈŒKßCHxú*”•¦ré;8+ré»(D*Äryº(üÿÿÿ6ÌåêÉÈ#ˆ'ï endstream endobj 1028 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚuÏ1jÃ0àg<þÅ7ˆÿ 4²‘ã1'…z(¤S‡$ MH×XGÓQ|„ŒJÝW\(TˆôúŸ 7uN3uúk‘i1Ó}.Gq%CËáf÷&u#öU])ö‰±ØæYϧƒØzµÐ\ìR×¹fi–Šè €éÆWà‚Op_ÝPIÓ!õ I@Ò*¤#f %×#ý¸~á,üK{ÇT#ç¼³¶,„ΰq`É(°nìYÜsLøâ¾Þ–ÇF^䃷V2 endstream endobj 1029 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ¿NÃ0Æ?+C$/~„Ü @pK§V*E"L02€`«÷ÉÈ£Dâ`ž”7Ѭ$7ëãî¨d¸¬*¦ ¯:}§¿$ X endstream endobj 1030 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚÍα Â@ à;:ò’'ðzxµ: µ‚7:9ˆ“: *:{ÖGñ;œs]úÈù“!¹éë3pç‡cÜk8ƒ‰YǸØ¡´ Öh PsNAÙ^/·¨r9E ªÂÆl ¶BéuL[“Vùeˆ¦T³½ôÉŽdÞø@ú‡`_µ¬‹’wV| ýÿšð‡äˆš …oafaosKƒ endstream endobj 1031 0 obj << /Length 125 /Filter /FlateDecode >> stream xÚ32×3°P0P0b#S3s…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒØ€ÿ‚ˆ¥ˆŒþÃûæ? : æ ÿÿÿ€ .WO®@.»P endstream endobj 1032 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ32×3°P0P0b#S3K…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒþÃûæ? ŒC 1ÿcøÿÿq¹zrrp^Ú endstream endobj 1033 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ= Â@…GR¦É2ÐMtý©bSZYˆ•ZZ(Ú‰ÉÑr2EH|›((vÂðí̛ݷ«Ga_<éIÛ=Ý—½Ï'Ö]ˆžQêÎîÈAÄj-ºËj™U´Ëùz`,§â³ eã‹·å(¢8!"«Ê@'-À1¹à4r²Sjed=L A Ñ‹]l»ÓŒßÄñ V0ùee˜þǯÛ̬äsnãÄ…«òíž ²Áœ¬Ì”/óÍKÝ´í*ëßàYÄ+~PûZ> endstream endobj 1034 0 obj << /Length 218 /Filter /FlateDecode >> stream xڭнŽÂ0 p[*yé#à€4"€øè€t7Ýpº ‘Á }4¥Ð±CHpH'n¼[~ƒ­8{`zzÄ9÷¹«Ç<Ðl o5É„jÎÃ~ÛÚìiVúb3"µ’:©bÍçÓeGjö1gMjÁßšó*Œ6±Þf¾'i%°ôQ|”p”Þ´Dй£+”7Y´¦Ñ&˜Dí»èþêï™ñÇÖºÍã^ÙÜ+­džF˰ÅU6ºƒ´uÒˆ“¬;Ò‰wþÛĽoÞ¤eAŸô$”Šš endstream endobj 1035 0 obj << /Length 144 /Filter /FlateDecode >> stream xÚ36׳4R0P0a3…C®B.c˜ˆ ’HÎåròäÒW06âÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(0ÿ`þðÿ‡üŸÿ?lìþÿ(¨gÿñà?óÏÿ6ügü  u@lÃøŸñþC{Ì ´÷ÿÿpÌåêÉÈÈöPê endstream endobj 1036 0 obj << /Length 160 /Filter /FlateDecode >> stream xÚ36׳4R0P0RÐ5T06V03TH1ä*ä26PA3#ˆLr.—“'—~¸‚±—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEó¡a9$lÄuPüˆÙXþÿÿÿ¡$N#ÌC®ca¨gc{ ùù ì00þ?À”àrõä äùJm endstream endobj 1037 0 obj << /Length 202 /Filter /FlateDecode >> stream xÚ]Í= Â@àYÑ6sݬ®+Á0… •…‚Z *Z»G²´ÌQr„”!ënÄ5Ø|Å›7¼¾èȈBêR[ìÑ^àË0$)?—ÝG1òÉùÌÄÈã9]/·òÑbLù„Ö‚Â ÆÒ:c:¯êk€{ê-Ŭ`m8ë¦8•u¨ t&p2 l©µ™Bâ̘ÑϘúê½> stream xÚeɱJÄ@…á; $p ¤M!æ¾€ÎdÍF 1°®` A+ ÔÒBÑv362°eЏãì]X'ñqι>­g¤iF'5TŸÑk…ØÌè©®÷ÏË;.:TÔÌQ݆UwG_Ÿßo¨÷×T¡ZÒSEú»%yïB­7ÿ‘zÈ· CÇD`AlÙ`Áï^Ѓ\ƒ„Fö´&i!‰QÚ¤5#+§È]VÚ‚QäS¤›"wš¡Ó)ä ÓÍŠ±’SˆÑÉÁ2¬8`ܼ?†aàÏè€ÁÅhÖŒ+.Æ1À%ãˆûÞtø€¿ƒ}z= endstream endobj 1039 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚ½½ ÂP F¿Ò¡¥Ð¼€ÞVn«“‚?`A'qRGE7Áúf}”>BÇÅšÞ‚Šè*3$|9º×î†ì³æV‡uÈQÄÛ€¤}®+ê5“Íž†1©%kŸÔTڤ⟎ç©á|Ä©1¯öר8Ux·èã”À*à%V7±38©“ÂÎ \Aî&°rOP ådeyÜ¿¡>Xý ?c\%éý#øë£æË'q¶(I£©fÔ‰µNšÄ´ ƒ…) endstream endobj 1040 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ3±Ð37U0P°bC33…C®B.c# ßÄI$çr9yré‡+qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<] >00013Ëñÿ ÿAø9³ùà óÿúóCýÿÿÿa˜ËÕ“+ Ìt^@ endstream endobj 1041 0 obj << /Length 259 /Filter /FlateDecode >> stream xÚ]ÐÁJ…@ÆñOf!"·."ç åÚÍE0p»A.‚Zµˆ ¨vµ ôÑ|Á¥‹ËÎgH0?˜ñ?p´¬NÎNmn¹ÊÒ®×ö¹wYUºÏ¹å‹§7ÙÔâîìªw¥§âêkûùñõ"nssa q[{_ØüAê­…ÙÈB´aD4%;˜>Ú#îp¨§Ýà{%*eÌdl”鈧W”]èHÿ‹ùOË·ž¦…dfä 3Âױt¢KÒ‡óF¼oæû¼³MØfl=³oÂ,"†EÌ"pLΉ~WІh–Fš¥F³*Ö4×€& !Œ3ž´DWþËZnåÎvj endstream endobj 1042 0 obj << /Length 238 /Filter /FlateDecode >> stream xڭбJÄ@à?ìÂ4y1󺉗‹[8O0… •…‚Z *Úš<Ú>Ê=BÊKÖD¸Òæ+f™™¶ö‡Ç+.yÅG\×Ü4üPÑ -½Knü÷Ëý­;r×¼ôäÎ¥L®»à·×÷GrëËS®Èmø¦âò–º ÁØ`#úÁ¦” ÌJT&e« 0m´ã?H‚M¦ÈF3âC‚ …P J°@¤#ßJ“ÿ2 ‹_â.N”^‘v2%5+w:ù‹gY9–º×Cbì)û@;ä@¯ùf,B‘M¥—B‘~2ÑYGWô îøeß endstream endobj 1043 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚuпJÄ@ðoÙ"0…y!óšDr1•óSZ)ˆ ¨¥ ¢­É£åQò[¦X2ÎæN¼²ð[˜ý÷ÍÕñéŠ3.øè„‹—%?çôNEÆa”Õvåé•Ö ¥·\d”^j™ÒæŠ??¾^(]_ŸsNé†ïsΨÙ0yµ("=¬·¢I 5p‡oI—àu·ë~ѽvŒ§ œÚ§î´„©5âÐF‡à rˆ¤“ q/ošAz½ ¹FÅÌxé¶`Úcο¤ý=!õ‚)Ùa¦$¼ï°ãÜ ¹Ðï íkÙkRý—:ô5±Œ€•ðš†.º¡Ö̈% endstream endobj 116 0 obj << /Type /Font /Subtype /Type3 /Name /F17 /FontMatrix [0.01004 0 0 0.01004 0 0] /FontBBox [ 1 -25 68 75 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 45 /LastChar 119 /Widths 1044 0 R /Encoding 1045 0 R /CharProcs 1046 0 R >> endobj 1044 0 obj [32.5 27.08 48.75 48.75 48.75 48.75 0 0 48.75 48.75 0 0 0 27.08 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 43.33 0 48.75 54.17 27.08 0 0 27.08 0 0 48.75 54.17 0 37.92 0 37.92 0 51.46 70.42 ] endobj 1045 0 obj << /Type /Encoding /Differences [45/a45/a46/a47/a48/a49/a50 51/.notdef 53/a53/a54 55/.notdef 58/a58 59/.notdef 101/a101 102/.notdef 103/a103/a104/a105 106/.notdef 108/a108 109/.notdef 111/a111/a112 113/.notdef 114/a114 115/.notdef 116/a116 117/.notdef 118/a118/a119] >> endobj 1046 0 obj << /a45 1027 0 R /a46 1024 0 R /a47 1025 0 R /a48 1039 0 R /a49 1040 0 R /a50 1041 0 R /a53 1042 0 R /a54 1043 0 R /a58 1026 0 R /a101 1028 0 R /a103 1029 0 R /a104 1030 0 R /a105 1031 0 R /a108 1032 0 R /a111 1033 0 R /a112 1034 0 R /a114 1035 0 R /a116 1036 0 R /a118 1037 0 R /a119 1038 0 R >> endobj 1047 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×31R0P0F¦ :Å« Ì ƒYɹ\Nž\úá@—¾˜ôôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàg°?Pÿàÿ¬`€ŸËÕ“+ è±"g endstream endobj 1048 0 obj << /Length 374 /Filter /FlateDecode >> stream xÚÓ1KÃ@Àñ 7´_ Øûš¤CI P¨Ì èÔAœÔQ¨¢s#~±lý·¹IÆ !ÏÜ»{w5‰Ö Ç—„ð?.qŸEs‰™8‰4i"bþÌS5ŒD™[÷O|•ñp#Ò9/Õœ‡Ù•x}y{äáêú\Ä<\‹ÛXDw<[ ¨™ºvÿ1ÈÑc(Ù²A2¿-õ#ÌkgSrí̪öC›wYÉX@–­ÁÙ7öŠ®skÏØÏ».БÕÒy§=ê¹DŸ¨e©=AW=/Ô2ÕNе³ ÞöÜPºÇ¯›ø{Ro0åR¼¶öó¾ J7ñÞ=Œ7ÆàÑ€KgŒŸW/´1>1®1x;à†ÒM¼4†Ÿö$.ÊÕñd¬s».(ãM.Æ[·Á£A—ÎmüdÐ¥c|b];·ÁÛA7”ŽñÒíYû@¹ÊïÖ|äÃÞ[3Ø3çOçÝ×/nœéþËæØ÷<.;Çí=ó‹ŒßðoZÎ) endstream endobj 1049 0 obj << /Length 287 /Filter /FlateDecode >> stream xڕѽNÃ0à‹> stream xÚ‘±J1†'lq0…ûÞ¼€f̰pžà‚Vb¥–Š‚]òhy”}„-¯86ÎL¢œ‡• Ù/Ìü;“üq«Ó5äè¤%×QwFO-¾¢kHfçræñ×Ú;r Ú+£®éýíãíúæ‚Z´ºo©yÀaCÕ 2–i¤´å¯™5º˜À€z„>‚¬%k<&rš¥,«¶`vŒìd+q3Ëß’1«^+ü ô\úoxE<@ØG*Ðqˆ ÷ù/|AüýoŒÙ¸=˜¨×,¨¢8U(`‡Ø´ fA-©‘pœûžçÚŸ¹Ú¤Pjí"ê{mœ¤ÔIš€‘ƒã倷øYRŽ endstream endobj 1051 0 obj << /Length 142 /Filter /FlateDecode >> stream xÚ36×31R0P0bcCKS…C®B.#ßÄ1’s¹œ<¹ôÃŒL¹ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  Œÿ˜ÿ30°ÿoÀŠAr 5 µTì ü@;þ£af f€áú!Žÿ``üÿè¯ÿ ȘËÕ“+ > stream xÚ36×31R0P0bc#C…C®B.#3 €˜’JÎåròäÒW02ãÒ÷ sé{ú*”•¦ré;8+ré»(D*Äryº(0°70ðÿo`ø†™˜†ëG1Õñÿ ŒÿÃúÿdÌåêÉȸ§‰ô endstream endobj 1053 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚ­‘±NÃ@ †}êÉK!~¸5Ç©©*ÁÔ1#æÜ£õQú3T9l× êÈÝIßɾü±‡Ûë5•TÓUEá†Âš^+üÀ:p°¤PŸ3/ï¸éÐï©è·Fßíèëóû ýæáŽ*ô-=UT>c×€Kxåiôi$Þ«Š@v”#W@Áø!ç'=rå4à8 E\)™æGCÎ †B1Š:‹6ŠÓ½bê¥:wZ¹KÿŠ??²"XÖi=Ì1w«½fùbpêYœ4?Í]óšeä[›ƒã©ÄßÙÄt~xßá#þ°´”ð endstream endobj 1054 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚÝÏ? ÂP ð¯,d°«ƒÐœÀ×ÚVt*øì èä ‚ Ž‚ŠÎ¯GëQzÇNÆ÷:ˆƒx‡üÈ—@ i¿—Drj*ñ æCDJb“Cíb¢qNjÍILjn¦¤òß®÷#©ñr©)oÌ™-åS†¯†/ž–ÂX¥ˆSeF·Ô•+^¡+ˆkÛª»d%ôA¢è3ðv×X}Xþ´øÅ~äÈö"õ7i–ÓŠ^¤Ds. endstream endobj 1055 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚ35Ò31T0P0RÐ5T01U°°PH1ä*ä21 (XXBd’s¹œ<¹ôÃLŒ¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. Ñ@ƒb¹<] @€ò>’ƒdF"Ù‘H~$RLÚƒÉz0ùD2ƒIþÿ@ÀðƒD1aˆ’Œ¨L²ÿ``n@'Ù˜ÿ0°3€H~`¼ücà1ƒ(¸l@Aÿà(ÀáÍþÿ8¸\=¹¹~@‡Ø endstream endobj 1056 0 obj << /Length 328 /Filter /FlateDecode >> stream xÚ’±JÄ@†'¤XØ&oàÎ h.r98œ'˜BÐÊB¬ÔÒBQ°2y´{”<•[„Œ»ó¯ÁÂòÁÌÎÏ?›¿>;Yò‚k>>åºâõ’+ûbW±¸àuÎóݶ¶¼åÕÒ–—¡lËöŠß^ߟl¹½>çÊ–;¾«xqoÛ¡ø4rßLd¢X鉜ÏdZ=5¡ù Dá-FÊBÁL”‡v.dú8šÐQOöÅx…ºÁMÿEãÙ  Hÿ…žÔÍOs˜Q¡¶ åZDæç3½è „EÊ!Iàösiãçg’‰ä,¹þÞ¡K€™óÍoø9\˜`5àFøøÿ¡ñºUÀ PSÍá–6ð¹ù#Àá) ˆF>hP2Ć&˜7·t>«Ç¸!|ºH‡kÕ`Ú‹ÖÞØ/U=Å¡ endstream endobj 1057 0 obj << /Length 246 /Filter /FlateDecode >> stream xÚÍÒÁJÄ0€á† sè¾@©yÓ¢]+ÖìAГÙÓêQ¨¢°7û&¾JßÄ>Bž\ó´¸wÂÇ$2™ŸëLÛ5?Ò§…¾ËåQŠrÌ3›ÚƒÍƒ,k17º(Å\Œ»bêKýüôr/fyu¦s1+}›ël-õJ6† ø©Âpb„³‰ø:q÷[õî ½oÎÈË}1¦˜`…[lpÀÞ©0ì°uF^úŽ1Å+ÜbƒöN…a‡­3òò>1¦˜`…%68`ïT8–q¶ÎÈËf˜b‚–Øà€;Ý>ÿš÷qñÁÿúüž³í·Ý§œ×r-_³c·Å endstream endobj 1058 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚ½ÑÁJÃ@à-9æ`^ ˜yÝDL×@h ­`‚ž<ˆ'õXh‹…œj-²c¥uÍþ-f¡<8—f–º¼æˆ_\ñ áTñ[LsJ”IFœ¦¶ò:¥QAò‰EòΤI÷ü±X¾“=Œ9&9á瘣*&|&lœÃpo×p×FuÌÜ*ºnáæà°½­YëLÜ´6&c¢§am*&<èWPXh­¿íà –p†aKOÃÚêA³ú88Ò‡,q½ÐÝ6žvÚ8íÇÐYA‡Ž+Ç-Ü ý½½ë®þ ƒ†ÍïæôóŸÌ±¦°þ¹º-葾YïšÓ endstream endobj 1059 0 obj << /Length 380 /Filter /FlateDecode >> stream xÚ’¿NÃ0ÆÏò`ÉK!~HƒÚ N‘J‘È€bF¬M-’GðèÁÄÜw.*$D駞Ͼᄏæôxé®qG'®©ÝzéjûlW.ܺÉ'÷OvÓÙêÆ­–¶ºà°­ºK÷úòöh«ÍÕ™«mµu·µ[ÜÙnëˆt"üÊä”"!–5Q¥‘&|ÔdÑŽ9‡?5“â1p·'ÍYœf€r0#0@ñ…˜JÀüñS¾'KŸ ß(‡b΀ò–L ɤ ’5º‹¤¸;–¬ÒLÚ£Y‚Ö>‰º6MÜ"v(™Þ÷Nì}N~˜U¤ÿÍù •UTã[¤²Tä°ðµåçfñ‹SUÄ•AT §H#ä°dÈQ)÷ž¼Ò{ˆ£6´R2ô"@¤òX:î!rTŒ¿Aÿ\§ü¦ú„ÔS^ªë¬EŽj,òp ŸÇdØïŠtÌS‘Ž'BZIÌÊë¦òò±â®,¦=ïìµýÖYÙá endstream endobj 115 0 obj << /Type /Font /Subtype /Type3 /Name /F16 /FontMatrix [0.00697 0 0 0.00697 0 0] /FontBBox [ 2 -2 99 100 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 46 /LastChar 116 /Widths 1060 0 R /Encoding 1061 0 R /CharProcs 1062 0 R >> endobj 1060 0 obj [37.42 0 0 0 0 67.4 67.4 0 0 67.4 67.4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 101.06 0 0 0 0 0 0 0 0 0 0 67.4 0 0 0 59.9 0 0 0 37.42 0 0 37.42 0 0 67.4 0 0 52.41 0 52.41 ] endobj 1061 0 obj << /Type /Encoding /Differences [46/a46 47/.notdef 51/a51/a52 53/.notdef 55/a55/a56 57/.notdef 86/a86 87/.notdef 97/a97 98/.notdef 101/a101 102/.notdef 105/a105 106/.notdef 108/a108 109/.notdef 111/a111 112/.notdef 114/a114 115/.notdef 116/a116] >> endobj 1062 0 obj << /a46 1047 0 R /a51 1056 0 R /a52 1057 0 R /a55 1058 0 R /a56 1059 0 R /a86 1048 0 R /a97 1049 0 R /a101 1050 0 R /a105 1051 0 R /a108 1052 0 R /a111 1053 0 R /a114 1054 0 R /a116 1055 0 R >> endobj 1063 0 obj << /Length1 1438 /Length2 6052 /Length3 0 /Length 7022 /Filter /FlateDecode >> stream xÚwTÓ}Û?RÂPI‘f*pÝÝ)’c ±m#é’îTR¥DBR@¥ABBEéx‡z?Ïs?ÿÿ9ï{vÎö»úú|¯Ïõ=¿qÞ¼kįh´ƒ©!X~°H ¨¬«« A aHÀÉi ǺÂþÖ8Mah ‰úe4 ‚ÅëT X¼£.Ôzà  ÁbR`q)(IþíˆDKU p{ ®P ‰€aœÊH”7îè„Å×ùûÈ å‚%%Åïü *ºÁÐp(Ô…``nøŠPˆ+Ð …ðÞÿHÁ-ã„Å¢¤=== n$ÚQŽçÐŽuÂ00´Ìx¨qƒý&à;Á1¿ FH¬' â®p( Á‡<@ØÃÐ@|u ‘¦PCüvÖùípøçp€`ð¿Òý‰¾HGü †@¡H7á G8à®0 ¾šŽÖ {AØ_8B\1H|<Äw…Øá~µª)!x„ða h8 ‹ÀÀ]/0 ^¤Á³*Â^éæC`1€‹þTàhîÞ‚†ë‚@z"|þ–à{‡ öP‚&¸û˜¦Ê¼ ðo# Iˆ Kˆaî@˜ÔI𢀱7 ö˾Pã1øù ( ÌîÃÿ|0‹~óóùOÃ?% ´‡C±@;˜#øwv¼æð[ÆÏ ÷Z€ðôAŸ=YáfD¸zÿÛý׈î©ÝU2åûù_F%%¤Ї_XÈ/$ ‚A"@qüƒß?óüëþFÿK{ÿÓÝdÔD8 %.Pàïo$¨Áýgox€ÿ,¡‡Ääþ7ÿ-A¢ (þ üÞ‚_!ÿ?ò_dù_ùÿß©=puýeçþíðÿØ!npWï?xB?Àâ—C‰_Ä»šÁ~o´.ÌþÀí¿­šX~IŽx¢óƒE@"¿õpŒÜ fŽ…:ý&ÓßÓÀ×p…#`w‘øÅŃþˆß=¨ þrÁàgöÛÁàûk¼2 ¿jÿìCEÚ_줨‚FC¼xJà%Q ¿¼ö0¯_œ X|Ùè€D.-&t¼¸áðÇ€7üÖ€‚®M\(þQ úÆ·ó‹&øVþ–]0˜ ˜œ@B¥ƒ«ƒ[+™=ùW†dH¶ÒÍ…ø‡ ¬É°Ýª£6‹ FÙYSÚÏÕ&»ÀjÖÎmzJî‡9sv|–kØk½EöùÙÕÖÙíâ&Î÷/'ú°Üš l$xb–¢Ä&UŒî&¸ËEÕN.oïØmÄIéûWuçÇDO.º5q­½ÖöÊ’,zIÓ/Ÿ ±Mv}Æ+¢» å~r‹ ZжŒHÕ˸¥-ÓzHð¬ Zèíîbíˆ Ôòx´ò#K­*ÝÇ¢"r¹ÂtæéµŸ¹Å›4>vê´ ›öÝ/æyR«õ¶–·7­nr'µ‹;Ù&9Dƒ¿àŽX©Q3tJiè¼üÕHûéœ0v¢†^¹ÄŒig:\ãõ\Ù'V­°mï©ñΑ…Ÿ´S5-†{‚¹ïè&Èž•.ñ«ã|ãáJØüWe õ²*}φŸCÐÓ×ì™}îq3! ‰4§c¹¢Éàæsjaá«ð´r“k‚uŸ{/ÞÛ÷Á‰œ=ÝimUâšr¯ˆBÄÐDãjf|3 žoßÔBÓ«¢•qžn‹û¾^‹V:½nÈB¿2\‹›è×…Ô£‘R@öœgm‘Á1 ͷʦ—ºÂ÷ØJ ãì Jôò^ïÒ¿íA¶Ù .Ð 9Èó¸7=S)Ôèñ“€ªÞÍÍÌÖ¸iz0h_³>@Ú^äi¾q!夨ԥcºÛPíXÞ™ i>ÜðõËæÑ4¸«.ÀcóžÝr÷;±pŒæqÓ6Wˆ<ìÝûƒxÙ𠇦z™ïÎÚ?q¸4ºîÏqÚìºqXQ¥K.ñwå­Üpè GmÊÇÎøÕ`‹i觯ye>:£›\áíí€~ólÉ¥þ¢…ãƒouórò´S˵Æyûß =3Æ¥al™°¦-€à6yDó+K½÷Éׯk~ÁyaØÕ)ó§AͷĶݱÁ Ç~í4«#I<•¡ÄF†cæÉÞ7hd²0µBÎÉúÖ-‹AÍTœíWbM²›C|äÆcóJ+ž)»!çW@Cœ¥~OPÓ7ì?û8Ñ‹ÈEÒD^¶öT)ú®3ص¿ÖE´Ûß±^Ph«“'C] K³T*u7)²ÂNNØzw÷®Ü*Ó†®¯Ú»r?ßü4FŽÈð²Ð6¾8ö.˜¼¢%åH7bTd‹Ý–bÈn`§>â><‡šj2V‰qÛ uoF`Cì‚fŸëm† YAáÅ}‘sÙ-Ö·èô—ÞÓNÖ¼Ú“U¾–»ïExÒÖ1énæ ßá­ëŠôõx^(Yt£2÷–¤¥–úìÞz†_‘Ø3!?í Ð7ÓJú¡—Ñ—§‹ÅÚý"@Û.J á=g®ßä<æÌ7d>iÜ‹©ì!öò yEë°¬ÆÏ‘y+ÓŽî&wÎEÅÀÐ+]Ó{mݹ ±+Û…bYq_¤lŒTä(}w¾fæÜY‘7ÓÖq4ÌàyU59wÑgéÀJƒ«&ìÁÊ(»µ· ҇ʒ°u.5 î(ÀÓŸ!GqGEòC 1h‚ȯi-Í6»å!—©GôÉÌæÞ.•ä–<8ÍÄǸ&”sUˆî]y3ZrT÷þ#y`ÿ¼Î=ÓûÏí¾ˆ˜çX ‚ :ÓË©Ž»TTß4ïn׉k­?|Òo’Z¹Ÿ¹Ô s=6Ö`éCŒžygvÁLzzÎbB‰g²"‘!ÂìC¾VìÀ «ôåUf\Sà¬^9W2S’ú{°B]¨€ $¡tïˆæ¥a5\GQk€ÉGAmB"×b^î y¬äÞ€jO¿ªG‚5¼œÇÓvÉ.‰?ïUy#½ÞÕ;—Kõʯ6z•Fdé]ǃ¸!ßœcºöH«ž‘툔½Ù’gA›tH«  Iýà É;káÀ(K¨KC/<ÆÃÙòãY9U¢ûóòz}n’6Kþû7£Ùr6µ:<,hƒý¸:VÑýü‡Æ v:~‚rC¢.4_d <ŸêŸ‰Ó‹þ ¿Í,•üáÎSz»òñu½ý7ô”ËWt÷ß÷Þ_’K¾FÝ3|¾reå‡0ïçÛfÙ*kQÛc¾Û97Ô"çû#Ϙ֧t¥mì R´49ê›S:ïõqd w3t_£=Èײ`Hðw˜ "’¼“òB¬æÓ ðqþ˜¿'âåæ3£;$òàXù 2Š ÅñîyoWîGK:—š†±/󨉶Lâh¾}Y#og|á¦0ÊKgL'7­ÚDXh¦ïÈ?•2ÑMY©±ŽZe¸Ñ e»Ef‰+8}M%8:ƬêlJâ“ ŽØW%›êœŽŠz›iûâFw–R¿ûNÕc/8+Ù¯‡˜Ê–ã&…§Ú'´ü[V-ª[ëÎÞ Ûžzä¡è “+º¦fÏ3÷>ÓÞãÇ®¥§­W–U á²ßÿˆ.$ȉaÁu®]³¶/í2V# r› 47éGXmx²ï§ïŒÛÀ¨T¯a¯š@E¿¼U^Tˆz„ì¥êõÒQyÛ¦˜Yÿð´[¯ˆõ!P'êk–Cת wÊ£AD^õÔDÖ4|&æùðȳhÌÕÎÉ–˜ OÇè9²J"¶U‹güD¥§ _ö®­•â^¥¬Ä¢ËI(7F9 •žSè FÆ}–jT¢ßNÌ}à PgÎ?Yal »É¾͉ÜUô"¹óÅÜëß•ªOù©]Z^6åô¤¸.îž¼Ôf+w‹šU˜³)PükõCûýæ±v²;†0r·q ¢²˜ö”ÿÀ÷òï¤æ3‰Š§nЏɽÏYÄö­zÒ·–ÓýHGJZQó-û©×•Õ‹®$ê½Ë­|Ü5ï+ Ô¾üMŒª]qþ`¼×Öv¹ÕYJ‚ðÁýšØ€ó3“"NÞc1fË;õJ«‹‰Sñ2ý+w£9PDÎeí=ëžØ>xɼ¼@ëùxNÃÏqà+“Âî{ÍÙÎ!~O–¯±Ê—·úØÒ*‹+À—ýä>pX×Ò•t¢R™'Ì­羯|R¡•a®‡ ÇùáÜÅôS•ÉÒø¾½eid™¼ßx†ârý ‚SÖr¨>OPÓˆq#à™¿1W LRŠ7\gºr€8½\nž*§KH®¶âéçâ¯3¢ðùkéë«ê²]Ö/œ>nð¸Td6ÁÉ%ìÆâ0Ö7½ÔÏâCÉ(7ôB3îG}s®XR£3žiywõd+ˆÉpºòãT›_ðÑÒ-êFVñ­>$ \'èPݳۊº£\î¾ÓÉzjN»©™ŸÙ3žFŒ~e9]ÿúÑ›óO'†0¤­GÂb3ÚþJþËðxyE–Ã{å¡ë¤UÏ&šÌHöQ¡ã;.¤Oƒ†ú󨩏'­t—?PS’SÑíÏÄY–¼×O®r~ç-˲[bUdÄqœ=€~ ¸E¢b_)~'t*Fc(B^…Û’h½Mp†ƒòeWUã*š“¶„¬Ð5…R¹Ü¬r¥°µ©»ƒ³5ãÒ{?< ös3ËZçÿQ§»¨8„ÃØbìüâr¢'O;1 t6‰˜AÂÔœ%µð¶`JýÕ×/R]¿EÍ9YªÛÚ]Ú‡°Id4ppÏm÷Y›ÓV¸gÔŽïm-í(“ÜzqîÑÕ¸ç|FM#Ÿ–{<3 È:Ö°**P‚‘jµêe–Ö*yU-ïÚV[ ¥£Y>#¸[x°{F–?½Á?þ(È$Øo'šœ8sêr"¸â3Oº>’„ÌÊ£ Ž}ÛC´ô¥PB“:5Ôòf³§A÷‡ÔXò1âô5Ô(`“Yôæó„œfPrä§)…›)õþË*äc·%¤¯<|²]{¾ƒ!f͵ި”uTþþ4¾6pVþhmóî²tŒUb ÚÿP#±"Bû“¢sgMLù™¸ºã㦴£7ÌR”GJ²’{—ôn2pdò6ˆÅï÷9¡)÷n‘³ÃJ¥×®Œšu ”Øû¨ŸTÓ‡È æÀËõ…1^ðÊHÓçîWâ+^$•QM >;è]òô¶šŸ°ÌšÁ¹»};“ÏøX¨]¼/í³·gÜ$òˆ*´=÷ul±ÞÓ­qªÒV—Í….û¯M'UÙÞ âðB«+4Ð8¡Ýïjó7ÍG'_3…fËo_- #N?Ûè¶ ¯L¼O€>8õn21 tY ŠÃ¿‘ÔõG0¿xØìÛb~w<ÏôU7÷:nndÃÍÇãÕãN=,oîà (JzÕ S…4Öe|Ž?3{C„•³¸¸žD­äh+ñÊáì×j¦KDŠú¹Ü塘7UœÜ3'¨!•i[B\$iü¨H í-ÿÊ»¥]ᛲTw Ö“Rɸ7Ud¤kœ+»úŽç'5WŽ„0t¬OëçOkCÕßêõFB{„Æ6@Ó„Î.‰¿W~l­¬”·µVI';‹Ž±MÙ¦Ëru/㲚mK׃1gk¯%jX¿È¢À)?(¬cÒ¶¯Ñ]§¶½ëotÎ.«={.¯z´ªÍœ™ÉU÷‘¶ä"ç°ø-è5n%ØütÏäI©{I/¡møì@‘¢,ÑD¢§·Ç‹Â\a9ºªZ¸ïêRl§€0àÛ”6ŒFä$Dy‡VÐOÖû±½\Ó^ÿ¨mjtû…ÓbtN2JUªÕ³?;g„^JC‘˜ÛYÚ)«¹·Q¬ÕkûýM’9¡×Ö\ÂzQ—¹èˆÀ”SÉm²f ÆÜIP!´Î¿£‰^«ðÊRhãV`¡”;1}OŸ“·öl홚´Ì½óÜw!?ý;}·_4Ì“SÓî ¢ÛN‹Ø+¶»ì6ZzókO–]K9]q»  ˆ?æs¢Ê]e=mËúÙíUyÕÛ? £É·6]nÏæî&(åûjQðœïjX3“ÒùÝIõ0‘W‘á HÙ²*È<-ø–üò{Bé§¹uõw½Ô‰$ Ækšºû‹ÞQô"‚º¬¾• m·semŘzHIâ±Wi‡$\úÙàO×He쎒³r›.–rÂùؤe¯f«O?|ˆ“ 7B£¸B«9"\ö–ß*,‘Õ¥EAtÂ_§Ü »Ý_ ó=IÛµ«øÄ–Nq«&1RJí÷ÛhÕgã™w·B¥–Œ%OÑÏ%Ì—õª.lî&‰šºú±Èfµ[ö<‘ê”/µbT_r%TÑoá‰%Å¢·5åY/›èŽ&$/cÛ矈铅9+M-IȇÈ^Q!yCÏbñx×[%i²í²›Y‘Íí»(ÈyН'µ¦íeY'ñ…ô`^ñ he£n ÷)*p­z+¼úJÿiì‘ )ia{ Rp?;ÂDáE‘¼³Ç7HÏ+^¿¥1lsh ³ËöÀè4_ª™vy/šjoŽ9NÑx\dïb†_q÷6•ée[ô¢ÝåÏò'þ©>LçWy¯éš>¾[1ÌÏ'üáf:1Ï]ª“‘²dæõìÒzHV°Š² ¬fì§jõ£EøÉ|±' —n£wLþ=å‚$r»£¥Æ¢>rEÏëÚù€ƒW@–²ø,ò|U±eVW3t˜ ©ÈÙ¡n¿ “•qxºÿ_i¬'òÞç…w9‹I;(Ò|ù+¡:TÄÁ»µÆÄÔ¹ßpþ}ÔÔ„YçÌ:ÇL¡âã…eê|÷Ûr•¢«æ#Û6dÉx¹Å_Hø? ‹»6ºÐÓæšüZ‚ýz={u÷«F'­“†¢Ž<–§ÜÎ1çv+¼ô²¾Øhæ;ÐÑDM7ȵa«²ö-FÆ´Ù“ ´<štð„—=V1h;•¿¤sºæˆú!)ÔW8󢯾”ˆJõaâI?W'Ý£¤=ŇušäAµ³üï—¦Œl•¯<w‡gÐËØR PØê†¹ÑJ¬±™¾m(Ëèw}/¯¯ÏÔ?š72æ•8Jh«ÓÙ|ÕÜ œ@îâŠÌ‚¾À¥zIÍZø¶‰SµkZÚ~N{~~†q3.muz$†žÚØÖIä’2»ÙÕ’\r|^P§c/F¨}9óªÂ‰ð{ËoFzROòéÿr$^/š'3‘ŸãY7´ã9™BF7¤­ÉEŠ]]êêõçI#×O¼xÖkî)úVðÖÀ¢¯Kz 7Œ‘CaNëE«:EãB"[ï^G HwyÛ 5b¼ÎÙµ½r‰ß0[®wè˜|´äKŸh¸SËÚV³¯¦€èƒ[ƒ»ùxl> endobj 1065 0 obj << /Length1 1407 /Length2 5930 /Length3 0 /Length 6890 /Filter /FlateDecode >> stream xÚxTSëÒ6Ò¤7¥^Þ;Hï RB $¡ƒô*A:‚ô" ½+U@ºT¤Hï  ‚~Ñã¹÷žûÿk}ßÊZ;ûyfæ}Þyf'ks² *AQö0u#JTt-A@(*ŠpršÀ1ØßvN3˜;ŽBJÿBÅÆ`mª` ¨‹Bîy QH\$! D€@©¿(wi€*Øè î¡04 § ÊÍÇîè„ÁÖùûÀဤ¤$~‡”\aîp Ðcœ`®ØŠ0`Œ‚ÀaŸ¤à‘uÂ`ܤ……½¼¼„À®h!”»£<¯À ŽqÁÐ0wOð‹2@ì ûCMˆ„`âGÿå0F9`¼Àî0Ö€€C`H46Ä …¹°ÕÆZ:}7ò/°Î_ÀŸÃ€„@ÿJ÷'úW"8òw0A¹º‘>p¤#ÀŽ€ôÕu„0Þ ý#Ð(l<Ø G€í±€ß[Ô• `,Ã?üÐw¸-„†#~qþ•{ÌjH¨ ÊՆĠI~íOîƒ`ÏÝGøOs](/¤ßß+8êð‹ÔÃMØ èÓRýƒÁšHþms„ab@)qq1öó†8 ÿ*`âãûíümÆrðsC¹°4`pö‹Ä ö„0î°¿ÿtüsE p`s„#Iþk†9üµÆößî °bå}þugU…Døüþ»ÅšJ÷L•uùÿPþ—SYå ð‘J‰ H !!øgžÀßì[ Àð?»ûŒZH@ê/ØÓû›ˆçeðü^À?+è¡°z†xþ-ÿ@1 {ýŸ‡àwÈÿOû¿²ü¯òÿï©{ ¿ý<þ?ØŽðùƒÀêÙƒ ]vBÿ 5‡ý5к0(ÜÃõ¿½Z0vF”ŽX ‚î ïþe‡£ÕáÞ0¨qúKK7[G Phø¯ç6 ü/vô .Øg Û²ß.v²þYW AA ˆ˜8ìîö!Á*»ø°³ …yÿ–8@X‰Â`CXŽ”;ɯƂ°:¶C\Ð0Úé—äù!îîØü-lñ¿×¿çó†AHægP™0ç—aí5JL^‚ŸG––;£-û¢Ä0\³Ïüœt35&*ÛA«n ?5˜+‹˜˜ñgâÛ¿õ~ð:;x1M3ƒ£Ö·ª|(˜?øõäµ#ŒŠbt“x½JudÈBag…oÅb>s.Ñ-ºñb½ðª½q_jà (>£dKcÂÄ)åvîà>¶dãXÆ Y> Œ§v·J÷0Ñ2»Â} ?Wneøê³jŸ1ôñã›ìþ¾§¢ÇÚ=ÕâU4 ´¾÷Ør‡“è’²ï5¡q¸”ÅÎTÊRÙŠ\#¸ñì$¿Oô·% ˆz48ê©ßÐô¶Ñ£%6#—Û½xÌl»–eòU˜ìVsr´“@ÍSeÎj(ÎÙPúAµ("¯Ÿž@P×ùþ§îª¤ôÜRw¡1–ðQ¨¨Íúø­ »¸Ì$ˆuªBràÓseq«Û°ƒùÂ¥l*€†‘“Æ@ OÍyÙcøŽ€Ð—ç}ð ‹Û)ÈÓÍæ7íCÝ‘‡(Ž}ºÉàD‹ŽÌÞí¤&-±³wTf|jâ˜ZíYT—-oBnÂT Q^.¾A[§†Ì}E©¹qö3QŠ|ªY œt=bKép¥ )Jr—ý2– •âoŸÉ…4Ë¥J½?¼¦j¸›@Y»zðûëu›D{÷Ca"í¼ÎûNv%zÜ÷0wá;‰—›Ê–“Á‡3‹yÊ?LmiJ=Èsˆûÿeã´á ÏB©.ê>"úI×dàªíó·,÷ûã™Ó_ïötp§nxk6|;Ã?¤±Ò`+BT4&ˆµª|ì§‹6µêë´Ÿ6¹w¿uh<ýJ ²:—¹»ìf³Ù wàö½ü¡²*€š‚{.\JtµJ7ˆKÊŸ4Ê,P•ì‹$5x¼!Dd)„ãäÐH²†PÐ^ /رâxÜCU÷MÃíð¬‡ù#Mk-³ð½_È9^QˆºäwOÑŸ„-ôÅßø(¡ºj÷ílX›?dR Ñm!ˆ²¼»TrÑLU`™0ý¶ÀÂ@íPçJdÕV¤åFUKJ3ÕtÓ{’vp›»«ÝƒÁ¿ EvqöÍ\ï6‹Q¦Ú“ã⽌–„)ÜÓï\OVÓ·ÕÒ?Ô¡Â5r½`Uϵ?*® àD©\XŠ‹Þwó…1{:L£BùÆneëîìÝ® 8G(0Cø£Ø÷«l*×­Ë]#Ö(ßÁK´Ëõ'ãÙ´nľœzù}ãÖ#ª¶˜)s™Œ®·GéŠËöó_ýòÅ0,úY½—Úy"é_ÉDX8‰IÖ4W*í®Z‘©c[0[ÿA¦Ò:Dj†ª{úÞ³5w7Y¡»îÉm™'ÙµrÃäÂúWK*:°W|mLͼ9a´wÝÓH%u®?ÛPÕ‰„|JÑV w€~8›¢Ã…š>ÎÞ±¡¤ua`ƒ[^—á5ŸIS ÕÔôuᜋ†zOd Þ525ЪsðÓ-A3†“îXV·çï ïz¾N³Êoù>Çڬ韯¸“¡‘B-»hÀïùðû@Ϥi~Žzv'Ó]…Óº…å7¾™0 OòÙ›rï @è€U ŠÅB½d1›CÑÔh“Ïu’­FÃâÈÐ}Þ°z²J ÄÔú$'y8q˜iá·d#ßç4''[~‘ã6TªNNe× ü22V”S‡·g¾½êŸÏE‹8p«œø,®Ôؼ˜z¡h a•L©E2J<äeX¿¦uy×E_îæÞ ÅS@ré„ÀG”ÚãÅ›ë.¸ï2øÈ%ˆâY-°ìžkÛœz€j ±™åhâŠý|rlM%‰HMXkB·p……½N\Y±áÍd3ùÜ&;Á]®ÜŸ¯[¦î0fÏ—IØL½ô°Á1Ž&Q;ÎW–£z_à‰|Ÿa²JT•‘P;ÖÎ>q^Fc-L0"à5Ñ?¨˜7•Æÿ˜9N~íª uC¾_­Ÿú4íWN¦W‚sàĉþZ¾u˜ Ài™]Ö+¤Yû\i¶°6:Ú.Ë´>ÝT˜ ÅÝ;¶Çä#RÒ(Å“~êGyvÛ–m½­“J4Øà챺¿Nd:oq?o-STw?m³«ÍsŽUÊ…Ô‡*ž¾A3ÙÇM†Qupvâ̰Ê—>4 ³®ü˜eï«¡¢ÀÎâûXäŶY›6"7\dd°É±ÞÔ"ý³ãï`G¼Ú¹Í"(weÏç.&Á–FÒ7"8ÂL}Σø€Èù.¦Ø¹7I]‡Ã«ï_2öèK޽:ƒ Ÿ4Œ¡hçq+c²t4‹Þµj8=iÌåMÿBø0—ö=ÄÒ'µo¤­(/ë ­îÛØ+;AÅ:B µÁ÷iöXíøYƸt°ªð±Ö‚Ÿ†'Ô24¼÷ÜEϼÁòÕžúœì¦r@]Ú–KÝûÂ%£=ž…é1‘9NJ ®ÒåÕ®kXNì(ÅÂß55õf·ì.ƒáçVºª°|Ÿÿ”„ÏÛÔü óX{Ÿ¨5@âß½œÇKÖíß™®:c¡ßÁÌ…ã]jÂ2#æ Tê·<õö7Ø5ÄH‹wÉö ór­@ùJ7_Å>á÷ߨáYk1›>ZŠÑ(­DH„h;0™Óú.ºçÙîÉ}×`÷ã.¿;a¡ (æéºÕ“ZqÀà+ü¡®qÞwR§ç~˜K´ê5Öþ»‚_—j{n1Œ÷¿5Ÿ( ,GVEÕ½Yf˜kVZ{Òòºƒè¬ռʷÂ1 öFê°„DóÕ?ƒÁÊŠŠ;q¼\"o±^h‚x%ˆJàìqã=!@–¹Áõ=f ð.jêhß“ Éþ>ÿ®"yèOg“̸àž3×õ§Ë KÞ:ª 1$$̽jͼ&å{½í³I”Êb p/æQkR_zÄõ ßÞS©Ø~÷±i­Çù(çjÓ=í3oçüV!b‚‘ ~{PÍÌË#Ò­,„ªÎá}<ÑàóFA$ê´ý¸ƒ[vܲc‰&¸ ¾ Í“ŽåS»óyTˆŠOó³V)—çø§NìëÈ6Å÷ÕŠ3uÝ9æ Þ÷ད¢‘*Ô±dBŸ¶—¡ãÇ8·l> yˆÐLLTÎh÷N-©ŽYô£Ó7?//\ÉhàQ2kNÚ]!öb»Ä¶2Û†Mpæ@Æ5·Wg}ñ¬C„„èd\1!‹Ð<æÉ‘¼GëÌ&ù{8ÅgPv^KEÅÛçDLH ïÍr,Ë·F7%ì€ËÌ ·8}ænÝ{Ù2gQÈXÐ-ŠÑòöv>ŸºÝg•r§%TõŽÚ»d7·ju¾ŠÒ/µ‹éžîúSÐQ¤òF!Õ$žƒT(_5Ó®…ô—Î ùöLi¾‘EÜ‘8º©d.p²³ ?‹]0’˜w|A)Ù±§F›o;ØB»÷½Y#·ïüý“·J, ¼ÄÈý³±uÓ&íO¨z2ßëŒ.‘ßÛ98Þ²Q…—^YJ£es>4‹t³Ñ.šF~óÏÂI»CðUÌ,lÇaÂ4fû¡ApÀù夿ÜÏØLìÿ™n1}ƒ‚Mt¦ÔQ k|ÀÚç>~G7¥ ×rþÎ"bT*ƒ!Y_¦I“ÒªžÎ1S m «—21 ¶  Ò0FÙË­1¸BìÌ^0R'F†.rƒ g°µW·ãý{‘¨zÅšÚ•´àŸ¶‡ÛJ“¢%+†t[]ʬf§8¥Ô ZéåH[+*6sü¼®WÛRˆ‰ž©ï;NuÕÝÍQÎØ\ËÚU*­ ^îxørìp˜âöҫʼn» „1¬‘…‰ãû ·ÞWžÌ÷剟®¶_g~æ^Xb•ôñµ§Ý'Òö†Úïq7O»½Ï58~æ1…m ä·ŒÞxû¤©ô懱Nõ‘Œ'šṲ́¹[U¯Øn^»Í7ÜQ.D ¼áEÐm$ÙÊ£8?ÿ8Ó— Òܡأǥåú4÷ãsy ¶7®©°£!ÅQ=¹ùOöI3ÍÍ‹Éw.7§“®Ëú\dëyŸn•vô ÷àbôê‹z£"/)›]”´¬#yoê^P6¬ÿ´L›G60†Äd$Ls•òÙij $q_Bq(Vn]r5 úË.ö>=ïd`Ü«¡þ¹=_ÎÿB^Ô(›ÿȇÛu-›aº,åÆfÛ‰[bؾðe»X/K£þ`ùzº<9n_éÈ+gëzj䉨…ü½|_…yÕ½ 9½‹ðköH2–8¿‡7í-yäÙç%ù6wޏ”úˆ^ Vb.p>‚N¢5W»ÉT½VZ.¬ ƒH;˜év ÏüԒ醊z{Ï3,gP qЙ-o81b²Ï|]8\\8¬ïîTÓáBšó¿US¶©à›§)Ÿ|Í9{êvaXý,Åp=#ß~¹”NØíäZÃÉ3f“”‡ê’ø¶?¦•¨’»;4†ï¸jÇûqùÊÈNw廯ZÁ%ÞŽÑ×ïd??âæ£¿zhdr yŒ‘ešŽu9&R(qeàÍs8m©ÞK]^)¸ð¹Ã³ZmǹàWÎDYÂÖnÈš- äB/y·œ:l(WðWN»?>P[:°ÂL,8êk3Ç>çøÆñRŽ–ñSÈl¶Â6TQÂKi-ZΘF¾=Í<Ãɧ ÉÜØ±U”+£}¾œ~}ÐÝ­ƒ¡Dë|•§NÅHÙ G³`R÷4¸ÏWT¤µºñâWñžüȶ½IUÀ[;ÍÓò-«¨á†®n+IC]ÙÃ~O®Æê¡s•¥Ï¢z8:÷Ñu^&~IôèöÖ±š ƒÜÇü‚9Ueù¦ŸÖª1½0`oÓˆà¯hŸ´ì„IÐ(+xRψàP&¦LzGB©×Ô<–Z‚‰±»_öeì¦é6֕Ɖ4¥ë_<[¶Ôd±¥4¬´iø5{…ÙXNd2 <ãP/}—¦©:lƨàvLè3ñ´…Ö`‘S]®-¤{ _9’àlþ,_C{ÎÀ©î‘^½U3¾ÖívT Ñ¡ ½ïâ¤ñ±ìTÚ“ØËàkvw±¿Êj ™{ÜíWË9쌈 (B”Q­è‰¸8€OP÷$Ds)·ë=—·»Nµß›ûeëN-Š*Ì&Ä•é[•6g¡¥ò¼N™~ÝbEæz˜òídâè š!ƒe-…<6“Â(€Ð&4ý.Þ™©õÚ‹Ðd¹ ‹˜7®’Åê_Źébä}äª#øVƒíUð:Ùu`ú˜”ÜkóÜ}Å©—'לžÏå 2ëãî„æ¤pI`0¸g¾2ÚŽwN&âXeš¼ü¢ò¨N¡ë^h›p²:»¸©P P~ƒ÷”ÿƒ¶áT}hªbBn'ø½µ¸êºg½<[ÎöÖëR\ÿ£PÀãÜ ÌÎp ÕaÙÊpY%UQSeÕ«K‰˜:StHæ‹™²~ŸÏC½)„&y±*b—îŽ+¦½”bo9"ŸÆrù×$4tÅ=Jý¨Q¾6'™ût›,¿š@×óóóMLIèê€ìh¬y´—e=jÝgˆûÖüV¸þ\c”+¹PìóøªCb#«Î›ãé(=Yç;ëD?¸C6zÛAU4sä¯dnS†?Ð ÌÌðHÏÁjÎÂ#ViîgÜeÕŽrŒÄ/ëÛ,ì.Û  QŒÍ6©|˜æŸ±sökûÛj|*x³zì¡‘MpÂtÕ+)%t5SÒ¶aÏè© áTëâW +ŽâBHZ´È#O‰µÔ7¤º1Oæ ŒMõG!ýäÎ"*®VEŸ*ô%äƒ]Ì¿¹”uà[Ts‡¾Üg)¦Ï¦ ë–5-y9«÷^Ru~ž%¥Œ”'͸ÃÄx”6á¶H…ÒIñ«IÔê­e@c%ýú¬c][r„#nôQæ¶ÍÆÓA=[âFX¦ý¸í…r£9ÝÊ`ËPë5È‘PW@Ýëu6 Z9®bÏz혢“;Ú7o°*£lc˜ _–"úµ‹Où†h]¨² £iI«Ÿ|ûgž­>ì‡Ý;’Û鯖ìB¥è …{‹>ëÖÁ‚ræ^ nOÖ4\c¥ÜuZóŽ)¶?ì"¾ÚjÛ®°Ý‘¸IëçǧÜÅ0w—×Xe×F1ÜËÿQ¦¯XÈ©›¤²¸E†)n˜ó$˜~ÀØ"l¿:Ñs¬k¦N7û9Êï¢õYÄ\JÞ!- ¬ @9~ÑÛx*Љl¬øÙšï\QÜãÏ^R¿~ºŸ8C’70hE7¥㔇oIMWÇ;‡“p¡[ú‘r‡3P3ùŽ@¥÷¨ÿ)ºí½W¤™+«®Mµº9w}dÏ©äFË}ññ[á8®‹NÆ‚æ÷©ÈñFïÝânª9’+]ûà¥÷9§Œ(—Žæ¸Ð[2X óê±Vưi/ŠF³Û|žøêøð‡°ÖA­ŸGÆ]îÇdV(ËE½7­2¼¼C¬ÿõhÇŽzˆ¨Ä-9ݯy©TKü¦Jšö• ž°WMŽ+-aŇ!ãw/ ¿³N¨èœœ$5Ó{§{ê,f Wo^̺ÎEöˆ=lM-E~$¿QÆŸ¢Ôó;çÅí…j«=È õA 7†]ã©)£sÜRA˜OÌ!ÆÓ{ZÚj˜DïqßÇ–ö¥ ”=¥ü¹=ÿÆkýë9Dµ÷'nq¯ãUq‹—*”]ªÚ¬ú„ ¯#²x½¬ŠÍ2†»­¶íĂԿn±ÚP(‰zV¬ègyNV37Š\ó$%ñýöÙ¤yñÛ0pþ#­ý³¬kVY¾>cÉÓø0På{—i±§P#¥];ž¾pE¿D¹ë>æò]‡Qkòß’ª7|×û~¶˜.#úýJ¡GSfâ—v(ë£l/Q†`ãòNh=¼®Xùî •Hšÿ¾ÃcmûN÷î:{zà9·Çþ?›ü{ÑïÀú¸›=íÏm¦_<¹Å;!èפŸÐR£?óM„Ò¨´»žÂûÍæÑí(Ã>¢S/eÇñ¤•ö+ã«¶Ü,öÙrD–ýᙯLKmº–ÏôµÙ믇·£ÝÜK]tI› »a\¯ž‰¦¦#z†¢1Æç뽜,Á{¼›ÂnF‹ó¯ÊÙo‰4x¤«Á’Å.ø{çkÐ%÷¹‰hk[J¾¤Ú°2|ÉxzXcŒ Îsî;$20úz2àP.­<â¢Ñö} G›¶q¹zN¯¶M(° 3™¤’Ó½‰¢á¥ ¾0ûT(=Éh:/2Ñ,?Šš}“ÂNÑehÞú,TÿêËDÒ]>}ßï­BægÈ“ K®Ë¥ssc4 »Ûr;ÔO,oeÔŸ]¼9ÜPCi-©Ç¤ g+\¾ÉX&³£…êõø6^š´Ö&¤Ž4*È™°N2~bßt]°V:^{æ^~ì ý¨çé]ãqP]ÌÉ¢í¶-íÞô$ñ9b¦YN·ãßš7W@áCe‚*^07rå⼩PÊÑê±s¡ª½8Eúxyg1ì‡öµ‹uõÆO ¾›@ÐàÕøäüHÿFzaL}áþ×­ä…¢)÷Ë-Øz õqÎÙ”¨\ùgñøEáng <Õ«½‘¯ý4_¢k7€ÞY9 úKø“•¶í¶7•jÔR«TÐŽ£åó¼IôóдÆMÕ.#ÇŸvw›ÌJïŒ)בé|-·z˜ Cúnë뙸ÉY¨GM/qù@¿ÏzþdžÞ[ɲ4¦ª:…,RM1cÞGMS)]!Æù«Ö•ÕuŸMSÁ%:ÿUœ¦ë§¡M«.ˆ çõg/ V´2?HiQ÷¾u´Õ„_¨ ̶ áˆ@‡™wzC-‹Z¨þ7a¯ endstream endobj 1066 0 obj << /Type /FontDescriptor /FontName /HAJUBM+CMSY10 /Flags 4 /FontBBox [-29 -960 1116 775] /Ascent 750 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 40 /XHeight 431 /CharSet (/backslash) /FontFile 1065 0 R >> endobj 176 0 obj << /Type /Font /Subtype /Type1 /BaseFont /SYFPBV+CMMI10 /FontDescriptor 1064 0 R /FirstChar 60 /LastChar 62 /Widths 624 0 R >> endobj 300 0 obj << /Type /Font /Subtype /Type1 /BaseFont /HAJUBM+CMSY10 /FontDescriptor 1066 0 R /FirstChar 110 /LastChar 110 /Widths 530 0 R >> endobj 118 0 obj << /Type /Pages /Count 6 /Parent 1067 0 R /Kids [110 0 R 138 0 R 155 0 R 159 0 R 164 0 R 168 0 R] >> endobj 178 0 obj << /Type /Pages /Count 6 /Parent 1067 0 R /Kids [172 0 R 180 0 R 184 0 R 188 0 R 192 0 R 196 0 R] >> endobj 203 0 obj << /Type /Pages /Count 6 /Parent 1067 0 R /Kids [200 0 R 205 0 R 209 0 R 213 0 R 217 0 R 221 0 R] >> endobj 228 0 obj << /Type /Pages /Count 6 /Parent 1067 0 R /Kids [225 0 R 230 0 R 234 0 R 239 0 R 243 0 R 247 0 R] >> endobj 254 0 obj << /Type /Pages /Count 6 /Parent 1067 0 R /Kids [251 0 R 256 0 R 260 0 R 264 0 R 268 0 R 272 0 R] >> endobj 282 0 obj << /Type /Pages /Count 6 /Parent 1067 0 R /Kids [279 0 R 284 0 R 290 0 R 297 0 R 303 0 R 307 0 R] >> endobj 320 0 obj << /Type /Pages /Count 6 /Parent 1068 0 R /Kids [315 0 R 322 0 R 326 0 R 330 0 R 334 0 R 338 0 R] >> endobj 346 0 obj << /Type /Pages /Count 6 /Parent 1068 0 R /Kids [342 0 R 348 0 R 355 0 R 363 0 R 369 0 R 379 0 R] >> endobj 388 0 obj << /Type /Pages /Count 6 /Parent 1068 0 R /Kids [385 0 R 390 0 R 394 0 R 399 0 R 403 0 R 408 0 R] >> endobj 415 0 obj << /Type /Pages /Count 6 /Parent 1068 0 R /Kids [412 0 R 417 0 R 421 0 R 425 0 R 429 0 R 433 0 R] >> endobj 440 0 obj << /Type /Pages /Count 6 /Parent 1068 0 R /Kids [437 0 R 442 0 R 446 0 R 450 0 R 454 0 R 458 0 R] >> endobj 465 0 obj << /Type /Pages /Count 4 /Parent 1068 0 R /Kids [462 0 R 467 0 R 471 0 R 475 0 R] >> endobj 1067 0 obj << /Type /Pages /Count 36 /Parent 1069 0 R /Kids [118 0 R 178 0 R 203 0 R 228 0 R 254 0 R 282 0 R] >> endobj 1068 0 obj << /Type /Pages /Count 34 /Parent 1069 0 R /Kids [320 0 R 346 0 R 388 0 R 415 0 R 440 0 R 465 0 R] >> endobj 1069 0 obj << /Type /Pages /Count 70 /Kids [1067 0 R 1068 0 R] >> endobj 1070 0 obj << /Type /Outlines /First 3 0 R /Last 107 0 R /Count 27 >> endobj 107 0 obj << /Title 108 0 R /A 105 0 R /Parent 1070 0 R /Prev 103 0 R >> endobj 103 0 obj << /Title 104 0 R /A 101 0 R /Parent 1070 0 R /Prev 99 0 R /Next 107 0 R >> endobj 99 0 obj << /Title 100 0 R /A 97 0 R /Parent 1070 0 R /Prev 95 0 R /Next 103 0 R >> endobj 95 0 obj << /Title 96 0 R /A 93 0 R /Parent 1070 0 R /Prev 91 0 R /Next 99 0 R >> endobj 91 0 obj << /Title 92 0 R /A 89 0 R /Parent 1070 0 R /Prev 87 0 R /Next 95 0 R >> endobj 87 0 obj << /Title 88 0 R /A 85 0 R /Parent 1070 0 R /Prev 83 0 R /Next 91 0 R >> endobj 83 0 obj << /Title 84 0 R /A 81 0 R /Parent 1070 0 R /Prev 79 0 R /Next 87 0 R >> endobj 79 0 obj << /Title 80 0 R /A 77 0 R /Parent 1070 0 R /Prev 75 0 R /Next 83 0 R >> endobj 75 0 obj << /Title 76 0 R /A 73 0 R /Parent 1070 0 R /Prev 71 0 R /Next 79 0 R >> endobj 71 0 obj << /Title 72 0 R /A 69 0 R /Parent 1070 0 R /Prev 67 0 R /Next 75 0 R >> endobj 67 0 obj << /Title 68 0 R /A 65 0 R /Parent 1070 0 R /Prev 63 0 R /Next 71 0 R >> endobj 63 0 obj << /Title 64 0 R /A 61 0 R /Parent 1070 0 R /Prev 59 0 R /Next 67 0 R >> endobj 59 0 obj << /Title 60 0 R /A 57 0 R /Parent 1070 0 R /Prev 55 0 R /Next 63 0 R >> endobj 55 0 obj << /Title 56 0 R /A 53 0 R /Parent 1070 0 R /Prev 51 0 R /Next 59 0 R >> endobj 51 0 obj << /Title 52 0 R /A 49 0 R /Parent 1070 0 R /Prev 47 0 R /Next 55 0 R >> endobj 47 0 obj << /Title 48 0 R /A 45 0 R /Parent 1070 0 R /Prev 43 0 R /Next 51 0 R >> endobj 43 0 obj << /Title 44 0 R /A 41 0 R /Parent 1070 0 R /Prev 39 0 R /Next 47 0 R >> endobj 39 0 obj << /Title 40 0 R /A 37 0 R /Parent 1070 0 R /Prev 35 0 R /Next 43 0 R >> endobj 35 0 obj << /Title 36 0 R /A 33 0 R /Parent 1070 0 R /Prev 31 0 R /Next 39 0 R >> endobj 31 0 obj << /Title 32 0 R /A 29 0 R /Parent 1070 0 R /Prev 27 0 R /Next 35 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 1070 0 R /Prev 23 0 R /Next 31 0 R >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 1070 0 R /Prev 19 0 R /Next 27 0 R >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 1070 0 R /Prev 15 0 R /Next 23 0 R >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 1070 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 1070 0 R /Prev 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 1070 0 R /Prev 3 0 R /Next 11 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R /Parent 1070 0 R /Next 7 0 R >> endobj 1071 0 obj << /Names [(Doc-Start) 114 0 R (page.1) 113 0 R (page.10) 190 0 R (page.11) 194 0 R (page.12) 198 0 R (page.13) 202 0 R] /Limits [(Doc-Start) (page.13)] >> endobj 1072 0 obj << /Names [(page.14) 207 0 R (page.15) 211 0 R (page.16) 215 0 R (page.17) 219 0 R (page.18) 223 0 R (page.19) 227 0 R] /Limits [(page.14) (page.19)] >> endobj 1073 0 obj << /Names [(page.2) 140 0 R (page.20) 232 0 R (page.21) 236 0 R (page.22) 241 0 R (page.23) 245 0 R (page.24) 249 0 R] /Limits [(page.2) (page.24)] >> endobj 1074 0 obj << /Names [(page.25) 253 0 R (page.26) 258 0 R (page.27) 262 0 R (page.28) 266 0 R (page.29) 270 0 R (page.3) 157 0 R] /Limits [(page.25) (page.3)] >> endobj 1075 0 obj << /Names [(page.30) 274 0 R (page.31) 281 0 R (page.32) 286 0 R (page.33) 292 0 R (page.34) 299 0 R (page.35) 305 0 R] /Limits [(page.30) (page.35)] >> endobj 1076 0 obj << /Names [(page.36) 309 0 R (page.37) 317 0 R (page.38) 324 0 R (page.39) 328 0 R (page.4) 161 0 R (page.40) 332 0 R] /Limits [(page.36) (page.40)] >> endobj 1077 0 obj << /Names [(page.41) 336 0 R (page.42) 340 0 R (page.43) 344 0 R (page.44) 350 0 R (page.45) 357 0 R (page.46) 365 0 R] /Limits [(page.41) (page.46)] >> endobj 1078 0 obj << /Names [(page.47) 371 0 R (page.48) 381 0 R (page.49) 387 0 R (page.5) 166 0 R (page.50) 392 0 R (page.51) 396 0 R] /Limits [(page.47) (page.51)] >> endobj 1079 0 obj << /Names [(page.52) 401 0 R (page.53) 405 0 R (page.54) 410 0 R (page.55) 414 0 R (page.56) 419 0 R (page.57) 423 0 R] /Limits [(page.52) (page.57)] >> endobj 1080 0 obj << /Names [(page.58) 427 0 R (page.59) 431 0 R (page.6) 170 0 R (page.60) 435 0 R (page.61) 439 0 R (page.62) 444 0 R] /Limits [(page.58) (page.62)] >> endobj 1081 0 obj << /Names [(page.63) 448 0 R (page.64) 452 0 R (page.65) 456 0 R (page.66) 460 0 R (page.67) 464 0 R (page.68) 469 0 R] /Limits [(page.63) (page.68)] >> endobj 1082 0 obj << /Names [(page.69) 473 0 R (page.7) 174 0 R (page.70) 477 0 R (page.8) 182 0 R (page.9) 186 0 R (section*.1) 143 0 R] /Limits [(page.69) (section*.1)] >> endobj 1083 0 obj << /Names [(section*.15) 276 0 R (section*.16) 277 0 R (section*.17) 287 0 R (section*.18) 288 0 R (section*.19) 293 0 R (section*.20) 294 0 R] /Limits [(section*.15) (section*.20)] >> endobj 1084 0 obj << /Names [(section*.22) 295 0 R (section*.24) 301 0 R (section*.27) 310 0 R (section*.28) 311 0 R (section*.29) 312 0 R (section*.30) 313 0 R] /Limits [(section*.22) (section*.30)] >> endobj 1085 0 obj << /Names [(section*.31) 318 0 R (section*.32) 319 0 R (section*.35) 345 0 R (section*.36) 351 0 R (section*.37) 352 0 R (section*.38) 353 0 R] /Limits [(section*.31) (section*.38)] >> endobj 1086 0 obj << /Names [(section*.39) 358 0 R (section*.40) 359 0 R (section*.41) 360 0 R (section*.42) 361 0 R (section*.43) 366 0 R (section*.44) 367 0 R] /Limits [(section*.39) (section*.44)] >> endobj 1087 0 obj << /Names [(section*.45) 372 0 R (section*.46) 373 0 R (section*.47) 374 0 R (section*.48) 375 0 R (section*.49) 376 0 R (section*.50) 377 0 R] /Limits [(section*.45) (section*.50)] >> endobj 1088 0 obj << /Names [(section*.51) 382 0 R (section*.52) 383 0 R (section.10) 34 0 R (section.11) 38 0 R (section.12) 42 0 R (section.13) 46 0 R] /Limits [(section*.51) (section.13)] >> endobj 1089 0 obj << /Names [(section.14) 50 0 R (section.2) 2 0 R (section.21) 54 0 R (section.23) 58 0 R (section.25) 62 0 R (section.26) 66 0 R] /Limits [(section.14) (section.26)] >> endobj 1090 0 obj << /Names [(section.3) 6 0 R (section.33) 70 0 R (section.34) 74 0 R (section.4) 10 0 R (section.5) 14 0 R (section.53) 78 0 R] /Limits [(section.3) (section.53)] >> endobj 1091 0 obj << /Names [(section.54) 82 0 R (section.55) 86 0 R (section.56) 90 0 R (section.57) 94 0 R (section.58) 98 0 R (section.59) 102 0 R] /Limits [(section.54) (section.59)] >> endobj 1092 0 obj << /Names [(section.6) 18 0 R (section.60) 106 0 R (section.7) 22 0 R (section.8) 26 0 R (section.9) 30 0 R] /Limits [(section.6) (section.9)] >> endobj 1093 0 obj << /Kids [1071 0 R 1072 0 R 1073 0 R 1074 0 R 1075 0 R 1076 0 R] /Limits [(Doc-Start) (page.40)] >> endobj 1094 0 obj << /Kids [1077 0 R 1078 0 R 1079 0 R 1080 0 R 1081 0 R 1082 0 R] /Limits [(page.41) (section*.1)] >> endobj 1095 0 obj << /Kids [1083 0 R 1084 0 R 1085 0 R 1086 0 R 1087 0 R 1088 0 R] /Limits [(section*.15) (section.13)] >> endobj 1096 0 obj << /Kids [1089 0 R 1090 0 R 1091 0 R 1092 0 R] /Limits [(section.14) (section.9)] >> endobj 1097 0 obj << /Kids [1093 0 R 1094 0 R 1095 0 R 1096 0 R] /Limits [(Doc-Start) (section.9)] >> endobj 1098 0 obj << /Dests 1097 0 R >> endobj 1099 0 obj << /Type /Catalog /Pages 1069 0 R /Outlines 1070 0 R /Names 1098 0 R /PageMode/UseOutlines/PageLabels<>1<>]>> /OpenAction 109 0 R >> endobj 1100 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.10)/Keywords() /CreationDate (D:20150606134850-04'00') /ModDate (D:20150606134850-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-1.40.10-2.2 (TeX Live 2009/Debian) kpathsea version 5.0.0) >> endobj xref 0 1101 0000000000 65535 f 0000000015 00000 n 0000010823 00000 n 0000361882 00000 n 0000000060 00000 n 0000000084 00000 n 0000010879 00000 n 0000361797 00000 n 0000000129 00000 n 0000000157 00000 n 0000010937 00000 n 0000361710 00000 n 0000000202 00000 n 0000000234 00000 n 0000010996 00000 n 0000361621 00000 n 0000000280 00000 n 0000000317 00000 n 0000017454 00000 n 0000361532 00000 n 0000000363 00000 n 0000000393 00000 n 0000053637 00000 n 0000361443 00000 n 0000000439 00000 n 0000000481 00000 n 0000057022 00000 n 0000361354 00000 n 0000000527 00000 n 0000000573 00000 n 0000058954 00000 n 0000361265 00000 n 0000000619 00000 n 0000000670 00000 n 0000063697 00000 n 0000361176 00000 n 0000000717 00000 n 0000000743 00000 n 0000066063 00000 n 0000361087 00000 n 0000000790 00000 n 0000000823 00000 n 0000068318 00000 n 0000360998 00000 n 0000000870 00000 n 0000000909 00000 n 0000070230 00000 n 0000360909 00000 n 0000000956 00000 n 0000000999 00000 n 0000071905 00000 n 0000360820 00000 n 0000001046 00000 n 0000001104 00000 n 0000078375 00000 n 0000360731 00000 n 0000001151 00000 n 0000001214 00000 n 0000080879 00000 n 0000360642 00000 n 0000001261 00000 n 0000001300 00000 n 0000083222 00000 n 0000360553 00000 n 0000001347 00000 n 0000001388 00000 n 0000085540 00000 n 0000360464 00000 n 0000001435 00000 n 0000001482 00000 n 0000088162 00000 n 0000360375 00000 n 0000001529 00000 n 0000001570 00000 n 0000102352 00000 n 0000360286 00000 n 0000001617 00000 n 0000001659 00000 n 0000118673 00000 n 0000360197 00000 n 0000001706 00000 n 0000001747 00000 n 0000146047 00000 n 0000360108 00000 n 0000001794 00000 n 0000001846 00000 n 0000162156 00000 n 0000360019 00000 n 0000001893 00000 n 0000001919 00000 n 0000162213 00000 n 0000359930 00000 n 0000001966 00000 n 0000001995 00000 n 0000164752 00000 n 0000359841 00000 n 0000002042 00000 n 0000002071 00000 n 0000164811 00000 n 0000359750 00000 n 0000002118 00000 n 0000002153 00000 n 0000168285 00000 n 0000359657 00000 n 0000002201 00000 n 0000002236 00000 n 0000169102 00000 n 0000359577 00000 n 0000002284 00000 n 0000002315 00000 n 0000002620 00000 n 0000002850 00000 n 0000002367 00000 n 0000002732 00000 n 0000002792 00000 n 0000341935 00000 n 0000336638 00000 n 0000328689 00000 n 0000357787 00000 n 0000003910 00000 n 0000004061 00000 n 0000004211 00000 n 0000004363 00000 n 0000004515 00000 n 0000004667 00000 n 0000004818 00000 n 0000004970 00000 n 0000005121 00000 n 0000005274 00000 n 0000005427 00000 n 0000005580 00000 n 0000005733 00000 n 0000005886 00000 n 0000006038 00000 n 0000006190 00000 n 0000006341 00000 n 0000007434 00000 n 0000006614 00000 n 0000003650 00000 n 0000002948 00000 n 0000006494 00000 n 0000302793 00000 n 0000288484 00000 n 0000006554 00000 n 0000270061 00000 n 0000007587 00000 n 0000007739 00000 n 0000007890 00000 n 0000008043 00000 n 0000008196 00000 n 0000008349 00000 n 0000008502 00000 n 0000008655 00000 n 0000008808 00000 n 0000009021 00000 n 0000007230 00000 n 0000006725 00000 n 0000008961 00000 n 0000011055 00000 n 0000010651 00000 n 0000009119 00000 n 0000010763 00000 n 0000242844 00000 n 0000013078 00000 n 0000012906 00000 n 0000011166 00000 n 0000013018 00000 n 0000015137 00000 n 0000014965 00000 n 0000013176 00000 n 0000015077 00000 n 0000017513 00000 n 0000017282 00000 n 0000015235 00000 n 0000017394 00000 n 0000217949 00000 n 0000357497 00000 n 0000210782 00000 n 0000357905 00000 n 0000020335 00000 n 0000020163 00000 n 0000017676 00000 n 0000020275 00000 n 0000023200 00000 n 0000023028 00000 n 0000020472 00000 n 0000023140 00000 n 0000026094 00000 n 0000025922 00000 n 0000023337 00000 n 0000026034 00000 n 0000028920 00000 n 0000028748 00000 n 0000026231 00000 n 0000028860 00000 n 0000031088 00000 n 0000030916 00000 n 0000029070 00000 n 0000031028 00000 n 0000033923 00000 n 0000033751 00000 n 0000031212 00000 n 0000033863 00000 n 0000358023 00000 n 0000036364 00000 n 0000036192 00000 n 0000034073 00000 n 0000036304 00000 n 0000038818 00000 n 0000038646 00000 n 0000036501 00000 n 0000038758 00000 n 0000041704 00000 n 0000041532 00000 n 0000038942 00000 n 0000041644 00000 n 0000043885 00000 n 0000043713 00000 n 0000041854 00000 n 0000043825 00000 n 0000046246 00000 n 0000046074 00000 n 0000044035 00000 n 0000046186 00000 n 0000048705 00000 n 0000048533 00000 n 0000046357 00000 n 0000048645 00000 n 0000358141 00000 n 0000051482 00000 n 0000051310 00000 n 0000048842 00000 n 0000051422 00000 n 0000053696 00000 n 0000053465 00000 n 0000051606 00000 n 0000053577 00000 n 0000202439 00000 n 0000055335 00000 n 0000055163 00000 n 0000053846 00000 n 0000055275 00000 n 0000057081 00000 n 0000056850 00000 n 0000055433 00000 n 0000056962 00000 n 0000059013 00000 n 0000058782 00000 n 0000057192 00000 n 0000058894 00000 n 0000062025 00000 n 0000061853 00000 n 0000059124 00000 n 0000061965 00000 n 0000358259 00000 n 0000063756 00000 n 0000063525 00000 n 0000062123 00000 n 0000063637 00000 n 0000066122 00000 n 0000065891 00000 n 0000063867 00000 n 0000066003 00000 n 0000068375 00000 n 0000068146 00000 n 0000066246 00000 n 0000068258 00000 n 0000070289 00000 n 0000070058 00000 n 0000068512 00000 n 0000070170 00000 n 0000072080 00000 n 0000071733 00000 n 0000070400 00000 n 0000071845 00000 n 0000200283 00000 n 0000071962 00000 n 0000072022 00000 n 0000074021 00000 n 0000073849 00000 n 0000072204 00000 n 0000073961 00000 n 0000358377 00000 n 0000075789 00000 n 0000075498 00000 n 0000074119 00000 n 0000075610 00000 n 0000075670 00000 n 0000075729 00000 n 0000078494 00000 n 0000078084 00000 n 0000075900 00000 n 0000078196 00000 n 0000078256 00000 n 0000078316 00000 n 0000078434 00000 n 0000080996 00000 n 0000080707 00000 n 0000078618 00000 n 0000080819 00000 n 0000357641 00000 n 0000080936 00000 n 0000083281 00000 n 0000083050 00000 n 0000081133 00000 n 0000083162 00000 n 0000085839 00000 n 0000085368 00000 n 0000083418 00000 n 0000085480 00000 n 0000085599 00000 n 0000085659 00000 n 0000085719 00000 n 0000085779 00000 n 0000088221 00000 n 0000087871 00000 n 0000085976 00000 n 0000087983 00000 n 0000088043 00000 n 0000088102 00000 n 0000358495 00000 n 0000090819 00000 n 0000090647 00000 n 0000088345 00000 n 0000090759 00000 n 0000092877 00000 n 0000092705 00000 n 0000090930 00000 n 0000092817 00000 n 0000095207 00000 n 0000095035 00000 n 0000092988 00000 n 0000095147 00000 n 0000097172 00000 n 0000097000 00000 n 0000095331 00000 n 0000097112 00000 n 0000099745 00000 n 0000099573 00000 n 0000097296 00000 n 0000099685 00000 n 0000102471 00000 n 0000102180 00000 n 0000099869 00000 n 0000102292 00000 n 0000102411 00000 n 0000358613 00000 n 0000104888 00000 n 0000104537 00000 n 0000102621 00000 n 0000104649 00000 n 0000104709 00000 n 0000104769 00000 n 0000104828 00000 n 0000107473 00000 n 0000107061 00000 n 0000104999 00000 n 0000107173 00000 n 0000107233 00000 n 0000107293 00000 n 0000107353 00000 n 0000107413 00000 n 0000109736 00000 n 0000109446 00000 n 0000107584 00000 n 0000109558 00000 n 0000109618 00000 n 0000109676 00000 n 0000112147 00000 n 0000111615 00000 n 0000109860 00000 n 0000111727 00000 n 0000111787 00000 n 0000111847 00000 n 0000111907 00000 n 0000111967 00000 n 0000112027 00000 n 0000112087 00000 n 0000114498 00000 n 0000114206 00000 n 0000112245 00000 n 0000114318 00000 n 0000114378 00000 n 0000114438 00000 n 0000116603 00000 n 0000116431 00000 n 0000114609 00000 n 0000116543 00000 n 0000358731 00000 n 0000118732 00000 n 0000118501 00000 n 0000116701 00000 n 0000118613 00000 n 0000120697 00000 n 0000120525 00000 n 0000118856 00000 n 0000120637 00000 n 0000182450 00000 n 0000123269 00000 n 0000123097 00000 n 0000120821 00000 n 0000123209 00000 n 0000126146 00000 n 0000125974 00000 n 0000123393 00000 n 0000126086 00000 n 0000179136 00000 n 0000128941 00000 n 0000128769 00000 n 0000126283 00000 n 0000128881 00000 n 0000131554 00000 n 0000131382 00000 n 0000129052 00000 n 0000131494 00000 n 0000358849 00000 n 0000133442 00000 n 0000133270 00000 n 0000131652 00000 n 0000133382 00000 n 0000135657 00000 n 0000135485 00000 n 0000133553 00000 n 0000135597 00000 n 0000138377 00000 n 0000138205 00000 n 0000135768 00000 n 0000138317 00000 n 0000141211 00000 n 0000141039 00000 n 0000138488 00000 n 0000141151 00000 n 0000143539 00000 n 0000143367 00000 n 0000141348 00000 n 0000143479 00000 n 0000146106 00000 n 0000145875 00000 n 0000143650 00000 n 0000145987 00000 n 0000358967 00000 n 0000149179 00000 n 0000149007 00000 n 0000146230 00000 n 0000149119 00000 n 0000151540 00000 n 0000151368 00000 n 0000149303 00000 n 0000151480 00000 n 0000154220 00000 n 0000154048 00000 n 0000151664 00000 n 0000154160 00000 n 0000157255 00000 n 0000157083 00000 n 0000154331 00000 n 0000157195 00000 n 0000160113 00000 n 0000159941 00000 n 0000157353 00000 n 0000160053 00000 n 0000162272 00000 n 0000161984 00000 n 0000160224 00000 n 0000162096 00000 n 0000359085 00000 n 0000164870 00000 n 0000164580 00000 n 0000162396 00000 n 0000164692 00000 n 0000168345 00000 n 0000168113 00000 n 0000164994 00000 n 0000168225 00000 n 0000169160 00000 n 0000168930 00000 n 0000168456 00000 n 0000169042 00000 n 0000169284 00000 n 0000169468 00000 n 0000169634 00000 n 0000169863 00000 n 0000170037 00000 n 0000170212 00000 n 0000170384 00000 n 0000170709 00000 n 0000171000 00000 n 0000171307 00000 n 0000171495 00000 n 0000171808 00000 n 0000172021 00000 n 0000172290 00000 n 0000172539 00000 n 0000172867 00000 n 0000173116 00000 n 0000173380 00000 n 0000173641 00000 n 0000173901 00000 n 0000174169 00000 n 0000174443 00000 n 0000174657 00000 n 0000174972 00000 n 0000175194 00000 n 0000175370 00000 n 0000175540 00000 n 0000175786 00000 n 0000176004 00000 n 0000176275 00000 n 0000176545 00000 n 0000176759 00000 n 0000177028 00000 n 0000177242 00000 n 0000177450 00000 n 0000177713 00000 n 0000178030 00000 n 0000178308 00000 n 0000178507 00000 n 0000178807 00000 n 0000179386 00000 n 0000179757 00000 n 0000180177 00000 n 0000180737 00000 n 0000181026 00000 n 0000181342 00000 n 0000181614 00000 n 0000181901 00000 n 0000182167 00000 n 0000182700 00000 n 0000182790 00000 n 0000182955 00000 n 0000183061 00000 n 0000183084 00000 n 0000183398 00000 n 0000183703 00000 n 0000183957 00000 n 0000184134 00000 n 0000184598 00000 n 0000184970 00000 n 0000185286 00000 n 0000185673 00000 n 0000185983 00000 n 0000186272 00000 n 0000186526 00000 n 0000186907 00000 n 0000187109 00000 n 0000187294 00000 n 0000187665 00000 n 0000187895 00000 n 0000188254 00000 n 0000188612 00000 n 0000188979 00000 n 0000189245 00000 n 0000189577 00000 n 0000189962 00000 n 0000190205 00000 n 0000190494 00000 n 0000190877 00000 n 0000191190 00000 n 0000191500 00000 n 0000191795 00000 n 0000192097 00000 n 0000192404 00000 n 0000192652 00000 n 0000193014 00000 n 0000193262 00000 n 0000193474 00000 n 0000193775 00000 n 0000193963 00000 n 0000194253 00000 n 0000194496 00000 n 0000194790 00000 n 0000195098 00000 n 0000195340 00000 n 0000195644 00000 n 0000195898 00000 n 0000196145 00000 n 0000196442 00000 n 0000196799 00000 n 0000197114 00000 n 0000197462 00000 n 0000197751 00000 n 0000198043 00000 n 0000198250 00000 n 0000198597 00000 n 0000198936 00000 n 0000199233 00000 n 0000199567 00000 n 0000199912 00000 n 0000200534 00000 n 0000200953 00000 n 0000201403 00000 n 0000202188 00000 n 0000202686 00000 n 0000202712 00000 n 0000202773 00000 n 0000202809 00000 n 0000202990 00000 n 0000203365 00000 n 0000203748 00000 n 0000204037 00000 n 0000204340 00000 n 0000204624 00000 n 0000204945 00000 n 0000205234 00000 n 0000205557 00000 n 0000205873 00000 n 0000206161 00000 n 0000206413 00000 n 0000206774 00000 n 0000207090 00000 n 0000207374 00000 n 0000207698 00000 n 0000207967 00000 n 0000208241 00000 n 0000208513 00000 n 0000208823 00000 n 0000209115 00000 n 0000209456 00000 n 0000209776 00000 n 0000210116 00000 n 0000210407 00000 n 0000211033 00000 n 0000211344 00000 n 0000211614 00000 n 0000211994 00000 n 0000212029 00000 n 0000212329 00000 n 0000212622 00000 n 0000212916 00000 n 0000213234 00000 n 0000213508 00000 n 0000213825 00000 n 0000214135 00000 n 0000214403 00000 n 0000214732 00000 n 0000214985 00000 n 0000215332 00000 n 0000215638 00000 n 0000215909 00000 n 0000216172 00000 n 0000216453 00000 n 0000216712 00000 n 0000217009 00000 n 0000217328 00000 n 0000217625 00000 n 0000218199 00000 n 0000218409 00000 n 0000218656 00000 n 0000218956 00000 n 0000219169 00000 n 0000219442 00000 n 0000219710 00000 n 0000219958 00000 n 0000220135 00000 n 0000220378 00000 n 0000220573 00000 n 0000220770 00000 n 0000221003 00000 n 0000221259 00000 n 0000221511 00000 n 0000221696 00000 n 0000221890 00000 n 0000222119 00000 n 0000222371 00000 n 0000222568 00000 n 0000222785 00000 n 0000222965 00000 n 0000223203 00000 n 0000223391 00000 n 0000223627 00000 n 0000223818 00000 n 0000224044 00000 n 0000224228 00000 n 0000224412 00000 n 0000224624 00000 n 0000224822 00000 n 0000225071 00000 n 0000225403 00000 n 0000225731 00000 n 0000226051 00000 n 0000226395 00000 n 0000226667 00000 n 0000226932 00000 n 0000227203 00000 n 0000227502 00000 n 0000227766 00000 n 0000227994 00000 n 0000228220 00000 n 0000228528 00000 n 0000228729 00000 n 0000228918 00000 n 0000229217 00000 n 0000229421 00000 n 0000229679 00000 n 0000229954 00000 n 0000230205 00000 n 0000230460 00000 n 0000230750 00000 n 0000231028 00000 n 0000231345 00000 n 0000231550 00000 n 0000231798 00000 n 0000232068 00000 n 0000232346 00000 n 0000232653 00000 n 0000232926 00000 n 0000233189 00000 n 0000233461 00000 n 0000233729 00000 n 0000233992 00000 n 0000234266 00000 n 0000234548 00000 n 0000234783 00000 n 0000235117 00000 n 0000235359 00000 n 0000235572 00000 n 0000235822 00000 n 0000236101 00000 n 0000236297 00000 n 0000236549 00000 n 0000236785 00000 n 0000237049 00000 n 0000237330 00000 n 0000237622 00000 n 0000237861 00000 n 0000238127 00000 n 0000238363 00000 n 0000238592 00000 n 0000238859 00000 n 0000239114 00000 n 0000239397 00000 n 0000239715 00000 n 0000239972 00000 n 0000240256 00000 n 0000240478 00000 n 0000240781 00000 n 0000241088 00000 n 0000241350 00000 n 0000241638 00000 n 0000241960 00000 n 0000242224 00000 n 0000242518 00000 n 0000243094 00000 n 0000243738 00000 n 0000244251 00000 n 0000245522 00000 n 0000245803 00000 n 0000246080 00000 n 0000246266 00000 n 0000246451 00000 n 0000246721 00000 n 0000246990 00000 n 0000247174 00000 n 0000247396 00000 n 0000247670 00000 n 0000247863 00000 n 0000248087 00000 n 0000248270 00000 n 0000248519 00000 n 0000248711 00000 n 0000248945 00000 n 0000249135 00000 n 0000249357 00000 n 0000249534 00000 n 0000249708 00000 n 0000249927 00000 n 0000250277 00000 n 0000250661 00000 n 0000250912 00000 n 0000251179 00000 n 0000251415 00000 n 0000251683 00000 n 0000252092 00000 n 0000252367 00000 n 0000252704 00000 n 0000252993 00000 n 0000253337 00000 n 0000253614 00000 n 0000253879 00000 n 0000254119 00000 n 0000254462 00000 n 0000254665 00000 n 0000254847 00000 n 0000255095 00000 n 0000255439 00000 n 0000255658 00000 n 0000255992 00000 n 0000256334 00000 n 0000256664 00000 n 0000256910 00000 n 0000257308 00000 n 0000257622 00000 n 0000257966 00000 n 0000258199 00000 n 0000258476 00000 n 0000258828 00000 n 0000259254 00000 n 0000259632 00000 n 0000259933 00000 n 0000260260 00000 n 0000260540 00000 n 0000260812 00000 n 0000261077 00000 n 0000261354 00000 n 0000261626 00000 n 0000261862 00000 n 0000262207 00000 n 0000262445 00000 n 0000262648 00000 n 0000262902 00000 n 0000263181 00000 n 0000263367 00000 n 0000263636 00000 n 0000263868 00000 n 0000264125 00000 n 0000264398 00000 n 0000264679 00000 n 0000264904 00000 n 0000265172 00000 n 0000265403 00000 n 0000265633 00000 n 0000265913 00000 n 0000266230 00000 n 0000266525 00000 n 0000266851 00000 n 0000267132 00000 n 0000267401 00000 n 0000267604 00000 n 0000267916 00000 n 0000268234 00000 n 0000268503 00000 n 0000268813 00000 n 0000269129 00000 n 0000269410 00000 n 0000269743 00000 n 0000270312 00000 n 0000270892 00000 n 0000271476 00000 n 0000272694 00000 n 0000273028 00000 n 0000273356 00000 n 0000273560 00000 n 0000273817 00000 n 0000274364 00000 n 0000274772 00000 n 0000275120 00000 n 0000275539 00000 n 0000275878 00000 n 0000276187 00000 n 0000276460 00000 n 0000276890 00000 n 0000277094 00000 n 0000277280 00000 n 0000277705 00000 n 0000277943 00000 n 0000278335 00000 n 0000278732 00000 n 0000279138 00000 n 0000279428 00000 n 0000279931 00000 n 0000280302 00000 n 0000280729 00000 n 0000280986 00000 n 0000281300 00000 n 0000281728 00000 n 0000282268 00000 n 0000282710 00000 n 0000283076 00000 n 0000283479 00000 n 0000283804 00000 n 0000284069 00000 n 0000284381 00000 n 0000284721 00000 n 0000284988 00000 n 0000285298 00000 n 0000285516 00000 n 0000285898 00000 n 0000286284 00000 n 0000286590 00000 n 0000286956 00000 n 0000287351 00000 n 0000287671 00000 n 0000288091 00000 n 0000288735 00000 n 0000289102 00000 n 0000289461 00000 n 0000290074 00000 n 0000290350 00000 n 0000290620 00000 n 0000290855 00000 n 0000291089 00000 n 0000291494 00000 n 0000291808 00000 n 0000292134 00000 n 0000292481 00000 n 0000292803 00000 n 0000293114 00000 n 0000293401 00000 n 0000293752 00000 n 0000294050 00000 n 0000294292 00000 n 0000294647 00000 n 0000294924 00000 n 0000295310 00000 n 0000295676 00000 n 0000296019 00000 n 0000296307 00000 n 0000296706 00000 n 0000297036 00000 n 0000297383 00000 n 0000297662 00000 n 0000297983 00000 n 0000298307 00000 n 0000298706 00000 n 0000299063 00000 n 0000299386 00000 n 0000299714 00000 n 0000300005 00000 n 0000300247 00000 n 0000300564 00000 n 0000300885 00000 n 0000301180 00000 n 0000301503 00000 n 0000301835 00000 n 0000302123 00000 n 0000302464 00000 n 0000303042 00000 n 0000303326 00000 n 0000303613 00000 n 0000304156 00000 n 0000304426 00000 n 0000304695 00000 n 0000304880 00000 n 0000305063 00000 n 0000305321 00000 n 0000305576 00000 n 0000305760 00000 n 0000305950 00000 n 0000306161 00000 n 0000306406 00000 n 0000306592 00000 n 0000306804 00000 n 0000306979 00000 n 0000307213 00000 n 0000307395 00000 n 0000307616 00000 n 0000307804 00000 n 0000308016 00000 n 0000308191 00000 n 0000308362 00000 n 0000308565 00000 n 0000308846 00000 n 0000309190 00000 n 0000309622 00000 n 0000309998 00000 n 0000310251 00000 n 0000310507 00000 n 0000310741 00000 n 0000311030 00000 n 0000311300 00000 n 0000311711 00000 n 0000311977 00000 n 0000312293 00000 n 0000312583 00000 n 0000312924 00000 n 0000313199 00000 n 0000313461 00000 n 0000313708 00000 n 0000314043 00000 n 0000314249 00000 n 0000314436 00000 n 0000314682 00000 n 0000315006 00000 n 0000315227 00000 n 0000315552 00000 n 0000315876 00000 n 0000316196 00000 n 0000316444 00000 n 0000316746 00000 n 0000317083 00000 n 0000317314 00000 n 0000317586 00000 n 0000317907 00000 n 0000318295 00000 n 0000318655 00000 n 0000318967 00000 n 0000319252 00000 n 0000319531 00000 n 0000319794 00000 n 0000320073 00000 n 0000320343 00000 n 0000320565 00000 n 0000320883 00000 n 0000321119 00000 n 0000321322 00000 n 0000321553 00000 n 0000321830 00000 n 0000322019 00000 n 0000322277 00000 n 0000322505 00000 n 0000322774 00000 n 0000323052 00000 n 0000323336 00000 n 0000323558 00000 n 0000323835 00000 n 0000324068 00000 n 0000324303 00000 n 0000324568 00000 n 0000324883 00000 n 0000325175 00000 n 0000325476 00000 n 0000325741 00000 n 0000326011 00000 n 0000326214 00000 n 0000326524 00000 n 0000326841 00000 n 0000327111 00000 n 0000327419 00000 n 0000327744 00000 n 0000328023 00000 n 0000328370 00000 n 0000328943 00000 n 0000329535 00000 n 0000330114 00000 n 0000331380 00000 n 0000331557 00000 n 0000331805 00000 n 0000331992 00000 n 0000332168 00000 n 0000332460 00000 n 0000332817 00000 n 0000333066 00000 n 0000333273 00000 n 0000333465 00000 n 0000333756 00000 n 0000334056 00000 n 0000334282 00000 n 0000334524 00000 n 0000334808 00000 n 0000335136 00000 n 0000335425 00000 n 0000335638 00000 n 0000335979 00000 n 0000336299 00000 n 0000336891 00000 n 0000337141 00000 n 0000337429 00000 n 0000337744 00000 n 0000337922 00000 n 0000338378 00000 n 0000338747 00000 n 0000339096 00000 n 0000339320 00000 n 0000339525 00000 n 0000339856 00000 n 0000340123 00000 n 0000340396 00000 n 0000340806 00000 n 0000341134 00000 n 0000341473 00000 n 0000342188 00000 n 0000342397 00000 n 0000342664 00000 n 0000342876 00000 n 0000350019 00000 n 0000350254 00000 n 0000357265 00000 n 0000359187 00000 n 0000359307 00000 n 0000359427 00000 n 0000359500 00000 n 0000361954 00000 n 0000362128 00000 n 0000362299 00000 n 0000362468 00000 n 0000362637 00000 n 0000362808 00000 n 0000362978 00000 n 0000363149 00000 n 0000363319 00000 n 0000363490 00000 n 0000363660 00000 n 0000363831 00000 n 0000364005 00000 n 0000364208 00000 n 0000364411 00000 n 0000364614 00000 n 0000364817 00000 n 0000365020 00000 n 0000365214 00000 n 0000365401 00000 n 0000365585 00000 n 0000365775 00000 n 0000365939 00000 n 0000366057 00000 n 0000366176 00000 n 0000366299 00000 n 0000366402 00000 n 0000366504 00000 n 0000366544 00000 n 0000366716 00000 n trailer << /Size 1101 /Root 1099 0 R /Info 1100 0 R /ID [ ] >> startxref 367043 %%EOF verilator-3.874/verilator.txt0000664000177100017500000045746112534631201016311 0ustar wsnyderwsnyderNAME Verilator - Convert Verilog code to C++/SystemC SYNOPSIS verilator --help verilator --version verilator --cc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so] verilator --sc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so] verilator --lint-only [top_level.v]... DESCRIPTION Verilator converts synthesizable (not behavioral) Verilog code, plus some Synthesis, SystemVerilog and a small subset of Verilog AMS assertions, into C++ or SystemC code. It is not a complete simulator, but a compiler. Verilator is invoked with parameters similar to GCC, Cadence Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage and waveform tracing code. For C++ and SystemC formats, it outputs .cpp and .h files. The files created by Verilator are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module, and passes this filename on the command line. These C files are compiled in C++, and linked with the Verilated files. The resulting executable will perform the actual simulation. To get started, jump down to "EXAMPLE C++ EXECUTION". ARGUMENT SUMMARY This is a short summary of the arguments to Verilator. See the detailed descriptions in the next sections for more information. {file.v} Verilog top level filenames {file.c/cc/cpp} Optional C++ files to compile in {file.a/o/so} Optional C++ files to link in +1364-1995ext+ Use Verilog 1995 with file extension +1364-2001ext+ Use Verilog 2001 with file extension +1364-2005ext+ Use Verilog 2005 with file extension +1800-2005ext+ Use SystemVerilog 2005 with file extension +1800-2009ext+ Use SystemVerilog 2009 with file extension +1800-2012ext+ Use SystemVerilog 2012 with file extension --assert Enable all assertions --autoflush Flush streams after all $displays --bbox-sys Blackbox unknown $system calls --bbox-unsup Blackbox unsupported language features --bin Override Verilator binary -CFLAGS C++ Compiler flags for makefile --cc Create C++ output --cdc Clock domain crossing analysis --clk Mark specified signal as clock --compiler Tune for specified C++ compiler --converge-limit Tune convergence settle time --coverage Enable all coverage --coverage-line Enable line coverage --coverage-toggle Enable toggle coverage --coverage-user Enable SVL user coverage --coverage-underscore Enable coverage of _signals -D[=] Set preprocessor define --debug Enable debugging --debug-check Enable debugging assertions --debugi Enable debugging at a specified level --debugi- Enable debugging a source file at a level --default-language Default language to parse +define+= Set preprocessor define --dump-tree Enable dumping .tree files --dump-treei Enable dumping .tree files at a level --dump-treei- Enable dumping .tree file at a source file at a level -E Preprocess, but do not compile --error-limit Abort after this number of errors --exe Link to create executable -F Parse options from a file, relatively -f Parse options from a file --gdb Run Verilator under GDB interactively --gdbbt Run Verilator under GDB for backtrace --help Display this help -I Directory to search for includes --if-depth Tune IFDEPTH warning +incdir+ Directory to search for includes --inhibit-sim Create function to turn off sim --inline-mult Tune module inlining -LDFLAGS Linker pre-object flags for makefile -LDLIBS Linker library flags for makefile --language Default language standard to parse +libext++[ext]... Extensions for finding modules --lint-only Lint, but do not make output --MMD Create .d dependency files --MP Create phony dependency targets --Mdir Name of output object directory --mod-prefix Name to prepend to lower classes --no-clk Prevent marking specified signal as clock --no-pins64 Don't use vluint64_t's for 33-64 bit sigs --no-skip-identical Disable skipping identical output +notimingchecks Ignored -O0 Disable optimizations -O3 High performance optimizations -O Selectable optimizations -o Name of final executable --no-order-clock-delay Disable ordering clock enable assignments --output-split Split .cpp files into pieces --output-split-cfuncs Split .cpp functions --output-split-ctrace Split tracing functions -P Disable line numbers and blanks with -E --pins-bv Specify types for top level ports --pins-sc-uint Specify types for top level ports --pins-sc-biguint Specify types for top level ports --pins-uint8 Specify types for top level ports --pipe-filter Filter all input through a script --prefix Name of top level class --profile-cfuncs Name functions for profiling --private Debugging; see docs --public Debugging; see docs --report-unoptflat Extra diagnostics for UNOPTFLAT --savable Enable model save-restore --sc Create SystemC output --stats Create statistics file --stats-vars Provide statistics on variables -sv Enable SystemVerilog parsing +systemverilogext+ Synonym for +1800-2012ext+ --top-module Name of top level input module --trace Enable waveform creation --trace-depth Depth of tracing --trace-max-array Maximum bit width for tracing --trace-max-width Maximum array depth for tracing --trace-params Enable tracing parameters --trace-structs Enable tracing structure names --trace-underscore Enable tracing of _signals -U Undefine preprocessor define --unroll-count Tune maximum loop iterations --unroll-stmts Tune maximum loop body size --unused-regexp Tune UNUSED lint signals -V Verbose version and config -v Verilog library +verilog1995ext+ Synonym for +1364-1995ext+ +verilog2001ext+ Synonym for +1364-2001ext+ -Werror- Convert warning to error -Wfuture- Disable unknown message warnings -Wno- Disable warning -Wno-lint Disable all lint warnings -Wno-style Disable all style warnings -Wno-fatal Disable fatal exit on warnings --x-assign Initially assign Xs to this value --x-initial-edge Enable initial X->0 and X->1 edge triggers -y Directory to search for modules ARGUMENTS {file.v} Specifies the Verilog file containing the top module to be Verilated. {file.c/.cc/.cpp/.cxx} Specifies optional C++ files to be linked in with the Verilog code. If any C++ files are specified in this way, Verilator will include a make rule that generates a *module* executable. Without any C++ files, Verilator will stop at the *module*__ALL.a library, and presume you'll continue linking with make rules you write yourself. See also the -CFLAGS option. {file.a/.o/.so} Specifies optional object or library files to be linked in with the Verilog code, as a shorthand for -LDFLAGS "". If any files are specified in this way, Verilator will include a make rule that uses these files when linking the *module* executable. This generally is only useful when used with the --exe option. +1364-1995ext+*ext* +1364-2001ext+*ext* +1364-2005ext+*ext* +1800-2005ext+*ext* +1800-2009ext+*ext* +1800-2012ext+*ext* Specifies the language standard to be used with a specific filename extension, *ext*. For compatibility with other simulators, see also the synonyms "+verilog1995ext+"*ext*, "+verilog2001ext+"*ext*, and "+systemverilogext+"*ext*. For any source file, the language specified by these options takes precedence over any language specified by the "--default-language" or "--language" options. These options take effect in the order they are encountered. Thus the following would use Verilog 1995 for "a.v" and Verilog 2001 for "b.v". verilator ... +1364-1995ext+v a.v +1364-2001ext+v b.v These flags are only recommended for legacy mixed language designs, as the preferable option is to edit the code to repair new keywords, or add appropriate "`begin_keywords". Note "`begin_keywords" is a SystemVerilog construct, which specifies *only* which the set of keywords is to be recognized. Whatever set is chosen, the semantics will be those of SystemVerilog. By contrast "+1364-1995ext+" etc. specify both the syntax *and* semantics to be used. --assert Enable all assertions. See also --x-assign and --x-initial-edge; setting "--x-assign unique" and/or "--x-initial-edge" may be desirable. --autoflush After every $display or $fdisplay, flush the output stream. This insures that messages will appear immediately but may reduce performance; for best performance call "fflush(stdout)" occasionally in the main C loop. Defaults off, which will buffer output as provided by the normal C stdio calls. --bbox-sys Black box any unknown $system task or function calls. System tasks will be simply NOPed, and system functions will be replaced by unsized zero. Arguments to such functions will be parsed, but not otherwise checked. This prevents errors when linting in the presence of company specific PLI calls. --bbox-unsup Black box some unsupported language features, currently UDP tables and the cmos and tran gate primitives. This may enable linting the rest of the design even when unsupported constructs are present. --bin *filename* Rarely needed. Override the default filename for Verilator itself. When a dependency (.d) file is created, this filename will become a source dependency, such that a change in this binary will have make rebuild the output files. -CFLAGS *flags* Add specified C compiler flags to the generated makefiles. When make is run on the generated makefile these will be passed to the C++ compiler (gcc/g++/msvc++). --cc Specifies C++ without SystemC output mode; see also --sc. --cdc Experimental. Perform some clock domain crossing checks and issue related warnings (CDCRSTLOGIC) and then exit; if warnings other than CDC warnings are needed make a second run with --lint-only. Additional warning information is also written to the file {prefix}__cdc.txt. Currently only checks some items that other CDC tools missed; if you have interest in adding more traditional CDC checks, please contact the authors. --clk *signal-name* Sometimes it is quite difficult for Verilator to distinguish clock signals from other data signals. Occasionally the clock signals can end up in the checking list of signals which determines if further evaluation is needed. This will heavily degrade the performance of verilated model. With --clk , user can specified root clock into the model, then Verilator will mark the signal as clocker and propagate the clocker attribute automatically to other signals derived from that. In this way, Verilator will try to avoid taking the clocker signal into checking list. Note signal-name is specified by the RTL hiearchy path. For example, v.foo.bar. If the signal is the input to top-module, the directly the signal name. If you find it difficult to find the exact name, try to use "/*verilator clocker*/" in RTL file to mark the signal directly. --compiler *compiler-name* Enables tunings and work-arounds for the specified C++ compiler. clang Tune for clang. This may reduce execution speed as it enables several workarounds to avoid silly hardcoded limits in clang. This includes breaking deep structures as for msvc as described below. gcc Tune for Gnu C++, although generated code should work on almost any compliant C++ compiler. Currently the default. msvc Tune for Microsoft Visual C++. This may reduce execution speed as it enables several workarounds to avoid silly hardcoded limits in MSVC++. This includes breaking deeply nested parenthesized expressions into sub-expressions to avoid error C1009, and breaking deep blocks into functions to avoid error C1061. --converge-limit Rarely needed. Specifies the maximum number of runtime iterations before creating a model failed to converge error. Defaults to 100. --coverage Enables all forms of coverage, alias for "--coverage-line --coverage-toggle --coverage-user". --coverage-line Specifies basic block line coverage analysis code should be inserted. Coverage analysis adds statements at each code flow change point, which are the branches of IF and CASE statements, a super-set of normal Verilog Line Coverage. At each such branch a unique counter is incremented. At the end of a test, the counters along with the filename and line number corresponding to each counter are written into logs/coverage.pl. Verilator automatically disables coverage of branches that have a $stop in them, as it is assumed $stop branches contain an error check that should not occur. A /*verilator coverage_block_off*/ comment will perform a similar function on any code in that block or below, or /*verilator coverage_on/coverage_off*/ will disable coverage around lines of code. Note Verilator may over-count combinatorial (non-clocked) blocks when those blocks receive signals which have had the UNOPTFLAT warning disabled; for most accurate results do not disable this warning when using coverage. --coverage-toggle Specifies signal toggle coverage analysis code should be inserted. Every bit of every signal in a module has a counter inserted. The counter will increment on every edge change of the corresponding bit. Signals that are part of tasks or begin/end blocks are considered local variables and are not covered. Signals that begin with underscores, are integers, or are very wide (>256 bits total storage across all dimensions) are also not covered. Hierarchy is compressed, such that if a module is instantiated multiple times, coverage will be summed for that bit across ALL instantiations of that module with the same parameter set. A module instantiated with different parameter values is considered a different module, and will get counted separately. Verilator makes a minimally-intelligent decision about what clock domain the signal goes to, and only looks for edges in that clock domain. This means that edges may be ignored if it is known that the edge could never be seen by the receiving logic. This algorithm may improve in the future. The net result is coverage may be lower than what would be seen by looking at traces, but the coverage is a more accurate representation of the quality of stimulus into the design. There may be edges counted near time zero while the model stabilizes. It's a good practice to zero all coverage just before releasing reset to prevent counting such behavior. A /*verilator coverage_off/on */ comment pair can be used around signals that do not need toggle analysis, such as RAMs and register files. --coverage-underscore Enable coverage of signals that start with an underscore. Normally, these signals are not covered. See also --trace-underscore. --coverage-user Enables user inserted functional coverage. Currently, all functional coverage points are specified using SVA which must be separately enabled with --assert. For example, the following statement will add a coverage point, with the comment "DefaultClock": DefaultClock: cover property (@(posedge clk) cyc==3); -D*var*=*value* Defines the given preprocessor symbol, without allowing. Similar to +define; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility. --debug Select the debug built image of Verilator (if available), and enable more internal assertions (equivelent to "--debug-check"), debugging messages (equivelent to "--debugi 4"), and intermediate form dump files (equivilent to "--dump-treei 3"). --debug-check Rarely needed. Enable internal debugging assertion checks, without changing debug verbosity. Enabled automatically when --debug specified. --debugi --debugi- Rarely needed - for developer use. Set internal debugging level globally to the specified debug level (1-10) or set the specified Verilator source file to the specified level (e.g. "--debugi-V3Width 9"). Higher levels produce more detailed messages. --default-language *value* Select the language to be used by default when first processing each Verilog file. The language value must be "1364-1995", "1364-2001", "1364-2005", "1800-2005", "1800-2009" or "1800-2012". Any language associated with a particular file extension (see the various +*lang*ext+ options) will be used in preference to the language specified by --default-language. The --default-language flag is only recommended for legacy code using the same language in all source files, as the preferable option is to edit the code to repair new keywords, or add appropriate "`begin_keywords". For legacy mixed language designs, the various +*lang*ext+ options should be used. If no language is specified, either by this flag or +*lang*ext+ options, then the latest SystemVerilog language (IEEE 1800-2012) is used. +define+*var*=*value* +define+*var*=*value*+*var2*=*value2*... Defines the given preprocessor symbol, or multiple symbols if separated by plusses. Similar to -D; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility. --dump-tree Rarely needed. Enable writing .tree debug files with dumping level 3, which dumps the standard critical stages. For details on the format see the Verilator Internals manual. --dump-tree is enabled automatically with --debug, so "--debug --no-dump-tree" may be useful if the dump files are large and not desired. --dump-treei --dump-treei- Rarely needed - for developer use. Set internal tree dumping level globally to a specific dumping level or set the specified Verilator source file to the specified tree dumping level (e.g. "--dump-treei-V3Order 9"). Level 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9 enables dumping of every stage. -E Preprocess the source code, but do not compile, as with 'gcc -E'. Output is written to standard out. Beware of enabling debugging messages, as they will also go to standard out. --error-limit After this number of errors or warnings are encountered, exit. Defaults to 50. --exe Generate an executable. You will also need to pass additional .cpp files on the command line that implement the main loop for your simulation. -F *file* Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the directory containing the specified file. See also -f. Note -F is fairly standard across Verilog tools. -f *file* Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the current directory. See also -F. Note -f is fairly standard across Verilog tools. The file may contain // comments which are ignored to the end of the line. Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment variable. --gdb Run Verilator underneath an interactive GDB (or VERILATOR_GDB environment variable value) session. See also --gdbbt. --gdbbt If --debug is specified, run Verilator underneath a GDB process and print a backtrace on exit, then exit GDB immediately. Without --debug or if GDB doesn't seem to work, this flag is ignored. Intended for easy creation of backtraces by users; otherwise see the --gdb flag. --help Displays this message and program version and exits. -I*dir* See -y. --if-depth *value* Rarely needed. Set the depth at which the IFDEPTH warning will fire, defaults to 0 which disables this warning. +incdir+*dir* See -y. --inhibit-sim Rarely needed. Create a "inhibitSim(bool)" function to enable and disable evaluation. This allows an upper level testbench to disable modules that are not important in a given simulation, without needing to recompile or change the SystemC modules instantiated. --inline-mult *value* Tune the inlining of modules. The default value of 2000 specifies that up to 2000 new operations may be added to the model by inlining, if more than this number of operations would result, the module is not inlined. Larger values, or a value <= 1 will inline everything, will lead to longer compile times, but potentially faster runtimes. This setting is ignored for very small modules; they will always be inlined, if allowed. -LDFLAGS *flags* Add specified C linker flags to the generated makefiles. When make is run on the generated makefile these will be passed to the C++ linker (ld) *after* the primary file being linked. This flag is called -LDFLAGS as that's the traditional name in simulators; it's would have been better called LDLIBS as that's the Makefile variable it controls. (In Make, LDFLAGS is before the first object, LDLIBS after. -L libraries need to be in the Make variable LDLIBS, not LDFLAGS.) --language *value* A synonym for "--default-langauge", for compatibility with other tools and earlier versions of Verilator. +libext+*ext*+*ext*... Specify the extensions that should be used for finding modules. If for example module *x* is referenced, look in *x*.*ext*. Note +libext+ is fairly standard across Verilog tools. Defaults to .v and .sv. --lint-only Check the files for lint violations only, do not create any other output. You may also want the -Wall option to enable messages that are considered stylistic and not enabled by default. If the design is not to be completely Verilated see also the --bbox-sys and --bbox-unsup options. --MMD Enable creation of .d dependency files, used for make dependency detection, similar to gcc -MMD option. On by default, use --no-MMD to disable. --MP When creating .d dependency files with --MMD, make phony targets. Similar to gcc -MP option. --Mdir *directory* Specifies the name of the Make object directory. All generated files will be placed in this directory. If not specified, "obj_dir" is used. The directory is created if it does not exist and the parent directories exist; otherwise manually create the Mdir before calling Verilator. --mod-prefix *topname* Specifies the name to prepend to all lower level classes. Defaults to the same as --prefix. --no-clk Prevent the specified signal from being marked as clock. See "--clk". --no-pins64 Backward compatible alias for "--pins-bv 33". --no-skip-identical Rarely needed. Disables skipping execution of Verilator if all source files are identical, and all output files exist with newer dates. +notimingchecks Ignored for compatibility with other simulators. -O0 Disables optimization of the model. -O3 Enables slow optimizations for the code Verilator itself generates (as opposed to "-CFLAGS -O3" which effects the C compiler's optimization. -O3 may reduce simulation runtimes at the cost of compile time. This currently sets --inline-mult -1. -O*optimization-letter* Rarely needed. Enables or disables a specific optimizations, with the optimization selected based on the letter passed. A lowercase letter disables an optimization, an upper case letter enables it. This is intended for debugging use only; see the source code for version-dependent mappings of optimizations to -O letters. -o Specify the name for the final executable built if using --exe. Defaults to the --prefix if not specified. --no-order-clock-delay Rarely needed. Disables a bug fix for ordering of clock enables with delayed assignments. This flag should only be used when suggested by the developers. --output-split *bytes* Enables splitting the output .cpp/.sp files into multiple outputs. When a C++ file exceeds the specified number of operations, a new file will be created at the next function boundary. In addition, any slow routines will be placed into __Slow files. This accelerates compilation by as optimization can be disabled on the slow routines, and the remaining files can be compiled on parallel machines. Using --output-split should have only a trivial impact on performance. With GCC 3.3 on a 2GHz Opteron, --output-split 20000 will result in splitting into approximately one-minute-compile chunks. --output-split-cfuncs *statements* Enables splitting functions in the output .cpp/.sp files into multiple functions. When a generated function exceeds the specified number of operations, a new function will be created. With --output-split, this will enable GCC to compile faster, at a small loss in performance that gets worse with decreasing split values. Note that this option is stronger than --output-split in the sense that --output-split will not split inside a function. --output-split-ctrace *statements* Enables splitting trace functions in the output .cpp/.sp files into multiple functions. Defaults to same setting as --output-split-cfuncs. -P With -E, disable generation of `line markers and blank lines, similar to GCC -P flag. --pins64 Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64. --pins-bv *width* Specifies SystemC inputs/outputs of greater than or equal to *width* bits wide should use sc_bv's instead of uint32/vluint64_t's. The default is "--pins-bv 65". Versions before Verilator 3.671 defaulted to "--pins-bv 33". The more sc_bv is used, the worse for performance. Use the "/*verilator sc_bv*/" attribute to select specific ports to be sc_bv. --pins-sc-uint Specifies SystemC inputs/outputs of greater than 2 bits wide should use sc_uint between 2 and 64. When combined with the "--pins-sc-biguint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. --pins-sc-biguint Specifies SystemC inputs/outputs of greater than 65 bits wide should use sc_biguint between 65 and 512, and sc_bv from 513 upwards. When combined with the "--pins-sc-uint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512. --pins-uint8 Specifies SystemC inputs/outputs that are smaller than the --pins-bv setting and 8 bits or less should use uint8_t instead of uint32_t. Likewise pins of width 9-16 will use uint16_t instead of uint32_t. --pipe-filter *command* Rarely needed and experimental. Verilator will spawn the specified command as a subprocess pipe, to allow the command to perform custom edits on the Verilog code before it reaches Verilator. Before reading each Verilog file, Verilator will pass the file name to the subprocess' stdin with 'read_verilog ""'. The filter may then read the file and perform any filtering it desires, and feeds the new file contents back to Verilator on stdout with 'Content-Length'. Output to stderr from the filter feeds through to Verilator's stdout and if the filter exits with non-zero status Verilator terminates. See the t/t_pipe_filter test for an example. To debug the output of the filter, try using the -E option to see preprocessed output. --prefix *topname* Specifies the name of the top level class and makefile. Defaults to V prepended to the name of the --top-module switch, or V prepended to the first Verilog filename passed on the command line. --profile-cfuncs Modify the created C++ functions to support profiling. The functions will be minimized to contain one "basic" statement, generally a single always block or wire statement. (Note this will slow down the executable by ~5%.) Furthermore, the function name will be suffixed with the basename of the Verilog module and line number the statement came from. This allows gprof or oprofile reports to be correlated with the original Verilog source statements. --private Opposite of --public. Is the default; this option exists for backwards compatibility. --public This is only for historical debug use. Using it may result in mis-simulation of generated clocks. Declares all signals and modules public. This will turn off signal optimizations as if all signals had a /*verilator public*/ comments and inlining. This will also turn off inlining as if all modules had a /*verilator public_module*/, unless the module specifically enabled it with /*verilator inline_module*/. --report-unoptflat Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the 10 widest variables in the loop, and the 10 most fanned out variables in the loop. These are candidates for splitting into multiple variables to break the loop. In addition produces a GraphViz DOT file of the entire strongly connected components within the source associated with each loop. This is produced irrespective of whether --dump-tree is set. Such graphs may help in analyzing the problem, but can be very large indeed. Various commands exist for viewing and manipulating DOT files. For example the *dot* command can be used to convert a DOT file to a PDF for printing. For example: dot -Tpdf -O Vt_unoptflat_simple_2_35_unoptflat.dot will generate a PDF Vt_unoptflat_simple_2_35_unoptflat.dot.pdf from the DOT file. --savable Enable including save and restore functions in the generated model. The user code must create a VerilatedSerialize or VerilatedDeserialze object then calling the << or >> operators on the generated model and any other data the process needs saved/restored. For example: void save_model(const char* filenamep) { VerilatedSave os; os.open(filenamep); os << main_time; // user code must save the timestamp, etc os << *topp; } void restore_model(const char* filenamep) { VerilatedRestore os; os.open(filenamep); os >> main_time; os >> *topp; } --sc Specifies SystemC output mode; see also --cc. --stats Creates a dump file with statistics on the design in {prefix}__stats.txt. --stats-vars Creates more detailed statistics including a list of all the variables by size (plain --stats just gives a count). See --stats, which is implied by this. -sv Specifies SystemVerilog language features should be enabled; equivalent to "--language 1800-2005". This option is selected by default, it exists for compatibility with other simulators. +systemverilogext+*ext* A synonym for "+1800-2012ext+"*ext*. --top-module *topname* When the input Verilog contains more than one top level module, specifies the name of the top level Verilog module to become the top, and sets the default for if --prefix is not used. This is not needed with standard designs with only one top. --trace Adds waveform tracing code to the model. Verilator will generate additional {prefix}__Trace*.cpp files that will need to be compiled. In addition verilated_vcd_sc.cpp (for SystemC traces) or verilated_vcd_c.cpp (for both) must be compiled and linked in. If using the Verilator generated Makefiles, these will be added as source targets for you. If you're not using the Verilator makefiles, you will need to add these to your Makefile manually. Having tracing compiled in may result in some small performance losses, even when waveforms are not turned on during model execution. --trace-depth *levels* Specify the number of levels deep to enable tracing, for example --trace-level 1 to only see the top level's signals. Defaults to the entire model. Using a small number will decrease visibility, but greatly improve runtime and trace file size. --trace-max-array *depth* Rarely needed. Specify the maximum array depth of a signal that may be traced. Defaults to 32, as tracing large arrays may greatly slow traced simulations. --trace-max-width *width* Rarely needed. Specify the maximum bit width of a signal that may be traced. Defaults to 256, as tracing large vectors may greatly slow traced simulations. --no-trace-params Disable tracing of parameters. --trace-structs Enable tracing to show the name of packed structure, union, and packed array fields, rather than a simgle combined packed bus. Due to VCD file format constraints this may result in significantly slower trace times and larger trace files. --trace-underscore Enable tracing of signals that start with an underscore. Normally, these signals are not output during tracing. See also --coverage-underscore. -U*var* Undefines the given preprocessor symbol. --unroll-count *loops* Rarely needed. Specifies the maximum number of loop iterations that may be unrolled. See also BLKLOOPINIT warning. --unroll-stmts *statements* Rarely needed. Specifies the maximum number of statements in a loop for that loop to be unrolled. See also BLKLOOPINIT warning. --unused-regexp *regexp* Rarely needed. Specifies a simple regexp with * and ? that if a signal name matches will suppress the UNUSED warning. Defaults to "*unused*". Setting it to "" disables matching. -V Shows the verbose version, including configuration information compiled into Verilator. (Similar to perl -V.) -v *filename* Read the filename as a Verilog library. Any modules in the file may be used to resolve cell instantiations in the top level module, else ignored. Note -v is fairly standard across Verilog tools. +verilog1995ext+*ext* +verilog2001ext+*ext* Synonyms for "+1364-1995ext+"*ext* and "+1364-2001ext+"*ext* respectively -Wall Enable all warnings, including code style warnings that are normally disabled by default. -Werror-*message* Convert the specified warning message into an error message. This is generally to discourage users from violating important site-wide rules, for example "-Werror-NOUNOPTFLAT". -Wfuture-*message* Rarely needed. Suppress unknown Verilator comments or warning messages with the given message code. This is used to allow code written with pragmas for a later version of Verilator to run under a older version; add -Wfuture- arguments for each message code or comment that the new version supports which the older version does not support. -Wno-*message* Disable the specified warning message. This will override any lint_on directives in the source, i.e. the warning will still not be printed. -Wno-lint Disable all lint related warning messages, and all style warnings. This is equivalent to "-Wno-ALWCOMBORDER -Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEWITHX -Wno-CMPCONST -Wno-ENDLABEL -Wno-IMPLICIT -Wno-LITENDIAN -Wno-PINCONNECTEMPTY -Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED -Wno-WIDTH" plus the list shown for Wno-style. It is strongly recommended you cleanup your code rather than using this option, it is only intended to be use when running test-cases of code received from third parties. -Wno-style Disable all code style related warning messages (note by default they are already disabled). This is equivalent to "-Wno-DECLFILENAME -Wno-DEFPARAM -Wno-INCABSPATH -Wno-PINCONNECTEMPTY -Wno-PINNOCONNECT -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNUSED -Wno-VARHIDDEN". -Wno-fatal When warnings are detected, print them, but do not exit the simulator. Having warning messages in builds is sloppy. It is strongly recommended you cleanup your code, use inline lint_off, or use -Wno-... flags rather than using this option. -Wwarn-*message* Enables the specified warning message. -Wwarn-lint Enable all lint related warning messages (note by default they are already enabled), but do not affect style messages. This is equivalent to "-Wwarn-ALWCOMBORDER -Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX -Wwarn-CMPCONST -Wwarn-ENDLABEL -Wwarn-IMPLICIT -Wwarn-LITENDIAN -Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED -Wwarn-WIDTH". -Wwarn-style Enable all code style related warning messages. This is equivalent to "-Wwarn ASSIGNDLY -Wwarn-DECLFILENAME -Wwarn-DEFPARAM -Wwarn-INCABSPATH -Wwarn-PINNOCONNECT -Wwarn-SYNCASYNCNET -Wwarn-UNDRIVEN -Wwarn-UNUSED -Wwarn-VARHIDDEN". --x-assign 0 --x-assign 1 --x-assign fast (default) --x-assign unique Controls the two-state value that is replaced when an assignment to X is encountered. --x-assign=fast, the default, converts all Xs to whatever is best for performance. --x-assign=0 converts all Xs to 0s, and is also fast. --x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more likely to find reset bugs as active high logic will fire. --x-assign=unique will call a function to determine the value, this allows randomization of all Xs to find reset bugs and is the slowest, but safest for finding reset bugs in code. If using --x-assign unique, you may want to seed your random number generator such that each regression run gets a different randomization sequence. Use the system's srand48() or for Windows srand() function to do this. You'll probably also want to print any seeds selected, and code to enable rerunning with that same seed so you can reproduce bugs. Note. This option applies only to variables which are explicitly assigned to X in the Verilog source code. Initial values of clocks are set to 0 unless --x-initial-edge is specified. Initial values of all other state holding variables are set as though --x-assign unique had been specified. --x-initial-edge Enables emulation of event driven simulators which generally trigger an edge on a transition from X to 1 ("posedge") or X to 0 ("negedge"). Thus the following code, where "rst_n" is uninitialized would set "res_n" to "1'b1" when "rst_n" is first set to zero: reg res_n = 1'b0; always @(negedge rst_n) begin if (rst_n == 1'b0) begin res_n <= 1'b1; end end In Verilator, by default, uninitialized clocks are given a value of zero, so the above "always" block would not trigger. While it is not good practice, there are some designs that rely on X → 0 triggering a "negedge", particularly in reset sequences. Using --x-initial-edge with Verilator will replicate this behavior. It will also ensure that X → 1 triggers a "posedge". Note. Some users have reported that using this option can affect convergence, and that it may be necessary to use --converge-limit to increase the number of convergence iterations. This may be another indication of problems with the modelled design that should be addressed. -y *dir* Add the directory to the list of directories that should be searched for include files or libraries. The three flags -y, +incdir and -I have similar effect; +incdir and +y are fairly standard across Verilog tools while -I is an alias for GCC compatibility. Verilator defaults to the current directory ("-y .") and any specified --Mdir, though these default paths are used after any user specified directories. This allows '-y "$(pwd)"' to be used if absolute filenames are desired for error messages instead of relative filenames. EXAMPLE C++ EXECUTION We'll compile this example into C++. mkdir test_our cd test_our cat <our.v module our; initial begin $display("Hello World"); $finish; end endmodule EOF cat <sim_main.cpp #include "Vour.h" #include "verilated.h" int main(int argc, char **argv, char **env) { Verilated::commandArgs(argc, argv); Vour* top = new Vour; while (!Verilated::gotFinish()) { top->eval(); } delete top; exit(0); } EOF If you installed Verilator from sources, or a tarball, but not as part of your operating system (as an RPM), first you need to point to the kit: export VERILATOR_ROOT=/path/to/where/verilator/was/installed export PATH=$VERILATOR_ROOT/bin:$PATH Now we run Verilator on our little example. verilator -Wall --cc our.v --exe sim_main.cpp We can see the source code under the "obj_dir" directory. See the FILES section below for descriptions of some of the files that were created. ls -l obj_dir We then can compile it cd obj_dir make -j -f Vour.mk Vour (Verilator included a default compile rule and link rule, since we used --exe and passed a .cpp file on the Verilator command line. You can also write your own compile rules, as we'll show in the SYSTEMC section.) And now we run it cd .. obj_dir/Vour And we get as output Hello World - our.v:2: Verilog $finish Really, you're better off writing a Makefile to do all this for you. Then, when your source changes it will automatically run all of these steps. See the test_c directory in the distribution for an example. EXAMPLE SYSTEMC EXECUTION This is an example similar to the above, but using SystemC. mkdir test_our_sc cd test_our_sc cat <our.v module our (clk); input clk; // Clock is required to get initial activation always @ (posedge clk) begin $display("Hello World"); $finish; end endmodule EOF cat <sc_main.cpp #include "Vour.h" int sc_main(int argc, char **argv) { Verilated::commandArgs(argc, argv); sc_clock clk ("clk",10, 0.5, 3, true); Vour* top; top = new Vour("top"); // SP_CELL (top, Vour); top->clk(clk); // SP_PIN (top, clk, clk); while (!Verilated::gotFinish()) { sc_start(1, SC_NS); } delete top; exit(0); } EOF If you installed Verilator from sources, or a tarball, but not as part of your operating system (as an RPM), first you need to point to the kit: export VERILATOR_ROOT=/path/to/where/verilator/was/installed export PATH=$VERILATOR_ROOT/bin:$PATH Now we run Verilator on our little example. verilator -Wall --sc our.v We then can compile it make -j -f Vour.mk Vour__ALL.a make -j -f Vour.mk ../sc_main.o verilated.o And link with SystemC. Note your path to the libraries may vary, depending on the operating system. export SYSTEMC_LIBDIR=/path/to/where/libsystemc.a/exists export LD_LIBRARY_PATH=$SYSTEMC_LIBDIR:$LD_LIBRARY_PATH # Might be needed if SystemC 2.3.0 export SYSTEMC_CXX_FLAGS=-pthread g++ -L$SYSTEMC_LIBDIR ../sc_main.o Vour__ALL*.o verilated.o \ -o Vour -lsystemc And now we run it cd .. obj_dir/Vour And we get the same output as the C++ example: Hello World - our.v:2: Verilog $finish Really, you're better off using a Makefile to do all this for you. Then, when your source changes it will automatically run all of these steps. See the test_sc directory in the distribution for an example. BENCHMARKING & OPTIMIZATION For best performance, run Verilator with the "-O3 --x-assign=fast --noassert" flags. The -O3 flag will require longer compile times, and --x-assign=fast may increase the risk of reset bugs in trade for performance; see the above documentation for these flags. Minor Verilog code changes can also give big wins. You should not have any UNOPTFLAT warnings from Verilator. Fixing these warnings can result in huge improvements; one user fixed their one UNOPTFLAT warning by making a simple change to a clock latch used to gate clocks and gained a 60% performance improvement. Beyond that, the performance of a Verilated model depends mostly on your C++ compiler and size of your CPU's caches. By default, the lib/verilated.mk file has optimization turned off. This is for the benefit of new users, as it improves compile times at the cost of runtimes. To add optimization as the default, set one of three variables, OPT, OPT_FAST, or OPT_SLOW lib/verilated.mk. Or, use the -CFLAGS and/or -LDFLAGS option on the verilator command line to pass the flags directly to the compiler or linker. Or, just for one run, pass them on the command line to make: make OPT_FAST="-O2" -f Vour.mk Vour__ALL.a OPT_FAST specifies optimizations for those programs that are part of the fast path, mostly code that is executed every cycle. OPT_SLOW specifies optimizations for slow-path files (plus tracing), which execute only rarely, yet take a long time to compile with optimization on. OPT specifies overall optimization and affects all compiles, including those OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2", and link with "-static". Nearly the same results can be had with much better compile times with OPT_FAST="-O1 -fstrict-aliasing". Higher optimization such as "-O3" may help, but gcc compile times may be excessive under O3 on even medium sized designs. Alternatively, some larger designs report better performance using "-Os". Unfortunately, using the optimizer with SystemC files can result in compiles taking several minutes. (The SystemC libraries have many little inlined functions that drive the compiler nuts.) For best results, use GCC 3.3 or newer. GCC 3.2 and earlier have optimization bugs around pointer aliasing detection, which can result in 2x performance losses. If you will be running many simulations on a single compile, investigate feedback driven compilation. With GCC, using -fprofile-arcs, then -fbranch-probabilities will yield another 15% or so. Modern compilers also support link-time optimization (LTO), which can help especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in both compilation and link. Note LTO may cause excessive compile times on large designs. If you are using your own makefiles, you may want to compile the Verilated code with -DVL_INLINE_OPT=inline. This will inline functions, however this requires that all cpp files be compiled in a single compiler run. You may uncover further tuning possibilities by profiling the Verilog code. Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run either oprofile or gprof to see where in the C++ code the time is spent. Run the gprof output through verilator_profcfunc and it will tell you what Verilog line numbers on which most of the time is being spent. When done, please let the author know the results. I like to keep tabs on how Verilator compares, and may be able to suggest additional improvements. FILES All output files are placed in the output directory name specified with the -Mdir option, or "obj_dir" if not specified. Verilator creates the following files in the output directory: {prefix}.mk // Make include file for compiling {prefix}_classes.mk // Make include file with class names For -cc and -sc mode, it also creates: {prefix}.cpp // Top level C++ file {prefix}.h // Top level header {prefix}{each_verilog_module}.cpp // Lower level internal C++ files {prefix}{each_verilog_module}.h // Lower level internal header files In certain optimization modes, it also creates: {prefix}__Dpi.h // DPI import and export declarations {prefix}__Inlines.h // Inline support functions {prefix}__Slow.cpp // Constructors and infrequent routines {prefix}__Syms.cpp // Global symbol table C++ {prefix}__Syms.h // Global symbol table header {prefix}__Trace.cpp // Wave file generation code (--trace) {prefix}__cdc.txt // Clock Domain Crossing checks (--cdc) {prefix}__stats.txt // Statistics (--stats) It also creates internal files that can be mostly ignored: {each_verilog_module}.vpp // Post-processed verilog (--debug) {prefix}.flags_vbin // Verilator dependencies {prefix}.flags_vpp // Pre-processor dependencies {prefix}__verFiles.dat // Timestamps for skip-identical {prefix}{misc}.d // Make dependencies (-MMD) {prefix}{misc}.dot // Debugging graph files (--debug) {prefix}{misc}.tree // Debugging files (--debug) After running Make, the C++ compiler should produce the following: {prefix} // Final executable (w/--exe argument) {prefix}__ALL.a // Library of all Verilated objects {prefix}{misc}.o // Intermediate objects ENVIRONMENT LD_LIBRARY_PATH A generic Linux/OS variable specifying what directories have shared object (.so) files. This path should include SystemC and any other shared objects needed at runtime. OBJCACHE Optionally specifies a caching or distribution program to place in front of all runs of the C++ Compiler. For example, "objcache --read --write", or "ccache". If using distcc, it would generally be run under either objcache or ccache; see the documentation for those programs. SYSTEMC Deprecated. Used only if SYSTEMC_INCLUDE or SYSTEMC_LIBDIR is not set. If set, specifies the directory containing the SystemC distribution. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). SYSTEMC_ARCH Deprecated. Used only if SYSTEMC_LIBDIR is not set. Specifies the architecture name used by the SystemC kit. This is the part after the dash in the lib-{...} directory name created by a 'make' in the SystemC distribution. If not set, Verilator will try to intuit the proper setting, or use the default optionally specified at configure time (before Verilator was compiled). SYSTEMC_CXX_FLAGS Specifies additional flags that are required to be passed to GCC when building the SystemC model. System 2.3.0 may need this set to "-pthread". SYSTEMC_INCLUDE If set, specifies the directory containing the systemc.h header file. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/include. SYSTEMC_LIBDIR If set, specifies the directory containing the libsystemc.a library. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/lib-SYSTEMC_ARCH. VCS_HOME If set, specifies the directory containing the Synopsys VCS distribution. When set, a 'make test' in the Verilator distribution will also run VCS baseline regression tests. VERILATOR_BIN If set, specifies an alternative name of the Verilator binary. May be used for debugging and selecting between multiple operating system builds. VERILATOR_GDB If set, the command to run when using the --gdb option, such as "ddd". If not specified, it will use "gdb". VERILATOR_ROOT Specifies the directory containing the distribution kit. This is used to find the executable, Perl library, and include files. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). It should not be specified if using a pre-compiled Verilator RPM as the hardcoded value should be correct. CONNECTING TO C++ Verilator creates a .h and .cpp file for the top level module and all modules under it. See the test_c directory in the kit for an example. After the modules are completed, there will be a *module*.mk file that may be used with Make to produce a *module*__ALL.a file with all required objects in it. This is then linked with the user's top level to create the simulation executable. The user must write the top level of the simulation. Here's a simple example: #include // Defines common routines #include "Vtop.h" // From Verilating "top.v" Vtop *top; // Instantiation of module vluint64_t main_time = 0; // Current simulation time // This is a 64-bit integer to reduce wrap over issues and // allow modulus. You can also use a double, if you wish. double sc_time_stamp () { // Called by $time in Verilog return main_time; // converts to double, to match // what SystemC does } int main(int argc, char** argv) { Verilated::commandArgs(argc, argv); // Remember args top = new Vtop; // Create instance top->reset_l = 0; // Set some inputs while (!Verilated::gotFinish()) { if (main_time > 10) { top->reset_l = 1; // Deassert reset } if ((main_time % 10) == 1) { top->clk = 1; // Toggle clock } if ((main_time % 10) == 6) { top->clk = 0; } top->eval(); // Evaluate model cout << top->out << endl; // Read a output main_time++; // Time passes... } top->final(); // Done simulating // // (Though this example doesn't get here) delete top; } Note signals are read and written as member variables of the lower module. You call the eval() method to evaluate the model. When the simulation is complete call the final() method to wrap up any SystemVerilog final blocks, and complete any assertions. CONNECTING TO SYSTEMC Verilator will convert the top level module to a SC_MODULE. This module will plug directly into a SystemC netlist. The SC_MODULE gets the same pinout as the Verilog module, with the following type conversions: Pins of a single bit become bool. Pins 2-32 bits wide become uint32_t's. Pins 33-64 bits wide become sc_bv's or vluint64_t's depending on the --no-pins64 switch. Wider pins become sc_bv's. (Uints simulate the fastest so are used where possible.) Lower modules are not pure SystemC code. This is a feature, as using the SystemC pin interconnect scheme everywhere would reduce performance by an order of magnitude. DIRECT PROGRAMMING INTERFACE (DPI) Verilator supports SystemVerilog Direct Programming Interface import and export statements. Only the SystemVerilog form ("DPI-C") is supported, not the original Synopsys-only DPI. DPI Example In the SYSTEMC example above, if you wanted to import C++ functions into Verilog, put in our.v: import "DPI-C" function integer add (input integer a, input integer b); initial begin $display("%x + %x = %x", 1, 2, add(1,2)); endtask Then after Verilating, Verilator will create a file Vour__Dpi.h with the prototype to call this function: extern int add (int a, int b); From the sc_main.cpp file (or another .cpp file passed to the Verilator command line, or the link), you'd then: #include "svdpi.h" #include "Vour__Dpi.h" int add (int a, int b) { return a+b; } DPI System Task/Functions Verilator extends the DPI format to allow using the same scheme to efficiently add system functions. Simply use a dollar-sign prefixed system function name for the import, but note it must be escaped. export "DPI-C" function integer \$myRand; initial $display("myRand=%d", $myRand()); Going the other direction, you can export Verilog tasks so they can be called from C++: export "DPI-C" task publicSetBool; task publicSetBool; input bit in_bool; var_bool = in_bool; endtask Then after Verilating, Verilator will create a file Vour__Dpi.h with the prototype to call this function: extern bool publicSetBool(bool in_bool); From the sc_main.cpp file, you'd then: #include "Vour__Dpi.h" publicSetBool(value); Or, alternatively, call the function under the design class. This isn't DPI compatible but is easier to read and better supports multiple designs. #include "Vour__Dpi.h" Vour::publicSetBool(value); // or top->publicSetBool(value); Note that if the DPI task or function accesses any register or net within the RTL, it will require a scope to be set. This can be done using the standard functions within svdpi.h, after the module is instantiated, but before the task(s) and/or function(s) are called. For example, if the top level module is instantiated with the name "dut" and the name references within tasks are all hierarchical (dotted) names with respect to that top level module, then the scope could be set with #include "svdpi.h" ... svSetScope (svGetScopeFromName ("dut")); (Remember that Verilator adds a "V" to the top of the module hierarchy.) Scope can also be set from within a DPI imported C function that has been called from Verilog by querying the scope of that function. See the sections on DPI Context Functions and DPI Header Isolation below and the comments within the svdpi.h header for more information. DPI Display Functions Verilator allows writing $display like functions using this syntax: import "DPI-C" function void \$my_display (input string formatted /*verilator sformat*/ ); The /*verilator sformat*/ indicates that this function accepts a $display like format specifier followed by any number of arguments to satisfy the format. DPI Context Functions Verilator supports IEEE DPI Context Functions. Context imports pass the simulator context, including calling scope name, and filename and line number to the C code. For example, in Verilog: import "DPI-C" context function int dpic_line(); initial $display("This is line %d, again, line %d\n", `line, dpic_line()); This will call C++ code which may then use the svGet* functions to read information, in this case the line number of the Verilog statement that invoked the dpic_line function: int dpic_line() { // Get a scope: svScope scope = svGetScope(); const char* scopenamep = svGetNameFromScope(scope); assert(scopenamep); const char* filenamep = ""; int lineno = 0; if (svGetCallerInfo(&filenamep, &lineno)) { printf("dpic_line called from scope %s on line %d\n", scopenamep, lineno); return lineno; } else { return 0; } } See the IEEE Standard for more information. DPI Header Isolation Verilator places the IEEE standard header files such as svdpi.h into a separate include directory, vltstd (VeriLaTor STandarD). When compiling most applications $VERILATOR_ROOT/include/vltstd would be in the include path along with the normal $VERILATOR_ROOT/include. However, when compiling Verilated models into other simulators which have their own svdpi.h and similar standard files with different contents, the vltstd directory should not be included to prevent picking up incompatible definitions. Public Functions Instead of DPI exporting, there's also Verilator public functions, which are slightly faster, but less compatible. VERIFICATION PROCEDURAL INTERFACE (VPI) Verilator supports a very limited subset of the VPI. This subset allows inspection, examination, value change callbacks, and depositing of values to public signals only. To access signals via the VPI, Verilator must be told exactly which signals are to be accessed. This is done using the Verilator public pragmas documented below. Verilator has an important difference from an event based simulator; signal values that are changed by the VPI will not immediately propagate their values, instead the top level header file's eval() method must be called. Normally this would be part of the normal evaluation (IE the next clock edge), not as part of the value change. This makes the performance of VPI routines extremely fast compared to event based simulators, but can confuse some test-benches that expect immediate propagation. Note the VPI by it's specified implementation will always be much slower than accessing the Verilator values by direct reference (structure->module->signame), as the VPI accessors perform lookup in functions at runtime requiring at best hundreds of instructions, while the direct references are evaluated by the compiler and result in only a couple of instructions. VPI Example In the below example, we have readme marked read-only, and writeme which if written from outside the model will have the same semantics as if it changed on the specified clock edge. module t; reg readme /*verilator public_flat_rd*/; reg writeme /*verilator public_flat_rw @(posedge clk) */; endmodule There are many online tutorials and books on the VPI, but an example that accesses the above would be: void read_and_check() { vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.readme", NULL); if (!vh1) { error... } const char* name = vpi_get_str(vpiName, vh1); printf("Module name: %s\n"); // Prints "readme" s_vpi_value v; v.format = vpiIntVal; vpi_get_value(vh1, &v); printf("Value of v: %d\n", v.value.integer); // Prints "readme" } CROSS COMPILATION Verilator supports cross-compiling Verilated code. This is generally used to run Verilator on a Linux system and produce C++ code that is then compiled on Windows. Cross compilation involves up to three different OSes. The build system is where you configured and compiled Verilator, the host system where you run Verilator, and the target system where you compile the Verilated code and run the simulation. Currently, Verilator requires the build and host system type to be the same, though the target system type may be different. To support this, ./configure and make Verilator on the build system. Then, run Verilator on the host system. Finally, the output of Verilator may be compiled on the different target system. To support this, none of the files that Verilator produces will reference any configure generated build-system specific files, such as config.h (which is renamed in Verilator to config_build.h to reduce confusion.) The disadvantage of this approach is that include/verilatedos.h must self-detect the requirements of the target system, rather than using configure. The target system may also require edits to the Makefiles, the simple Makefiles produced by Verilator presume the target system is the same type as the build system. Cadence NC-SystemC Models Similar to compiling Verilated designs with gcc, Verilated designs may be compiled inside other simulators that support C++ or SystemC models. One such simulator is Cadence's NC-SystemC, part of their Incisive Verification Suite. (Highly recommended.) Using the example files above, the following command will build the model underneath NC: cd obj_dir ncsc_run \ sc_main.cpp \ Vour__ALLcls.cpp \ Vour__ALLsup.cpp \ verilated.cpp For larger designs you'll want to automate this using makefiles, which pull the names of the .cpp files to compile in from the make variables generated in obj_dir/Vour_classes.mk. CONFIGURATION FILES In addition to the command line, warnings and other features may be controlled by configuration files, typically named with the .vlt extension. An example: `verilator_config lint_off -msg WIDTH lint_off -msg CASEX -file "silly_vendor_code.v" This disables WIDTH warnings globally, and CASEX for a specific file. Configuration files are parsed after the normal Verilog preprocessing, so `ifdefs, `defines, and comments may be used as if it were normal Verilog code. The grammar of configuration commands is as follows: `verilator_config Take remaining text up the the next `verilog mode switch and treat it as Verilator configuration commands. coverage_off [-file "" [-lines [ - ]]] Disable coverage for the specified filename (or wildcard with '*' or '?', or all files if omitted) and range of line numbers (or all lines if omitted). Often used to ignore an entire module for coverage analysis purposes. lint_off [-msg ] [-file "" [-lines [ - ]]] Disables the specified lint warning, in the specified filename (or wildcard with '*' or '?', or all files if omitted) and range of line numbers (or all lines if omitted). Using '*' will override any lint_on directives in the source, i.e. the warning will still not be printed. If the -msg is omitted, all lint warnings are disabled. This will override all later lint warning enables for the specified region. tracing_off [-file "" [-lines [ - ]]] Disable waveform tracing for all future signals declared in the specified filename (or wildcard with '*' or '?', or all files if omitted) and range of line numbers (or all lines if omitted). LANGUAGE STANDARD SUPPORT Verilog 2001 (IEEE 1364-2001) Support Verilator supports most Verilog 2001 language features. This includes signed numbers, "always @*", generate statements, multidimensional arrays, localparam, and C-style declarations inside port lists. Verilog 2005 (IEEE 1364-2005) Support Verilator supports most Verilog 2005 language features. This includes the `begin_keywords and `end_keywords compiler directives, $clog2, and the uwire keyword. SystemVerilog 2005 (IEEE 1800-2005) Support Verilator supports ==? and !=? operators, ++ and -- in some contexts, $bits, $countones, $error, $fatal, $info, $isunknown, $onehot, $onehot0, $unit, $warning, always_comb, always_ff, always_latch, bit, byte, chandle, const, do-while, enum, export, final, import, int, interface, logic, longint, modport, package, program, shortint, struct, time, typedef, union, var, void, priority case/if, and unique case/if. It also supports .name and .* interconnection. Verilator partially supports concurrent assert and cover statements; see the enclosed coverage tests for the syntax which is allowed. SystemVerilog 2012 (IEEE 1800-2012) Support Verilator implements a full SystemVerilog 2012 preprocessor, including function call-like preprocessor defines, default define arguments, `__FILE__, `__LINE__ and `undefineall. Verilator currently has some support for SystemVerilog synthesis constructs. As SystemVerilog features enter common usage they are added; please file a bug if a feature you need is missing. Verilog AMS Support Verilator implements a very small subset of Verilog AMS (Verilog Analog and Mixed-Signal Extensions) with the subset corresponding to those VMS keywords with near equivalents in the Verilog 2005 or SystemVerilog 2009 languages. AMS parsing is enabled with "--language VAMS" or "--language 1800+VAMS". At present Verilator implements ceil, exp, floor, ln, log, pow, sqrt, string, and wreal. Synthesis Directive Assertion Support With the --assert switch, Verilator reads any "//synopsys full_case" or "//synopsys parallel_case" directives. The same applies to any "//ambit synthesis", "//cadence" or "//pragma" directives of the same form. When these synthesis directives are discovered, Verilator will either formally prove the directive to be true, or failing that, will insert the appropriate code to detect failing cases at runtime and print an "Assertion failed" error message. Verilator likewise also asserts any "unique" or "priority" SystemVerilog keywords on case statement, as well as "unique" on if statements. However, "priority if" is currently simply ignored. LANGUAGE EXTENSIONS The following additional constructs are the extensions Verilator supports on top of standard Verilog code. Using these features outside of comments or `ifdef's may break other tools. `__FILE__ The __FILE__ define expands to the current filename as a string, like C++'s __FILE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!) `__LINE__ The __LINE__ define expands to the current filename as a string, like C++'s __LINE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!) `error *string* This will report an error when encountered, like C++'s #error. $c(*string*, ...); The string will be embedded directly in the output C++ code at the point where the surrounding Verilog code is compiled. It may either be a standalone statement (with a trailing ; in the string), or a function that returns up to a 32-bit number (without a trailing ;). This can be used to call C++ functions from your Verilog code. String arguments will be put directly into the output C++ code. Expression arguments will have the code to evaluate the expression inserted. Thus to call a C++ function, $c("func(",a,")") will result in 'func(a)' in the output C++ code. For input arguments, rather than hard-coding variable names in the string $c("func(a)"), instead pass the variable as an expression $c("func(",a,")"). This will allow the call to work inside Verilog functions where the variable is flattened out, and also enable other optimizations. If you will be reading or writing any Verilog variables inside the C++ functions, the Verilog signals must be declared with /*verilator public*/. You may also append an arbitrary number to $c, generally the width of the output. [signal_32_bits = $c32("...");] This allows for compatibility with other simulators which require a differently named PLI function name for each different output width. $display, $write, $fdisplay, $fwrite, $sformat, $swrite Format arguments may use C fprintf sizes after the % escape. Per the Verilog standard, %x prints a number with the natural width, and %0x prints a number with minimum width. Verilator extends this so %5x prints 5 digits per the C standard (it's unspecified in Verilog). `coverage_block_off Specifies the entire begin/end block should be ignored for coverage analysis. Same as /* verilator coverage_block_off */. `systemc_header Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the output .h file's header. Despite the name of this macro, this also works in pure C++ code. `systemc_ctor Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class constructor. Despite the name of this macro, this also works in pure C++ code. `systemc_dtor Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class destructor. Despite the name of this macro, this also works in pure C++ code. `systemc_interface Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class interface. Despite the name of this macro, this also works in pure C++ code. `systemc_imp_header Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the header of all files for this C++ class implementation. Despite the name of this macro, this also works in pure C++ code. `systemc_implementation Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into a single file of the C++ class implementation. Despite the name of this macro, this also works in pure C++ code. If you will be reading or writing any Verilog variables in the C++ functions, the Verilog signals must be declared with /*verilator public*/. See also the public task feature; writing an accessor may result in cleaner code. `SYSTEMVERILOG The SYSTEMVERILOG, SV_COV_START and related standard defines are set by default when --language is 1800-*. `VERILATOR `verilator `verilator3 The VERILATOR, verilator and verilator3 defines are set by default so you may `ifdef around compiler specific constructs. `verilator_config Take remaining text up the the next `verilog mode switch and treat it as Verilator configuration commands. `verilog Switch back to processing Verilog code after a `systemc_... mode switch. The Verilog code returns to the last language mode specified with `begin_keywords, or SystemVerilog if none were specified. /*verilator clock_enable*/ Used after a signal declaration to indicate the signal is used to gate a clock, and the user takes responsibility for insuring there are no races related to it. (Typically by adding a latch, and running static timing analysis.) For example: reg enable_r /*verilator clock_enable*/; wire gated_clk = clk & enable_r; always_ff @ (posedge clk) enable_r <= enable_early; The clock_enable attribute will cause the clock gate to be ignored in the scheduling algorithm, sometimes required for correct clock behavior, and always improving performance. It's also a good idea to enable the IMPERFECTSCH warning, to insure all clock enables are properly recognized. /*verilator clocker*/ /*verilator no_clocker*/ Used after a signal declaration to indicate the signal is used as clock or not. This information is used by Verilator to mark the signal as clocker and propagate the clocker attribute automatically to derived signals. See "--clk" for more information. /*verilator coverage_block_off*/ Specifies the entire begin/end block should be ignored for coverage analysis purposes. /*verilator coverage_off*/ Specifies that following lines of code should have coverage disabled. Often used to ignore an entire module for coverage analysis purposes. /*verilator coverage_on*/ Specifies that following lines of code should have coverage re-enabled (if appropriate --coverage flags are passed) after being disabled earlier with /*verilator coverage_off*/. /*verilator inline_module*/ Specifies the module the comment appears in may be inlined into any modules that use this module. This is useful to speed up simulation time with some small loss of trace visibility and modularity. Note signals under inlined submodules will be named *submodule*__DOT__*subsignal* as C++ does not allow "." in signal names. When tracing such signals the tracing routines will replace the __DOT__ with the period. /*verilator isolate_assignments*/ Used after a signal declaration to indicate the assignments to this signal in any blocks should be isolated into new blocks. When there is a large combinatorial block that is resulting in a UNOPTFLAT warning, attaching this to the signal causing a false loop may clear up the problem. IE, with the following reg splitme /* verilator isolate_assignments*/; // Note the placement of the semicolon above always @* begin if (....) begin splitme = ....; other assignments end end Verilator will internally split the block that assigns to "splitme" into two blocks: It would then internally break it into (sort of): // All assignments excluding those to splitme always @* begin if (....) begin other assignments end end // All assignments to splitme always @* begin if (....) begin splitme = ....; end end /*verilator lint_off *msg**/ Disable the specified warning message for any warnings following the comment. /*verilator lint_on *msg**/ Re-enable the specified warning message for any warnings following the comment. /*verilator lint_restore*/ After a /*verilator lint_save*/, pop the stack containing lint message state. Often this is useful at the bottom of include files. /*verilator lint_save*/ Push the current state of what lint messages are turned on or turned off to a stack. Later meta-comments may then lint_on or lint_off specific messages, then return to the earlier message state by using /*verilator lint_restore*/. For example: // verilator lint_save // verilator lint_off SOME_WARNING ... // code needing SOME_WARNING turned off // verilator lint_restore If SOME_WARNING was on before the lint_off, it will now be restored to on, and if it was off before the lint_off it will remain off. /*verilator no_inline_task*/ Used in a function or task variable definition section to specify the function or task should not be inlined into where it is used. This may reduce the size of the final executable when a task is used a very large number of times. For this flag to work, the task and tasks below it must be pure; they cannot reference any variables outside the task itself. /*verilator public*/ (typedef enum) Used after an enum typedef declaration to indicate the emitted C code should have the enum values visible. Due to C++ language restrictions, this may only be used on 64-bit or narrower integral enumerations. typedef enum logic [2:0] { ZERO = 3'b0 } pub_t /*verilator public*/; /*verilator public*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will also declare this module public, otherwise use /*verilator public_flat*/. Instead of using public variables, consider instead making a DPI or public function that accesses the variable. This is nicer as it provides an obvious entry point that is also compatible across simulators. /*verilator public*/ (task/function) Used inside the declaration section of a function or task declaration to indicate the function or task should be made into a C++ function, public to outside callers. Public tasks will be declared as a void C++ function, public functions will get the appropriate non-void (bool, uint32_t, etc) return type. Any input arguments will become C++ arguments to the function. Any output arguments will become C++ reference arguments. Any local registers/integers will become function automatic variables on the stack. Wide variables over 64 bits cannot be function returns, to avoid exposing complexities. However, wide variables can be input/outputs; they will be passed as references to an array of 32-bit numbers. Generally, only the values of stored state (flops) should be written, as the model will NOT notice changes made to variables in these functions. (Same as when a signal is declared public.) You may want to use DPI exports instead, as it's compatible with other simulators. /*verilator public_flat*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will not declare this module public, which means the name of the signal or path to it may change based upon the module inlining which takes place. /*verilator public_flat_rd*/ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat (see above), but read-only. /*verilator public_flat_rw @() */ (variable) Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat_rd (see above), and also writable, where writes should be considered to have the timing specified by the given sensitivity edge list. /*verilator public_module*/ Used after a module statement to indicate the module should not be inlined (unless specifically requested) so that C code may access the module. Verilator automatically sets this attribute when the module contains any public signals or `systemc_ directives. Also set for all modules when using the --public switch. /*verilator sc_clock*/ Rarely needed. Used after an input declaration to indicate the signal should be declared in SystemC as a sc_clock instead of a bool. This was needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require clock pins to be sc_clocks and this is no longer needed. /*verilator sc_bv*/ Used after a port declaration. It sets the port to be of sc_bv<*width*> type, instead of bool, vluint32_t or vluint64_t. This may be useful if the port width is parametrized and different of such modules interface a templated module (such as a transactor) or for other reasons. In general you should avoid using this attribute when not necessary as with increasing usage of sc_bv the performance increases significantly. /*verilator sformat*/ Attached to the final input of a function or task "input string" to 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. /*verilator tracing_off*/ Disable waveform tracing for all future signals that are declared in this module, or cells below this module. Often this is placed just after a primitive's module statement, so that the entire module and cells below it are not traced. /*verilator tracing_on*/ Re-enable waveform tracing for all future signals or cells that are declared. LANGUAGE LIMITATIONS There are some limitations and lack of features relative to a commercial simulator, by intent. User beware. It is strongly recommended you use a lint tool before running this program. Verilator isn't designed to easily uncover common mistakes that a lint program will find for you. Synthesis Subset Verilator supports only the Synthesis subset with a few minor additions such as $stop, $finish and $display. That is, you cannot use hierarchical references, events or similar features of the Verilog language. It also simulates as Synopsys's Design Compiler would; namely a block of the form: always @ (x) y = x & z; This will recompute y when there is even a potential for change in x or a change in z, that is when the flops computing x or z evaluate (which is what Design Compiler will synthesize.) A compliant simulator would only calculate y if x changes. Use verilog-mode's /*AS*/ or Verilog 2001's always @* to reduce missing activity items. Avoid putting $displays in combo blocks, as they may print multiple times when not desired, even on compliant simulators as event ordering is not specified. Bind Verilator only supports "bind" to a target module name, not an instance path. Dotted cross-hierarchy references Verilator supports dotted references to variables, functions and tasks in different modules. However, references into named blocks and function-local variables are not supported. The portion before the dot must have a constant value; for example a[2].b is acceptable, while a[x].b is not. References into generated and arrayed instances use the instance names specified in the Verilog standard; arrayed instances are named {cellName}[{instanceNumber}] in Verilog, which becomes {cellname}__BRA__{instanceNumber}__KET__ inside the generated C++ code. Verilator creates numbered "genblk" when a begin: name is not specified around a block inside a generate statement. These numbers may differ between other simulators, but the Verilog specification does not allow users to use these names, so it should not matter. If you are having trouble determining where a dotted path goes wrong, note that Verilator will print a list of known scopes to help your debugging. Floating Point Floating Point (real) numbers are supported. Latches Verilator is optimized for edge sensitive (flop based) designs. It will attempt to do the correct thing for latches, but most performance optimizations will be disabled around the latch. Structures and Unions Verilator only presently supports packed structs and packed unions. Rand and randc tags on members are simply ignored. All structures and unions are represented as a single vector, which means that generating one member of a structure from blocking, and another from non-blocking assignments is unsupported. Time All delays (#) are ignored, as they are in synthesis. Unknown states Verilator is mostly a two state simulator, not a four state simulator. However, it has two features which uncover most initialization bugs (including many that a four state simulator will miss.) Identity comparisons (=== or !==) are converted to standard ==/!== when neither side is a constant. This may make the expression result differ from a four state simulator. An === comparison to X will always be false, so that Verilog code which checks for uninitialized logic will not fire. Assigning a variable to a X will actually assign the variable to a random value (see the --x-assign switch.) Thus if the value is actually used, the random value should cause downstream errors. Integers also randomize, even though the Verilog 2001 specification says they initialize to zero. All variables are randomly initialized using a function. By running several random simulation runs you can determine that reset is working correctly. On the first run, the function initializes variables to zero. On the second, have it initialize variables to one. On the third and following runs have it initialize them randomly. If the results match, reset works. (Note this is what the hardware will really do.) In practice, just setting all variables to one at startup finds most problems. Note. --x-assign applies to variables explicitly initialized or assigned to X. Uninitialized clocks are initialized to zero, while all other state holding variables are initialized to a random value. Event driven simulators will generally trigger an edge on a transition from X to 1 ("posedge") or X to 0 ("negedge"). However, by default, since clocks are initialized to zero, Verilator will not trigger an initial negedge. Some code (particulary for reset) may rely on X->0 triggering an edge. Verilator provides a switch (see --x-initial-edge) to enable this behavior. Comparing runs with and without this switch will find such problems. Tri/Inout Verilator converts some simple tristate structures into two state. Pullup, pulldown, bufif0, bufif1, notif0, notif1, pmos, nmos, tri0 and tri1 are also supported. Simple comparisons with === 1'bz are also supported. An assignment of the form: inout driver; wire driver = (enable) ? output_value : 1'bz; Will be converted to input driver; // Value being driven in from "external" drivers output driver__en; // True if driven from this module output driver__out; // Value being driven from this module External logic will be needed to combine these signals with any external drivers. Tristate drivers are not supported inside functions and tasks; an inout there will be considered a two state variable that is read and written instead of a four state variable. Functions & Tasks All functions and tasks will be inlined (will not become functions in C.) The only support provided is for simple statements in tasks (which may affect global variables). Recursive functions and tasks are not supported. All inputs and outputs are automatic, as if they had the Verilog 2001 "automatic" keyword prepended. (If you don't know what this means, Verilator will do what you probably expect -- what C does. The default behavior of Verilog is different.) Generated Clocks Verilator attempts to deal with generated and enabled clocks correctly, however some cases cause problems in the scheduling algorithm which is optimized for performance. The safest option is to have all clocks as primary inputs to the model, or wires directly attached to primary inputs. For proper behavior clock enables may also need the /*verilator clock_enable*/ attribute. Ranges must be big-bit-endian Bit ranges must be numbered with the MSB being numbered greater or the same as the LSB. Little-bit-endian busses [0:15] are not supported as they aren't easily made compatible with C++. Gate Primitives The 2-state gate primitives (and, buf, nand, nor, not, or, xnor, xor) are directly converted to behavioral equivalents. The 3-state and MOS gate primitives are not supported. Tables are not supported. Specify blocks All specify blocks and timing checks are ignored. Array Initialization When initializing a large array, you need to use non-delayed assignments. Verilator will tell you when this needs to be fixed; see the BLKLOOPINIT error for more information. Array Out of Bounds Writing a memory element that is outside the bounds specified for the array may cause a different memory element inside the array to be written instead. For power-of-2 sized arrays, Verilator will give a width warning and the address. For non-power-of-2-sizes arrays, index 0 will be written. Reading a memory element that is outside the bounds specified for the array will give a width warning and wrap around the power-of-2 size. For non-power-of-2 sizes, it will return a unspecified constant of the appropriate width. Assertions Verilator is beginning to add support for assertions. Verilator currently only converts assertions to simple "if (...) error" statements, and coverage statements to increment the line counters described in the coverage section. Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. (Arguably SEREs are much of the point, but one must start somewhere.) Language Keyword Limitations This section describes specific limitations for each language keyword. `__FILE__, `__LINE__, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `define, `else, `elsif, `end_keywords, `endif, `error, `ifdef, `ifndef, `include, `line, `systemc_ctor, `systemc_dtor, `systemc_header, `systemc_imp_header, `systemc_implementation, `systemc_interface, `timescale, `undef, `verilog Fully supported. always, always_comb, always_ff, always_latch, and, assign, begin, buf, byte, case, casex, casez, default, defparam, do-while, else, end, endcase, endfunction, endgenerate, endmodule, endspecify, endtask, final, for, function, generate, genvar, if, initial, inout, input, int, integer, localparam, logic, longint, macromodule, module, nand, negedge, nor, not, or, output, parameter, posedge, reg, scalared, shortint, signed, supply0, supply1, task, time, tri, typedef, var, vectored, while, wire, xnor, xor Generally supported. ++, -- operators Increment/decrement can only be used as standalone statements or in for loops. They cannot be used as side effect operators inside more complicate expressions ("a = b++;"). '{} operator Assignment patterns with order based, default, constant integer (array) or member identifier (struct/union) keys are supported. Data type keys and keys which are computed from a constant expression are not supported. cast operator Casting is supported only between simple scalar types, signed and unsigned, not arrays nor structs. chandle Treated as a "longint"; does not yet warn about operations that are specified as illegal on chandles. disable Disable statements may be used only if the block being disabled is a block the disable statement itself is inside. This was commonly used to provide loop break and continue functionality before SystemVerilog added the break and continue keywords. inside Inside expressions may not include unpacked array traversal or $ as an upper bound. Case inside and case matches are also unsupported. interface Interfaces and modports, including with generated data types are supported. Generate blocks around modports are not supported, nor are virtual interfaces nor unnamed interfaces. priority if, unique if Priority and unique if's are treated as normal ifs and not asserted to be full nor unique. specify specparam All specify blocks and timing checks are ignored. string String is supported only to the point that they can be assigned, concatenated, compared, and passed to DPI imports. Standard method calls on strings are not supported. timeunit, timeprecision All timing control statements are ignored. uwire Verilator does not perform warning checking on uwires, it treats the uwire keyword as if it were the normal wire keyword. $bits, $countones, $error, $fatal, $finish, $info, $isunknown, $onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time, $unsigned, $warning. Generally supported. $display, $write, $fdisplay, $fwrite, $swrite $display and friends must have a constant format string as the first argument (as with C's printf). The rare usage which lists variables standalone without a format is not supported. $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc The sized display functions are rarely used and so not supported. Replace them with a $write with the appropriate format specifier. $finish, $stop The rarely used optional parameter to $finish and $stop is ignored. $fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fscanf, $fwrite File descriptors passed to the file PLI calls must be file descriptors, not MCDs, which includes the mode parameter to $fopen being mandatory. $fscanf, $sscanf Only integer formats are supported; %e, %f, %m, %r, %v, and %z are not supported. $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal, $setup, $setuphold, $skew, $timeskew, $width All specify blocks and timing checks are ignored. $random $random does not support the optional argument to set the seed. Use the srand function in C to accomplish this, and note there is only one random number generator (not one per module). $readmemb, $readmemh Read memory commands should work properly. Note Verilator and the Verilog specification does not include support for readmem to multi-dimensional arrays. $test$plusargs, $value$plusargs Supported, but the instantiating C++/SystemC testbench must call Verilated::commandArgs(argc, argv); to register the command line before calling $test$plusargs or $value$plusargs. $timeformat Not supported as Verilator needs to determine all formatting at compile time. Generally you can just ifdef them out for no ill effect. Note also VL_TIME_MULTIPLER can be defined at compile time to move the decimal point when displaying all times, model wide. ERRORS AND WARNINGS Warnings may be disabled in two ways. First, when the warning is printed it will include a warning code. Simply surround the offending line with a warn_off/warn_on pair: // verilator lint_off UNSIGNED if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop; // verilator lint_on UNSIGNED Warnings may also be globally disabled by invoking Verilator with the "-Wno-*warning*" switch. This should be avoided, as it removes all checking across the designs, and prevents other users from compiling your code without knowing the magic set of disables needed to successfully compile your design. List of all warnings: ALWCOMBORDER Warns that an always_comb block has a variable which is set after it is used. This may cause simulation-synthesis mismatches, as not all commercial simulators allow this ordering. always_comb begin a = b; b = 1; end Ignoring this warning will only suppress the lint check, it will simulate correctly. ASSIGNIN Error that an assignment is being made to an input signal. This is almost certainly a mistake, though technically legal. input a; assign a = 1'b1; Ignoring this warning will only suppress the lint check, it will simulate correctly. ASSIGNDLY Warns that you have an assignment statement with a delayed time in front of it, for example: a <= #100 b; assign #100 a = b; Ignoring this warning may make Verilator simulations differ from other simulators, however at one point this was a common style so disabled by default as a code style warning. BLKANDNBLK BLKANDNBLK is an error that a variable comes from a mix of blocked and non-blocking assignments. Generally, this is caused by a register driven by both combo logic and a flop: always @ (posedge clk) foo[0] <= ... always @* foo[1] = ... Simply use a different register for the flop: always @ (posedge clk) foo_flopped[0] <= ... always @* foo[0] = foo_flopped[0]; always @* foo[1] = ... This is good coding practice anyways. It is also possible to disable this error when one of the assignments is inside a public task. Ignoring this warning may make Verilator simulations differ from other simulators. BLKSEQ This indicates that a blocking assignment (=) is used in a sequential block. Generally non-blocking/delayed assignments (<=) are used in sequential blocks, to avoid the possibility of simulator races. It can be reasonable to do this if the generated signal is used ONLY later in the same block, however this style is generally discouraged as it is error prone. always @ (posedge clk) foo = ... Disabled by default as this is a code style warning; it will simulate correctly. BLKLOOPINIT This indicates that the initialization of an array needs to use non-delayed assignments. This is done in the interest of speed; if delayed assignments were used, the simulator would have to copy large arrays every cycle. (In smaller loops, loop unrolling allows the delayed assignment to work, though it's a bit slower than a non-delayed assignment.) Here's an example always @ (posedge clk) if (~reset_l) begin for (i=0; i<`ARRAY_SIZE; i++) begin array[i] = 0; // Non-delayed for verilator end This message is only seen on large or complicated loops because Verilator generally unrolls small loops. You may want to try increasing --unroll-count (and occasionally --unroll-stmts) which will raise the small loop bar to avoid this error. CASEINCOMPLETE Warns that inside a case statement there is a stimulus pattern for which there is no case item specified. This is bad style, if a case is impossible, it's better to have a "default: $stop;" or just "default: ;" so that any design assumption violations will be discovered in simulation. Ignoring this warning will only suppress the lint check, it will simulate correctly. CASEOVERLAP Warns that inside a case statement you have case values which are detected to be overlapping. This is bad style, as moving the order of case values will cause different behavior. Generally the values can be respecified to not overlap. Ignoring this warning will only suppress the lint check, it will simulate correctly. CASEX Warns that it is simply better style to use casez, and "?" in place of "x"'s. See Ignoring this warning will only suppress the lint check, it will simulate correctly. CASEWITHX Warns that a case statement contains a constant with a "x". Verilator is two-state so interpret such items as always false. Note a common error is to use a "X" in a case or casez statement item; often what the user instead intended is to use a casez with "?". Ignoring this warning will only suppress the lint check, it will simulate correctly. CDCRSTLOGIC With --cdc only, warns that asynchronous flop reset terms come from other than primary inputs or flopped outputs, creating the potential for reset glitches. CLKDATA Warns that clock signal is mixed used with/as data signal. The checking for this warning is enabled only if user has explicitly marked some signal as clocker using command line option or in-source meta comment (see "--clk"). The warning can be disabled without affecting the simulation result. But it is recommended to check the warning as this may degrade the performance of the Verilated model. CMPCONST Warns that you are comparing a value in a way that will always be constant. For example "X > 1" will always be true when X is a single bit wide. Ignoring this warning will only suppress the lint check, it will simulate correctly. COMBDLY Warns that you have a delayed assignment inside of a combinatorial block. Using delayed assignments in this way is considered bad form, and may lead to the simulator not matching synthesis. If this message is suppressed, Verilator, like synthesis, will convert this to a non-delayed assignment, which may result in logic races or other nasties. See Ignoring this warning may make Verilator simulations differ from other simulators. DECLFILENAME Warns that a module or other declaration's name doesn't match the filename with path and extension stripped that it is declared in. The filename a modules/interfaces/programs is declared in should match the name of the module etc. so that -y directory searching will work. This warning is printed for only the first mismatching module in any given file, and -v library files are ignored. Disabled by default as this is a code style warning; it will simulate correctly. DEFPARAM Warns that the "defparam" statement was deprecated in Verilog 2001 and all designs should now be using the #(...) format to specify parameters. Disabled by default as this is a code style warning; it will simulate correctly. DETECTARRAY Error when Verilator tries to deal with a combinatorial loop that could not be flattened, and which involves a datatype which Verilator cannot handle, such as an unpacked struct or a large unpacked array. This typically ocurrs when -Wno-UNOPTFLAT has been used to override an UNOPTFLAT warning (see below). The solution is to break the loop, as described for UNOPTFLAT. ENDLABEL Warns that a label attached to a "end"-something statement does not match the label attached to the block start. Ignoring this warning will only suppress the lint check, it will simulate correctly. GENCLK Warns that the specified signal is generated, but is also being used as a clock. Verilator needs to evaluate sequential logic multiple times in this situation. In somewhat contrived cases having any generated clock can reduce performance by almost a factor of two. For fastest results, generate ALL clocks outside in C++/SystemC and make them primary inputs to your Verilog model. (However once need to you have even one, don't sweat additional ones.) Ignoring this warning may make Verilator simulations differ from other simulators. IFDEPTH Warns that if/if else statements have exceeded the depth specified with --if-depth, as they are likely to result in slow priority encoders. Unique and priority if statements are ignored. Solutions include changing the code to a case statement, or a SystemVerilog 'unique if' or 'priority if'. Disabled by default as this is a code style warning; it will simulate correctly. IMPERFECTSCH Warns that the scheduling of the model is not absolutely perfect, and some manual code edits may result in faster performance. This warning defaults to off, and must be turned on explicitly before the top module statement is processed. IMPLICIT Warns that a wire is being implicitly declared (it is a single bit wide output from a sub-module.) While legal in Verilog, implicit declarations only work for single bit wide signals (not buses), do not allow using a signal before it is implicitly declared by a cell, and can lead to dangling nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for Emacs, available from Ignoring this warning will only suppress the lint check, it will simulate correctly. IMPURE Warns that a task or function that has been marked with /*verilator no_inline_task*/ references variables that are not local to the task. Verilator cannot schedule these variables correctly. Ignoring this warning may make Verilator simulations differ from other simulators. INCABSPATH Warns that an `include filename specifies an absolute path. This means the code will not work on any other system with a different file system layout. Instead of using absolute paths, relative paths (preferably without any directory specified whatever) should be used, and +incdir used on the command line to specify the top include source directories. Disabled by default as this is a code style warning; it will simulate correctly. INITIALDLY Warns that you have a delayed assignment inside of an initial or final block. If this message is suppressed, Verilator will convert this to a non-delayed assignment. See also the COMBDLY warning. Ignoring this warning may make Verilator simulations differ from other simulators. LITENDIAN Warns that a packed vector is declared with little endian bit numbering (i.e. [0:7]). Big endian bit numbering is now the overwhelming standard, and little numbering is now thus often due to simple oversight instead of intent. Ignoring this warning will only suppress the lint check, it will simulate correctly. MODDUP Error that a module has multiple definitions. Generally this indicates a coding error, or a mistake in a library file and it's good practice to have one module per file to avoid these issues. For some gate level netlists duplicates are unavoidable, and this error may be disabled. MULTIDRIVEN Warns that the specified signal comes from multiple always blocks. This is often unsupported by synthesis tools, and is considered bad style. It will also cause longer runtimes due to reduced optimizations. Ignoring this warning will only slow simulations, it will simulate correctly. MULTITOP Error that there are multiple top level modules, that is modules not instantiated by any other module. Verilator only supports a single top level, if you need more, create a module that wraps all of the top modules. Often this error is because some low level cell is being read in, but is not really needed. The best solution is to insure that each module is in a unique file by the same name. Otherwise, make sure all library files are read in as libraries with -v, instead of automatically with -y. PINCONNECTEMPTY Warns that a cell instantiation has a pin which is connected to .pin_name(), e.g. not another signal, but with an explicit mention of the pin. It may be desirable to disable PINCONNECTEMPTY, as this indicates intention to have a no-connect. Disabled by default as this is a code style warning; it will simulate correctly. PINMISSING Warns that a module has a pin which is not mentioned in a cell instantiation. If a pin is not missing it should still be specified on the cell declaration with a empty connection, using "(.pin_name())". Ignoring this warning will only suppress the lint check, it will simulate correctly. PINNOCONNECT Warns that a cell instantiation has a pin which is not connected to another signal. Disabled by default as this is a code style warning; it will simulate correctly. REALCVT Warns that a real number is being implicitly rounded to an integer, with possible loss of precision. REDEFMACRO Warns that you have redefined the same macro with a different value, for example: `define MACRO def1 //... `define MACRO otherdef The best solution is to use a different name for the second macro. If this is not possible, add a undef to indicate the code is overriding the value: `define MACRO def1 //... `undef MACRO `define MACRO otherdef SELRANGE Warns that a selection index will go out of bounds: wire vec[6:0]; initial out = vec[7]; // There is no 7 Verilator will assume zero for this value, instead of X. Note that in some cases this warning may be false, when a condition upstream or downstream of the access means the access out of bounds will never execute or be used. wire vec[6:0]; initial begin seven = 7; ... if (seven != 7) out = vec[seven]; // Never will use vec[7] STMTDLY Warns that you have a statement with a delayed time in front of it, for example: #100 $finish; Ignoring this warning may make Verilator simulations differ from other simulators. SYMRSVDWORD Warning that a symbol matches a C++ reserved word and using this as a symbol name would result in odd C compiler errors. You may disable this warning, but the symbol will be renamed by Verilator to avoid the conflict. SYNCASYNCNET Warns that the specified net is used in at least two different always statements with posedge/negedges (i.e. a flop). One usage has the signal in the sensitivity list and body, probably as an async reset, and the other usage has the signal only in the body, probably as a sync reset. Mixing sync and async resets is usually a mistake. The warning may be disabled with a lint_off pragma around the net, or either flopped block. Disabled by default as this is a code style warning; it will simulate correctly. TASKNSVAR Error when a call to a task or function has a output from that task tied to a non-simple signal. Instead connect the task output to a temporary signal of the appropriate width, and use that signal to set the appropriate expression as the next statement. For example: task foo; output sig; ... endtask always @* begin foo(bus_we_select_from[2]); // Will get TASKNSVAR error end Change this to: reg foo_temp_out; always @* begin foo(foo_temp_out); bus_we_select_from[2] = foo_temp_out; end Verilator doesn't do this conversion for you, as some more complicated cases would result in simulator mismatches. UNDRIVEN Warns that the specified signal is never sourced. Verilator is fairly liberal in the usage calculations; making a signal public, or loading only a single array element marks the entire signal as driven. Disabled by default as this is a code style warning; it will simulate correctly. UNOPT Warns that due to some construct, optimization of the specified signal or block is disabled. The construct should be cleaned up to improve runtime. A less obvious case of this is when a module instantiates two submodules. Inside submodule A, signal I is input and signal O is output. Likewise in submodule B, signal O is an input and I is an output. A loop exists and a UNOPT warning will result if AI & AO both come from and go to combinatorial blocks in both submodules, even if they are unrelated always blocks. This affects performance because Verilator would have to evaluate each submodule multiple times to stabilize the signals crossing between the modules. Ignoring this warning will only slow simulations, it will simulate correctly. UNOPTFLAT Warns that due to some construct, optimization of the specified signal is disabled. The signal specified includes a complete scope to the signal; it may be only one particular usage of a multiply instantiated block. The construct should be cleaned up to improve runtime; two times better performance may be possible by fixing these warnings. Unlike the UNOPT warning, this occurs after netlist flattening, and indicates a more basic problem, as the less obvious case described under UNOPT does not apply. Often UNOPTFLAT is caused by logic that isn't truly circular as viewed by synthesis which analyzes interconnection per-bit, but is circular to simulation which analyzes per-bus: wire [2:0] x = {x[1:0],shift_in}; This statement needs to be evaluated multiple times, as a change in "shift_in" requires "x" to be computed 3 times before it becomes stable. This is because a change in "x" requires "x" itself to change value, which causes the warning. For significantly better performance, split this into 2 separate signals: wire [2:0] xout = {x[1:0],shift_in}; and change all receiving logic to instead receive "xout". Alternatively, change it to wire [2:0] x = {xin[1:0],shift_in}; and change all driving logic to instead drive "xin". With this change this assignment needs to be evaluated only once. These sort of changes may also speed up your traditional event driven simulator, as it will result in fewer events per cycle. The most complicated UNOPTFLAT path we've seen was due to low bits of a bus being generated from an always statement that consumed high bits of the same bus processed by another series of always blocks. The fix is the same; split it into two separate signals generated from each block. The UNOPTFLAT warning may also be due to clock enables, identified from the reported path going through a clock gating cell. To fix these, use the clock_enable meta comment described above. The UNOPTFLAT warning may also occur where outputs from a block of logic are independent, but occur in the same always block. To fix this, use the isolate_assignments meta comment described above. To assist in resolving UNOPTFLAT, the option "--report-unoptflat" can be used, which will provide suggestions for variables that can be split up, and a graph of all the nodes connected in the loop. See the Arguments section for more details. Ignoring this warning will only slow simulations, it will simulate correctly. UNPACKED Warns that unpacked structs and unions are not supported. Ignoring this warning will make Verilator treat the structure as packed, which may make Verilator simulations differ from other simulators. UNSIGNED Warns that you are comparing a unsigned value in a way that implies it is signed, for example "X < 0" will always be true when X is unsigned. Ignoring this warning will only suppress the lint check, it will simulate correctly. UNUSED Warns that the specified signal is never sinked. Verilator is fairly liberal in the usage calculations; making a signal public, a signal matching --unused-regexp ("*unused*") or accessing only a single array element marks the entire signal as used. Disabled by default as this is a code style warning; it will simulate correctly. A recommended style for unused nets is to put at the bottom of a file code similar to the following: wire _unused_ok = &{1'b0, sig_not_used_a, sig_not_used_yet_b, // To be fixed 1'b0}; The reduction AND and constant zeros mean the net will always be zero, so won't use simulation time. The redundant leading and trailing zeros avoid syntax errors if there are no signals between them. The magic name "unused" (-unused-regexp) is recognized by Verilator and suppresses warnings; if using other lint tools, either teach to tool to ignore signals with "unused" in the name, or put the appropriate lint_off around the wire. Having unused signals in one place makes it easy to find what is unused, and reduces the number of lint_off pragmas, reducing bugs. VARHIDDEN Warns that a task, function, or begin/end block is declaring a variable by the same name as a variable in the upper level module or begin/end block (thus hiding the upper variable from being able to be used.) Rename the variable to avoid confusion when reading the code. Disabled by default as this is a code style warning; it will simulate correctly. WIDTH Warns that based on width rules of Verilog, two operands have different widths. Verilator generally can intuit the common usages of widths, and you shouldn't need to disable this message like you do with most lint programs. Generally other than simple mistakes, you have two solutions: If it's a constant 0 that's 32 bits or less, simply leave it unwidthed. Verilator considers zero to be any width needed. Concatenate leading zeros when doing arithmetic. In the statement wire [5:0] plus_one = from[5:0] + 6'd1 + carry[0]; The best fix, which clarifies intent and will also make all tools happy is: wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]}; Ignoring this warning will only suppress the lint check, it will simulate correctly. WIDTHCONCAT Warns that based on width rules of Verilog, a concatenate or replication has an indeterminate width. In most cases this violates the Verilog rule that widths inside concatenates and replicates must be sized, and should be fixed in the code. wire [63:0] concat = {1,2}; An example where this is technically legal (though still bad form) is: parameter PAR = 1; wire [63:0] concat = {PAR,PAR}; The correct fix is to either size the 1 ("32'h1"), or add the width to the parameter definition ("parameter [31:0]"), or add the width to the parameter usage ("{PAR[31:0],PAR[31:0]}". The following describes the less obvious errors: Internal Error This error should never occur first, though may occur if earlier warnings or error messages have corrupted the program. If there are no other warnings or errors, submit a bug report. Unsupported: .... This error indicates that you are using a Verilog language construct that is not yet supported in Verilator. See the Limitations chapter. Verilated model didn't converge Verilator sometimes has to evaluate combinatorial logic multiple times, usually around code where a UNOPTFLAT warning was issued, but disabled. For example: always @ (a) b=~a; always @ (b) a=b will toggle forever and thus the executable will give the didn't converge error to prevent an infinite loop. To debug this, run Verilator with --profile-cfuncs. Run make on the generated files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in your main.cpp. This will cause each change in a variable to print a message. Near the bottom you'll see the code and variable that causes the problem. For the program above: CHANGE: filename.v:1: b CHANGE: filename.v:2: a FAQ/FREQUENTLY ASKED QUESTIONS Does it run under Windows? Yes, using Cygwin. Verilated output should also compile under Microsoft Visual C++ Version 7 or newer, but this is not tested by the author. Can you provide binaries? Verilator is available as a RPM for SuSE, Fedora, and perhaps other systems; this is done by porters and may slightly lag the primary distribution. If there isn't a binary build for your distribution, how about you set one up? Please contact the authors for assistance. Note people sometimes request binaries when they are having problems with their C++ compiler. Alas, binaries won't help this, as in the end a fully working C++ compiler is required to compile the output of Verilator. How can it be faster than (name-the-simulator)? Generally, the implied part of the question is "... with all of their manpower they can put into it." Most commercial simulators have to be Verilog compliant, meaning event driven. This prevents them from being able to reorder blocks and make netlist-style optimizations, which are where most of the gains come from. Non-compliance shouldn't be scary. Your synthesis program isn't compliant, so your simulator shouldn't have to be -- and Verilator is closer to the synthesis interpretation, so this is a good thing for getting working silicon. Will Verilator output remain under my own license? Yes, it's just like using GCC on your programs; this is why Verilator uses the "GNU *Lesser* Public License Version 3" instead of the more typical "GNU Public License". See the licenses for details, but in brief, if you change Verilator itself or the header files Verilator includes, you must make the source code available under the GNU Lesser Public License. However, Verilator output (the Verilated code) only "include"s the licensed files, and so you are NOT required to release any output from Verilator. You also have the option of using the Perl Artistic License, which again does not require you release your Verilog or generated code, and also allows you to modify Verilator for internal use without distributing the modified version. But please contribute back to the community! One limit is that you cannot under either license release a commercial Verilog simulation product incorporating Verilator without making the source code available. As is standard with Open Source, contributions back to Verilator will be placed under the Verilator copyright and LGPL/Artistic license. Small test cases will be released into the public domain so they can be used anywhere, large tests under the LGPL/Artistic, unless requested otherwise. Why is Verilation so slow? Verilator needs more memory than the resulting simulator will require, as Verilator creates internally all of the state of the resulting simulator in order to optimize it. If it takes more than a minute or so (and you're not using --debug since debug is disk bound), see if your machine is paging; most likely you need to run it on a machine with more memory. Verilator is a full 64-bit application and may use more than 4GB, but about 1GB is the maximum typically needed. How do I generate waveforms (traces) in C++? See the next question for tracing in SystemC mode. Add the --trace switch to Verilator, and in your top level C code, call Verilated::traceEverOn(true). Then create a VerilatedVcdC object, and in your main loop call "trace_object->dump(time)" every time step, and finally call "trace_object->close()". For an example, see below and the test_c/sim_main.cpp file of the distribution. You also need to compile verilated_vcd_c.cpp and add it to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag. Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file. #include "verilated_vcd_c.h" ... int main(int argc, char **argv, char **env) { ... Verilated::traceEverOn(true); VerilatedVcdC* tfp = new VerilatedVcdC; topp->trace (tfp, 99); tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd"); ... while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) { main_time += #; tfp->dump (main_time); } tfp->close(); } How do I generate waveforms (traces) in SystemC? Add the --trace switch to Verilator, and in your top level C sc_main code, include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then create a VerilatedVcdSc object as you would create a normal SystemC trace file. For an example, see the call to VerilatedVcdSc in the test_sc/sc_main.cpp file of the distribution, and below. Alternatively you may use the C++ trace mechanism described in the previous question, however the timescale and timeprecision will not inherited from your SystemC settings. You also need to compile verilated_vcd_sc.cpp and verilated_vcd_c.cpp and add them to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag. Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file. #include "verilated_vcd_sc.h" ... int main(int argc, char **argv, char **env) { ... Verilated::traceEverOn(true); VerilatedVcdSc* tfp = new VerilatedVcdSc; topp->trace (tfp, 99); tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd"); ... sc_start(1); ... tfp->close(); } How do I view waveforms (traces)? Verilator makes standard VCD (Value Change Dump) files. They are viewable with the public domain Dinotrace or GtkWave programs, or any of the many commercial offerings. How do I reduce the size of large waveform (trace) files? First, instead of calling VerilatedVcdC->open at the beginning of time, delay calling it until the time stamp where you want to tracing to begin. Likewise you can also call VerilatedVcdC->open before the end of time (perhaps a short period after you detect a verification error.) Next, add /*verilator tracing_off*/ to any very low level modules you never want to trace (such as perhaps library cells). Finally, use the --trace-depth option to limit the depth of tracing, for example --trace-depth 1 to see only the top level signals. Also be sure you write your trace files to a local disk, instead of to a network disk. Network disks are generally far slower. How do I do coverage analysis? Verilator supports both block (line) coverage and user inserted functional coverage. First, run verilator with the --coverage option. If you're using your own makefile, compile the model with the GCC flag -DVM_COVERAGE (if using Verilator's, it will do this for you.) Run your tests in different directories. Each test will create a logs/coverage.pl file. After running all of your tests, verilator_coverage is executed. Verilator_coverage reads the logs/coverage.pl file(s), and creates an annotated source code listing showing code coverage details. For an example, after running 'make test' in the Verilator distribution, see the test_sc/logs directory. Grep for lines starting with '%' to see what lines Verilator believes need more coverage. Where is the translate_off command? (How do I ignore a construct?) Translate on/off pragmas are generally a bad idea, as it's easy to have mismatched pairs, and you can't see what another tool sees by just preprocessing the code. Instead, use the preprocessor; Verilator defines the "VERILATOR" define for you, so just wrap the code in an ifndef region: `ifndef VERILATOR Something_Verilator_Dislikes; `endif Why do I get "unexpected `do'" or "unexpected `bit'" errors? Do, bit, ref, return, and other words are now SystemVerilog keywords. You should change your code to not use them to insure it works with newer tools. Alternatively, surround them by the Verilog 2005/SystemVerilog begin_keywords pragma to indicate Verilog 2001 code. `begin_keywords "1364-2001" integer bit; initial bit = 1; `end_keywords If you want the whole file to be parsed as Verilog 2001, just create a file with `begin_keywords "1364-2001" and add it before other Verilog files on the command line. (Note this will also change the default for --prefix, so if you're not using --prefix, you will now need to.) How do I prevent my assertions from firing during reset? Call Verilated::assertOn(false) before you first call the model, then turn it back on after reset. It defaults to true. When false, all assertions controlled by --assert are disabled. Why do I get "undefined reference to `sc_time_stamp()'"? In C++ (non SystemC) code you need to define this function so that the simulator knows the current time. See the "CONNECTING TO C++" examples. Why do I get "undefined reference to `VL_RAND_RESET_I' or `Verilated::...'"? You need to link your compiled Verilated code against the verilated.cpp file found in the include directory of the Verilator kit. This is one target in the $(VK_GLOBAL_OBJS) make variable, which should be part of your Makefile's link rule. Is the PLI supported? Only somewhat. More specifically, the common PLI-ish calls $display, $finish, $stop, $time, $write are converted to C++ equivalents. You can also use the "import DPI" SystemVerilog feature to call C code (see the chapter above). There is also limited VPI access to public signals. If you want something more complex, since Verilator emits standard C++ code, you can simply write your own C++ routines that can access and modify signal values without needing any PLI interface code, and call it with $c("{any_c++_statement}"). How do I make a Verilog module that contain a C++ object? You need to add the object to the structure that Verilator creates, then use $c to call a method inside your object. The test_regress/t/t_extend_class files show an example of how to do this. How do I get faster build times? Between GCC 3.0 to 3.3, each compiled progressively slower, thus if you can use GCC 2.95, or GCC 3.4 you'll have faster builds. Two ways to cheat are to compile on parallel machines and avoid compilations altogether. See the --output-split option, and the web for the ccache, distcc and icecream packages. ccache will skip GCC runs between identical source builds, even across different users. You can use the OBJCACHE environment variable to use these CC wrappers. Why do so many files need to recompile when I add a signal? Adding a new signal requires the symbol table to be recompiled. Verilator uses one large symbol table, as that results in 2-3 less assembly instructions for each signal access. This makes the execution time 10-15% faster, but can result in more compilations when something changes. How do I access functions/tasks in C? Use the SystemVerilog Direct Programming Interface. You write a Verilog function or task with input/outputs that match what you want to call in with C. Then mark that function as an external function. See the DPI chapter in the manual. How do I access signals in C? The best thing is to make a SystemVerilog "export DPI task" or function that accesses that signal, as described in the DPI chapter in the manual and DPI tutorials on the web. This will allow Verilator to better optimize the model and should be portable across simulators. If you really want raw access to the signals, declare the signals you will be accessing with a /*verilator public*/ comment before the closing semicolon. Then scope into the C++ class to read the value of the signal, as you would any other member variable. Signals are the smallest of 8-bit chars, 16-bit shorts, 32-bit longs, or 64-bit long longs that fits the width of the signal. Generally, you can use just uint32_t's for 1 to 32 bits, or vluint64_t for 1 to 64 bits, and the compiler will properly up-convert smaller entities. Signals wider than 64 bits are stored as an array of 32-bit uint32_t's. Thus to read bits 31:0, access signal[0], and for bits 63:32, access signal[1]. Unused bits (for example bit numbers 65-96 of a 65-bit vector) will always be zero. if you change the value you must make sure to pack zeros in the unused bits or core-dumps may result. (Because Verilator strips array bound checks where it believes them to be unnecessary.) In the SYSTEMC example above, if you had in our.v: input clk /*verilator public*/; // Note the placement of the semicolon above From the sc_main.cpp file, you'd then: #include "Vour.h" #include "Vour_our.h" cout << "clock is " << top->v->clk << endl; In this example, clk is a bool you can read or set as any other variable. The value of normal signals may be set, though clocks shouldn't be changed by your code or you'll get strange results. Should a module be in Verilog or SystemC? Sometimes there is a block that just interconnects cells, and have a choice as to if you write it in Verilog or SystemC. Everything else being equal, best performance is when Verilator sees all of the design. So, look at the hierarchy of your design, labeling cells as to if they are SystemC or Verilog. Then: A module with only SystemC cells below must be SystemC. A module with a mix of Verilog and SystemC cells below must be SystemC. (As Verilator cannot connect to lower-level SystemC cells.) A module with only Verilog cells below can be either, but for best performance should be Verilog. (The exception is if you have a design that is instantiated many times; in this case Verilating one of the lower modules and instantiating that Verilated cells multiple times into a SystemC module *may* be faster.) BUGS First, check the the coding limitations section. Next, try the --debug switch. This will enable additional internal assertions, and may help identify the problem. Finally, reduce your code to the smallest possible routine that exhibits the bug. Even better, create a test in the test_regress/t directory, as follows: cd test_regress cp -p t/t_EXAMPLE.pl t/t_BUG.pl cp -p t/t_EXAMPLE.v t/t_BUG.v There are many hits on how to write a good test in the driver.pl documentation which can be seen by running: cd $VERILATOR_ROOT # Need the original distribution kit test_regress/driver.pl --help Edit t/t_BUG.pl to suit your example; you can do anything you want in the Verilog code there; just make sure it retains the single clk input and no outputs. Now, the following should fail: cd $VERILATOR_ROOT # Need the original distribution kit cd test_regress t/t_BUG.pl # Run on Verilator t/t_BUG.pl --debug # Run on Verilator, passing --debug to Verilator t/t_BUG.pl --vcs # Run on a commercial simulator t/t_BUG.pl --nc|--iv|--ghdl # Likewise on other simulators The test driver accepts a number of options, many of which mirror the main Verilator option. For example the previous test could have been run with debugging enabled. The full set of test options can be seen by running driver.pl --help as shown above. Finally, report the bug using the bug tracker at . The bug will become publicly visible; if this is unacceptable, mail the bug report to "wsnyder@wsnyder.org". HISTORY Verilator was conceived in 1994 by Paul Wasson at the Core Logic Group at Digital Equipment Corporation. The Verilog code that was converted to C was then merged with a C based CPU model of the Alpha processor and simulated in a C based environment called CCLI. In 1995 Verilator started being used also for Multimedia and Network Processor development inside Digital. Duane Galbi took over active development of Verilator, and added several performance enhancements. CCLI was still being used as the shell. In 1998, through the efforts of existing DECies, mainly Duane Galbi, Digital graciously agreed to release the source code. (Subject to the code not being resold, which is compatible with the GNU Public License.) In 2001, Wilson Snyder took the kit, and added a SystemC mode, and called it Verilator2. This was the first packaged public release. In 2002, Wilson Snyder created Verilator3 by rewriting Verilator from scratch in C++. This added many optimizations, yielding about a 2-5x performance gain. In 2009, major SystemVerilog and DPI language support was added. Currently, various language features and performance enhancements are added as the need arises. Verilator is now about 3x faster than in 2002, and is faster than many popular commercial simulators. AUTHORS When possible, please instead report bugs to . Wilson Snyder Major concepts by Paul Wasson, Duane Galbi and Jie Xu. CONTRIBUTORS Many people have provided ideas and other assistance with Verilator. The major corporate sponsors of Verilator, by providing significant contributions of time or funds include include Atmel Corporation, Cavium Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc., and SiCortex Inc. The people who have contributed major functionality are Byron Bradley, Jeremy Bennett, Jie Xu, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers include Jeff Dutton, Jonathon Donaldson, Ralf Karge, David Hewson, Iztok Jeras, Wim Michiels, Alex Solomatnikov, Sebastien Van Cauwenberghe, Gene Weber, and Clifford Wolf. Some of the people who have provided ideas and feedback for Verilator include: Yves Mathieu, David Addison, Nikana Anastasiadis, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad Bagri, Andrew Bardsley, Geoff Barrett, J Baxter, Julius Baxter, Jeremy Bennett, Michael Berman, David Binderman, David Black, Daniel Bone, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Charlie Brej, Lane Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Ted Campbell, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike Denio, John Deroo, Philip Derrick, John Dickol, R. Diez, Ruben Diez, Danny Ding, Ivan Djordjevic, Jonathon Donaldson, Alex Duller, Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete, Fabrizio Ferrandi, Andrea Foletto, Bob Fredieu, Christian Gelinek, Glen Gibb, Shankar Giri, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Junji Hashimoto, Thomas Hawkins, David Hewson, Hiroki Honda, Alex Hornung, Jae Hossell, Ben Jackson, Krzysztof Jankowski, HyungKi Jeong, Iztok Jeras, James Johnson, Christophe Joly, Franck Jullien, Mike Kagen, Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Sobhan Klnv, Gernot Koch, Soon Koh, Steve Kolecki, Brett Koonce, Wojciech Koszek, Varun Koyyalagunta, David Kravitz, Roland Kruse, Ed Lander, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber, Igor Lesik, John Li, Eivind Liland, Charlie Lind, Andrew Ling, Paul Liu, Derek Lockhart, Arthur Low, Stefan Ludwig, Dan Lussier, Fred Ma, Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Wai Sum Mong, Sean Moore, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Bob Newgard, Cong Van Nguyen, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, David Pierce, Dominic Plunkett, David Poole, Rich Porter, Niranjan Prabhu, Usha Priyadharshini, Mark Jackson Pulver, Prateek Puri, Chris Randall, Frederic Requin, Alberto Del Rio, Oleg Rodionov, Jan Egil Ruud, John Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Steven Slatter, Brian Small, Wilson Snyder, Alex Solomatnikov, Art Stamness, John Stevenson, Todd Strader, John Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu Takatsukasa, Peter Tengstrand, Stefan Thiede, Gary Thomas, Kevin Thompson, Mike Thyer, Steve Tong, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston, Joshua Wise, Clifford Wolf, Johan Wouters, Ding Xiaoliang, Jie Xu, and Amir Yazdanbakhsh. Thanks to them, and all those we've missed including above. DISTRIBUTION The latest version is available from . Copyright 2003-2015 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. SEE ALSO verilator_coverage, verilator_profcfunc, make, "verilator --help" which is the source for this document, and internals.txt in the distribution. verilator-3.874/doxygen.config0000664000177100017500000022202512445131175016375 0ustar wsnyderwsnyder# Doxyfile 1.7.5 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = Verilator # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "Verilog to C translator" # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = veripool-logo.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doxygen-doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = doxygen-mainpage \ include \ src \ test_c \ test_regress \ test_sc \ test_v \ test_verilated # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to directory from which doxygen is run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is adviced to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # If the HTML_TIMESTAMP tag is set to YES then the generated HTML documentation will contain the timesstamp. HTML_TIMESTAMP = NO # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.veripool.verilator # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.veripool.verilator.documentation # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Veripool # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = YES # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) #Verilator: Note setting to YES is extremely slow. HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES verilator-3.874/doxygen-mainpage0000664000177100017500000000023312436221566016707 0ustar wsnyderwsnyder/*! \mainpage Verilator Doxygen Documentation * * \section intro_sec Introduction * * This is a full doxygen analysis of the Verilator source tree. */verilator-3.874/COPYING0000664000177100017500000010451312111011551014546 0ustar wsnyderwsnyder GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . verilator-3.874/verilator.pc.in0000664000177100017500000000045712525737622016504 0ustar wsnyderwsnyderprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ datarootdir=@datarootdir@ includedir=@pkgdatadir@/include Name: verilator Description: fast free Verilog simulator URL: http://www.veripool.org/verilator Version: @PACKAGE_VERSION@ Requires: Libs: Cflags: -I${includedir} -I${includedir}/vltstd verilator-3.874/internals.pdf0000664000177100017500000057671112534631201016233 0ustar wsnyderwsnyder%PDF-1.4 %ÐÔÅØ 1 0 obj << /S /GoTo /D (section.2) >> endobj 4 0 obj (1 NAME) endobj 5 0 obj << /S /GoTo /D (section.3) >> endobj 8 0 obj (2 INTRODUCTION) endobj 9 0 obj << /S /GoTo /D (section.4) >> endobj 12 0 obj (3 CODE FLOWS) endobj 13 0 obj << /S /GoTo /D (section.8) >> endobj 16 0 obj (4 CODING CONVENTIONS) endobj 17 0 obj << /S /GoTo /D (section.18) >> endobj 20 0 obj (5 TESTING) endobj 21 0 obj << /S /GoTo /D (section.22) >> endobj 24 0 obj (6 DEBUGGING) endobj 25 0 obj << /S /GoTo /D (section.27) >> endobj 28 0 obj (7 ADDING A NEW FEATURE) endobj 29 0 obj << /S /GoTo /D (section.33) >> endobj 32 0 obj (8 DISTRIBUTION) endobj 33 0 obj << /S /GoTo /D [34 0 R /Fit ] >> endobj 36 0 obj << /Length 197 /Filter /FlateDecode >> stream xÚ-ŽAkÃ0 …ïù:Ú+–lËöŽƒ:ØÍì2v¬Ý¡)YÖüýÚó@ˆ§‡ô>=–a<Ed Ê([Ì!xbʼ©W“:­ßó´-«6Žœr˜¢ïòxÑ,j;­—iþéÖËôçýN³~/Ï•¨ænŒÀH.‚ñ“÷ñ¥9ªm»>Œã¾ïxkc%^µ©bé}Æeýlà†\\{£°¥`¬ÔúGȘ…¥Ùc¢&XAŠÒ/¨-Oe¸-?S endstream endobj 34 0 obj << /Type /Page /Contents 36 0 R /Resources 35 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> endobj 37 0 obj << /D [34 0 R /XYZ 121.4 736.262 null] >> endobj 38 0 obj << /D [34 0 R /XYZ 122.4 698.4 null] >> endobj 35 0 obj << /Font << /F16 39 0 R /F17 40 0 R /F15 41 0 R >> /ProcSet [ /PDF /Text ] >> endobj 53 0 obj << /Length 401 /Filter /FlateDecode >> stream xÚm’ËN#1E÷ý^Ú‹WUûµÌ£5º5iˆE4 )MÈh~Ê8õÊ%ûߺeÏRuµ+¢ŽHOu-<:"‰ô(îå­ $wÇçýV<© ÈW.ŽjBTKÒÁ×¹$ÙyÚÛý[ÙºÙòž—¶{õ®¯–d¾Xí„)6ó¾KM—†¬¬šTý®ò‘pé‰4/~½T÷F<òѵ0šbß…/‚œ×ÈÕ^ ÕÏj–ÃaPkª~¦s!èšüÙöõ ˆsíx1òôVÅø¥Q#8 ç,¨ID+»éMÃ!œ—˜¡‹ Š‹®íÒZÊ~±™§¶ïÔ-Ù0ÎPaæý"ßÍc_þè3|70æb´ÿa…ª/TÛ­ Çüåa²_&MÀ(혡-hj†ôÎb´ÖÈ8bâŠrÑÌ6«UѺ€ ÆîõE=]|¶4-K×Ü墖KþDÍTq¦´Ys\¢;âÎÞíÖíló1ÆÚ¢Wìû' ø KÚ;øx·óÇú¹Áª endstream endobj 52 0 obj << /Type /Page /Contents 53 0 R /Resources 51 0 R /MediaBox [0 0 612 792] /Parent 42 0 R /Annots [ 43 0 R 44 0 R 45 0 R 46 0 R 47 0 R 48 0 R 49 0 R 50 0 R ] >> endobj 43 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 653.57 174.359 662.438] /A << /S /GoTo /D (section.2) >> >> endobj 44 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 619.7 232.239 628.568] /A << /S /GoTo /D (section.3) >> >> endobj 45 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 585.829 215.929 594.697] /A << /S /GoTo /D (section.4) >> >> endobj 46 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 551.959 277.364 560.827] /A << /S /GoTo /D (section.8) >> >> endobj 47 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 518.088 190.475 526.956] /A << /S /GoTo /D (section.18) >> >> endobj 48 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 484.218 211.931 493.085] /A << /S /GoTo /D (section.22) >> >> endobj 49 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 450.347 290.658 459.215] /A << /S /GoTo /D (section.27) >> >> endobj 50 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 416.477 225.571 425.344] /A << /S /GoTo /D (section.33) >> >> endobj 54 0 obj << /D [52 0 R /XYZ 121.4 736.262 null] >> endobj 57 0 obj << /D [52 0 R /XYZ 122.4 678.574 null] >> endobj 51 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F28 56 0 R /F29 58 0 R >> /ProcSet [ /PDF /Text ] >> endobj 61 0 obj << /Length 1692 /Filter /FlateDecode >> stream xÚXYsÛ6~÷¯àô%ÔŒE“/å-‡=ãL·±zÌ$y€IX”"U²âüúî”M·}H¸X,°×·»ß®Ï.®¢Ô[«,μõ½ÅqxyœÅJxëÊûâÿ¾(„¯Œ®å"òûÅ2ò[ Ìb)Dâ‹ È$…Ý,âÂï•idÝ1ë£^îd½ø¶þpq%‰ª¸A–¤^Èj܆¡ÿîæý%Ÿ¾úùoüãŸ]®Ïþ>‹@:ô¢ÁLDaî•»³/ßB¯‚­^ˆUáIpç‰,b jïöì׳·èo\xQˆ$‹G‡³¢‘³%X¦øŸÞ|¼d»OBz`]çÉÿÏiLè®SõpY’@¬­êت¾þ´þ¼‘óþ·wëë›OÿmÆz«!èIû_C‘ÔŠéJwå¡ëÐ*V‘„ðõÄ*–“MÅ[{ÓnŒÜí@X7æUª—º¶·ß·†‰Ñï¾5Áb™¥‘Ý¿²býVña´ÆtýxW'å©U·®ã ¨‚ J„C¦QþNBˆ‚„¦-úsäu{Ïß'‘CV)í™;Î.rHo]Û 0¹•Î#ÓFÉŠÑâTR[{ötå~Ï ÛÓRuÝ×0 á_4´ûCSb²^Ï âJLÏá>pƒÑ›&¶–:^t‚¥àÙ˜}üÇÊv·ã’‚E­Ë–†ABÉaî|MÔ-mÍ ±ºnàäòÄ)›`tn@ÓE†6 5Qæ×ê».©Àa!¼µXu¿eê ¤œDÅÄ^šŽ-ŠÒ‰ä[ݵ Öù*vÍ…)ò…_JÕ¹‹æB/ïºÞÈë#/üîÑ–Îw\¯üÞPMæ¯4|s»¦ Vj9ã¿\º@TªÓ› V¡ÜêOlyÍÅïq+ûS΃îô]m¯Ð³¦Ûæ üÀš)Ä ì ¹äž] wÛ™ìÊb~®!½9yŒâ¶¶7ÓS&|6¶,f"Do ;«ì™shf34‰dœ|Ò)€CîÝ#ørznŠb®¨7p, É1<3‰+Ÿa벯%p¢³Œ¦~tTiu²!)¥{Æ•çÀÍ\j+ÇÉÃÉ|]Ô–e£Ÿ"„[ÜpÃt”¥ž"Íí$aÈæŸ @(9Žüì$²˜\P``g˜ÙqOaJÒI®;fô4Â5E(I¯@¡¯Åè+p$¦èIâßS+4¼ ƒs28™&………œ®½9Ý þý€Œgá°Fr<€â1㤎 ² RýѶ»JνÓíš줻ƂÇRœ ÏÀR@aG–¦íìAî½ñSÇbòf‹3œå”jàw=†v¦Þé-h†—Åð6à˜Ÿ^Qsi™ÄAý›Â?º¸|D endstream endobj 60 0 obj << /Type /Page /Contents 61 0 R /Resources 59 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> endobj 62 0 obj << /D [60 0 R /XYZ 121.4 736.262 null] >> endobj 2 0 obj << /D [60 0 R /XYZ 122.4 698.4 null] >> endobj 6 0 obj << /D [60 0 R /XYZ 122.4 639.654 null] >> endobj 10 0 obj << /D [60 0 R /XYZ 122.4 522.627 null] >> endobj 64 0 obj << /D [60 0 R /XYZ 122.4 453.031 null] >> endobj 59 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F28 56 0 R /F31 63 0 R >> /ProcSet [ /PDF /Text ] >> endobj 67 0 obj << /Length 2815 /Filter /FlateDecode >> stream xÚ•ÉrÛÈõ®¯`ùfÌV57Û±\ž83IYãfæ-e@°H¶¿>ok  ²çBôòºûí_ß^]ßøÑ&SYÄ›Ûû*Ü$A¬ÒÌln‹ÍïÞ§mj<Û•U¾õ½a»ó½ÝvgLè•&!÷¾Þ©7خΫž—þ•ÃZâyµýóöçë£gO©Qqm4?càf­µ÷æ×¼åÓ7~Åÿû_½½½úß•ÐzãOhåëd³?]ýþ§Þ°õóF+“¥›G?ËÛ÷„ƒÃ±ìDû±z'5>“ó´"œä_XR |Áó¥¸À#xÿÈçy¿&˜¼ªØòr@ÔÄžûØ{²l貆šÜ KT8„>ðÎ}לx4 bñ€ÝÆ+È00D‡‡#ƒÔ '•ì—"øžfÑÕWÀ?0’ ÷¼Èb›á`)¤¡×7|ÉpDûD =«s!gN9R+×3!²ÓóÉò ¾Eöb¡`k¹g Ú²­Vm»¬'´Å©Lž&¿r_çW`¡ÏO2š9P¶(ˆ¼÷ïTü&^ï`ÅaëFí7h˜ áwWÖV^, K–2€&¡¥òY§fpn…û¥;… Bù†»F¦¨ ø}ƒ°ðœéPŠ˜‹œe^¸Ãw]^; fppÉ¢à¸,E)ÝIt¸Ñ²ºû¦;É]pk¹[ ‹cš<¾Ô í|)«(8÷6?þ’FâYtCp5*%^þØ•ƒû‘È`¼7?ᡟx2÷ìâ”ÄPˆ~Äâãà`2•†ŒÃ?->DÞ›*ï{z&¿õ`„þÃ$¡¼ Ÿ¶™ =4/Ý€–˜”•_ fÁò ¾ê‡_LQ5U¦c`n¤2Aí–žÌ"ïÕÇ[ ‡ÃogA˜½8Â)6ÂwpÇØ…d±‡‘| µâ­;qS ø=r`…†À$*¤ô÷h0±Šõ–C,¾=:¬ó»~èòý@š*RÚ±Ð~FnB—JF¾à…½“N70:åCY`ÅàÍ©e¿XŸÝ0n`\s¾GÔå1à¦3ÊßÙÚv0ŸRk¦¾ƒðÊ™\ƒYS-É=¸ÛvÆÇçœ "ù#)®‡©|]3¶=Ã’3ƒ5!.âŽ1¾!âì3Té@Eip!ϛۜÂÖç5Ò"ÈYÍ‚4||òdü$:m ¹!Ðx‘ÂôŸÉU¢1SlM<‰_dch×c'#‰¶ˆû:U:‹gˆßkŠÃ`RDÁëò²LמÝu›¯Ò~q—¸ QÊÔã¬5tJyÎvN”ß›ôÛ\<òŠTBå'?`c€¶™´ŒÜ“hxé Y$2í|’kÆŽGŒOYå”ìt)09@p®"'¸‚y UêO,jZ¿]spXºL@Ôù°Æ‡¾eQ¶Œ3M>siOöy²ÃQ‚@OIcŠ>´§ü;^ìòJÞÉÐ…)FšL>Ѝ‡J”?=óÙî9KæEÖßxT»”•§“C¥ €ˆ.-¡³SÓâ¡Ñåé+°]C¶¢8Rß`Üdÿ¡èK~j9¥u9!Žž•†`D35{¿ÆÖL鳽ϩÊBò,èžÞ‚‹Ó“_)×nö2édÁËämçåšFPk&i|‘ìÝ÷«©0›ìò¶j=¤©04g ž½jRX̽¢Ì;ˆÙóŒ‚N©ž8a®Œ)(qÃcHP0ǹÑÅÖ ÔÃ<^LÑ ¿Y­‰u±4'µÌ$+ðGkt™üÒ÷Xä«TÇg™gì/ÌœGú3—_ â\ú(Ùn`’í ¼„ÐÙÖ ¤éï>aÑÎ("ï—ß@>°í%€or©|¡¼·\©2C:Ù&Â¥ó,%عÈuôó…‚UœÍs;T Œê¢HEçCèÂKùåÓ\ÂÀ€ŒCv$ÇÔ*ˆÍEDí¬})Å=éZ$ùeíd)êè[$]#äÒÃD¡ç–DO#TźȻ‚g‹FÁÉ[½xRJ¸è+FƒfäEÊ6p•¨œ_T®¨ws¿(wC"o+Uí¥z¸`ÎѸ&HÂíLn@P¿œƒË@ Úeð×3ýâ‘kaNŽx0oz¬&°‰Ò:=g …m×s‹ì sy$çÏÓA4®dŒáìE µžèø‰ò£ð‡ÒéYv¿»NŽë;ˆ‘LþáܯÆy-@ìRÀ.Å`œQ®5að©ìËÁ%N?Tü&ðZWìb‹¦“ElÔN¾‘rUؽsM6sÈy”&{ìšsÕÛó2úQÔ]¦Å,â{ ¥ÿd§L>*ÞPGÎU+…cFFª'íc ëkÉ˹2Ö±ÒQ¼Ì÷ÙXÿ)¥†Zˆb|Ð,¢ý¹ã³é¸®%.L½šìËÕ¼0PÙ¹¼:K 9¶&¹(QQ0ëxDQÊE·ðV{®2 e±ÑñÀv>¡a ¿ ^j¤í-¯1‘#&™â*v™˜Æ‹Ò@9XûXZ# 2[0Õ½Í×-žlÖ|“T(Ô#¼hÊ!Á«v1iùÌ.>™w]ÞÌ&^a¢±K/Bn £BO&ƒkcoyñ@ïÐZ^š*¥µ>ƒPZŸ:rÉYü|ˆ‹Œ ¢)Æ=>$Y³r·ì³Ž;ëea]¯$ƒŠL›‹®jÃVrîó%•q ¤CÁ(’>ç.N"ï,`·— ¡Š²³XÏR—W».¯ž1Aæ|ÀŠ£~Z¶b…rÊë²+j_… öSãðÂ1?'¹~›qhÇa*|N|Ô”y.ú àιԻn‹jÚ?•ßÖޱaªl‹f˜ª¬S.ãçý6Ià­‹¤ø8 í߯¯ÑôP~Sìý×kµ­Nç(L­ ËÐä+}ÎþDƒÔšEŠåÉ»Ìä"¥JÁÿ²ìGgÊ9w÷qïœ<”Ò²"•–Üчä"”„7ù3Yþ2þ?µH÷Ö endstream endobj 66 0 obj << /Type /Page /Contents 67 0 R /Resources 65 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> endobj 68 0 obj << /D [66 0 R /XYZ 121.4 736.262 null] >> endobj 69 0 obj << /D [66 0 R /XYZ 122.4 496.378 null] >> endobj 65 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F31 63 0 R /F32 70 0 R /F33 71 0 R /F34 72 0 R >> /ProcSet [ /PDF /Text ] >> endobj 75 0 obj << /Length 2483 /Filter /FlateDecode >> stream xÚ½Y[ܶ~ß_1Ø'mà‘EQ¥-b;ÞÖA£ðÂ}H‚B;âÌÑH]<6úçsnÔeVÛ4@чÅP‡äṇÜ×7/ïU¼Éü, “ÍÃ~£ÂÐ6&Lü4Ó›‡bó£÷ñ.ÕžmË*¿S^·U^ƒön«uäi?5µ÷®¾ S¯·mW“¾Ïf¼!¯î~~øîå½fG…©ö“(Þ|ŒÎAxoÞû–wßÿý=rüçÜ|óöáæ×«ƒÅÔ¾ Ìfwºùñç`SÀÔw›À×Yº¹ÐÂÓF'ÆaTm>Üüãæ5ê«Ã'ú&iêGÚˆ¾ú¯m~>~´-)k?³ì 3…‘ŸÉf«b?ÖŠ÷=KP;ԙǿ`‹£eÂcÞÉhGVì±,Ú7-O}BeáÐrgŸš—äüy@±ü»m¤4:%Z.>渟™0%¯å·ëoWæ½-Äs+è õU¬+öyÝ ýŠÚZùÚŒ{±Â —ùq˜‚i”ŸÅ ¯Ü5h¹bFãøåõšl*ƒËÜš6¯Ycø™J&Á¶:3ÞåXî0üŽð Ö:‘¾àGì=‚AÈP83t`"£Å‘’W‡¦-ûã©c:9 'š¶€T¨L&#ùТGѵg —â,õ^¡¨›­ |cB1IÌ2l ŒvkÎоIC§ ÈÖ>§ðh¹—+l BÓ9“óºý£dôçÉžÐBbš–“ðÓ]{y[æ•eJ)É YÞðèÜ6{ z 6(lá³æiæ«(ZæÉDzí±"lµJáÌþÈÁYtLÉ[Ëǵ,È;@éþíÎ,âÛã©èUeİ¢ÎO£ T{2îŽù™“eq̱§Ø¨ìò %¨K°ôÇ f'g)(ÐôL€Ü9½$ê1>—»¼ª¾ðBô†$ÿLG&`tq w(]g]­h›ÓŠ«Cùz ÿÿ¦€mÝžEžrƤ”1à×KYU\æ[‹¦>+{²TÒ{^ï$,œ'A‡Î-6óû;€†¼oPum´øÙèk?…ÌKvPÝd9e&ÒjY„ж8Ø.‰®­MÌDÄù‘’ðÌvŹG äýéOkçô§øQ,úQˆÃØû)ˆñÁÛ=p°8y_‘;@Ü3/ü3ÿ|GÙÏçí_Êúµ=”õÀŸÂå_“|€Ç  r!$1úzMü§G@–?ØÏýxŸƒkþ-Å %éRµQ›ƒýC`¨“Às¿lS0âˆb›‡\`aP”­Ýõäø"ßÊ6ÎEJÔ eˆ­y朗T t&{&ͱÔgã‹+ Œ­,^ æŠs 9åð3}?“Ђ±Ú^ly8®ÂgìFÍáŽøOÀ„‡qU…ÑQ´¦°kà„~ŽÀ½zªÓ+G'~ŒëÐ$1ÂñF(⎎Ë÷(ÅØ«™ÿ (AåÅhÏ–Îøßƒ“+O!ð WQÁµÖÚDÐI†£ôXŠŸ…Ôäw[èKÝš¾Yãk‚`\ÓÚ~hë±ærQ¾EnE_ &ÜöÍ­3怋y*ä<ÑÑ}É‹ VB#˜­À*V€g@[-J=S´ÕÐV‚¥jÚû/2s”MU.n­§U,ý"s®…B´q=±}œðRX¾Õ€âiæÞ¿²ˆß¿X({÷JZA ?=&ÀªàëH»dBc@—b¹W©†Ói'à?}2(ñ ¤&àJia,¯>( á#(Wasa»òÀ~*¡#ç’žÈ9S»²>T"$ Ù AA£í+~oñRÄîC¥’¹Rà°¡.\2žšNð§+{^3] á~‘Iü¾Ç­¡»¾‡‰‡1ÚÒ^DY±HÈ<è2ŸºÕfz „â# %©\ÂÁ½ã™².û’z ?ЍÿÒ oŽKI„»ílßWÖ½ÞÝòvbÅT'9|¨,² Ó`ôc˜¤ »á[Ò\å«~b¨èP+A“yEE“/ Óº”cWÜ<8ìç–·rL*žÆH¡7Z¢bº•îKÿ,‘ÊH£ÃìÊõl·Ìù$=‹CÒ¥C𷇋^Ç—cÞ3¸þÒň£˜ø1^Ö¸Ùs¤àÛiïÝþ™kœË ÷ºce“ŠƒÙï ö^f%Zb”¸õ íÜâg:ûë ÕŠÃ h3/âžÉ‹8yíE\ñ Oqn5•¶áZ q6ŸFžÊèÕÝà«{'/[-õÀ\è/PÇy4“ÔÅ ŒS3ñ €¿b63HiVwj®™ÿJéîâß|5j{¯öüQ¨¥--9Çp!u/02@£×ã›^mKM1„kF?ãÌ,8d)6+tFãV@SyBãñBÈcM®ün}­T9û_Ý ÆÑ‹®„;|Žã=z&øåg¼¹b <¸5d÷ÁÕÐÖÎ0Ä.=+·€ü—õj.ßcfR›mï×Âê Œ ²Æp›âV&\®OïRHÝè­zBŽÈvL^/ ¦”5ÿæ+'xó¯ïß>üíý·/Vcßր帝Ôñ—KZj¸lP€‚r¾+¬¼¸âlÏ¿‰ÍPüÙÔnÁøÖ‚ÿá¼+§Šµð»Î”I0ÖKÁÜM5¢¤\äþ¹õY¦%r endstream endobj 74 0 obj << /Type /Page /Contents 75 0 R /Resources 73 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> endobj 76 0 obj << /D [74 0 R /XYZ 121.4 736.262 null] >> endobj 77 0 obj << /D [74 0 R /XYZ 122.4 272.928 null] >> endobj 73 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F31 63 0 R >> /ProcSet [ /PDF /Text ] >> endobj 80 0 obj << /Length 2106 /Filter /FlateDecode >> stream xÚ…XK“ã6¾÷¯på$'mµHêåÉiÒ™Évª¶'ÙöÎ’Ô-Ñ6wôp$z:½¿>ɲ[S{±øAàÃÐ?lnîÞ‹d±שL›ÝBHÆ‹L¦a¾V‹M¹ø-ø¸ÌU`:[é¥Ür%‚Ýr¥T¨0Ïblªà¡YÊp2˳Êá g½õ k ãʰ þОª’„¸ß§§=áà Z­÷¶ æÁèrPÙµ¬XÓŸº“l§»òúRÚ+iá¶yÃH“Ót²) S"£åîn¹Jd¬¾]Q£nKó†šàõï©U¬v°ÒW½ò‚oŠb…ë¿9Ëx ÏÕܱO[2—Ao·^]Ë_´6ü‘ž¹J)ÍNŸ*×aÆ0 )%:Â¸êØ™R{RÆž¦Ïý= ËY˜˜Rð 1D ƒÒŒ1(üÀ‹ïê®§.rá¾¥öóÁŽÝöŒõ®³¥áÄÕ*oƒ½4x¶Ž÷ýôøo>Ûy®ªxý•ÕÀaqž{q3ú+0÷j"tjJ²Á€Y$í13ϱÕ:Ìc18’)I%ÓU2ƒJe=Nºw{PrFZ,B•Çú¾èìÑÍa(ÍÃ\ªK¢{jkÎoÞ-˜ð¡αÅÙ±¸ÆÖÇÊÔfŒ@Ÿ;|ÞÄMšJøÒ6¥UȹöU/Ôí ›³Î’owÌg¸³ö%2nØz¬N•XÍy¦f'ÕÙ«¦÷§íª¨tßÓ$\üu˜ (³Ñ¦o{÷!:cT•†i4®ÃèIâàŸÏþbDŽÝ- 8&Ä|ÍÊÃx(ÿˆ¬2fÔxe¡b¤³d‡•Hø4¾4‡ÞÚʺIRL6Ì¢º™ÉÓ0]Vf¤D.Î}Úòù½èÚ~޵°’¯’^ìkA8ƒ¾ëCgOáà–µÄö©'XÁˆ¦‘_(Ò+ê!À‡ânç(:à»x.p.}—„iœ Ë$Qûó#.üå»±Mqô¶µýŸ' èrNîÉw’8ø‹ t>œåžéYP†ƒS|ˆ±†óÏŽ%âh{B`pLG "Ã[手¿Q†3°Ï„ÿGáUøá!³!ù$ÎëGhÌVâãRð§O{_6_ ð\…išžsËLêǬŠH^Ö1^ýuáÕó~¹Žƒ1¿þò‘ÿço /õ“ÏìØ:;žÈÊ i&£Æƒ3Taæþ&@¹Gîøºõ:eДu¬Hgð©Ð\Mû:ŒObJ•|‘ºäª#TÆ¿qÄuµþJåÜïÍQÌ}n1¼ ¡q¤ªÂoÝCD¹CMÝ]×ÖÓµ2 Þ‚]ŸÐÀÆB'µ.v­ãégK¬ÊQý( þcá¹Í¯m‹5º”þ ,™©VÆ,ä™ÏøòTð³Aò³Aω٭)Ìѱ&,¥®R¯\ìrpîøæîÎ4á3+•y¥Âé¿Ûßá0˜áŽ â?y æær¶È13%AœŸä€àÌ#9þÜK†ÿÿ²o9 endstream endobj 79 0 obj << /Type /Page /Contents 80 0 R /Resources 78 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> endobj 81 0 obj << /D [79 0 R /XYZ 121.4 736.262 null] >> endobj 14 0 obj << /D [79 0 R /XYZ 122.4 599.76 null] >> endobj 82 0 obj << /D [79 0 R /XYZ 122.4 527.286 null] >> endobj 84 0 obj << /D [79 0 R /XYZ 122.4 329.249 null] >> endobj 85 0 obj << /D [79 0 R /XYZ 122.4 142.17 null] >> endobj 78 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F28 56 0 R /F31 63 0 R /F32 70 0 R /F35 83 0 R /F34 72 0 R /F33 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 88 0 obj << /Length 2943 /Filter /FlateDecode >> stream xÚµYÛÆù}…>˜ VcÎ Ï<pœu±A¼n³Š" ®4Z±¦H…¤¼õ¿ïwÌðgèÓŒæúî“ú~}ñúŒ¹È•,Ö»…TJD‹T%"Ëõb½]ü|\f:0mYKôË• ˜´Ë•ÖQ E–F8ÕÁu½TYЛ¶.ªŽ—Þ°–§¢Zþ¾þñõ;N@)-E¦³EÈ`à†aðöÃ×7ãûo?Ü|¼ºY_¸¹Å.®Ö\H¸.䀪2L›Ãů¿‡‹-lý¸…γÅ<,t’ ³jq{ñ‹ï¡9É2锑yƒ¤:¨›ÞlyZÜ-W@Kƒ}FJÍ%ld*(ªŠO|.»²oZ{µh O¶À;¾`_ÚTE×{¬ÙYÖ¨)kT(r™:Ö¼éú›ü8ž¡§"Vî¨X®âDoN‡w@Ó¼’RäqÌOx1’Z$¹š"Ôl™HŠ(dZŽ•9VŒå*ÊAöÆó|’ •jw­Øḻ÷¼®¡’áõƒé÷ % ¶ ŠX‡Áþܠ|öVñ‰HïøgA#¬½?Í‘*xhÍδ¦ÞæŽLB‘j9çN£Ä[óXÖ]_àú‚@xhýJ“ä+™’AùäšHëÈŸ A‘ .v­8«ÒØUä4!óA(6_ÜšpÎâ½ï|ùJÆ`Qs><­“À¹l@Y†ÖL᤬#j>•õ=¯’R1RÃ9Ç[üõ[‡¥0§iŠ1Ü—©¹QÁsRX3ˆ•|I.%郞Šupd»ï‹]yWíζü-ÔÉæTõHÊ^Ð4öû¢Ç*-lÈQÐVã£!à¡|ÞÀ厖x(& Ä=Óîšö`A×¼c¶eÏ36‘ M„H0]ß6ôÆ€·Sÿ<i~&öz"¡( ðU[³1V=;^)ÜèŒ- zpNQ–k¯’IBžÎÉ¿=Ý‘}´ÆülúS[_>ÑJ•Á<õxÆÂëÓ¢L$qþ¼Oí Eœ'sN”D  ŽÌ¾Ïå–\,¬¾ÃˆÖøÅ7—"Ôñó‚ŽD:ø:2q|´%>X@dP´Ø²%ErF¨( KÆÞ*wg·›¶¼/!hŸ]¶Z b‘^_Ó®gÚƒ&8KÝYîíØqÂÕÌjËGÜ•‡’¢Ìþ}êìÚ@>œüÉ„­GF 禽æ‹Ypdz/X‚MËËÍŽG w‘WÇð ?J;lT¥ƒ-Ü»³ÆI Gj[5ÅÖº¾ü·«²D¤£G $|n-±Ôiwª7}ÙÔ tÇÞTXBè”g*Ìô%Š™ÆØÇAñk\ É£„ðÃaîYDzNp´¾ÞñjÁCgÝב‰6¼ˆAkH"À…=®y¸ÛñÈJ“]sª1ÐI>:2ðc*Êç¤w_ºÞ “Ì2«g8CßÎÚÓ|╲摵gÈRš8¢ÇEi"‘tešô(‹Ž7ND ±GŸføGYïK6Ìá)С¶h­&õô{Pã) ïp‡µ<ü „Ë?0Ô ry“È_â{’|7°Û›fzª×;¿rFcÒ3Zt5²Ùfœ" Æ lþΟŠ$"ÌstÊPzØåsSóc[#¡)z!F ¸ý-®EäÀϘã%ŸAMþ¥3í·ööéˆNÃÇì§@ÜØW¯wöºù¸íýÿ$y9?ਗò!C¿õà)2À8ÜÜBoñ†£2®´‚H¢âGЬTc…Ug¬Pñ'ÃÀYÇ’‚eå ‚ÂuâПæe¸×l¨8‡‰µZþQCÂIÅ3=d8j &ab£¨Ç;{ù(A†±ž°ñ·Ö±rà!¤(¦ežy RÏ¿)¼0­fùIÖ=ËÔIñVmÌÖêY#, " cŽºZNØß¯Z7ílÃÂåë¨õÙ±!õN«Nž# 3øÌì.mž2~(;ãRžÒÖ<Ób jưàAc»•Óü£3g]‰Óñ88y{ë•-Z@µ’mD©ˆÖÅ€µ²Ú¡l Á ¯`—©ïÛòîÔSºi\ÙÁë!MJ_Ð^Ó˜ëO[ÖÉ©|zˆâ›=sÓô®er®>Y2¸7ªˆë7·kœLª(3²?”œe㡞Oë¹WÄ=–ý¸ƒ)<çÆÖÛ¥J„áY3áÄÌÂféÀ¬KÏÚ°Xb“ô’"©Õ–.CËÉn)7èp,m[úÞÁ:¹ÐûX»K%™HÆÆ4b)‘Õd< =ºRHkšÓ½OÈÀÃhÏ¿æAüÄë‘i"= ä¶zQ·cÉ qHm/¨qÔÛC«[<Ñ?­Î{R!„ÿlª”¤Ý^3­ç®¡YN0/§ãŠò|Æèã¼Br™œwdå¸ÎD”Íä?õ|Ød±Õ`À@^ÅN±L†ä—{ÚZ—œ /UåŽC ÌwmsàÙ}[÷|¿o‹ñ;BÛñ÷‘Å R‚(ÕsOyd·ñiC¸¸7ݬ«!åÈÊpUjÌ€ñZa‹[)( Á†0nvü“5µP‹FNÇYqÜᆷN=ë:îáG N¥ öÅñ™kûî;JT@"y‹8­¡xB2R‡”ÛG.mOÔ'ËôW= J+™M}W»p(ÚOyº<yûX“¢ ÈÐù‡kvšAÂi8B¶¼bK• ñ/øGqA?›‚¾@í,OŠAb!æBfƒ•PU¶²L’ç ÁdüÕóP*ÒhfmOyµYzq‰éQ€‡Æj'ÛΊi/ÓÇ7E×ó^q<¶Í’ÞTÔÉÀ—"( ÞÿBN¯(ホ NÍÓIòçq¦Y.’,=Ï+ŸbMü§X38 ß{s‡÷Ø{ƒ¾";n?¼¿ZÿIúûÕlOµPa6ùšEL›?Uig¶ZAÂÓy…º•0—_ÐöX +Wt£©‚ß2βíG.` <ó9™o Ÿfö6§2-Oc)áXR>§\³$¯ëOØ~´ý÷ ‹r³Æ,lÿwVàS™N<мÍ0o)ÏD†u‰ÈCÅð_¿æ¦ÆÍ‡®xv»~³¾òuOÜÑ·\‚ñS÷%2˜z&†òãªô[8Þ—qxB {xiŒM+•€°»¦©O×íÉBÖàXÖàxÝÚ¾$¯Ê½®wsüUÝÊ~ cF mê]€{ïœ}Ók¸b?g)LlÝŠWr¨ˆfîÞôÄ Dë‹<~å÷ø Ñá…’*ß(LŸJ¨¨Ë²ü%å-$óa2èí«Î›¸2¹'o{&+ÌÕ ª1l+>Š–õ¶Ü€w´¿ìW._^¹^Ù}3Ö9Ã=–;c±.lòƒr#ºÒ¦‰ûãÄŒ`­Ó endstream endobj 87 0 obj << /Type /Page /Contents 88 0 R /Resources 86 0 R /MediaBox [0 0 612 792] /Parent 93 0 R >> endobj 89 0 obj << /D [87 0 R /XYZ 121.4 736.262 null] >> endobj 90 0 obj << /D [87 0 R /XYZ 122.4 409.539 null] >> endobj 91 0 obj << /D [87 0 R /XYZ 122.4 317.883 null] >> endobj 86 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F29 58 0 R /F11 92 0 R >> /ProcSet [ /PDF /Text ] >> endobj 96 0 obj << /Length 2335 /Filter /FlateDecode >> stream xÚYKsä¶¾ëWL9S©˜ H‚LN»ÊnJ®D›ÔÊòÁöBÚ|ŒIÎÊú÷é@rf(iœƒïþÐýu7æÃíÅwŸd²ÊEžFéêöa%£HÄ+¥"ËÕê¶XýÜ]f*°]Y™K —k´Pé.×Jřޱª‚ëæ2Ê‚Áv©znú·6ìMuùËí÷ß}Rál«HI‘©lò6°Š Ã0¸úüë›òü«Ï7won¯?ß|Á.>Þ^ü~!aF¸’ãQ•¡^mꋟ~ Wt}¿ …ʳÕ ¬W*Õ"‚Zµúrñß‹§2ÇZ¨0]¥Y&b¥ù8·[ÛÛËu©`ÓÖµeázn1uEAYï.×ÐÑvƒá<`h¹¬ÍoØêê÷«‡G4ÇCÆ"LF<ö½íþòs˜„ð'yøÁ©ãPd2õ£ÛÆ/LÅ#ÜPù±‡ƒŸn•Ì}ß7maöX«0i¾ZK)ò$ááJôÌr[¾§²gmhìW·ãæ{S6ü "\{hþÐbOø¯åž¢ü9TÊvÖÉ£vû÷ÓAÛ£þY®x^a-‘Ç|´›vÀÉ$¶fàÚÆT¢‡8B§B"~UYÓÝâ.]‚f¨8öSHpØäÁôÃ;¬fAéö-Z–¾o¾u-$¦©~ó'ôG…Üܾå¦røÖ-ÜúÑ-‰ ‚ºGñሌ«)»ê™ëíÃ`ú'Á§Ë,<æöSï*ñ7¸í«zÛøp]c¨`XZÖ*d€gž]³ Åž–ÐQ% ‡Àá1& ÿáЙÚYÀÆQÃV Wî½^áÇÎô¤2³ŽIa¬uSI¬|-ûrhý’¥ëÞTmï YÌø¦i»ÚTßð×þ٠eK³%8š”;‹h-,©Íro˜ìIåÍ%P © ôû’ï*½Ý´M± ˜ô,œôìë~· ‹nœcvR^º}p{˜ëéNY$²ä€ ~;X" ‚q3²/ºim©#$A5Ã#L*¤B:jP6äÁuöü9Ô¨ÔYÜïÝê¥+wû.ÀYªdvòºEŽViÔ¶ïQÅSÒ6¾æz ëãl9`š‚ÐPØ]g7f°ž?ŽäôIÁZÓó´è§z>Ú (1îúaù¼“õÀ2]98Ã’àK[ÛÂi$t§„ì7ؼµµ›XχMf=­ç°½Ã>M'Æ¡%‡Xí+÷äv`3ƒö]×>‚rœß‘BÁ3çœØš\g=H \C›˜SR÷ü´¿!&© H ¨"rf ¨9¸ùµÊEæÆ5˜‹!Ê85ŒÝ½zËK¢'ŽòÑ ;ƪ,,E 1ûdÀÛüêŽe9nNŸ3 ™MY•ƒ,{·AnšÝEç¦nÝXô%póZêà£áûå9ƒ Dz6ZwäS¿>¹â(úqOh"Y¶qá ôÝsÁš;zæZ,ÑØïÖ% Po³Þ]¨æluGG!‡½°UŠ‚j?žÅhܶ;dSñ—‹1J™£˜ˆÂ¬É 0þòœ§g[GR ¨CX_ n ÓLÏAY1¢\¿ B6ÊSö_—TS‹0üHäè–ÌöqÞ‡êÄ P¶ëãST 휛KîJ¶I®ÍÜúlÄè™98¥Htzˆ˜Ë¦+ïà5%!ºp–^͵<£J¼LîúaRÇs>QÆá\ÆRŠ8NçÈ'‰s¸#†øXÙcÌ É< 7N¤Î¬XPé·í¾ò=ž_x– ©FÿÙ´Ã’V`2Š6r°;Oá®Â<á<O+pOŽQS‘š{_9NÝ6FWG/PfvŽú˜¨ì+Ɉ§VŠÅ¥Ï JÇÔ¿î{țݮ*­kFÍ:Ý;ÇxdTY³ÙØÝTB:Å> s[ç}ðûÚi,t½ÿ(Œ^§˜§Ö<ÂØE+jŠ!Å"A$ZHéÃâäÝ÷MqCÉÍÃ5EM‹rx j'À„ª~Aâ$¹Öç ª•zUíP_ë}ËBF‚„ê(jZ½Lw‹é­L…Œü YÈsXqðÞl~[Z1‚ˆ<ÉŽ ”þa¤GëYT ­÷ü0]:Õ‹?© ž½µAêøm¸¨ ä!@ó“xE!Ò N˜Ÿ¥I*ç .(ƒïr`*¸~`ä:w*{èÉlA¬gÝiïÑ/<óD‡ â ø{¢)æ¬ûØû‚Qg€'…ÒÉA˜£ˆÿ–Ø6dÎ$=óhÊÆ-¼g++-{ŠšaC¯+þQÂ÷.Ó§Û3Í£]TO™$"Œ’EÞúÙª >€I<™®èÏt“šêø%5•‚ËsP‘á²+Àµ)òu¢ótTMWO:ª)¾ÇI‹R#ȃÓ ¯cÇS‰™ž“Çš~p§k–!€Â¢<^„üj‹÷ QHç_÷Îá„ç×<"ŠSäqõèT$SzêýƒÑ˜‡PÐAõ²Z¢ØLÆ[hwr·,\¤Òé¢k÷KWª´H§gv¿½XéN<ì»e÷ 9€SxóNþSx~¯ãT¨‰Cÿ„áÉP‹Då/SxÄ8]¶¾zI =·¿qI<žsIÑ”*¾tI‹qJ€w¡Dž=;ÍnÌynM>õ×ú»þ+³§Ç¾µÊœ¶BùCϯÕPÞèóÇ­¥1qpEÐPãqæòG¯wãÓ¤ C~šåjgw•ÙX×޸ʜ¶á“k({Kùh(y¾0ý‰åìe :9%)wê 2¡ÁÍïÜ’5°DT¿¶ÝÒ«Œ{"î]Æøžµd|–£tp[N:“:¯›Né"¤‚ã>~û|²ßϧ. õÁŒÆÚ¯Úr9=KÑ\ÿ`ARñîfñ• ]úø3ÛOé j|÷"~2œøÍÃüÑ:ÛŒqÁŒÍØm®ã8Æwvø\Ìø7~N΀;$)fät*íÔú]WÿB endstream endobj 95 0 obj << /Type /Page /Contents 96 0 R /Resources 94 0 R /MediaBox [0 0 612 792] /Parent 93 0 R >> endobj 97 0 obj << /D [95 0 R /XYZ 121.4 736.262 null] >> endobj 98 0 obj << /D [95 0 R /XYZ 122.4 642.665 null] >> endobj 99 0 obj << /D [95 0 R /XYZ 122.4 522.613 null] >> endobj 100 0 obj << /D [95 0 R /XYZ 122.4 139.658 null] >> endobj 94 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F31 63 0 R /F33 71 0 R /F34 72 0 R /F29 58 0 R >> /ProcSet [ /PDF /Text ] >> endobj 103 0 obj << /Length 1929 /Filter /FlateDecode >> stream xÚµXmsÔ6þž_qßêK9aYòf 4 Ú0`:Š­ã >û°| ™Nÿ{wµòÙNÜBúáÆ«•¼Ú]=ûh}–·ñp–²4 ¢Ùr5ãAÀä,"–¤b¶Ìgo¼WóDxº)J5ç^;_p¯¡™/„ž`I,QÞI5¯ÕM¥JCªg t±·SåüÝòÉíGÂlΑÌ|Ú¬pß÷½‡Ï>9}Lï?|~úêøtyòüô />pxßñ½«‚q?že›ƒ7ïüYSOf>i2»´ 73Å,©œüzðcÁ0f)˜àÑ,J&ELîܾ=_„AèUu®·‹ûåÚl1ô·~èÃÓdað)=§>ó@Hˆ=…Ýœ³4 ÉZoWn;+‹ûäKµú¨ÊOõçõ¸€1†Ów1%¡¿÷EU9 »*× ‰Y}¡sÃ×±ŸÙZ¡Ùê½6SÞ}C¬a'òûÆj2ã"ðY X˜98¾.ÊÑ‘z—ˆ­ºùH£·¾•¾É=…”¾§/“º¢%ÅŠ´íZ÷ï4¦%­sf2µ3ÚQ¤ªô%«z¾€sí¬Õ4ߪè3@{Àô¶T™ÓÕ«~n˜¸ˆ"žÆIo× ½  óÂI—E õWÒ`'æä8(¬s €#påC¨‡’I(lWs÷'’³X¦Ý‚1”оŠ FgàOÝé3U–{G”ÕM£³¶¼ÂaoèÞ&bÁ£€2)ó[+@-›/¤”ÞQiÙ¥-.(Ñ…«;ŽY†=›rK0¾7Y*î„Â/—ÇØÃò=¿£[4îö½1?µS¹íªwVJÏhäð¿wŠ«^>}z÷ðôß@7 =³)7ß!Ž$þ§L|%_,׸¡àa‡G°PàÖ4j¤w¾{ïVÕ =•[Z7š¤|·ÙbYò„è…SHøìvPd,‡–Eõž”T¡uÑ]f‘€_8Þ¹7mq-å…Qçå$QXÆI%ÔQK¡àôëm_V4,Ü“*„à êœ|ÃÕÄ”n¥Û`ƒ”¶×š]£÷–Œm¬º³×-P{‹u‘ëœMñQUƒ³xjPÚvCTç$aRpÏP2uV@Kag2eyÅMm,ÅØà„+_‰×EÞ®Þ­ÅÝÎ,ÓÛölw¾˜òµm´þM·»¦:6w¹.ˆ£`èÃUäœÃ[Ä8¦Þ,0`h LÉ{¢v+,‚¾±Û¸÷éÈpµ½|@ØÚ»§C!˜º1˜´<•½ÂÆm2õ§5Ýs¢ûZ„4›“Ú áÀ¨ë[ÕeIsP›Ã{T€ÿ†}9cñwŽa„×ÛïDÖ¡´±cHY"ÉüI §-VWT–1”3´´s8yÄ*²RC¼wW {ZJé¼=¢³z³±ç 6ýÉzаkôFÛ¶·¥¹Âeúáè xãfÖî4zxcg’MeG,àû üÈ´§ÀÅ>CøiÐ-³¡Ñ—]Aãá7Nȵž‚rƒ‹ŠvMÀYaĸcüY}Ñ6–ïMK rÆC1¦o°øXW“F%~íO÷Æù®%áfygÜH9Ìtœò BR¬læ{ˆÁE§Œ[lAqgÒkΠ Æ%zDNÕIɶ"¢… :–ë“Õá ?p×>ο4ºqS»m_ºãÛ›ûL†ÉxÛ_Í h©ëƒ€è!©3Fi´Uô(á}YuÀ²ïÖôìË +5*~)ê og=IãùÕ>!,m» z^ívŸÆt»Ì—úýWì+×U¡ˆ$ä$Wá?~˜K>¢nÉ1]ö惉sº¬¼mèê/r[ú¨RÎãWCÄ{6Q¦={þìxù;îùâxLÇ㉾¬“‰$¯,Ølß„ s¼fÛk7hCTÔõÂô§Îàý£³%Á âv€¸&Ó”|Hºÿ1ÿ¾\sÙ endstream endobj 102 0 obj << /Type /Page /Contents 103 0 R /Resources 101 0 R /MediaBox [0 0 612 792] /Parent 93 0 R >> endobj 104 0 obj << /D [102 0 R /XYZ 121.4 736.262 null] >> endobj 105 0 obj << /D [102 0 R /XYZ 122.4 348.931 null] >> endobj 101 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F11 92 0 R /F31 63 0 R >> /ProcSet [ /PDF /Text ] >> endobj 108 0 obj << /Length 2035 /Filter /FlateDecode >> stream xÚXY“ã¶~Ÿ_¡Ú'Nj‘ÅcSI•g¼ë¬+ÞÚx”}±][’ó2ÑοO7º!R#&ë'F£Ï Þïn6ïƒí*i$£Õn¿ ¤á*–‘HRµÚå«_¼Ï·‰òLW”ú6ð†Ûuà50èn×J…žIâPyê[™xƒéj]öDúI-öF]Þþ¶ûqó^ù³£”‰(NV>³ɾï{»w»À 7ïv7ÜÀᯂ³jJ~¼Êª›_~óW9,ý¸ò…J“ÕÉ2V+ÅB¨\=Þüëæm”É*… #9%‰U<\žþÊ3þ LqÒ†÷蕼 ÓÔ3× v7èg4ÙtÏ…7xaOߣå`âÐÐîSW †HšWL?ÐZoxe8òàþß?<ºµl(šúòˇ«SاfÛ•î^Ð84'DºÝ’9•¶ÑƒH · ŽNZý0`¡W¿ûHt Oêužôì]X+˜Ô²dT3õg.†µÌâ˜evÞE!G _0:A惱„oú1wk*Îbþ_ëÞˆå¨H) ©²aͽÐ87{=–¼‹úw±È¾»Ìïù•Õhoµ’¡iæ-•ømÒOÂàlKä%ÖÂÜ€C\·ià=6Ä¥i‘Á §cƒá½–`K|áyà‡6Ù9†Íð¥z!q‡pvrq âäœr§Â¢3È7_]̆™rrr^¸ÔEÁU >ô¾€âüªdêÜx­p‰0 ®õ¨ð󂺑qx ¬‹PAzXÀ“®‚Á”ÐHµÁÒõÁæ3Æž²P¦ÿ«bC%‚èüòšö˨֨WµTº3¾L®K÷Ž\¤‚D„g¹÷“ëÆÝó÷O^X¯´Á—ôò]ƒ/£Éoð]û×o^\±{ƒHMƒº®£é¡CÎQ£kI!`TVÛ­÷Ÿù¯¥Úñ‚ÞöËAÅ?dºyþaœÊ϶!÷ñáÎ-aßøÈ³Ÿ¨³Ë×KUgÊÇ¢BÃQ¿¿à;û%1£^üW¹£wm­åÃ<ç· Qà’çðöÙ¦t‹íU M¾É±ºÁòÌî’çémùž¾³':Ò"+½dÜÔèp30{"]€8wJÍÀûÊØ×O¼LÛ_v<ö¯[Ó½ÕCï· à¢HE’ð“5u?ûþ ÓZA endstream endobj 107 0 obj << /Type /Page /Contents 108 0 R /Resources 106 0 R /MediaBox [0 0 612 792] /Parent 93 0 R >> endobj 109 0 obj << /D [107 0 R /XYZ 121.4 736.262 null] >> endobj 18 0 obj << /D [107 0 R /XYZ 122.4 698.4 null] >> endobj 110 0 obj << /D [107 0 R /XYZ 122.4 522.922 null] >> endobj 111 0 obj << /D [107 0 R /XYZ 122.4 369.595 null] >> endobj 106 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F28 56 0 R /F32 70 0 R /F11 92 0 R /F31 63 0 R >> /ProcSet [ /PDF /Text ] >> endobj 114 0 obj << /Length 1608 /Filter /FlateDecode >> stream xÚW_sÓ8ï§ðtxpfaK¶cssÌ@[ Žæ¸`:ª­$;XvÓÎÍ}÷ÛÕÊÆ)掗DZ­V»¿ýëçË£Ç/ÂØËX–ðÄ[®¼sy ž°4Þ²ð>ùg©ðU£K9 ýv6ýÍl.Dä –."\ ÿU5ã©ßª¦’¥!Ò¥ÚÂïd9û²|ýø…FO‰ aÉ"õz&ÉAøËó«å«·/ñÂÑùòèÛQª  /ß}úx½ö&²ÔÛ[Æ­'’ã°*½«£?Žž£‚mœ¥qê%iÊ"± ç]©r5ú÷m‰¶ÿÌæ1ÀÒ¹5×pM\æ«Þ}âàø£Å¥³ÕnÊ{ÜŇi5ü8 f(XŒîw+À.Žüvƒrm¶Ò‚{»Øâ¿³jjXÕ•!r»‘-±çÀnI7³9\sBŒj{ÑMÝ­7Ä"›u·Uä;ãÎkç®1j<ÔÒÁ]y½ÝéR5fE1IÔ3ʪ˜f,þî{u§ò®U²ÄH0È:A€+‰Àqà²,Žé¬Ý( ºU]–5š³×Õš¢T6îl'›Vç])tR:£V]ùdBÅàÐ/·ÎÕÍõÊ:X® ŸP˜G, P-fYD7ŸÑK¥6-­ê©õ91ˆ!"þw™Õ×UwÏp‹¶õÊi¿Q­È-`8›°h>(4îp[I éú?†„Ä{¥Ú±²‘ꮫBç²uÊ»x´+EüV½¢×êº"Zo#ƒ,Óˤ²R@ÍED¯ìØa/°nYá!àu'·»RÑÆ±Û<  í±hÕ]YÐÖìÈ%¹^Ý;dY˜9¼{kà¨Qß:Ý(Ó¿’ö(½&B¡ÀéQEç™MK×Ösã˜VwýÓ-/~4þabM”—«T‘°nÙ·xÀ²09|ð{#D+ r{í÷§ôÿéx~vuùìââúôâÝé"ÎÏ^>à Ëó³ëÓw——ço—Ç_N¦,¢h;N2Žj¦€ÚoO¸ b2±€äKûÀü Ö€¹!/,b9Ë"J/¹+°8S·3uµ¬wˆ<$ÒTðcîCS‰€x Ý`/ÙìsÁ¹×eI+èyÎ36z¨^·‡>Ë%qG>ƒxœ×úk\vì5}{Ãd7p¤îÚFÒ™«®dñìç%ësÀcUÉ›RÍó|? aõk5ëTBaD#“Ðe/,n:msi¨WÂ}ÓZ“Ðö=ü·ZÃ;½»/ ñî ÃrLE4ucÆBjK%ÐÖµ…™~‹±Ü¾ &Ã(BB*ƒ(NÄQ…Ж øn×ßæX‰H8šÆ…¿V¶ùÁ, Ðœà:ñ7õà 1éÖI±–«6PwRWÐThãj3ð —ê­rY¹ […±+,‘Õz2/Œ®rx& ±ë¦Àelûš3·Ö¸"g'dîlÁTËdÝjå@¢¢aqP šÇ†#ÿêÞ´j{Š©Hœ[‰±}O›ªnéÒ}LÑfäþÉüo”b‘{Øš’â·¬«5éùKá ³èœsŽÎÔT›q‡hÛ´œ즅,D$ŸžÐ¿3Ûñ8V˜Mq\5"[H;`Õ£³‰Q*ƒ6 û©ï]ÛÊ‹R%–ú‰Y±¿tçO†«”%PºÆâ[ Qþ‚ LlÑ0eпrè/ð$p!Ì!Ï:ãü /F#YÊÂhÑ ØÊ¯IÚ·§&Ä€ÅIÖ³C´Eÿ6ô †¿[Ú ÿ R䯅® µ’]Ùºþß‹@<“ úÀàO‘á8N/‡Ž Ç»¦†¶Ž™Š.õ~`¯ÁƒÍ^E§+ˆeGÇ,O;À)‰H_Køä´‰$p/þÇìò!bmüÛ6†;Š5xóÁ‘0ê°^T¢ö_^–ÿýù‡ :ÙºÂוÊÁœ¹O+¥\ùqûÎŽ 1Ý4SQ¼ýl=LàùNVSãJ?„Œ+;”†£Á 7VúøÉ“÷MC·¯'[÷|Jä¼è¦Òá[€À²e#w¦pÛhní¨‹‡CvÓU•³ 6ãÑCôÕ1 ‡?WX”: Â ÿ°ý«7 endstream endobj 113 0 obj << /Type /Page /Contents 114 0 R /Resources 112 0 R /MediaBox [0 0 612 792] /Parent 93 0 R >> endobj 115 0 obj << /D [113 0 R /XYZ 121.4 736.262 null] >> endobj 116 0 obj << /D [113 0 R /XYZ 122.4 392.767 null] >> endobj 112 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F31 63 0 R /F29 58 0 R /F34 72 0 R >> /ProcSet [ /PDF /Text ] >> endobj 119 0 obj << /Length 1852 /Filter /FlateDecode >> stream xÚ•Xß“Ó6~¿¿Âouf.Šeù'}‚W:ÀPtZ`'Vƒm[¾Üñп½+í*NŽÜž²ZK«Õ·ŸvWy´¼X<å±—³< o¹ñx²ÈKÄe¹ð–¥÷Þ7Ë„/ûª.fÜ׳9÷ýl.Dä –¥‘…ÿ¬…™¯eßõ€ªèR,êÙÇå‹§"8Ú*Ì2– á¸M–ƒ ð?yôöêêÙË+³äâÉòâë‡9ÇΠƃÔ[7ï?^ Ÿþð&òÌÛÛ‰'’”… ÕÞ›‹?/™SŠäø”"e"н\ˆDŠ|y€nž b$îœük'[8ZšúksØ´?_ªv‹Z½“(¼xøòÙÓ'o–—wôZ¥}U×(­Š~ƒ’"ãc+oºÙLK€z­eI›*«,ÉXÕNÖÁqprÎ9Ëãønà´ê1 º—’ÍæQùoªšâ‹‰‘ÄÑ0ö$iúŽ_†¼°q¾uóüdýKÑ?ªQUéìíä±ȇã Ìé9‡ß0þñ˜¼TÑÀ/ÐÀ^YÇ·ƒ–Í€ƒªôaâ+3Möu‰¸®Q»rç¹”›b¬5`Ç‘¿ÜUÎ ý¶R–ÀßX”A xÀù¢#§,Ëcçö‡ Œw²îÎo„Suº² '1!Ž!¾D]Ñ–$ÔMCÏ@èå¶—Ã@vbKG ¯¡DºãÁ¼uA­l@%;IöÇÁðþ˜x zºîŠö!ßø€å<õæaÌò@LsÜ0ž"c¯TùàÉ5¯lxÖçP:1¢¹v†aˆDH-Ìð@3@tŒ¤>BÈžÔæx­Æ¢/QÙxÏg1 º•8Å‚j¾j€Í ¤þkI+~/ô⩽¥ê‹Åo“£Îáåøž3&á‰ÜQ¦›ÅÜÐuþJ©œ#8F>PÊY®É%Þ¾ý®ªé">–«ªhoW£EI‹çpË'ÈlÇ«¤qt¿£<ã,Œ¾÷ô~ï„`PfÜ‚³ Á\ž&?Ÿ^mksr˜g'œ7ã¦p ¼Ù£IÉ8sPc¿–qAꪑ¨9J,fH|2È1¤×Õz¬‹¾¾=—Ž»¨¶†rìªqŸÜ7uµ5\/Ñì8X2—®§ÄþKË1[g×½,r rÍ@FMR0¿p *k]]ÛWßâ'ž\ Ø-‹hç¶D!º ò„óziÓv’ûÔ;*?˜åÔ?”ŠÊ_`o*]~Dˆh¢$·Ú’®ƒ­Ž™¿Íé5β© ~§Ûó}R7PÒߥëòœó½ü:V® É²Òè)U£ïTíL–:-¤^/¹¶Þõ•¾]ÔUSé­U»9CA."DÙ”à1Þf»‚"ЧÒÄ÷0óx­HbF‹B–EP£ò65FüncŽC?dj—ÂÁEÌÒ$™ŠK)WãöŒ›f*´K‘8mi¸Jô#i÷•Þ¡4uUÎBk*¯´1!AE×WMÑS1…~ µ3Fè¸U·åË ‘§«‹µ+®”‡ÔI…½oå RôçOeÕS¾c¦Ý  `a]©(¡¡»R(Ã%(\“Æîÿ ìc»€§î¨ÜpŒhPŽMgu ^&žºcÚ&5Û¾èv4Ë6| »2:3ñºúF®‹“ª²09t;­»‹Å~¿gÖ,bʬs4æ!ãS*/Ý1 ÞÍ-覷cN‹XSØ.) Œ²ÅT¤œLÀx zH‚[0-”&dYxÚÔàd×,s×Ô€¨u¨Mn¯Ð¯«VâLEN ºT#MÒ»‚$ÓáœaЊºnËHÄåi3¼9zþp¿ÁÚƒ^÷ÐÞ"=ˆ}ÔxE¶¿1kЦ«A–÷öG‰Á^Uâ~ÓÍ—†+VRøûï¢`N§V@zc¿êï´ê>m”²”½¯oº³Íß&ÛÚ»?uöaA}à1ØðÁll›ÆÈ¬Œhe:ÕV3èz¹‘î©D®6‡nÈbÊL?2½ Ÿ:q9´¿ÐV[‰ÏN#ëâÐ}bo›þP ÕO!ÝŒ5µB˜Ù :P³·4¯Û¡Â[3çhÑ$×ó•·mÑ€çv`× x]É=v0€:aÞ?´äŸ«×3ιÿ¦à»ãÜÕ 2ðäÎÕýv­†½É†n®d­Ô‹oÛv€öö•Ö³nêswÚ3ç'Ý Ëd´Sàžmˆ©@_Z…™)¾A-=´–ÄòëÃѨÞÕR;ÜÝk8JÆ~EÕ\¬¾rˆ`Y8DîR‰{Âv_§0º‚ð™|i"«²ØÕ `.Áår-<ð‹)„‡o–(,Í]9ÂztlÄõ{åˆuTÄã©°J{%ዼƘß⮼QýÏc´ÞªùÙ¦ho©kßïÞ3ôÀÖrÕIR†U6Iy<Í4(sÈúIHï,ÎÝß3ÿ.Þ´å endstream endobj 118 0 obj << /Type /Page /Contents 119 0 R /Resources 117 0 R /MediaBox [0 0 612 792] /Parent 93 0 R >> endobj 120 0 obj << /D [118 0 R /XYZ 121.4 736.262 null] >> endobj 22 0 obj << /D [118 0 R /XYZ 122.4 495.872 null] >> endobj 122 0 obj << /D [118 0 R /XYZ 122.4 423.674 null] >> endobj 123 0 obj << /D [118 0 R /XYZ 122.4 341.536 null] >> endobj 124 0 obj << /D [118 0 R /XYZ 122.4 131.876 null] >> endobj 117 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F36 121 0 R /F34 72 0 R /F32 70 0 R /F28 56 0 R /F31 63 0 R /F33 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 127 0 obj << /Length 1916 /Filter /FlateDecode >> stream xÚ¥koÛFò»á|¡Ë}ðe4Å9‰“sÏMÒDÉáàÆJ\[D)RGR‘ÝCþ{gv–”HQîÖpvv^;¯ÝW³“Þ²ÀI¼$ä¡3»wçžt"zq"œYêܸ_'±pu•åjÂÜf2en @5™ !]áÅ‘DP¸WÅ„Çn£«Bå5¡~Q€‹ÜÊ'·³Ÿx+ü=Q<޽XÇ'1!pö}ß}sùêË»wWïßá–“ËÙÉNÐøë”ó#g±:¹¹õ–~v|O$±³5„+G„‘ÇÊÏ'¿ž¼B+ß·RÆ^ '¤ˆH÷—³ë«Ï³É4àë?&þ=Ú:÷}Âü¨ÙOýWùßQ9gxœ'Δ1/ âÂΉè—o¾\_vÌŸsdg˜I`†qÌyÇ3þŽ|·)׺æD}ƒÄoÊü;çVì׋O;™*ŠdFòE'’óïþ=m^úŠëPú¿ä­0ÊÈP™¸å¦¹CÔ6K5í¹ùpKÀ¿®>]ÕF½ÁÏ[¼ºø|õúÍ ¹üûcçÚº˜3™´êi.÷Ôk–¸1«Q½ôku7eE£tE´¿oÓ—=D¥Šܪ_ÞvîßR$ö‚~Ê}/a¡1 álÃ~¶CEì»÷ež—ÚÛ 9!ªÞ¬VªÊþÐ5}7-­šO¦ð%Fý7ÜcñúQ­Ö¹ýH7«õ€ ºíB䪬Úeݨ,'¸,ì~µ@n–ö7_H§Æé¾uxHZgei@­MfØ@¶’vÚšãµ ¡FûOñÄN,‰€Wš-TƒFâ§a‰À2ƒüוªhæy=ÑJy¿#¥„ïe]y—mÂc¨ž‹½P†-MV?Ǫ”ÜÑ–k¾aÈñLƒ–R Ô-³¶VûM‘¶à¸¤´ xËÄæö¡,Á<±“uF·ËÌžÉ_!BC­êåIwl›Êú¸&p\¥b6`;ãÙ¨ñÒã"’´¬î¨t/êæ}iâ2Õ3 ¨§5Ei?<[v¶®ùÇØ©4­tm±´ÚÒ¥ñAªGƒßÅöŒ‹âÖôGŒŽ¼H&-†^xÈ‚IOÄÿ~:¤“b-[iUtÆ™F‘4% f%(^(t“gµ]Ýâq«¡£rÕ®¯¬O2¬+ ˆ;µ«;ÎG<8Ò‹ÃÁ™›Ö‚U${U$Ž,#\èÑB‹®tÔ©¥. ™g…&ˆsK^Ðwçü¨ËMµ°0“ëB­,ÿSuj2„„Ô•%äh­U™U(¨õq'¸Ò*=#ðôÓ›yØ,í¢*RK¥Ôé@šåhHRkö<¯ ø;ÿ—¸·ìSÕ({ ¦\S%ÐGÏ–>%U •õ¨rЇÿB­-Ö±ÔLË~Æâˆ¿ó¬©ÇSgœ7Ž¥:í¨½!g­z}S¥»Pµn𓻥o“ t¡ã«y>^9`B5¡Ò)ÓÇÇ ÔCM»&`ˆ€_”Ov‘¦À“@@ ÖŒR°Ô³…d›Ù›YaÖ6À™˜¶˜0;Á/uOc—ÝQ÷Âö'eýG²Þ4c¸BŠ·sLÈvs `É.†ÃTÈÚi¦&r8%YóáåjUZA¦2á†Ö­˜Î5QÓ@ø8Ä=‘”Žïº*§c9ŸnÚæçÜŽ4Ç[b-1욯ia©>?OÑ· 7©f@=,õ1ó¢ k+Ý,­ÎçD ô~G•Ì X<˜L' –I3. ÷b‚CpÁ¿§ñ1 ña¾e—Èýñ6ÖÏ"â¦ÈÖ„œ“çLlÁ·Iã.‹–îu+tÔ¼;¥Êî¦BaÉËÂ"ÍyÁζRXl«eG–§–ÿ^%‚Õe6 K;„Æí á²sAã“ }`eÚ ‚cã9âѺ³è݆ïºb0!ýkhž5úJ‰û¥nÙ£·cŒBÄW#¯Î úŠÐom Œ¿a ñ±7BŽŒc^"ol~à…ƒëØ’¦€ÈÅáÀ‚Të Œ4zeQª¡_[þ ¯ÚÊ5ù-§Oª«{”Ÿgg„‚æQÀ݃r*ÚË©£Ó| ƒqÜÍR…~lžK$`Ð Mr‡,§®\F}/¬+ýí¯8KvlhÆÒ"áF D èÚV*UYDM¿»zdñ ýZwc%9ïf–ý[ æÒòÛ]±Óß74òà# `¤ðà"é 5ö|üÞÄàÞ4åP|>þúÁ“Ja‹xôùÃ@[ÿðI"|ö„ÏÕ¢÷&a,LÊîÖÏäŽ;Ýïg>Þ5퓳¯ö9ľ7´‚__^__½‡?”pIÒüGü@%æ¬3K„qøâéßè{jIšÿCì‚¥ûbã‡O;±wwo>Ìîî2óìƒUs÷ ‹.-vD%˜Ç5=r.É|~p./: e4Ôp§ŒxFa_“sa#PìÕ2qNU¿1ýlmpc5Žáµœ›+HÒ¾â1Þ¾þ $®$ˆ endstream endobj 126 0 obj << /Type /Page /Contents 127 0 R /Resources 125 0 R /MediaBox [0 0 612 792] /Parent 129 0 R >> endobj 128 0 obj << /D [126 0 R /XYZ 121.4 736.262 null] >> endobj 125 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F11 92 0 R /F29 58 0 R /F33 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 132 0 obj << /Length 2580 /Filter /FlateDecode >> stream xÚ­YmoÛ¶þž_al&5KJÔ[±;Ü´I‹lY¶Û¸†®›‰‰+Kž$7I‡þ÷{EKÓ¸k‹š"Èóòœ7êåüèùkOr–'a2™_OD29IÄey4™/'‚÷Ó, T£Ëb*‚n:A ƒf:‹"D,K%£à¬š†YЩ¦*Ê–¦~-`. ¶E9ý8ÿùù눎 ³ŒeQ4átL;s΃“Ó—ïÞ¼9»xƒ¯Îþ:@Ã'Â11ÁÓÉb}ôá#Ÿ,aéç gQžMn áz%) aTN.þsôò¡”2eO& ° £”˜¯p… Â]‡,›‡ªXÛéúÚ.¯tk×êé D^Z‚ã˹¥@¡ï7°˜víOó¢¼Å…Õto·Ðý.Šî@o@'Øtç‚””û§«V¡j@¼™,cbQ7j7†£ºZÂoKݨEWÞã“ ºšfEëšPÆLî´jiù½®zOÝëM©¬ á Á"yÚ›ð×ßNÞŸÙHß‘daž÷dp÷p+‘ÁNaO3?¾üųQÈY.’ž•õŒX¼ÚvÄxÝ­fF=ð”2§c-©ÆB³h!X˜I|ƒ\ZEMáo¯©¢ìꆦœfðáq͈Œ³,s2_œÎÏÏÝÀ0”Oè&géžæåñåÙ«“ù¿ûT‡ j1Ô#ª0PÍ"¢r2JëéÇÓ( –K€‘AgdA!èh€ˆGå³d9øÔLÄŒƒ±í޳(΂èi© i½6*†¹Âæ 8µÁÄе`Þ¸ L¯Õºnî§™ ÐID¼kÕõ¶$"² P¡Ut¥«š¿ÕÝŠp{ë,ÕÕöæF5^M9±Š:/ÚŽ¢–ÚŽ*TÞvÿ_%©æ@%ývÐå$<@µ}W M±X8ÓþèÁIÊRé §*øãÙb»qOõ“‡IÁY9/«Ï& ¾4É¿—ï=ûD`(ŸdÆa߸{Ü®Tãó:4‚»S Ù’wgêvOû&ê‚!áÿ+BÕЂ4ÌòÑ$0°ãCi €Ë yÀ¹dAf‚o&‚µE¶¾¾§ Ê'82 OŽn “‘ ISèñì 2fi”õÒ|ï‘7céIrðñF)-·ë Ž2ToWzJ_Y2“ü6Àl‰ù §Öª¨Zb@0T½-ðawF£þ䑬ÔZQQB³Ìï¦Óký¹èt]ùâÁ¦hûD,¥ Þœ¼¤T±(* û·¸iÑõìâšK hÎg4lUÑhh±8ü9ƒœ˜àCÁ ·¦`#<ÖcÌœÉÐÄJ9Q<Y—õ¶YØ(Žº)í dPšD¨¾!fE<´»˜5‚'@!Kœ¬ßÝ¡O~ñ"ŰDòÞÍÍþ¯àÝ/8ÆcGg“<¶Rƒç$Q]‡~KË1¯í¸4óƺ4áO¸a³$MŸ$å1|ecôö¤ (‘†]ÙotAr4¼IsæÕ¢#r ˜Ä¶B…uœmÚ -ÀÙþ"-ÝEüÂW5°0̇ʗ½zaÓ01„£"¾â€æ@ùù›Hé€GøÇ8ËÀÇj.|rˆ<é¨Ð$G¬ÉIkSëAÀð×DK²=·ú¢!GÙ˜¤^k“çCzÊåªFcß¶Ä <}šÆIP”[ûh* áº«€~°ëXÆâ1úº'¯fïÎÏ®aNŠ®°ÕJtOòêÿÃædÀ«­W¦Çù4Ýõ?&rb½t·)õ¢¯™–h7ضÉ4A2øîßËî_ü¤þŽùkT™{u«'¬;ÕÚcQÛ”dÈwõýqÛ]ô"̇46pØ8¿g)g§–¹ó:;CS¥`tú±\Àh¿_„)³wšÊå0ó²Á´£Hú€MÊ!‘An´¤ oE£M£©ÅiÝ nõÒ¸ ëë½5HòkæÓãÜIŽ¡G•ÖÉ´ExÑ'¿¿¶Ê;x›7ââÆ¦S“>‹¦Xt»¶¬wÙž3 ëÍ«–êº.KëU/<cOï­·&Š]@ì]è¡ëkõM¥–Ì¡Ìv£C—ÿСVòe½½*ÕÌ>;½ÖPÐTV·¦ÚšÝ6«„#M ´†OÉrû„,æb#\l ;àö‘Š<×U:;Òû±ÑßAì@N·ÿÖ·U«?lëç5¶’äÿ<Ûjí±NG„ÐcìªÈÇ8,Üur½¾Ø%¯Í Ýz x á ãb/‡\ØË±7â¦ÚÚm® 1ÅÐJ£ 6Ü:Žl zåȼw³˜sR#&‚¾¿Ómwh2~÷9û—76¤4½C=TvÆ¡èveÅûã·¾Ò#gœ»ŠQw@ÛV©ƒ8¬â htq…µR ”Jx™Å€ÒƒÜ;h[zÞÅFz¦ CòÞ—Zz²@îÔØ Ñ'ßkòÀ^*ª…Æ 4©+¬øM …©:K -$ÙÝm7è‰ÌƒLš|{úÚw)³8s倆ÀxYÒˆòõw!$êo]FÇæ9#ôÛ}8ÿч—˜‰0Ú¿õ;]Äxæ|îÃÛöÁ¶Yíëâ´ ÉR]w4"Û›jM§ ¿¾Y t5ã3 1·Jµð­¶$^õùJzPƒÒy„Hš±=‹ âºVMÓÒÕ¶eöù™/SÛûÜ¼Å‹ð…€¿€ª0&ˆ`]øŸeÀq|—‡‹0Î3"ùQÅ<ÿ‰Æ«P~¡á-’Bª åiÆŒ^™¹ÝiÀaË"T9ï·LñœÝ®"í*s¨^€Àí|f7>»øýï–w6’Ô~q8ÃKŒœ7ªRMQ>Ã-r{{‰@À»&<ÅëJB„\P», Lêq(èÐb—Öª[YÓºòuuÀræÞy™ªx‰Å-ð´Øl<ǤÙÐAO²¿ZÃÁБp}Ýkªoœ"Fð#…<‡ (([sg3¸£—¸f‘†”fj¦a<ÛÕ.û68¯ çÒ ›ÊoS½ØÀbk \aÜ}*òƒYð1âÃîêÔ\²™ L?¥¦«en›˜‡v¹Àøêôüüìþy¿@ÂÎâ1Ô7p\ŒÖ5Í^ ‹î|͸àéðú¸Þˆ¯Ân$«ý8Õ«¶Á'‚´®dõ¬ÊdÏ*µèÔ²?†¿‡lIHÂ}=ªÔ]÷U¶¾ù› ”,Ÿßq_жOçR²4LGXºÔk]M9ˆÍ³çCñý˜´êû%Ûíš‹(/¼ ±åG½-Uû0¦ï>…]gµU ŒwëOAC²$Ó˜«b&á5 ›JQÿiøÕâ¥õ endstream endobj 131 0 obj << /Type /Page /Contents 132 0 R /Resources 130 0 R /MediaBox [0 0 612 792] /Parent 129 0 R >> endobj 133 0 obj << /D [131 0 R /XYZ 121.4 736.262 null] >> endobj 130 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F29 58 0 R /F11 92 0 R /F33 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 136 0 obj << /Length 1496 /Filter /FlateDecode >> stream xÚ•WmoÛ8 þÞ_l_\`VýþÒ»¸Þ¶b6à°Ü€aÅV­ŽíÉrÓüû#E9µ[oÃíÃBIõ|Hº×˳‹7~¼ÈYžÉb¹YøAÀ¢E$,ËÃŲ\|q>g¡#”¬ø¹ïès×wÔ¹†‘²,P ·õy9Z¨šWm½ç°—:=¯Î¿-ß]¼ ½ÑSA–±, =“€eÏóœW¯¯ÿ½¹yûᯜ½^žý8óAÇ[ø'p!ó½tQìϾ|ó%½[x,̳ÅÁ(îa’²¤jññ쟳kô2„ë>Ëã8xp3Q˜Òû¯Äºßne½èiì¤Þ‘tóêšÐOå-Ül–;ÚYþwz¥ÄV‰®»(•¼ÃÅڊλBÉV“Ì‹B´º£ÅW/ˆKÄ€ËÔ,·åÚmìeÍ•¦sÈJDYÑ¢Ó¾.…¢S¼ ˜%yM(y]Ây;k%ø-‰‡¨QŠà”v„RÆ$ˆ²£ßÔ¤3hã/­j¶Šï§êpƒÛM¯­vc-ßKÍÎÝ8Ìψ¿éi¿žæXÕ¾ô"bΫ ކX­5-ñ5üýÞwvgÍ äæ­V¼´eBa´ÿ(!:’ÀÀŒüÌY"ù­½Ñ‹Æ}Fiå`F½æëJ¼˜ÃMŽAqXÔܳA˜û>é½Ý€Z:GDn‹ƒìv$™Âï@  •([%@Dá«{Ã9¯pÅ.Œ[¡@Áî{™ Δ/´ÎÌø8ærZÚPa$ÁÌ­Ý×ÔDˆL¡…[©a-MK1%ÔF\˦¦[͆”îPgp{UnMê¢ÈycR§HIÜó}[ Û†‚qÇóXgPÍ!‹ …üúB¯xuX•¶»£)Þ8ˆ×%¯ž¶wÎL·kÛ¡#À’ú§ÇL0°CÀY÷(E³ßCè.Ú60Æ.î( ¦G«ÕZÖ«r½ ·Jlä=­>‘¨XVÇAãÞå]'·5­ûZþèÅÇOoî…U|_JEb³þ¾2 ß9…ó81ç;Qàù-nGŽ»¡cˆl¶½fwÖìCBŽìn.ü•“LÃÿÑ–FhÈÿ‚$œ†»ž‰kš°4Œ‡‘Dµõôµ gQ’ ZvR í!sJ칬-¡×¨m¿‡…™†ºc3/»yÌR˜&Ì@ÿšÛ™âcŒÍ×dì=,n²i;ljhù1A~M¼!lêP¶$¡ SF  8`Aî[T ¡²$ô¢Ÿ’ä?boÄGìÀÛS†<öÿå„•†OxÉܸ¸«ô Ê­••`ؤ|‡BëN0ÿ:ÀK±oÅ•…#Öp»mdmãŒm‘$aV€Å•Ú3XÝ]y÷ëÉÇFlxdODM¸Y&‘c þdÐëo>yʶ½L|¨îÜM> endobj 137 0 obj << /D [135 0 R /XYZ 121.4 736.262 null] >> endobj 138 0 obj << /D [135 0 R /XYZ 122.4 679.68 null] >> endobj 134 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F31 63 0 R /F32 70 0 R /F11 92 0 R >> /ProcSet [ /PDF /Text ] >> endobj 141 0 obj << /Length 1775 /Filter /FlateDecode >> stream xÚ}XÝoÛ6Ï_!ì%ò+õé§!m“¢Åt‹—nh‹‚–h›,¹’ÜÔö¿ïŽw”-GíCà#y<ÞýîSy1?»¼ bgæÍ‘8ó¥áEN*/›…μp>¸“,tU£K9 Ün2 ܈f2 ÃÈ ½, Ý7ÕDdn§šJ–-mÝJØKÝ,'Ÿæo/oBÿè)!|ÏÏŸ^IA°ïûîÕ«Woî^Óõ+ú¹»~OÄÍõê2ÿëÏk”wv=?ûz€ß zÍC/ðS'ßœ}øä;½u|/œeΓaÜ8a’z¨Ò¹?ûãìÅ H²Ì‹Â””{¿Vª0s_¿zAÄZ–]{t仺£=ÝÒï®UË]ItWó^…ÈŠ  ܶ“UÁ,kÙYJ±9‚ùØ52ç­']²È¼ÞlêªÜÓª]×Èú„ˆ€UÓ ðfqLz“¼, U#».wUÞéºjép1™‚Õ‘$µp¢H5]ÓÆ™ßp§6Wr RÀ æ®—ìeqâå4N­›¿éÐ2lÐ’}0h–Èú‡C<¼É4ž%î?|sGœD`*bxPÄ'@àíýVç²$ÜB·UŠBXÒzÙȲG_wªÊíªÞ¨n­«-Kýh0±5ð½(Î`ƒ¬àìñ ߀šZP_« Ìí]ùÄ bø¦eA˽‰Õ-ŠšüMº²`.€J=ÃRÉnרߌÙð‚ôħF Øs£K5±Ø­H"§—´ AÜ0›n«sÖT–’ÅÞÀk®´¬Vü\?+ÎmÃq0“í:·rÉìæ±Òº:D (8¨+~+9†Ê.ªírÙZU«^{&àøs£VjÛËî²û|ý÷Õí»ß¯³ºÙÈîâZ”Ñ ÅS/ g6Çç×÷sŒ†çÎŽb²€ÙÈ(³!ñ›Ã1²9oi!„»‚ÞȆT¹dµR-n ™\z1TJ™rl24Qä–TØêGbA¼ñ×€`^мcª ñSàjRWôHͪ<`q¦Y¯Þ¡sLÝ/ÏY•¶É/Þ¡Ù´ê5©ííñÎ…ºk˜´x9õAû¨ÙŽÌ†Óv·Ý’ MÇç¤=œAS*‰ºß·Ú`3í»{½¢£ ÛÉ_1M …¬íó’ÙꎌŰaKôt´àTÅBU1ö2¢²£áº“6Ù ðn$|÷e½5Õ›ÎÈ!·Û¦Þ6ª4;S)ãñ˜z/þ"Üì0´€W‘¢wC1Pèå~‘ ¢­n±£öɱÙ;ë(Ó¢£Ð«1W-§2w&jÁ¶JXfÐâ‚»”­VÚ^äzñ‚¬;ÖYµÞú Õ³ÂugËI¨ì©VÒ"‡IÍÍŽ‰_ž%ü¿F{<³¥â?o[ÒÎG_Ä…‚ú÷ ­ šQ‚³Ñ9xãW€àB.ÊQ,¥ÆGÀô³ëˆ°u®äêÙ@Hú¨XÃÇî—Ï…nXÛ^ÏË_½®±—?úaT2ý´ÖýˆsxˆÉˆžê»ÜèJ ½ÐO˜—K.¨¶tn!ËûÒl&,¨Õ¦*ãPwî•­Å¥í}Ôµ*ïÇ,“ó††6ãÏoGµ¼®è’©l “+ Vð|ß`DždËíbÆÈ«†H3 Ô<ðÏŽGöSjÀHž8‘tÚWÙ€Aó,Âo¶éϼ,b]¯&!ë‚€LciÄâa½•ðôøè§À cŒˆ!Õ:"²¹À‰Ü|ÁhYÒæ …àÆQx$îFrYšA2 "°C ‹„å?<ªÏ w¾¶èͶT¦,€Óѱ#±hfš”)I@Åwø$ï«'ñͭИã(è;nddB¼XXLï‘ùwæ%ñAÎzD ŒŠ~Ò‹¡Ld—M½!°áŽú®ÛŽü +-};úS]H„E®Z³ }$¸Æ1ŒÑ=üè§ôË›¸>e³Y|:Q¡¥ƒj07¹C\®}í#Í¢¡áTgx±Îhœ¸Xϱ —´EÎ9ð³sÐKZèJ6{¢)(*ó5†Òí-SP(uËŠbt’"Ì»j‰ÝfƒÏõâ‹g/cÓ^­Ò?•×jµ‚êE襱7Cðà7ì¿ bûO‰ÿgEyj endstream endobj 140 0 obj << /Type /Page /Contents 141 0 R /Resources 139 0 R /MediaBox [0 0 612 792] /Parent 129 0 R >> endobj 142 0 obj << /D [140 0 R /XYZ 121.4 736.262 null] >> endobj 26 0 obj << /D [140 0 R /XYZ 122.4 543.913 null] >> endobj 143 0 obj << /D [140 0 R /XYZ 122.4 460.382 null] >> endobj 144 0 obj << /D [140 0 R /XYZ 122.4 439.904 null] >> endobj 145 0 obj << /D [140 0 R /XYZ 122.4 419.978 null] >> endobj 146 0 obj << /D [140 0 R /XYZ 122.4 364.741 null] >> endobj 147 0 obj << /D [140 0 R /XYZ 122.4 220.447 null] >> endobj 139 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 70 0 R /F28 56 0 R /F34 72 0 R /F31 63 0 R >> /ProcSet [ /PDF /Text ] >> endobj 150 0 obj << /Length 572 /Filter /FlateDecode >> stream xÚmSKs›0¾ó+td=‰öÔ´MÆ™4MkÒ29`#'Ì`p…ÿ}v4™Öiµow¿]]”ÑâRd¤`E.sRn‰’¥DËœ™B‘²&ôWlµ®i«XP'‚ö ¸8Q*¥Š¢¨è²‹¥¡Þº®j‡ úVNÓCÕÆåõâRñw©¤†$¹&<¤1€Ì9§_–«òçòâ¾\~¿Å¨èký‰¸q"þÖ§˜àšlvÑÃ#'5˜® gª0ä8:îˆÊ5“ µdýˆ.°QiˆH™JsùÖin K•~+Aœ)áŽ8æ˜Öiˆ*Ÿmè¶­¼|_°o놦™(©¤—8ËhŒ®Û)vëúÝÄ‘z?Ž,c…13GÏÞï?,Ç㑽ÀDöq`=œšö-ëÚ=-Δ d1®åŒÃÐ…$2WŒçp+Vˆ`ùÜïåäš§çqœè’s“H.²ð\>(çô7nDÑØ+šWã&œjëXœ¤¼x·B¾w! ù@ß­³6h†yµ¶(x„8âQ9ûÅWl‚ ÷ endstream endobj 149 0 obj << /Type /Page /Contents 150 0 R /Resources 148 0 R /MediaBox [0 0 612 792] /Parent 129 0 R >> endobj 151 0 obj << /D [149 0 R /XYZ 121.4 736.262 null] >> endobj 30 0 obj << /D [149 0 R /XYZ 122.4 698.4 null] >> endobj 148 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F28 56 0 R /F33 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 152 0 obj << /Length 149 /Filter /FlateDecode >> stream xÚ31Ô35R0P0Bc3cs…C®B.c46K$çr9yré‡+pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä00üÿÃÀøÿûÿÿ üÿÿÿÿÿýÿÿ@¸þÿÿ0üÿÿÿ?Ä`d=0s@f‚ÌÙ² d'Èn.WO®@.Æsud endstream endobj 121 0 obj << /Type /Font /Subtype /Type3 /Name /F36 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 5 5 36 37 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 136 /LastChar 136 /Widths 153 0 R /Encoding 154 0 R /CharProcs 155 0 R >> endobj 153 0 obj [41.52 ] endobj 154 0 obj << /Type /Encoding /Differences [136/a136] >> endobj 155 0 obj << /a136 152 0 R >> endobj 156 0 obj [777.8 500 777.8] endobj 157 0 obj << /Length 225 /Filter /FlateDecode >> stream xÚ}1nÃ0 Ed0ÀEG0/ÐÊ ì¬Ò¨‡íÔ¡È”dìÐ í£©7É dñPä÷KÞ#Oà'ÁOª «Ú*kì!X¬nìôKùV¼õzÎ>uÓ©g^ý3eõÝ‹}ŸNê7¯OÔoí#Xµ×nkRþ 0ˆ,‹HŒ"`¢näX€¼,2…¥d;ˆ‹ÒF)ÆÔƒ"»G— Ù¦Ìì)ôeC$9ÙŽ‰}Ì‘ûÜîr²Ÿ9HÏ>Gi§´mÉe2¾bâÖ¿˜øɯäꢻNßôÕÇ€f endstream endobj 158 0 obj << /Length 225 /Filter /FlateDecode >> stream xÚu1NÄ0E”ÂÒ49Bæà˜M¶²´,) ¢@T@¹Å"è’£å(9‚K–‡ñ. #ëÉú3š?p—W=w<ð…ã~(ïÍÑ‘6[;î¯Ï×íF²O¼Ù’½S™ìxÏŸ_ïdw7ìÈîùÙq÷Bãž™#h%^²J"¨s-³,&ï&¢ M€ í ÛuôŠägTi:¿È d)ȧŸÖ¿HeeÓ_èæ3¾Õ Y}‘õET“Ô¼4©’ÅÇrsÀ$²jYÐhÔ%¦t;Ò#ýãk}– endstream endobj 159 0 obj << /Length 283 /Filter /FlateDecode >> stream xÚ}±JÄ@†çH˜fa÷4‰æ‚]à<Á‚Vr ¨¥…¢­YßlßÀWXß `“âÈøïD9-4„oÉ¿3ÿü“eµP»Òº=œËÒÕµ»­øëj隣¯«›{^u\\ººáâ:Ý™{z|¾ãbu~ì*.Öîªr冻µ£ÅD6’‘ µò!#õ"²%I\(3Éä}›CócŽ{mPÈD²ß„‡ýñùõý%ª›:“N¡4‘@™ˆò”&qTDæMøŠK2žv ;æQ9(ÕnhK IdÒvd="åâƒúÐ¢ÇÆ>yÅõšÔ &”ýɹf®Ÿ{[¤²¡ÉÓŽí ‰NŸ4:5þ¼®„8x’À'_ð'¹/¶t endstream endobj 160 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚÅÏ1 ÂP àt*dñÍ |­¼B·B­`A'qRGEççÑ<ŠGèØáñ~óì"^À!äO2¤,¦3+¹Ze.Öʱà ÛJûO‡37›­ØŠÍRS6ÝJn×û‰M³žKÁ¦•nî¹k…(QíS<É… =!8 *TÀS ¤Cí)ú"=‹7êãKú5üßÃÞÁgñ« ïŒŽÉ8åEÇ~P„z§ endstream endobj 161 0 obj << /Length 227 /Filter /FlateDecode >> stream xÚMŽ=NÄ0„ßj K¯Éò.ŽYo¶Œ´?) ¢@[%h‘(âp¥ÅGH™"ø1&+Aói4ž™çµ»¼òRÉF.œx/~-OŽ_yUìÄ×óËã o[¶÷²ªÙ^ÃfÛÞÈéíý™íöv'Ží^œTGn÷Be*ˆT¿ÂRUC‘Qf4¿Œ†.,„B"êÂtFó)‘’ºž Ç …ÄF#a~̇¦³ ˆLÍ¥2~"1e`9Cÿf˜1YD¨é5-´×üÝ úVM4åkcƒÐ‡A›-ßñÊ­€› endstream endobj 162 0 obj << /Length 177 /Filter /FlateDecode >> stream xڭб Â0à+ ·ø½Ð4%q-Ô ftr'ëè èœ>šâ#tì =/uÔ ßðÿÜAÎêIn(£œÆšŒ!k©ÖxB£%ÌÈN_Íþˆ¥Cµ!£Q-$Få–t9_¨ÊÕŒ$­h+3;tA|yÉ=8úÞ‚™àÅøM?´¿ìÿé`Ñ|Ò‹-x¹I ,vQ°Oz€xøEÄÜÉ:æVôv§Ü„#J‰s‡k|jVmx endstream endobj 83 0 obj << /Type /Font /Subtype /Type3 /Name /F35 /FontMatrix [0.01004 0 0 0.01004 0 0] /FontBBox [ 1 -24 51 55 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 97 /LastChar 116 /Widths 163 0 R /Encoding 164 0 R /CharProcs 165 0 R >> endobj 163 0 obj [51.24 0 0 0 51.24 0 51.24 0 0 0 0 0 0 51.24 0 0 0 0 51.24 51.24 ] endobj 164 0 obj << /Type /Encoding /Differences [97/a97 98/.notdef 101/a101 102/.notdef 103/a103 104/.notdef 110/a110 111/.notdef 115/a115/a116] >> endobj 165 0 obj << /a97 157 0 R /a101 158 0 R /a103 159 0 R /a110 160 0 R /a115 161 0 R /a116 162 0 R >> endobj 166 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ3²Ô37T0P0W04S0²T02TH1ä*ä2 (˜B$’s¹œ<¹ôÃÒ\ú ¦\úž¾ %E¥©\úNÎ @A…h ŽX.O…úÿ?€è?}àrõä ä¿Iz endstream endobj 167 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ%‰»@@ûóç ÜÝ»¶öHl!¡Rˆ ¥‚ð÷„)¦˜ñšxOÃŒjéSªãl±Á…7ê?¦y„ôtRS!±á±Ÿ $o ZHÉÁÒŒˆ%ï—몈 û¢ endstream endobj 168 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚ]ÐÁJ„PÆñO\gã DsŸ « ×ZÄÓ¹jÕ"ZUË`Š‚Cúhó(>‚KÃØù®Žf‚þ¸ žû¿.;™ÏMbœÞÙ©qgæ%•wq™®.ùáùM–¹Øã2±7úVl~k>?¾^Å.ï®L*veS“> stream xÚmѽJÄ@ðÿ±ÅÂÞ˜yÍ— pppž` A+ ±RK EÁBÈ>Z:_#oà–)BÖ™½wáGf6󱩧ł2Ê :)¨:£òœžrójÊ’£UyL=¾˜umÒ;*K“^qܤõ5½¿}<›t}sAü¾¡ûœ²So€qĬ¼=f¼ï–›9fîðùÅ©Ëh€¤FŽ÷PC@s€>ítü©“óh¤G˜[†€ ´Rd‡ÔúÃJÉ " h"ö|š÷<zØŽÙtÄí! Í#ݲsi‘DÚ0$§'x,.$cq/õcÁ÷¢¿­,±Òág J z·ß\ÖæÖü­U endstream endobj 170 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚµÎ?AAð•Wl2#˜ØdKÉó$¶P)D…RA¨9š£8‚òbìóÆóË|3ÍüÐz´8*ãqqïà!ælK,Ýêf!‚™ç+˜´ÀËùzS/§èÀ4¸qh·TQûƒÒy”~1}áÉ „3îÌMP u|˜žðf*¡e´ðz”7"êÈ…`–`_ÂâSt endstream endobj 171 0 obj << /Length 291 /Filter /FlateDecode >> stream xÚ]ÑÁJ„Pà#..œÅøÃÌ}‚Ô(u1 Lä"¨U‹hU-ƒ) \úhΛ½€ÐÆ…x;ç\G-PüëÿŸ(<‰Ou Ïè%œÇú)ÄWŒbZ¼äƒÇÜfèßé(FÿŠvÑÏ®õûÛÇ3úÛ› ¢¿Ó÷¡0ÛipM `L=GgŠ hTà6GÐ xŒŠa, B9Ǫ(A R}a9¡²Ø¬+ð,jX0ï?r¯•@5°dì'´ÛÂÆ¢ƒ„Qp,œÚé!@{F5Á(IÍ”’å€T@‘ÒÀõ£S’ _Ò =ß#¤ÂÏ% HÊŒVè–¿ HΈ^Z™ùƒGöÉ¿Ü (xš\Œ5™/3¼Å_Ë||Á endstream endobj 172 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚeÎ;Â0 ÐT¼ôõ H«*0V* Ñ &ÄŒ ˜Û£õ(=BGÔ`‡O1$ÏN;f2Î2LÐК¤h¦xLá†ó„Sg(JÐ[4ô’NA—+¼]ï'ÐÅz†)è9îRLöPÎQ¬µå°j¥¢Nå-ÑrÄ„TÿžD#ɉ~ –T?Bª¬”„frOMPÕ¨sÐÈ`à;¤vôî)Gÿ/¤O7ºr$òi%±O#É}jIå£$Ö£w{ðÆÚç?°(a/5ÿsR endstream endobj 173 0 obj << /Length 255 /Filter /FlateDecode >> stream xÚeбJÄ@à?¤Lqy1óš;ÉåÄÀy‚)­,ÄJ--í‚É£í£äR®\g& wÚ|°ó'ìü[”‡å1Ϲäƒ#^¼<áǽP±’¡ŒSòðLëšò[.V”_ʘòúŠß^ߟ(__Ÿ³œ7|·àù=ÕP¹…aHÂ(fîãTÆÈ AêÄ#{Ľš8=N¦Ý¯™Ø#Ã_+ÑíÚAïžtjÖ›£4HÃ`~AWÓQ‚~,¨‚·@Ekÿ¥flF[bÛ³î[ªúÏ µ~”ö“-´½(½ÛN[¶N£ÏA/ñ£¼†V—í­‹³è¢¦ú?Fj¤ endstream endobj 174 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚUϱjÃ@ `ZîB­'¨ã«S0Òâ¡ÐNB§¤c )-t³ÍâGðè!øz²3HôñKh{~\.hN™ í)'—Ó)Ã+º,ä9Çqs<ã¦Äôƒ\†é>Œ1-_éçû÷ ÓÍÛ …é–áæË-ÏÕÞ±wzð´¶L“Ô 73ˆnb¤. fV÷ c†éF ÓI, —m%‰¦‘¬5µ¤Ò€Ä+I¤¹IbM/1šNb5Ó'ë1UÞó…Wà®Äwüݦpt endstream endobj 175 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚUÎÁjÂ@à 9sÐ;/ ›UÖ¤*X æ èɃxRBZÚs·ôà­OP|–3ÿj˜€WòÄÄLĤ¹Å«ÈÀ3+¾®C ,¦Ít"‡”Éïå²y®¦\6´*ÀÒvè211©E[&:·|Ud–oÝäM~˜3óË\š<ü9äLæ ì…^|Ip…ÿù` endstream endobj 176 0 obj << /Length 212 /Filter /FlateDecode >> stream xÚMÎ?ŠÂ@ðoH1ðš\@È»€Nbj£àº°)´²+µ´P´ $`‘No°g‰7ñ)S„dgFA›ï/ê÷¢ˆ}q7`Âo:PhŠ>‡Ãgg³§iLjÉaDêG—IÅ¿|:žw¤¦ó/HÍx°¿¦xÆ@@6/ïcGÇÄP‰Âà”¨!×Rˆ^!ª'“ÌâTH3=™â,ÑšÅæ×R˜;÷â…g¹X²Kž%Hs$h%Æ¢uõg·+> stream xÚ]ο ‚PðOîœÅGð¼@]ÿ éb`955DS5¡öfö&>‚ã$»)5üÎð}œÃñü‘Ë6+X8!Cо¡ %j¡•P¦f•¢¶J`Rôò¢Ûþjµ×Ÿæ—­ùZzê FB”!Ì‚ž¥_©ºC4KhEoçM> endstream endobj 178 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚUαN„@àÙPLÃ#0/  ¼æHÎ3‘ÂD+ c¥–íH ± Ó7ðY0¾ˆ@IAXÿÝcCl¾bvæß?;9Î2Id#G©d¹¬Oå!åg^å&²Þ^îŸxW²¾‘UÎúcÖ奼¾¼=²Þ]IÊz/·©$w\î…ˆÔÌGï ~=ÑBç‰Oá \N nk¢m`ˆª`Â\MèðÕd³G :5"ìÀ€šÕ»>ƒfÆâ®g¢ä|w3±ãÇòÞŒT8Ú¦¢º¥ŠLH[e"4ûü 8 ¿Ð6IõÔŸ—|ͬÁkÞ endstream endobj 179 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚmÎ=‚@à!$¯á¼ èòS $Љ&ZY+µ´Ðh²…‘åfx“=%-l,¾f&™LCö9áQÀQÂÑ„)LLès›ý‰¦‰ ‡ ‰…‰IK¾^nGÓÕŒ9oöwTä ”€Ý×pŸ< ÑAZ-¤Ý@:ÒÔh½M¦,ÃÑ™òTYõ(ûÖPà zãõG÷ãߨ IaévíÁU.R8Uk®èÏÍ ZÓ¢ B endstream endobj 180 0 obj << /Length 229 /Filter /FlateDecode >> stream xÚUϱJÄ@Ð7¤^“ò~@gãfa„ÅuSne!Vj)¬¢`•̧åS"þ@Ê-ÂÆûFaæ0Üa.wª³Óª’™,䤜NžJ~å¹Cˆøü÷æñ…W5Û;™;¶×ˆÙÖ7òþöñÌvu{)%۵ܗ2{àz-” DfJ £HŸGº„"|„Z¥ÑÖ¦ÁçÑԠÛ)ä€ò`ötfTvhÌ"Ã?|@‘×QZ×計VШó@0ã1ØE–Îã×¶-eý¶ƒÒƒ¯nOæ;`ëDŽhI|Uó†´éd" endstream endobj 181 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚ…Í1 Â@ÐR,Lá^@ܹ€nŒ¦¢‚)­,ÄJ-m5âÅâMö)Sq79€3¯øÌ?ŠÃ<æ~ÈQÂq̇.ì6µŸý‰ÒŒô†£€ôžIgK¾]ïGÒéjÊ!éoCv”Í^a JH˸ìçø;%ü¢‡ŽB·‘Xœ[O”ë ÔŽgUð[¥kM•4FF~ŒúêÕxçÊÏ•€ÓìBTð hžÑš~; 9õ endstream endobj 182 0 obj << /Length 248 /Filter /FlateDecode >> stream xÚUαJÄ@àY¶X˜âòr™ÐM.ÞA\8O0… •…X©¥ ¢íeå _ë|“XÙFlR,‰3…m¾â˜ÿ/ʽe4§Ýœög4/é6ÇG,r|ð{¹¹Çe…ö’ŠÚSŽÑVgôüôr‡vy~L9Ú]å”]cµ"Ð-€"ÀŒ4ÉÈ6"ñn"ja ‰g\ô ôê½… ßÃ}abZvL£ºRÈ´WÝ€î¸Wq‘þæÏz=Aè…æ³ã=AF­…Zp2Ǥ>}Ýþ±áÄm¼§ÿ1¾fxÔ‘0Sè!9„¦ƒTxRáþé^ñ endstream endobj 183 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚ}Ì1 Â@…á‹ÀæbæºÙ…è ‚#˜BÐÊB¬ÔRPQH!š£å(9‚eŠÝÙµ¾êð”(E!¨/I )ÒtxA©M )»eÂ8E±!©Q,LF‘.év½QÄ«I m%…;L¿ð>?9›:À^ÖÓj¬šµœŠµ7óœ’ùNÁ‚ÿ÷Ö=¨»Öj •‘Av†G ¹Êç)®ñ ®E‡ endstream endobj 184 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚUÏAJÄ0à?dQÈÂ^`0¹€v:B[¡LaÁ.]¹WêR¨¢ÐU'GËQ2x€‹É¢t|MUÆÕG^Âÿ¿dùéyªæ*W'©Êçê,WO©xÙ‚†t,¦›Ç±ªEr§²…H®h,’úZ½¿}<‹dus¡R‘¬Õ==ˆz­˜Å€È!ò|¯e£2ŽL»Äñ²ä[+1“-ÿ2R•c;“–íë¶2l ›IÓTšõAp©ÝfÒvàî@tc[¥§Ö èÙÿư`æ)ôÏaTzÄCY?›ô£´‰/C ÷EåîPÚÌ5¡„Û&„së~´¡„o eŸôs*ÁP%Äe-nÅ7ã7x` endstream endobj 185 0 obj << /Length 225 /Filter /FlateDecode >> stream xÚUϱjÂPà?ÜáÂâ ˆ9/Pc0$Bj¡;u(ÚŽ…V2H¼à‹åQî#dtí¹É`]¾á¿çÿáÆÉ8ÉxÂ)?DÏxšògD¿GNxšõ/ß4/)|å8¢ðYb Ëo7»/ çëKºä7é¼S¹dÏâ蓺øù@7=æÊbTªEV´žÓŠUш?âI4›öà´õMÔÐâÚç;žØ@ê½A¯êmQSuj#Síêõ}7µ÷ÝÈ~Ô9ìÌÜ`^¹©ÀBË× è©¤ú’tUž endstream endobj 186 0 obj << /Length 190 /Filter /FlateDecode >> stream xÚ=ο ‚PðO„³ÜGð¼@]ÿAµ(˜AAM ÑT Em¢B/foâ#ÜÑA´«BÃßóÀ›;¼â™ËÇþ‚¯.=È÷tè°¿œ6—;Å)É#ûÉ­ŽI¦;~=ß7’ñ~Í.É„O.;gJ Àì+ˆ¯‚92´È =™ ¡¥Y5"¡ÙÕ$*GE1À_ßkÐMŒAÛŽÌfb)­n!ê ¢Êa—!"„ºt¨5¾}€6)è•GÏ endstream endobj 187 0 obj << /Length 238 /Filter /FlateDecode >> stream xÚ]Ï¿NÃ0ð/Êé!÷Òš?"R)èÄ€˜ZF¤‚@ê€j?šyó=D ç¤$¶ôî|§Ïjr¢ŸÊ=.ÏYMxzÁ«’ÞH•]õlºo-_iVSñȪ¤âNêTÔ÷üñþùBÅìᆥ:ç'z¦zÎÈLfÜU¸ò›/à2¸k`£­¸Ö&[ˆ~‡ÜÀõ6bòÓùÝ‘Tƒ~4óЃ{ÚÎh{“FRýD“öJÎÊÈ*+o£Ft:‡^˶ñCØÆf\8ØŒ&‡†Ñôи%F–Ó¶öŸt[Ó‚~JlÓ endstream endobj 188 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚUÍ1 Â0à_:ÿ`/PìMC”v(j3:9ˆ“: U:ˆÍÑz”¡£ƒˆIÄ!Ë7¼ï‰é8âQL#NN"¦#Ç ¡ÃˆDòkgÌ%²- l©cdrE·ëý„,_ω#+h§‡ö( ò¯¿ ß0¬R‚GéC:k3•d¦V™ª4PÖ`  {@û1¼ÿ€¡gy9x–Ρoi|KãZ”Cf1.$nð ñÿ> stream xÚ=ͱjÂ`à2î’7hî èŸäÇ6]ˆ fìÔ¡tÒŽ…*:H|±é(V;Qû¬›X¶’¤\FjÓÛeý%E)æM“TÌ‚k1åRvûO1Åjª±˜™¾Ç}H9S Ü Á¹B†4øÅ7Z4^ë7^󝿬üð;r<×ÿŽÌȇ0È)¤ Êèz§»!ËB–e,; eá£__ß=Fʼ”W¹|/Hd endstream endobj 190 0 obj << /Length 178 /Filter /FlateDecode >> stream xÚ]Ì1 Â@Ð )Óì„Ìt“MBÄ…Á-­,ÄJ-+³GËQr„”Bt ñóªÿá«|(¢œú1%Š2EûϨR.#Ê’ï²;baP®I¥(ç\£4 º^n”ÅrJ1Ê’61E[4%o!¨Aü™u4§x@ÕuŒ/øòØÓñYë¬qDówßûk;Ôp×pÒÐjh´WOü: ¬ðm 83¸Â7Ä¡B endstream endobj 191 0 obj << /Length 211 /Filter /FlateDecode >> stream xÚ…Ž1jÃ@E¿P±0Eöš $+1˜Ø`bp°Š@R¹0®œ”ÛØ Î:šŽ¢#l¹…Èf Å<†?ïÈ<ͧ\ñ”k–9Ë3Õt" +–Ùýrø¡UCnË"ä6“kÞùr¾~“[}¼rMnÍ»š«=5kFÞç¬7Ê`€åhÛøÄß –#2o²YA¡;´§Ð `’°Hh¼ÎZ‘´"i‹¤Í ´É °!ó(£ðRF½ÛØ£µ±ÃÑDmå#þ½5ôI@%?‡ endstream endobj 72 0 obj << /Type /Font /Subtype /Type3 /Name /F34 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 0 -16 73 59 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 122 /Widths 192 0 R /Encoding 193 0 R /CharProcs 194 0 R >> endobj 192 0 obj [42.44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 29.71 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 56.33 0 64.24 0 32.02 0 0 0 0 61.72 0 56.33 0 0 46.68 59.42 0 61.72 0 0 0 0 0 0 0 0 0 0 42.44 0 38.2 42.44 38.2 0 0 42.44 25.46 0 38.2 21.22 67.91 46.68 42.44 42.44 0 35.01 33.95 27.59 0 0 0 0 0 33.95 ] endobj 193 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 45/a45 46/.notdef 69/a69 70/.notdef 71/a71 72/.notdef 73/a73 74/.notdef 78/a78 79/.notdef 80/a80 81/.notdef 83/a83/a84 85/.notdef 86/a86 87/.notdef 97/a97 98/.notdef 99/a99/a100/a101 102/.notdef 104/a104/a105 106/.notdef 107/a107/a108/a109/a110/a111/a112 113/.notdef 114/a114/a115/a116 117/.notdef 122/a122] >> endobj 194 0 obj << /a21 167 0 R /a45 166 0 R /a69 168 0 R /a71 169 0 R /a73 170 0 R /a78 171 0 R /a80 172 0 R /a83 173 0 R /a84 174 0 R /a86 175 0 R /a97 176 0 R /a99 177 0 R /a100 178 0 R /a101 179 0 R /a104 180 0 R /a105 181 0 R /a107 182 0 R /a108 183 0 R /a109 184 0 R /a110 185 0 R /a111 186 0 R /a112 187 0 R /a114 188 0 R /a115 189 0 R /a116 190 0 R /a122 191 0 R >> endobj 195 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ52T2u ÍR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ(ª+¨ endstream endobj 196 0 obj << /Length 85 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3s…C®B.ˆMÎåròäÒW0çÒ÷ž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ €ËÕ“+ hz¯ endstream endobj 197 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ô35R0P0UÐ52T06W03RH1ä*ä26Š(XC¥’s¹œ<¹ôÃŒ ¹ô=€â\úž¾ %E¥©\úNÎ @Q…h ¦X.O ¶CÂu@\Å€ø3‚ðfáÌ ˜„ X„ Øžrãih4…ƃqs¹zrræŠH endstream endobj 198 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3cs…C®B.ˆOÎåròäÒW0çÒ÷ ré{ú*”•¦ré;8+ré»(D*Äryº(üƒì*ËåêÉÈžã: endstream endobj 199 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚuν Â@ ð”B–>‚y¯¥VÝ ~€ÄIõÑú(}Ç¥ñ’£¶î¹»$ÿ$Å ijOQ2£s„7Ƕ¥”‡Óçš=c4k{‹&ÛÐãþ¼ ™o¡YÒ!¢ðˆÙ’˜ù `-ÕZµWb ¬–b *ѯEO'«¯?rûÓuùU;ÍMNu—ìm2Ôl ¿T~7U7O“á-¦yëÐYˆÁÝë0ï÷ê4E_çºëUižR-ú™ \e¸Ã/-©J endstream endobj 200 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚ­=nA F=¢@r³GX_f–ÝE¢BâGÊH¡J¥ ” ¨wŽÆQæ”hÛ‰(!]š'Ùã±ü½ººšÕ4Q5¡±£M{¬Jn:ÒËçg Ú7ªJ´/ÜFÛ¬èx8mÑÎ^çT ]Ð{Aî›ô¢€<^™1FÃ> stream xڥб‚0à“[xï ,$a"ALì`¢“ƒqRGÎòh< ÀÈ@¨½6ÊêÐ/¹kÒÞý"]¦+ 0ÑG ^Cx@ë: ’..wÈ%ð#F1ð­î—;|=ß7àù~!ðO!g*¥*Æ´­±7ªÒX3¥Ë†ÌZÒïH¯'gŠdÖOi¬È̸¨Gýftnm§z®Ýß:¯ýüÕLçqçÌœùíFª6µ[Ûl”ŒMiHÌIR§  øOž“ endstream endobj 202 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31×3²P0P0bS …C®B.c3 ßÄI$çr9yré‡+›qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÁÜКì=,'Lp¹zrr˜‹r endstream endobj 203 0 obj << /Length 232 /Filter /FlateDecode >> stream xÚбnÂ0àC –ná¸(Nhš*€Ô •Ú©CÅŒ  vNÍÂ#xd@÷'@iÕ©Ë'û,ŸÏž'’H.cÉ™$²JyËYfEÛŽ»“å†ËŠý»dûg+³¯^äs÷µf_¾N%e?“T’W3!êkCD…LÕ ªœ¹§Akq"³Ž4 „#³¡^è©]yêÛ"wlEtF8Ü[„ßÖÍߢñ¿,4ÞkÝî%w¯ÿ^ÅäæºÎ#ÄO]į]D0@KÆ´”lÄb›^¼$i©ê-a¤ÍóŠßø ˜´ŒÉ endstream endobj 204 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚEÐ;NÄ0`G),Mã#Ø'À‰´ ÛEZ‰HPQ * ¤íÖÎM¸JŽ’#¤Ly˜\Pø“üÏ£»½éûЄ£¬® Ý1|´ôMœ5Øââý‹N#Å—pè)>È)Åñ1\~®ŸOOw¡¥x¯mhÞh<‡lŒñ+˜fÈ“X±ë íÝý ‡Eaš ±Ê°Þ¡Ý S%H” 1Í'Qrˆ5rf«:þ×ë›ñ>ýBöòg·B wdá y­à‚$†Ñ‡IZX©°Të‹Z¿Ó^lQ»«µÓª¨½ƒ|¤N:+’/êÜœÎÐ7Xït?Ò3ýuv endstream endobj 205 0 obj << /Length 168 /Filter /FlateDecode >> stream xÚåŒ1 Â@E¿X¦ñ;ÐÝ„ÄhˆÜBÐÊ"X©¥…¢õæh9ŠG°L!´ò ÂðÞüùY>qsvœó8áÌq6ãcLJ•ާßËáL¥'»ã4!»RMÖ¯ùv½ŸÈ–›Çd+®cv{ò Óþ3ƒ²hBóË¢>4 Ç色Ãð…HG—F¥´A"¢áBDßôZI§DPMKO[zü…„Õ endstream endobj 206 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚmÐ;N1€á±¶°4Ía}œ 8¢³”‰- ¢@T@I”´ìv)¹’o#d2ÅÊffØG ë“Å?vîêzaf¦¤ånŒ»5ï%nÐÍi?ã-_¼}â²BûlÜí=¢­Ìök÷vù¸2%Úµy¡—¯X­Mj@Ÿj&o‚à™"ô-ᛓ35 œÍĬPÝH‘G’‰SF(F·BÎbŠ0Ñ Ô䛊ñ ÔóýGœ ¦NPŒê«ØÃE4@ƳAêÑBÍaÄ^ð?á’ƒPá(äGÒ%:þÿà]…Oø )vh endstream endobj 207 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚuŒ± ÂP ES:²ÔÑAh~@_¯K§B­`A'qRGEçöÓü”úBcZÜD.gÉÍ=.¥“£©%—Kéhñ‚.¦>É·9œ1/ÑlÉÅh–zFS®èv½ŸÐäë9Y4í,Å{, ‚¨_B‘:yDÂvA;ÿ5R`Àãÿd¬V«‹£Îã¬ñ¸ªýé~ðY”ª¹j2ÎúͰ}s Oö:\”¸Á5y\, endstream endobj 208 0 obj << /Length 180 /Filter /FlateDecode >> stream xÚ½Ž½ Â0€¯8·ô¼Ð4¦N…ZÁ ‚N⤎ŠÎí£õQú;”œJÝ\Ìð…ûÿÒùlI -hª)•?¡‹Æ;#I u_9ß0·¨d ª¤QÙ-=¯+ª|·"‰ :jJNh ò ïˆ:AÌ‚ŒkðÌ 0³vY \Õ¨iôah@ù‰¬ú_ xØùþZ·ŽÛàâ‚UüD²ä ü$ø‹àÚâßu} endstream endobj 209 0 obj << /Length 179 /Filter /FlateDecode >> stream xÚ36Ó³4T0P0VÐ5T06U0¶TH1ä*ä2 (˜@e’s¹œ<¹ôÃŒ ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæ òÿ0ÔÿÀðÿÿÆÿÿÿ0!û†þ ò8€˜Á¾‚븈ÿ‘õÀ̱?ÀÀ4— h‡û†:ö?Ìÿ˜ÿÿÿtà[>€ÝÄþ‡ËÕ“+ ßrDª endstream endobj 210 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚ½Ž1Â0 E]u¨ä¥GÀ€$1E*E"L ˆ @077£Gé; š4°ÀÆÂò$ûÿÑp0!IšúŠô˜2I{…'ÔÚ‹’2õÚ쎘[kÒÅÜË(ì‚.çëE¾œ’Ÿ Ú(’[´€qÿCZ{˜‡³qóÍÅÌì’6a—6»^ ”ÎTþ¢³»2>ÐþŒ¯á³GùJ ¹é=~w‰»jQW¸í\Mh€3‹+|'bo endstream endobj 211 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚmŽ1‚@E?RL!G`. +¬šØH‚šHa¢•…±RK v8Gá”d×!R:Ékþäý=/BžpÄ£õŒõ‚¯!=HGNxÚo.wJRRGÖ©­Ä¤Ò¿žï©d¿âÔšORt¦tÍð 0@n ÇÚÒµ¶òZ¿ök·ñ+§ J´AO\ ‹e.d?:+°¦Ðaz²qw"–B…_c(/,]ã¹oÐé¹­¥¹„k@›”ô ÍUH endstream endobj 212 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ32Õ36W0P0b# 3C…C®B.#3 ßÄI$çr9yré‡+™qé{E¹ô=}JŠJS¹ôœ€|…h ÊX.O†ÿ Ìÿ0ð±<Ûq}ㆠ Aø3“ÿÿÿƒ™É4‹Z˜ËÕ“+ Û[þ endstream endobj 213 0 obj << /Length 234 /Filter /FlateDecode >> stream xÚ}±J1†ÿåŠÀ4y„Ì h6ç\·pžà‚Vr•ZZ(Úš> stream xÚ31Ò³T0P0bcs3…C®B.c4ƒH$çr9yré‡+pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ100Ð3þaøÇÿ¿áŸüÿÿêÿ?ø÷ÿÿ‡ÿ?äüÀþãÿæÿ˜ÿüo`üóŸÿÑs¹zrr¦…{ endstream endobj 215 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bCSs…C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þC¨'p¹zrr4ö+³ endstream endobj 216 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ½Î;‚@à%$Ópæ.bK‚˜¸…‰VÆJ--4Z³GÛx:)ã?ÁMöÛ×ìÌäÉ|Á ë̱$|NéFY†ótÔ‡Ó•JGvÏYFv[²nÃûóB¶Ü.9%[ñ!åäH®âÑ`ü›ÙÂD=ˆ;P´ n€x3‚8„„=ˆ:· h@í`'Òþ@ˆ|,oå…¿â‘EŒæ3µRxE ÅJ¤u#í TfÚP ­Ú¤™¨'<­íè 'µwÕ endstream endobj 217 0 obj << /Length 89 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bC3…C®B.s ×ĉ'çr9yré‡+˜sé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þQ¸\=¹¹6VLÖ endstream endobj 218 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚÕL;‚@\BAòŽÀ; ! V$ˆ‰[˜hea¬ÐÒB£µ{´= GX;ÌŽ‹–žÀb2¿Ì”Åd>å”Ë)ç3>ft¡"÷þcÇ¢=S­Hî¸ÈI®|JR­ùv½ŸHÖ›g$ÞgœH5,‚—{ábèÂ%0´{ ŒžðªO[YtÑ`b BG:„ˆzè~¸rßï!Z*ÚÒK=Ù endstream endobj 219 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ31Ò³T0P0bcsc …C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.OÆ? ÿøÿ7ü“ÿà_ýÿÿþÿÿðÿ‡üÿØü?ÀüãóŸÿ Œþ3 ð?:`.WO®@.²dG endstream endobj 220 0 obj << /Length 190 /Filter /FlateDecode >> stream xÚ1‚PDÇPlÃØ èç †X‘ &R˜hea¬ÔÒB£­p4ŽÂ()Œëw-hm^1“™Mìd6刧<¶œDÏùdéJqêÄ諨s¼P^’Ùqœ’Y9™L¹æûíq&“olɼ·¨,Þ@ 5I ˆô‰¼œî¿‡ èPÕA‹¬„MV#hü¶rèOÀë\š×ÿ‹áV1$kQè*-×:H§éHTÒ¡4ÐhYÒ–>Yñ]] endstream endobj 221 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ­Î;‚@à!$Óp纋‹D+ÄD ­,Œ•ZZh´†£qŽ@IAvœ5cibóóü£ÉxNšb…1EšÌŒN!^Ñ©jšF}ëxÁ4Gµ#cP­¤Ž*_Óýö8£J7 Qe´I0ϼÀ,$\e®™à&i«@(0<+À vJ!ù…âû¿/Ë×7.ý®OÐ$KU»|²àìÐû­ÛË·øfswo endstream endobj 222 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ð36W0P0b#sc …C®B.#rAɹ\Nž\úá F\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O†Ø?üáÿðÇþßúþøûŸáï†ÿþ?`øŒþ3@Ñ?Š—«'W Ì“C¥ endstream endobj 223 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚMÍ; Â@à ir„Ìt³‰­"1‚)­,DÔÒBQ°r÷h{”!¥…dc¾æŸW¢£„"Š©¯)‰(ÓAããTˆ†]g¼Dµ¦8E5—U¹ ëåvD•/§¤Q´Ñm±,L¿Àg¶³ Eö)ðmž}À?Óɬ¨[¹† ½Ñ@€ÛP&ØÉ„ª/ÿg"vâk tìŒeÙ3²¶wžòÈÎJ\ánONØ endstream endobj 224 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0TÐ5T0²P01WH1ä*ä22 (˜X@d’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒˆÁÿÿÿÇÀÄê¥ÿch`üÇØÀðŸýÐR®ÿÏÀ`””ÀÀåêÉÈ|Q  endstream endobj 225 0 obj << /Length 127 /Filter /FlateDecode >> stream xÚ31Ò³T0P0SÐ5T06¡C®B.c4¶€È$çr9yré‡+pé{…¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ10þ¡/f†bö?ÿäÿÔ7Ôÿ©ÿÿÿýÿŸ@üñÿÿƒ˜ÿ00p¹zrrÁja‚ endstream endobj 226 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚMÌ; Â@à?¤X˜&GØ=k ¢VÁ-­,ÄJ--m“ÜÄ›hŽ’#¤L¢³ ÂÂÌóŒæ£ÉBUÈÍlœCºQ4åºïØÁéJ‰!½WÑ”ôš»¤ÍF=îÏ éd»T!éTxóH&U_ ¨r@–ˆ‹’‘%rô2K7 j¯uð¿qðZ¿fD ´¢º>D”@ÞÃoËâÏ‹‘¸oKLjօV†vôg9Hã endstream endobj 227 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚEαNÃ0à‹> stream xÚUÎ1jÃ@ÐoT¦Ñ4pVkYÄ®¢"W.B*'e »t’ä*{’ #¨T!”Ì®¬Ãò`g˜?“¯îkÎXó\ßsîß»¦#å…T3.–×Öá“6%©=ç©'©“*Ÿù|º|Ú¼<°&µåWÍÙ•[þ’¦Rë1õˆ©R‹ ž¤´BÜ¢f=¢n¤CÔGfWZ`ˆ= ðå‘iT‰L ý©Kñ·ãw"ê'dÏ ­kxš‰Øc]T •ìXù™!à2Kr×KÚÑ?§êVv endstream endobj 229 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ36Ó3T0P0bccs…C®B.c˜ˆ ’HÎåròäÒW06äÒ÷Šré{ú*”•¦ré;8+E]¢Zb¹<]êÿÿÿƒ†00°``àbù@|€Á¾¡ˆÿ300üc``bæ?@ehJíQ•‚”1þASúMéÿÿÿþ£a.WO®@.—÷P endstream endobj 71 0 obj << /Type /Font /Subtype /Type3 /Name /F33 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 1 -21 60 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 46 /LastChar 122 /Widths 230 0 R /Encoding 231 0 R /CharProcs 232 0 R >> endobj 230 0 obj [23.07 41.52 0 0 0 0 0 0 0 0 0 0 23.07 0 0 0 0 0 0 0 55.36 53.05 59.97 0 47.28 55.36 0 0 0 57.66 0 0 0 0 0 0 0 0 0 57.09 55.36 0 0 0 0 0 0 0 0 64.58 0 39.9 42.9 36.91 42.9 36.91 25.37 41.52 42.9 19.84 0 40.6 19.84 65.97 42.9 41.52 42.9 0 28.37 31.83 29.99 42.9 38.29 56.74 0 38.29 36.1 ] endobj 231 0 obj << /Type /Encoding /Differences [46/a46/a47 48/.notdef 58/a58 59/.notdef 66/a66/a67/a68 69/.notdef 70/a70/a71 72/.notdef 75/a75 76/.notdef 85/a85/a86 87/.notdef 95/a95 96/.notdef 97/a97/a98/a99/a100/a101/a102/a103/a104/a105 106/.notdef 107/a107/a108/a109/a110/a111/a112 113/.notdef 114/a114/a115/a116/a117/a118/a119 120/.notdef 121/a121/a122] >> endobj 232 0 obj << /a46 196 0 R /a47 197 0 R /a58 198 0 R /a66 199 0 R /a67 200 0 R /a68 201 0 R /a70 202 0 R /a71 203 0 R /a75 204 0 R /a85 205 0 R /a86 206 0 R /a95 195 0 R /a97 207 0 R /a98 208 0 R /a99 209 0 R /a100 210 0 R /a101 211 0 R /a102 212 0 R /a103 213 0 R /a104 214 0 R /a105 215 0 R /a107 216 0 R /a108 217 0 R /a109 218 0 R /a110 219 0 R /a111 220 0 R /a112 221 0 R /a114 222 0 R /a115 223 0 R /a116 224 0 R /a117 225 0 R /a118 226 0 R /a119 227 0 R /a121 228 0 R /a122 229 0 R >> endobj 233 0 obj << /Length 132 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0S01T0¶P05TH1ä*ä26 (Be’s¹œ<¹ôÃŒ ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.OÆ 2ìÿìøÿ7ÔÉÿ?ðÏþÿç?õóÿÿøÇþÿÃæÿ~0ü?PÀ`ÏÀåêÉÈG(Ç endstream endobj 234 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚ…Ž1‚PD‡PlÃØ èÄŠ1‘ÂD+ c¥–m…£q@IAˆû;“WÍÎÎL0›† vÙ xólÎaÌgnäû¢ºEãét¥4'µgß'µT¾áÇýy!•n—ì‘Êøà±{¤> stream xÚ…O; ÂP±lãÜ è{IüÄ* L!he!Vj)¨h-GÉ,-$q̃´ÂT;ß…ÃñL­NuihuéÉ—›V'Ç/2OÅì4Ĭx“®õqžÅÌ7 õÅ$º÷Õ$Mô |€ ¨,G\ WÂ{¡ûFÇ9úé^Ù€"J[|š¼ ¬µÐîrè’YÁ"Ö±4nT?…”pGrjݬc_e*[ù«ËM* endstream endobj 236 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0U0Q0¶T01SH1ä*ä26Š(˜%’s¹œ<¹ôÃŒ¹ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. L@ÌÀß$äAD=ˆø$˜ÿÄÿ€Ä?€Ä ‹³ÃÅíáâÿáâ?Å@âP¢&VVÌŒ.ó.ó.S—áG—;ì&.WO®@.n=Þ endstream endobj 237 0 obj << /Length 162 /Filter /FlateDecode >> stream xÚ]± Â0†‡Â->‚ÿ˜ÄK…N…ZÁ ‚N⤎ŠÎú¨>‚c‡bMN8¤>È÷] çy’°ÈáÁü GGbŽÎÂO%ÎT2[0“YFK&¬p»ÞOdªõŽLƒÝS¨AZZFý¢HW 2"ÃòL}¦¾Tß©oþýï»­® ËÐ"І¾Öº?¦ endstream endobj 238 0 obj << /Length 114 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04WÐ5W01T0µPH1ä*ä22Š(˜™B¥’s¹œ<¹ôÃŒŒ¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ†þüa`üè?’›îçrõä ä—5ez endstream endobj 239 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0VÐ5W02W0µPH1ä*ä22 (˜™Bd’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿüÿÿ‚êÿÿc`¨ü¨æ`°›ÿp¹zrrléI endstream endobj 240 0 obj << /Length 175 /Filter /FlateDecode >> stream xÚµ± Â0DQXúKä'2Ò† á * D” ¨Ãh%#¤¤Âü#6HáWÜYòóMíÄÈà0žÃp œsº‘µf˜¹Øœ®Tz2{XKfÍ1¿Áãþ¼)·Käd*rdGò”R/¥RA-œ%¡a|¸½ݠЂ´V$‘Q¬ùµñžî†·êÞoÄ×e«ú¿U¿ïG+O;ú‚a endstream endobj 241 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚµ± Â0EQ Ýù €miCp¢ ” ¨“Ñ…(©0¾ó i~ñϧ{~37õ <& ¸ ~‰³¥9—Jƒ¹Ï“öJu }€s¤7©&¶xÜŸÒõnKºÁÑœ(4è^J©øåøqÄ^©.JùNQrŒ?)F#ŒPäëQ1H¢)3RŸ;™Ê;Ù˜J~.؆xCÙˆ?ZÚÓOYbÍ endstream endobj 242 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UеP0¶TÐ5RH1ä*ä26 (˜A$’s¹œ<¹ôÃŒ¹ô≠ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿÏÄÿа—«'W *› endstream endobj 243 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0S0W0¶P01VH1ä*ä26Š(›%’s¹œ<¹ôÃŒ ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h –X.OæöX±ûŽììþ±ø÷Ÿýà¿ÿÇÿûÿüü?ûÿÿðÿÿÿ€ùÿÿÆÿÿêÿ€1ˆ ÉÔ€Ô‚õõ‚Ì™2—} ·p¹zrr«xSº endstream endobj 244 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V0S01T01QH1ä*ä26ŠE-Àɹ\Nž\úá Ææ\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O† øA-Âþÿÿÿ€øÿ4‚Šv@  Ã¹\=¹¹emH™ endstream endobj 245 0 obj << /Length 136 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04UÐ54R0² R ¹ ¹ M€Â FÆ0¹ä\.'O.ýpC.} —¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒüûõ?€ðÚÿ‘ÿÃÿ‡áÆŒ?˜?°PààP—«'W ŸÒ,5 endstream endobj 246 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F †† )†\…\@Ú$l‘IÎåròäÒ pé{€IO_…’¢ÒT.}§g ßE!¨'–ËÓEAžÁ¾¡þÀÿ0XÀ¾AžËÕ“+ ‰;“ endstream endobj 247 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UÐ5W0¶T0µPH1ä*ä26 (˜™Bd’s¹œ<¹ôÃŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ì@ÌÀß#äÁHÌD؈:Q'þ€ˆ@Ì&> f0ñd˜82î>3Ñ dfâ ¸™¢Dp¹zrr@Ä:Õ endstream endobj 248 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F Æf )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêüƒõìäðì:¸\=¹¹{-= endstream endobj 249 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04UÐ54R06P06SH1ä*ä24 (˜XÀä’s¹œ<¹ôà M¸ô=€\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü òìÔ€Aûòøð Žöêá´ÿ#ÿ‡ÿÆ ?0`ÿ ÿ þÀÿ†ÿ@¡.WO®@.…8 endstream endobj 250 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V04S01T06QH1ä*ä26 (Z@d’s¹œ<¹ôÌ͹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿÿÿÄÿ °‘§\®ž\\ºâAŠ endstream endobj 251 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 252 0 obj << /Length 117 /Filter /FlateDecode >> stream xÚ31Ö3µT0P°T02W06U05RH1ä*ä22 ()°Lr.—“'—~8P€KßLzú*”•¦ré;8+ré»(D*Äryº(Ø0È1Ôá†úl¸ž;¬c°ÇŠí Èl ärõä äÇ\+ß endstream endobj 253 0 obj << /Length 168 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.cs ßÄI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.Ovþ;¢ù†: ÁPƒNØÿÿÿÿÿÿF0Ø1ü`€uŒ@¢†ñQÄf ñƒù„Àf2ØJÆìó~ ñ€¿‚ñ;—«'W ÇžsË endstream endobj 254 0 obj << /Length 251 /Filter /FlateDecode >> stream xÚ…±JA†'\!Ls­ÝÎ èÞ±žšÆ…Á+­,ÄJ--íÄ;ðÅy‘µ²4åB–[çO"h£ÍWì¿üßÌì¹Ýf,•4²s n,Í¡ÜÖüÀÎéc%ûÍ:¹¹çIËöRœc{ªÏlÛ3yz|¾c;9?–šíT®j©®¹ fDT„¿P&E—{åh+ç•9G2ËÏD~þ>/BG¯Eðô$E7è~ }§ø¬€ŸK…ÑvmV›:¶¼«$ê,HŠ@•%¡j»}¦W”}þa³ÂzHõ‘ ¦OØ#b£¼A=ðb2ñßãà~|Òò0Ž endstream endobj 255 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ1NÄ0Dg•"Òo|û$Q6ÍZZ‰HPQ *–’‚ÕÒ!ì£ýp!eŠUÌ8âi¾ý=o¶ýÕpíZ·-§uCçŽ|H?Я¶\¼¾Ë~”æÉõƒ4wœJ3Þ»óéóMšýã?¸çε/2"På˜<>Ïå uÁfA@5ãž`cÌO4ês´1dµ1gõÊ®šƒîêɧï:ÙôeÔPø~•KÙœ-ª˺QvõOÔhù9–ŒXÒÀÜ…H$%Ë RM ŸÒZÉlémb– „d·Ùr)}ÙA!·£<Ê/}L~ü endstream endobj 256 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚmÉ=‚` à’.žÀ߉1‘ÁD'㤎]…Ä‹‘8p n #¡~ $(}úö­ëL<ŸL²å¸6y6í-<¡Óvf{¶ÝÃÅšÅ\¶(â]Î׊p9% ED‹Ì-Æ4 ð•Óžgö&ëÉ{ô¼øâ!1îå¥qƒú?µ\ÀÜ P˜ùCÁµ#ýA“dZz–4Àu ×,iºÔu8‹q…/ÂaoM endstream endobj 257 0 obj << /Length 190 /Filter /FlateDecode >> stream xÚ}±‚0†K:˜ÜÂ#pO`iÀ‰1±ƒ‰NÆI4º æ£ðõ®ØîKÿëÝùÓd¹Ê0FM•j\i¼jx@½˜%\îPPGL2P[ê‚2;|=ß7PÅ~¤K<ÑäL‰•s ´Â9×óËy|¥9#l K#‚vÓœ_ó[¹Z²½äC„N Ò_‹¦C£•èFôŒÏ,úa8è—‘[NÔøXT®®þQ­€ü÷âŠÝ endstream endobj 258 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚÏ1NÃ@й°4¹¬—QY AÂTˆ (‘A‹ÃÍrÁå 3AzšWÌJÿ_¤ãæ”kN|y¹9á‡H/”–v¬¹Iû—û'Zun8-)\Ø™BwÉo¯ïVWg)¬ù6r}GÝšÅ3J•~ ZýôªýT™Mè¥Øa.åˆÊ)¥œ- ™oö̤Å/½ó`t™œÝÿ˜þRôø27ÈäVÖ¯½ifðöƒíh·¾hãÛ`+-·Rû¡ÔÑÒìNç]Ódvg9 endstream endobj 259 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.c ßÄI$çr9yré‡+[pé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿþÿÿD|?€bØ0ÿ ÿAD}°ò€ÿÁ&> f0ñH0b!þO ¶ƒn%Ørv¸ƒÀî³?sóˆ?À>û æË `Ÿs¹zrríÇG endstream endobj 260 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿÿÿÿÄÿ Øæ Œ„ † ‚ƒ`|$€lthv›bˆ)ØŒ‡6 ¢Žä£ÿQ Ø.WO®@.ÌŒ‡r endstream endobj 261 0 obj << /Length 145 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.c ßÄI$çr9yré‡+[pé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿÿÿâÿHìó"ˆ Á€ƒø$`@±ØCLÁmQDýÿ ÿ!Ä( ,ÆåêÉÈæxô endstream endobj 262 0 obj << /Length 227 /Filter /FlateDecode >> stream xÚÐ=NÃ@à±\¬4๬¥PY AÂT(PR$‚ÖÞŽkÍ ¸7eŠU†ÙI"QÒ|Åìß{;—Ý5袥ùŒº½´¸Á°ÐaC]8®<¿ár@ÿHaþVÇè‡;zß~¼¢_Þ_S‹~EO-5kVE*#TòÉPËŽaa¥'\¦BÙƒ°û‰«oè¹Ò\Qéõ4÷pf<á¢`2éß”²Oà$‡Ì˜gãßëíµúD> stream xÚ31Ö3µT0P0bc SC…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§g ßE!ÚPÁ –ËÓE¡þÿÿÿÿÿÿà >ÿ†Áޱ¹›ËÕ“+ H¨X~ endstream endobj 264 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚEÏ=nÂ@àE.,MÃvN€m M,ñ#ÅE¤P¥ˆR%)S€B‹9QPr„ø.]¬lÞÛÈ¢ØOš·ÒüLÒÑt¦±Žñ&c&ú•ÈFRf1K~|þÈ<—èMÓ™DÏH%Ê_ôw»û–hþºPÔK}O4þ|©…3EÓµ¦s|–Æ@F öÄAÖ¤ÃØÈHaÀž8pnÀ…\]Ï­GЈ-8¶j<ì\  8hP÷Ãýÿø­žHF¬é–=a…‹,oËÚ>“U.k¹9‰s endstream endobj 265 0 obj << /Length 123 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.cs ßÄI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿþÿÿ€L€Å˜ŒÁN|Œ?ˆ êÿÿÿÿã?*ûÀåêÉÈé f’ endstream endobj 266 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õøÿüÿÀ ÿBü`°ÿW$þð‰ü{ª1ˆy Ÿ‘‰ùŒ0¢Ÿñ1Œh†í͇ÄqÑ|¼F¼‡ï™aÄ Ñ𕨠‚l¢è·?`¿!°—«'W ±,ˆ endstream endobj 267 0 obj << /Length 194 /Filter /FlateDecode >> stream xÚUÏ-Â@à%ˆ&c¸Ì 迨¤”„ P‚$ޤu½Ö’[GEÓev›¶ æKÞ1Çî»hÑ8º&nL؃-;CF¹XïÀA_ í>¡ôpŠÇÃi º?!å—&+ŒRå"c¢(ɉ(§N+˜ÆµGÍSroˆ‰›‚W\¯Š‹"­àЬæüÏ ¦+éÕtI…–ðߣmÅ›h5|Ö ¸üˆ‹¢dXB]/†qsøº‰| endstream endobj 268 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚÅ1 Â@ERÓx„Ìt³Ž)R-Än!he!VÆÒBÑÖä¨9‚¥EØq™Š†Wüßü7sžæe”ÓÄ”Ϩ¶xAæƘ‡æxÆÒ£Ù3šUŒÑø5Ý®÷šr³ ‹¦¢½¥ì€¾"h é`,ò‚T¤'ÀuID ˆ§x¸/„ˆ¶Hÿ ¡øÙ÷®î9 ƒ›Zª¯šëpéq‹o¡lª endstream endobj 269 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bSC…C®B.cs ÌI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿ0üÿÿÿˆø"þ3Åþ70`øH؃þ@‚ýŒ`?€#^¬„ùŠ^°Q`Cƃ-YÉ ²œä fƒ€² Ô$êÿ700€ F"Àb\®ž\\æ„wN endstream endobj 270 0 obj << /Length 197 /Filter /FlateDecode >> stream xڕСÂ0à›jrfÐ{Ø::"#a‚‚ ‰€€îÞ e0‰XvtmC‚ùÄßöîOõh˜Ž)¦„Š´¦TÑ^á µ²aLiâOvGÌ ŒÖ¤FscT,èr¾0Ê–S²iNûf‹EN†`æÒY9†»Q‰¶3p‚qNÊNÙ3¼ÿ¶ßO0ïÉn‹ßè¶ ×ÄZ¿’J4½&}þ5tÊò›¦y+™A²ý ½-ؼ+Ô€³Wø2>z endstream endobj 271 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚu1NÄ@ E½Ú"’›a|˜„$ÕHË"‘ * D”H»$*â£å\!GØ2HQÌw€‰æÉãÿmÿ©«ãæT ©å¨”ºæDJÞsÕ ‰gõ­Ü?ñ¦åx#UÃñmŽí¥¼<¿>rÜ\IÉq+·¥wÜn…˜™åº2ûÐÌÌ4w„C0Mý€¤LúNÔéL”túAø ¨9ÁçÒ„Éa=tC¹6”8y€ÇF¢Ì›Ôa¥OÚ2éý/òaÁ<Ãô&ÄØùE>oùš¿åxv endstream endobj 272 0 obj << /Length 124 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿÿÿÿÄÿÿ¡êêð@†H0 zÂþÿ(Qÿÿ—ËÕ“+ +òT¬ endstream endobj 273 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚÕË1‚@…áG(L¦áÌtYY +ÄD ­,Œ•ZZh´†£qŽ@IaGhôf'_ñϬ‹gÉ‚#}SËÎqbùléF.b27§+e™=»˜ÌZ3™bÃûóB&Û.Ù’Éù`9:R‘s)U*µH]JóíØý^‡¿w˜ŸøÂ¤Ôè¨%ÂH«´RQCôª/ê‰~ú´*hGo8‚˜ endstream endobj 274 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚeÌ;‚@€á!$Ópæº,‚Š1q ­,Œ•ZZh´.FÇ5¸”\5šo’2ã¹s? ›šqòò98^Ñ}G›|ç»9^0ÈväÈV2#kºßgdÑfAYL{NöELi iÛwÐw?>Í,À¨Ì Ìʰ ]’ xB˜i ¿´LHäÊ›1VÞL0óJRþa”…¢Vèu¦èZ À¥À-¾òVi endstream endobj 275 0 obj << /Length 197 /Filter /FlateDecode >> stream xÚϯ ÂPð#†Á)>‚çt»ºËÂœà‚ É &5mÂ.øb_CY°N wíztøo,È¿ðNøìvÓéE‚‚ì69‚æWh .-rZùe¶D/@sL¶@³Ï5šÁ€6ëíMoØ%n}šðÏŸÂ :ƒš–ßæ}v%Ö$@ö—F•´T÷iX°zÒûÓ[õñ¬¿VÎÉ!zyMŽì-¹ß+_ªX=”Ey>JÍ3CN™.°àï{ŒK endstream endobj 276 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚ­Í= Â@à )Ó䙘ÿ"U F0… •…X©¥…¢mñb ¯a—Ò”)®³‹¨pØùà½)6 GqB¼Q@±O[ªÎSQ6{Ì t—&èN¹E·˜ÑéxÞ¡›ÍÇÄ9§•OÞ‹œªªA â‹î¬ì†q“©ÍÒÚÐð@# ~8 ©¡¸ôŽæÚØ7űÚdzm˜'cÈúðh„¢ü/–ämÙý¢:œ¸À“^[Õ endstream endobj 277 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚmÌ= Â@à Óx„¸ ‰‚Õ‚?` A+ ±RK E[“›™£ä)S,;Îh%Xìûfæùh<¥” }å:exÅ\³T¿:8^pV¢ÝQ>E»’m¹¦ûíqF;ÛÌ)C» }FéËEÜ$ s­´àXBט^H”ȃ©ÁÃ@ž?|be¨®ŸàzY©E—ƒâÿðTZ_Õq×-`öRÅ!a~…ˆƒ„®K<.KÜâj/\ endstream endobj 278 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚŽ= Â@…g°¦ñ™˜„Ä"•#¸… •…X©¥…¢­ÉÑr”aË€!ãN;±˜æï½GÓY‡®âg!ŸBºR¤³@[]/”òw%ä¯Ü”|³æûíq&?Ý,ØõïÝåLƹ©¿+ðx•ƒ“À—´€"Ò¡@±y‰Rx Œ-¶0ª±éþ~Ð*ž?¢uîmÖ½rç!0±ƒe¥æ] ÔEÓ`ç%ÐÒЖÞ*Åsz endstream endobj 279 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚŽ1 Â@E¿¤¦Ik—9›°° Än!he!Vji¡h›äh%G°L2ΦÐÖ…}ðgÙ?of§óÇœêÅlS>'t#k5Ñ?œ®”;2{¶–ÌZ§d܆÷ç…L¾]rB¦àCÂñ‘\Á¤"iJzŒDˆÆ=á[5/”ÈjLAOåQ~Ñý‰ß¡@«B_ÕZ¯h4èÊJ—â5¡Î«µ^RMuZ9ÚѲuEJ endstream endobj 280 0 obj << /Length 193 /Filter /FlateDecode >> stream xڕα‚@ à’.<} L— &Þ`¢“ƒqRG®â›á£øŒ—;[pqÓᾤ½´ý 5)+ÊHñ+•9ís<¡’^&¥|ìŽXLפ*LçÜÅÔ,èr¾0­—S⺡MNÙMC±€Ä  ÿ$z1Ú1Þwxï!"Ëûâ>ô<æôZ™iá&³N°?â>cíH ãRa¸ÊÉHŽ'c Ë:ÇÑ´m™¸O,Î ®ð —ºYK endstream endobj 281 0 obj << /Length 201 /Filter /FlateDecode >> stream xÚmޱŠÂPEï’âÁ4ù„ÌìKˆ¬® ›BÐÊB¬Ôr‹mM>í}ÊûËâì}VÌ™;ܹ“ú³™i©“Ô¥ÖS=Tò'uÃù9&aÿ+óNüFëFü·â»¥žO—£øùêK+ñ ÝVZî¤[(²€ÂÐÛ f#2³;܃J>ÂPD´Cˆv@Z }•ˆ„‹÷c½C  ¤7¸¾Ð'Ð* 4u‘ö.æ7ú¹mp Ìb2ræcÀòÝÉZþI÷_þ endstream endobj 282 0 obj << /Length 154 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0asSC…C®B.cßÄ1’s¹œ<¹ôÃŒ¹ô=€¢\úž¾ %E¥©\úNÎ @¾‹B´¡‚A,—§‹ÿû@âÿÆÿÿ˜AûŸz ñHð?°*;&põÿÿÿš4A€Åðk£aÿÿÿ[~ `1.WO®@.òÅ^£ endstream endobj 283 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿ#E`š}!óšÄä”k.pž` A+ ±RK E»#›ÎÇðUò(y„”[,g‚²ìǰóÿÿÌÖÕÉzßòq¹áºâꜟJz¥º`;볟Öã íZÊï¸.(¿ÒwÊÛk~ûx¦|wsÁ%å{¾/¹x vÏ’€4¸ˆlnfxYé•DdöItÁ§S¶n\Å#7@efd=º`’El6X4jB*²`„éá¾fÀ}E_éh0‡íb•ôj“1SLÍ€,xÝ>v*‹Å!*:MÃö–Æ¢ó½:²?-y‰%Û§F‚Í@—-ÝÒ7ãè‚> endstream endobj 284 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcSC…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @¾‹B4Pe,—§‹Bý øÿ¬“Œ‘ò@dý ùóÿ? ùûÿ ùB~°o’äAdƒü ÉÀ$ÿÉ?Häz“õÿøÿÿÇÿÿIˆ8—«'W ƒzú endstream endobj 285 0 obj << /Length 132 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcKS#…C®B.cC ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ì ò ØþÃÄ@òx@ýÿ@ü€á?×C1;}pýÿÿþÿÿÿ†A|.WO®@.üØO) endstream endobj 286 0 obj << /Length 169 /Filter /FlateDecode >> stream xÚÍ= Â@…_°¦Ð#d. ›ÍŸ B Fp !Vb¥–жnŽ–£xK q\‘`eïÀW¼ïñЉ£~2â€cîé!Gš“·š¦ÎO¤j‰Ô .»m÷Oñë1üêâþdXˆ÷„ÈVîŽ|¹¢-M -è§úX endstream endobj 287 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚÌ;‚@à%$Ópçò.¨H)L´²0Vji¡ÑV¸‰Wá(xŒ…[Æ_­Å~Éü³ó‡Á0ŠÑEŸ_ècäáÆƒ=’¹2Êb½ƒ4gA ΄Spò)§-8él„ôŒs˜ÃQ¹yÀ endstream endobj 288 0 obj << /Length 115 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b e¨bÈUÈel䃹 ‰ä\.'O.ýpc.} (—¾§¯BIQi*—¾S€³ï¢m¨`Ëåé¢PÿÿÃÿÿ‰zÁÀ<Œˆúÿÿÿ7ñÿ,ÆåêÉÈî{\W endstream endobj 289 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚ½Š= Â@…·[˜&GÈ\@7!Q°1#¸… •…X©¥…¢õ^,7ðæ[n±ì8šÎȃ÷WÃÑ3ä‚r„Å9œAl&’ø]ö'¨-˜\À,¤c—x½ÜŽ`êÕ s0 nå¹Û =œî=Cê¿bq䙣Ò1 S¥e¬”ö‰K•vI'ì’ö‡mrÿ/)Tžòì8R`ßû¾‡¹…5¼ízfÊ endstream endobj 290 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úòþÿ¨ÿ$þÿ$ÿÿÏÀPÿD2þÿ`ß$ȃÈù@’Hþ“Èô&ëÿ?:ñÿÿÿÿ7 “q.WO®@.‹£ll endstream endobj 291 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ}Ž=‚@…‡XLÃvNàBL¬H·0ÑÊÂX©¥…F[Ù£íQ8¥…a†‚Îb^2ï}¹™KJ)*%³ K†w4÷Ò‹ó +‹ú@¦@½á)j»¥çãuE]íV”¡®é˜QzB[Ä_P¥ ¢:˜…ðá9o’.êAµ@9(¡dq%Ÿ»7@â'a¸ý/=ßµÓGÃ.^¬ÄTyhÆ ‰”pÁ A!\\[Üã>P: endstream endobj 292 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚ¥= Â@…g°¦ñ™ èfI"¦üSZYˆ•ZZ(ښͣä[.(w“€–‚S|Åæ½7q4HRYs_8Ö ù éL‘WCNâvµ?Ñ$#µá(%µp:©lÉ×ËíHj²š²&5ã­æpGÙŒs” V,ÈS*7;(& A‰]ƒt,¾à -À•ÇýGTÎÀµ@Û8×=ÓF–>¼®á ¡¯†¾$Úñ¼Ë_È¥÷ªùF­Ñ<£5½Þ¯ì endstream endobj 293 0 obj << /Length 211 /Filter /FlateDecode >> stream xÚ­Ï= Â@à‘ ÓäÎ4 ÙˆVÀ‚Vb¥–ж&7ðJ{¯à Lig³ Z 6_ñBÞ¼Õq;éQH1µ¢.é„â­#Ü¡Ž$ )ѯO«-ö3 æ¤# Æ’cMè°?n0èO$éòÓ³!W© É¾Èùb Á|3à1³õP¢_6Äæ¬ri©Ölxz+=Õ>jO=®Ù]qÝu¿ôìªÊç÷B·V–ŸÅ´~…º[ëÎÿ)×DÅ\|kse8Ã'á·vG endstream endobj 294 0 obj << /Length 158 /Filter /FlateDecode >> stream xÚ­É1 Â@ПJø—ðŸÀÝu£Äj!Fp A+ ±RKAEëõh9J¼AÊÁqc!Ú[̃™Ií`4-ØԈËÞð™m»îjw쎜{Vk±«y\Yù…\/·«|9ê½e_Hx’+5ÐCôÑ8´äÂ#‚$ÒRC®¡¹šˆ\õ¡ì¸ÿBÿ"¨¿xo<ó¼âõõIw endstream endobj 295 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚMË1 Â@ЋÀ4!s7q5Æ@T0… •…X©¥EÁÊÍÑrr‹ñ,,Þ2³óÿÔŽg©D’€MÅ&rŽùÆv‚=ê×þpºr^°Ù‹°Yã—M±‘Çýya“o³YÊ!–èÈÅRÈùr¨êGB®ù7 }Kïÿ´D#"×eZS¨¡W¡ÿ!§ˆ("P÷B Ca÷£}­¢9ª6A«ª=> stream xÚ31Ö3µT0P0bc 3…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€Àž¢þÿÿÿ @ü¿A€ÅH2…‚ù`€hàÀ ß €AþAý~ [@óÿ Œÿ€LxÀÀåêÉÈþ:B„ endstream endobj 297 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úÌÿþÿ`ÿ…¬ÿÁ $0ð()DÚÉ? õþÜÆðêdƒ=˜”ÿH2ÿcÿÏÀåêÉÈÄ£d> endstream endobj 298 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ5Í= Â0ÀñW:oéúN`ú¥ÐÅB­`A'qRGE7©…^Ì­×è êØ¡4¾Ø”É? ‰Âé,&žQ@áœÎ>Þ0ÔÍÓ[}pºb*Qì)ŒQ¬¹¢zÜŸévI>ŠŒ>yG”½•¥:ÅôJ•^ý›]ƒS |Á-,ZHZX:È^<rœ[CÂ×Á准’qÊz¤b&Õg¤aì¦QŒ¥À½†¿À•Äþ$›Lã endstream endobj 299 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úÿ `Ôðÿ?ÃÙaCÄÙ00~ @2?ÀDv`²N2~¨+þߎ ¿#Èß``’ ?Ÿ‡“¿¿G#«¾g``¨?øA6 Hû†@Rž¡†ËÕ“+ Ém¢ endstream endobj 300 0 obj << /Length 202 /Filter /FlateDecode >> stream xÚEŒ; ÂPEoH!Lãœø£‚UÀ˜BÐÊB¬ÔÒBÑN!…Û²³t î@Ë!ãL@,ÞaæÌ»·µ{¸£¯Ûá¨ÏÛ™ lµÃfOÄܒ£¹©ZrÉŒOÇóŽÜp>âܘW!kJÆ‹/ŸLnRüQ;”H¡(Ô+€Øû­Üp{Íçh¼¯€/ O ¨.†êçê«oŸk> ¹¶´¬4¶ú…¥4Wè¬&F&ž”™äRŠ¢ª§ÚÑ$¡}¨xY& endstream endobj 301 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚEαjÃ@ àßdˆ‚ÁzöìØ)ÍCšB=Ò©CÉ”dÌÐÒnÆvÈÐ×jé‹:tÍ&É=Žûîî$%ñÍpÄ!ø:ºãdÀñ-¯"z¥X£!—Znh’‘yæxDæQâd²¿¿}¬ÉLæ÷‘™òKÄႲ)—Ö³µ[{²v§È­õöð+ïðOPy5À‘ Æ@®²äÌ©¤äUíð·-Gÿ[ùÙ;z¿Êßàµ[*ö‚l”ãŽBÉ;¥v\ɼHer”;åSú¾H‹R §Z88 ¾~íKôÑßÍa{ endstream endobj 302 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ}Ž1 ÂP †S2Y<‚9¯Å*B¡Vð ‚N⤎Š®­Gó(ï¤Ï¤c‡|?!?É'ãéœSžèä3>gt#Í”»Õ§+•žÜ^wrëŽ~ÃûóB®Ü.9#Wñ!ãôH¾â"Æ…ôPŒ‚¢x+š—"B I À/ >Š¡€i`˜¦$fà_£…$hŠ¡¨†¢Šj(ª¡D{£{-ÐÊÓŽ~æêb° endstream endobj 303 0 obj << /Length 203 /Filter /FlateDecode >> stream xÚ= Â@…_°L“#8ÐMLRØðL!he!Vji¡h'š£å({„”!qœ-–6ß²ó`ö}›ÄÃtÌ!'<ˆ8 9ñ1¢ Å© å»äp¦iNfËqJf)c2ùŠo×û‰Ìt=ãˆÌœw‡{ÊçŒÞ@в¶^m ´­…ו„û•W÷¨”x:ô däTLdOñ”€_Öû'¤X`–*ºw]!WÒ¢qµ½z¨‘º9KõUóïÐ"§ }}dà endstream endobj 304 0 obj << /Length 141 /Filter /FlateDecode >> stream xÚ31Ö3µT0Pac S#…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]Øø XŠí¸ˆÿ7001;×ñ¾Äójä‘Ô®ÿÿÿÁÿÿÿ?À0ˆÏåêÉÈÅFJÜ endstream endobj 305 0 obj << /Length 222 /Filter /FlateDecode >> stream xÚe1N1Eÿ*…¥i|„Ì ð.›-V Ab $¨(U ¤A›Ý£ù(>BÊÑóÓ„,?kÆÿWíEw¥µ®¸kí.õµ‘i;¯O%/¶ï²$=iÛIºó®¤á^¿>¿ß$­n´‘´ÑçFë6Šx0ڄʬ ˜íÍŽX⌾T†~ÂèËϰœfGvÄlŽâgØ×ÎOÈ —˜À<|žðHTGÇ‚+î©¥µ§Ë‡D5ÿWôTŒL3ü*Ù¡¸=·‡2šÿÐþ‚½,·ƒ<Ê8hñ endstream endobj 306 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚEнNÄ0 ðÿé†J^òñ @ZÚHH•îC¢L ˆ @°Ò>ZåáÆ§úl·ÀŸDZãTåe}Í9W|Qp•s}ů}PYkP·å|òòN›–Ò#—5¥[ SjïøëóûÒæ~Ë¥?œ?S»c„€Nz¬DÈDF‘â˜Mˆ&4=:4§WâLì• «hLºVÆÚšÄQ—5Aýâ1;Í,òw×Ki üs°Ä™ãÇ…à Îdw;«Ò-¯—y"ŸÍ§\Û¼>¹ÿí[z 3áVc4 endstream endobj 307 0 obj << /Length 181 /Filter /FlateDecode >> stream xÚ•Ï=‚@à!$Ópæ.¿ bâ&ZY+µ´Ðh £pJŠëL±hë$ó%ó^5YºÌ Š(áÍʺÄxÇT²HN)Î7¬4ª¥ª §¨ô–ž×Uµ[QŒª¦cLÑ uMþÁÄ„B9ÓÌÆ›‹‘ñGÐ3aç(if ãMŽÅ( Œ/½#ì˜`Ëc„÷—V2öOZË¿Z;ý®5îñÜþtý endstream endobj 308 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚ¥Î= Â@à‹À4{„Ìt³&)!à˜BÐÊB¬ÔÒBÑÖ,x¯’£xË’qFEÐÖæƒÙ}o“¸v)¢„ZŽ’ˆRGk‡;ŒSʱóÚ¬¶ØÏÑÎ)NÑŽeŒ6ŸÐaÜ íOäÐiá(Zb>$Ã\CÈÌßÈÌüǹ.ì5ïªTʺ)ñ7¢ ½œùPÐ €ù\è)'…ߘ'å-,e›ù$9óÒ‘• i«ÌŒþ `¾AƒYÒ Öš G9Îð-²c— endstream endobj 309 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚmŽ1NÄ0E”"Ò4¹ž @’T––E"Th+ ¤Ø´±æ£ø)S„ ãÍ“ü=3ÿuíEÅ5w|ÞpWsÉ/ ©í5ÔgûýóüF»ªGn{ªn5¦j¸ã÷ÓÇ+U»ûkn¨ÚóSÃõ†=6™Ì@! `dÕHpÑë³Îç³¢˜¢¢Œ°0g0º°¿p ã†\ÏF<'Ÿ"D´MÖbLz[‚Îë€õZj6]*7DEñã?°?(£j”A…LP5ãË GÕÔ¡˜µ(O•Y*GÒ@BRƒæ ›è þ5pI endstream endobj 310 0 obj << /Length 183 /Filter /FlateDecode >> stream xڕͽ Â0à+Â-¾Þ hÓ NB­`A'qRGEÁÉöÑú(}„ޤzW©Eqñ _Èå~3°#ò) ¾¦À';¤Æ#ËI~š×Ïö€¡Cµ"cQÍ8ÊÍé|ºìQ…‹ iT­5ùt]ãÁ‘ Ù'é`œ010%p1ßà ­‚içBÆt*R¦—€t 2;nB)¼û½¢¦•×4㪙_T+~Ѭý‹.œ:\âãM† endstream endobj 311 0 obj << /Length 213 /Filter /FlateDecode >> stream xÚ}O» Â@œ`q°M>!ûz‰I «€0… •…X©¥…¢­É§åSü„”Áõ²W؈p w»3s3Y:Ê'sÆÃ„³˜ó1ºPš»¡{¦~s8Ó´$»å4'»tc²åŠo×û‰ìt=ã„ìœw Ç{*ç Ó(¤Džˆ¼`D:„y#jAÔ BQ»SQ]9h@ø”¢9…׆mðÆ 3/"-PIÿoÓ™n•§ ÕªË×ÙñÍó?|ÉR3{¿¾‡6ÒnÚRûúæ}Z”´¡ëån endstream endobj 312 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚm1NÄ@ EmÉÍa|HB’b«‘–E"Tˆj¡¤`í&G›ŽkøéHÅü 4ÒÓØ£ñnêóv+¥4rVISJ{!O¿rÝ¢‰²þ~9¼ð®ãâ^ê–‹k´¹ènäíøþÌÅîöR*.öòPIùÈÝ^(Ÿ‰(`)3SÚ˜èç¹1›É+-:%ô8p'?, ó\üú‡%ᔀ^Ê‚úH½"È4Ÿ)ÂM¡ñ©úP¨9%7¹Hiè/üŠ!©¯ Gó«dLºâ!n&{„ÁÈë•|ÚÒöÍ J™MøÞc_u|Ç_ž!r· endstream endobj 70 0 obj << /Type /Font /Subtype /Type3 /Name /F32 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -1 -19 45 58 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 34 /LastChar 126 /Widths 313 0 R /Encoding 314 0 R /CharProcs 315 0 R >> endobj 313 0 obj [43.59 43.59 43.59 0 0 0 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 0 43.59 0 43.59 0 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 43.59 ] endobj 314 0 obj << /Type /Encoding /Differences [34/a34/a35/a36 37/.notdef 40/a40/a41/a42/a43/a44/a45/a46/a47/a48/a49/a50/a51/a52/a53/a54/a55/a56/a57/a58/a59/a60/a61/a62 63/.notdef 64/a64/a65/a66/a67/a68/a69/a70/a71 72/.notdef 73/a73 74/.notdef 75/a75/a76/a77/a78/a79/a80 81/.notdef 82/a82/a83/a84/a85/a86/a87 88/.notdef 89/a89 90/.notdef 91/a91 92/.notdef 93/a93 94/.notdef 95/a95 96/.notdef 97/a97/a98/a99/a100/a101/a102/a103/a104/a105/a106/a107/a108/a109/a110/a111/a112/a113/a114/a115/a116/a117/a118/a119/a120/a121/a122/a123 124/.notdef 125/a125/a126] >> endobj 315 0 obj << /a34 252 0 R /a35 253 0 R /a36 254 0 R /a40 234 0 R /a41 235 0 R /a42 243 0 R /a43 244 0 R /a44 245 0 R /a45 251 0 R /a46 246 0 R /a47 247 0 R /a48 303 0 R /a49 304 0 R /a50 305 0 R /a51 306 0 R /a52 307 0 R /a53 308 0 R /a54 309 0 R /a55 310 0 R /a56 311 0 R /a57 312 0 R /a58 248 0 R /a59 249 0 R /a60 236 0 R /a61 250 0 R /a62 237 0 R /a64 255 0 R /a65 256 0 R /a66 257 0 R /a67 258 0 R /a68 259 0 R /a69 260 0 R /a70 261 0 R /a71 262 0 R /a73 263 0 R /a75 264 0 R /a76 265 0 R /a77 266 0 R /a78 267 0 R /a79 268 0 R /a80 269 0 R /a82 270 0 R /a83 271 0 R /a84 272 0 R /a85 273 0 R /a86 274 0 R /a87 275 0 R /a89 276 0 R /a91 238 0 R /a93 239 0 R /a95 242 0 R /a97 277 0 R /a98 278 0 R /a99 279 0 R /a100 280 0 R /a101 281 0 R /a102 282 0 R /a103 283 0 R /a104 284 0 R /a105 285 0 R /a106 286 0 R /a107 287 0 R /a108 288 0 R /a109 289 0 R /a110 290 0 R /a111 291 0 R /a112 292 0 R /a113 293 0 R /a114 294 0 R /a115 295 0 R /a116 296 0 R /a117 297 0 R /a118 298 0 R /a119 299 0 R /a120 300 0 R /a121 301 0 R /a122 302 0 R /a123 240 0 R /a125 241 0 R /a126 233 0 R >> endobj 316 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ36Ô34R0P°b#CS…C®B. m„@ $‘œËåäÉ¥äsé{€IO_…’¢ÒT.}§gC.}…hCƒX.OöòìÔÿùÿÖÿ±ÿ!ÿý—«'W áš( endstream endobj 317 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ35Ó30T0B#SS3#K…C®B.SS°  D"9—ËÉ“K?\ÁÔ”KßCÁ„KßÓW¡¤¨4•Kß)ÀYÁKßE!hL,—§‹Â0ø‡•ârõä ä(-“ endstream endobj 318 0 obj << /Length 291 /Filter /FlateDecode >> stream xÚÑ1jÃ0€a ‚·øÒ jR'YbHS¨‡B;u(™ÚŽZڭؾI®â£ä=˜¼JïIq‰ÁT`ø$/ÿ“V‹«ëµIÍÂ~«ÌäkóšÁ,s»OÝÖýxy‡m É“YæÜÙSHÊ{óõùýÉöáÆdìÌsfÒ=”;#ìÒðkTÑNUç„ÝDö3’8L¤ð4£1è¤裵>+*bôùT)ôÑ?£dÐ C~yE}ˆŽºQÂKZq¾<Šš¥¬8ZµT°b+Ρ1ܼÏ×nÎ N”¿q÷Aªœ(ºF».äÀùgE¤žã…¸$ <†àAéÄñ‚óGÅ.!Ñ šÕP¼Ï/X-Å{Uü°­«£wÅî¿‚ÛáÆÁÊ’ endstream endobj 319 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚ¥ÒÁ ‚@à‘Â\zç ZÑ< f‡ N¢SuìPÔ¹ÍGñ> stream xÚÅ’=NÄ@ …MÉÍ!¾$)Èf«‘–E"Tˆ (‘AKr®’£äS¦XÅØ“Ù,=S$_> stream xÚÅÒ½ Â0ð‡Â-}„Þ˜ìÇV¨ì èä Nêè èl­ÒGpìPz&±M„ˆÐÉ@á—„$åÓ$BgüK|Œ<p8äs9‡3d°-Æ!°%_V¬ðv½Ÿ€eë9ÀrÜèï¡È‘ä°øxë©Ô)Q©TóÅ”ïxÔô²©íe¥4ÈG¤ªzMÄa)[¼"ei=šAikÊëL¹ôM¥!çCÕhÕ×ø.TC×Ê#³¦igÖ^w†£o¶êªî´î¾J„-ã$äŠKH…­We¦N'Q<‹6ð¯?K endstream endobj 322 0 obj << /Length 173 /Filter /FlateDecode >> stream xÚ37Ð31R0P0b3S3 …C®B.3rAɹ\Nž\úá f\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O…ÿÐ@€>À`ÿAJ3Bi†z(m¥å¡4?”f‡Ñ 43š+ÍøF3| @3€hf4;”æ‡Òõ`è+¢h˜z„~vö1’HƒiP¤~ ‚ærõä äœÏ endstream endobj 323 0 obj << /Length 300 /Filter /FlateDecode >> stream xÚÍÒ½N„@ðÝP\2 pó ÄX‘œg"…‰Væ*µ4Q£5÷&÷*< °åÆ™`¹øQ{ù±,ìÜÌ¿,OÓsL1Ç“ Ë3Ì/ð)ƒ7(r^L±ž<¾Àª†ä‹’k^†¤¾Á÷ÏgHV·—˜A²Æ‡ Ó Ôk4ü#gÌ«`Id ßKD-XûHT±ú…HžQìd[Ïë;'Ûøë¥n—ü1‰ªÞ“ÕÆi/jœ®óÇ{;_…ã÷ƒZŸÓöX\‹?b.®´ ê¿«QÙ_äËó%þ5Üt×õIÿ¥ôs&µüAÚÉciÇUÝ h’NËN SµÓ¤#þvPHDH‰&‡4MÎÒnL˜Ï•OÝ!“è|&%­Ig]‚«îà ê¤ùr endstream endobj 324 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ô37R0P0aK3 …C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÁlƒü†Q3è¸\=¹¹‹iƒ% endstream endobj 325 0 obj << /Length 290 /Filter /FlateDecode >> stream xÚÒ=N…@ð%[l2 G`O h„ŽäùL¤0ÑÊÂX©¥…F[àh…#PRlwgvÆö‘@~ËÇvvéÚ‹¶ñÏîÒ_wþ­Oh»8>¤azðúÇê'ßvPßÅ»P÷þûëçêãÃo >ùçóÃÉceõF4ª‚ˆBHn¥ú, !QiADõITŸÄ!I•Þ›ô=ܲ •EÉs¸g•ˆY}/+̳ òLq+qa­N´XäŽp¶\$F¨ÿkÚU¨ý¢¬_¥*©KÖÙ¡¬½UqO,Ý-ê‰4©¨§,Ùiê‰Tª¨§¬Uö<áÿ Šÿ¦x ç nx„?¡«ÿº endstream endobj 326 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚ37Ó35V0PasC3 …C®B.3s ßÄI$çr9yré‡+˜™sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ„ñÆøcüo€100ÈUòƒŒÿ@ õ  ûPˆ3øúÑ v,ŒÔf [Í=èn†ûæ/¸O¡~0”ñÆ85 †)šˆcp¹zrrÚõÏ\ endstream endobj 327 0 obj << /Length 251 /Filter /FlateDecode >> stream xÚ­Ñ1nƒ0€á‡: ½…”wÖ 4ÈYŠD©†Hí”!ê”d̪™áh9 GÈÈ`ñj°1RaKd}22²äây™PD zŠI¾P"éãeDÝ“¬Ì›ý ³Å–d„b­—Qúù¾Qdo£ÈiSô…ENÜôèÅW§Æ©uâJ3d€”k«¾YA¿¥W©¥í ù©² fuýM¿<7'MÕäž»¥ïnžÚÝ€ASýwMRàö \S¿ošÖ'ðæŠß%u—«vªrChë2<š>úï¿\+#_ç2ò˜o¶cibBרÂ÷?ñi h endstream endobj 328 0 obj << /Length 162 /Filter /FlateDecode >> stream xÚ37׳4T0P0bs3s…C®B.3K ßÄI$çr9yré‡+˜Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(Øÿ‡€D1þ1ðÿo`þÿ þˆÁ`ÿ¡þ˜!ÿ¡žÌ`G0ê æ5#F„Á€ñÊøñʨ †Áe0Œ2¨É`'â\®ž\\TÒË. endstream endobj 329 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚí’= Â@…G,Óä™ è&"ù©þ€)­,ÄJ--mMŽæQ> stream xÚнJÄ@Àñ )Ûän^@“øqäš œ'˜BÐê ±RK E»ã.÷f‘{‘tצÜ"dœÙÙUCPœÀò#»,6?;>ŸA 'p”A~ Ó3ý¢óø›ÎdçáY/J¬ OurE¿uR^ÃÛëû“N7éd w¤÷º\Ò(¥Pæ?RE¯x:¥ ôšˆ «"¤XÔ²êBR$jX´¨ˆ–PT³èˆŠI¨b™&|=v,åU°¶¬¹§nX6zm…ñY‰6^çs²D‡VÍÉý­ÈŠ£9^[q>'K´M¦T#É6ºQôÜ©ÿ¡ˆò×N(ÉöÍ×Î)Æ]ëõñ¥½S„ûÆëàâ¡öB§±ú] Q´íÇ*º¿41cÅíXQ3”¾,õ­þhñÀî endstream endobj 331 0 obj << /Length 232 /Filter /FlateDecode >> stream xÚ}ϽNÃ0ð«J¡l¬ü¹³;Ta?ùìûpÛœ7k©äBÎjiÑÃkÍïÜVb»¹Ì7/;Þô¥­8Üj˜C'Ÿ_o6÷×RsØÊS-Õ3÷[¡&Òå±0’Æ`Q·Ð0‘|T*õM *pŠÓŒ_¬°·ÃÅ2ô $ŠL‡o1ÔJc4|îÐåÝœŽä~82ý;á eSz™ñéºÒ)<Æ8`¯ÍŠN9y{ƒÑ2Êhà›žøål¡— endstream endobj 332 0 obj << /Length 229 /Filter /FlateDecode >> stream xÚÅ‘; Â@†7¤¦É2ÐM4ñÑ(øSZYˆ•ZZ(Ú ñhà̶Ü"8ÎÆP+q›æ±óÿ3Íz­ ‡ ¬ú¶±ÙÁµ;MÐÃV‘Ym¡œc€sd4ÁÃþ¸ÙŸÐ9Ä…Þ¢!Š8üˆ¾Â~Âúƒè̸¥Œ+‘fÜ’^Æ áÜke˜ÄÙ"eš,®”æŸˆÕ tŽÞGd?ÀË„bú›$UÊ5â“ÒŠflì$*lóÞÍMgnó ´C¦JÙæhVÊ·3Ë®FÌàiÔp endstream endobj 333 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚ­1 Â@E'l˜&GÈ\@7‘E±1#˜BÐÊB¬ÔÒBQ°’£í‘R¦gEì…áv>ÿ¯™'SŠÈÐ &3!3¦cŒ4#£Nq›ÃÓõ–ÌõRdÔùŠn×û uºžSŒ:£]LÑóŒ’> stream xÚÅÐ1 Â0à”…·äyдÒ*N­`A'qRGEçx¯ä ¼‚7бCéó=q(8‰òÁ ÿŸv«ÙŠ1Ä&]lwqÁ†Øy,ÖÐËÁN1‰Áy 6án»_íûÍpa8‡•‚&:2)Ñ™¡BztòŸÊU™«ÇUN­ËÇ+æIZÔà^Ü>¡àj©‹$qÍ©ÂÆIMîMRÚ'*ùmseÿ c¨ÒL@… ÜI 9Làwn¶i endstream endobj 335 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚu=nÂ@…gåb¥i|Ï’eÅÒYâGŠ‹H¡¢@T’Djûh>а¥ äÉÛX ÉŸVï½yšyñÏÞËD¦òä%¼J˜ÉÁó™C€8‘0Ï/*v[ ÝdvÕ»\/_Gv‹¥xv+Ù¡hÏÕJˆÊžˆ2Õ†(Wí ¨F¢ºO†¶öFF›l@²Ä&¿%`Ý}b —ÝÈzdüeL,¢>2½¿Ýÿ°~dgygL[41Ƕ¦³Š» ÚÖhKy“êJ BaûsµQø óºâ îDŠ endstream endobj 336 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ36Ñ32V0Pacs…C®B.cK ßÄI$çr9yré‡+[ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ700ðÿÀÀPÿÿãÿÿ?˜ÿ÷ÿaàÿÇÿAþ<ø$ìADýÁÿ‡áÿ0ÁüH0 ¤ÿA6b#È4oˆúÿ@ÁåêÉÈèü®  endstream endobj 337 0 obj << /Length 281 /Filter /FlateDecode >> stream xÚ•‘=NÄ0…ÚÂ’!sH›´––E"Tˆ ()@Ðß`¯ä£ä)·ˆ<ÌØ‹Å$Å'ÏÏ{ÏIן5-5tA§ç-ukZwôÜÚ7Û5¤oßZO¯v3ØúžºÆÖ×R·õpCïŸ/¶ÞÜ^Rkë-=ˆÔ£¶ð„/ÀqZq€gÞ XŸxÂqdWŒjï£Ip‹nIU¨ì¤iÿÀ+ÂÿñW%KK"5²-CiÖKìŒ #;–A˜ 58©E,˜ æ½k΢SvàYlK³ S^`‰%*#ÃGÝÅ4dP€ãã”ɲ€1ê:¼^.ei³À¥üiþ‘C–¨žÌ%ý>+éÁ^ öÎ~ÝèÈñ endstream endobj 338 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ33Ò32Q0Pa3 ²TH1ä*ä25òÁ\Dr.—“'—~¸‚©)—¾P”KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓE¡þüÿOb†PŒF±ÿSöÿ@Ôÿÿ€ÔÁÿÿ©ãìÿ©ó ò ê>ÿ? uBýP?Øÿ©(ÔlÔ¡Dýÿÿ¿ùÿÿø(.WO®@.Jå×m endstream endobj 339 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ36Ô34R0P0b#Ks…C®B.#ßÄ1’s¹œ<¹ôÃŒL¸ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. 5 Œÿ˜ÿ7°ÿ?Düÿ #ˆ P¨¨’¨?Pÿ1ÿ?ÀH{ôp¹zrrÙðD endstream endobj 340 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ36Ô34R0P0bc3K…C®B.#S ÌI$çr9yré‡+™ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ê0üÿ‰™˜qàÿÿÿ7 c.WO®@.„S—œ endstream endobj 341 0 obj << /Length 162 /Filter /FlateDecode >> stream xÚ33Ò32Q0Pa3 eªbÈUÈej 䃹 ‰ä\.'O.ýpSS.} (—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹C}û?†ÿÿìÿ7€¨ÿÿ©Æÿÿ©öö€Tƒüæÿóøÿ10þŸ¡ö@¨ ìÿÔê6êÀP¢þÿÿßüÿÿ?|—«'W ã[« endstream endobj 342 0 obj << /Length 213 /Filter /FlateDecode >> stream xÚ¥1 ÂP †#B–¡¹€¾[¥S¡Vð ‚N⤎ŠÎõh=JбC1&¶ÕE\|>øóó’?ádäùäј†>…c &tðñŒA$¢GÁ´éìO˜X4 "4 ‘ÑØ%]/·#šd5#MJ[ùh‡6%·y=æ\0`..³ªYå°€óßAK<ý@\À@Q‚#6·§-WQwˆu©;Sðwð ÷?ñkB·KƒnÏú•¾ÍÐ&jÑ×´…„–ìùû1³´Áa®>7k.ˆs‹k|]Åf endstream endobj 343 0 obj << /Length 227 /Filter /FlateDecode >> stream xڵѱjAàY,„i|çtïôN´Œ‚Wbe!V&eŠˆÖç£-ø>B|„-¯Xÿ•D„ÄT±X>ØÙeçŸíuÚLéJ+HÞ—,—×”?8»‰ô²¯ÒêGÛ¹äÛ)öÙϲYoߨŽ^ž$e;–E*É’‹±P鑪SݽêT+ðé†(5OTÓ@u%ƒBMwF=p§±ŒºoHý-euŸaø~ÏÿììÒnlÞ]£Tȇ`1æ)†6AâÆ¯bXiú DAãŸü O žñ¥ÜÆ endstream endobj 344 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ31Õ37U0P0bcS…C®B.cK ßÄI$çr9yré‡+[ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êêþÿoüÿàÿÿæÿþÿïÿÿHôÿùÿ¾ü?æÿûäÿ1þß"~À‰`‚ÿãÿì?€ã ÁÀ€L 7ñÿ?Ðbl—«'W n endstream endobj 345 0 obj << /Length 223 /Filter /FlateDecode >> stream xÚE1NÄ@ E?šb%79Âø0;Úì"ª‘–E"Tˆ (·AKÜq­%GH™"б´4o4ßßþv]_ä+^sÍç™k{wüšé6[í{¹T^Ž´o(=òfKéÖdJÍ~|½QÚß_s¦tà§ÌëgjŒ8êU•ʇ R:EZ Ê·cªV¢ÿG@­‚V‡•ŠjçU'Øø„3r¸Ø¹Ó–½µ—£å:ªÓ ¾Fg ñ¾©u·Ð1Ìv¥Mª#†bj¿2;Ý4ô@¿* endstream endobj 346 0 obj << /Length 173 /Filter /FlateDecode >> stream xÚ31Ö35S0P0RÐ5T0¶P03VH1ä*ä26 (˜™@d’s¹œ<¹ôÃŒM¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Œ°ÌXv8Á'äá„=ˆ¨ÿ3ˆàÿÿÿÃ,X  wˆ'€þüÿùC=„`?À`ÿƒ¿Aþ<Ø7@ïÿÿ ¡ÿ? ærõä ä ,t endstream endobj 347 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚÕÊ+Â@ài*6Ó#0€í6ÝÚ&¥$¬ … (ŠD@@/G[Ç5ê°8¤Ã‚¨Á£¾ü"e9¥”ÓÐP!Zj îÑZ)%Ÿe³ÃÊ¡^’µ¨§R£v3:N[ÔÕ|LuM+Cé]MàD Ì!æßÄ a9PIÒcУd€/-x>ƒo£;wàê*”Ì!aVBÌÝð7õœ8\à ¦ä¤d endstream endobj 348 0 obj << /Length 216 /Filter /FlateDecode >> stream xÚ}Í=jÃ` `-¾A¬䳋M)˜òõPH§ !SÚ±CC ÉÑ|”Á£'ꫯ¡¸’oþ4J$ëüQ²LÞSþâ<ÜØh‡õ'+v É3v/ز«^e»ùþ`7žO$e7•e*ÉŠ«©¨*…ÚÝ#ÐÑ3‘Q€Æs;Ðþ*ÑØ— ø‰/‚Ô@iàh#2ê+1@îð„[|áiöÆ¡ÙyÚÖ(ÛÆsöÄç“G=‘Ö· ·G¨Ô#¸ô¡î–ʳŠßøà•pH endstream endobj 349 0 obj << /Length 276 /Filter /FlateDecode >> stream xÚÐÍJÃ@ð 9æ’70û&‘ÒXµ‚9zò žl… …¬oè‹ì­×=¦3þwÛR<,û›Øù¸ÌÎg¹ÊÔN1S“‰ZæüÆÅqæB—xyåyÅé£*¦œÞâ•ÓêN}¼®8ß_«œÓ…zÂ7Ï\-”HŸˆèDìHC¥!Ú—%ZCÆ«%‚\Ä:Pm)î(0#µ”tB%ÔSØ@•=ER¥P¤GêéK(†b'$´GWP$d¥9óÒG…òmêæj9h m @¶Mi×^»£Hv:±vP{*ì½jÔÿ1ƒÄËuŒEü!7£è±blEèDna^ÔŸ(ôûö¯n ¾©ø™¶… endstream endobj 350 0 obj << /Length 267 /Filter /FlateDecode >> stream xÚ}ϽJÄ@àRn“7pî h~˜(Âb`]Á‚Vb¥–ŠB !y´ø&û)Sdw<óƒd„>¸ÃÌ™SŸ¥äRÊq™Ku&ZËsÁo\iLs9Õáèé•× g÷Riή1笹‘÷ÏÎÖ·—Rp¶‘‡BòGn6bŒ¡ØÌÿ™-Ñ‘eFGZ0ý‚Ucc^ÏpGí))€¡$ ·ô)ˆY†€È=ò ÜÆ¯ã—¥[Ç4Yêitìj·uGj†¿ wAlhA´_Bóí“gô6U¹ÊT÷¶2uƒ­Œ¶2H¾–òø’ƒo÷í^î_Ë„>áë>ƈ¯¾ã ø‹ endstream endobj 63 0 obj << /Type /Font /Subtype /Type3 /Name /F31 /FontMatrix [0.01004 0 0 0.01004 0 0] /FontBBox [ 0 -21 84 70 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 121 /Widths 351 0 R /Encoding 352 0 R /CharProcs 353 0 R >> endobj 351 0 obj [56.01 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 31.12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 84.59 79.64 80.91 85.86 0 70.42 88.05 0 41.72 0 87.71 0 0 0 0 76.53 0 83.56 0 77.91 86.09 84.59 0 0 0 0 0 0 0 0 0 0 54.46 62.24 49.79 62.24 51.11 34.23 56.01 62.24 31.12 0 0 31.12 0 62.24 56.01 62.24 0 45.75 44.19 43.56 62.24 59.12 80.91 0 59.12 ] endobj 352 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 46/a46 47/.notdef 65/a65/a66/a67/a68 69/.notdef 70/a70/a71 72/.notdef 73/a73 74/.notdef 75/a75 76/.notdef 80/a80 81/.notdef 82/a82 83/.notdef 84/a84/a85/a86 87/.notdef 97/a97/a98/a99/a100/a101/a102/a103/a104/a105 106/.notdef 108/a108 109/.notdef 110/a110/a111/a112 113/.notdef 114/a114/a115/a116/a117/a118/a119 120/.notdef 121/a121] >> endobj 353 0 obj << /a21 317 0 R /a46 316 0 R /a65 318 0 R /a66 319 0 R /a67 320 0 R /a68 321 0 R /a70 322 0 R /a71 323 0 R /a73 324 0 R /a75 325 0 R /a80 326 0 R /a82 327 0 R /a84 328 0 R /a85 329 0 R /a86 330 0 R /a97 331 0 R /a98 332 0 R /a99 333 0 R /a100 334 0 R /a101 335 0 R /a102 336 0 R /a103 337 0 R /a104 338 0 R /a105 339 0 R /a108 340 0 R /a110 341 0 R /a111 342 0 R /a112 343 0 R /a114 344 0 R /a115 345 0 R /a116 346 0 R /a117 347 0 R /a118 348 0 R /a119 349 0 R /a121 350 0 R >> endobj 354 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚ32Ó35V0P0b#CCc…C®B.C˜ˆ ’HÎåròäÒò¹ô=À¤§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒýƒúõþÿ€AÏþ—«'W !‘$‡ endstream endobj 355 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ}É+€0DQ?«˜ðúÚ4TóI¨ … (@" àÙy!Á#®9×i •êisZÇE±Ãú Ã7æ E„ ´Ò0@bËó¸VHÑ•THÅQi&ÄŠ)¥û/Ô=–Þ-˜ endstream endobj 356 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ31×37U0B#C #…C®B.s° 1D"9—ËÉ“K?\ÁÄœKßCÁ˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEá?üC&¹\=¹¹J®# endstream endobj 357 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚÕ1 A Eÿ²]¯8;êÀvë N!he!Vji¡h«{´9ŠG°´ãd±QÄÞ<~~ „¸~·p\p/•³ìJ^[ÚÑ L}¡­V[ª™9J2ãä’ >ì2ÕtÈ–LÍ ËÅ’BÍ@.ÀY®*åtÀßà“}4˜I“½¨™kÆ\Ðê7B <µÄ/z‰¢ñ…íž¿aúš×³?I£@3zóպà endstream endobj 358 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚ}бNÃ0€á‹ó[ñòŽ«í#•Ú[wж¾£¯Ïï7´«ûkÊÑ®é)§ìë5€Ú‚,ÝÇH‡Y˜1Fu˜EÃ1˜Û$Ì`„Ú³$ª] ½ciÕÝiÇ’˜¶MÓ6Òj T§Ä%˜0Òú©`t‰è)ßšô »µýÚ£Éî§ûì0„R7¡ ŒÇ’A¢«Ó\—þt‚‡dèC@ëf;„wÛ€75>à/G°ž% endstream endobj 359 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚÑ= Â0àJ‡Â[rß LK©¥S¡V0ƒ “ƒ8©£ƒ¢s{4Ò#tìP“ö¥qj |ä‡÷Ã[Æ‹$Dõ^†Åx àQ¢Î¾>ê‡ó 2ü€Q|£n‹->¯+ðl·ÂxŽÇýˆ¥^oÇémIiTEí¸²êud=X4ƒi;87v¶LNó7މoò™üTÏŒêd²T}Xö÷_õ§—QOË^Wþo5Q;ŽG2Ê7öOõ×Ò<êq.ÖœÔWX ØÃuRÖä endstream endobj 360 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚ½‘=NÄ@ …¥ÉÍ!¾L"±ËnC¤e‘H¢J ´$GóQr„-·­ñŒ7qF}#[ãŸ÷–«Óõ9Õ´ “†–g´XÑsƒo¨¬Sxm™§WÜtî5áZúúxÿ|Á°¹½¤Öª±Û´ (E¸TV";§‘èYäepšÒ{ðJý¥9†~P(eÔRÂé™XföìdH-Ø ÌXq*óKÏíÄ8§ãþ/÷ü§~ÖbyœoƃÑöq?´}Ý`ôƒéáÁô©ÀôºÓïëØ0fW Ø';´¬jœô÷#˜©†úcŠÍªþyÄ< ^ux‡ß³ = endstream endobj 361 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ37Ö32V0Pa3 Ss…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ@˜þ¥ÿÃè õ?ØÿÓp,ÿBóÿ‡ÐÌ@@4#P2Íðÿ„®ÿ€JÛÿ@£ÿ@hytúú?iBöÿAu?œ†ú«þª¿aá¥aá ?öÿ¨á[ÿþ°ø@‰Ÿ?P\®ž\\2oÉ™ endstream endobj 362 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ}б Â0à+Â-}½'0­Út µ‚ÄI‡‚¯ì˜¡Û¤…¦VÇÇår~>ÅS hR(Šéâ#^ô¦-Ç &ÙŽ"ŽlUÜ"“kºßgdÉfA!²”ö!”)isÞÀKT •¡oéY<py~# ³ˆ?@Iæz­S=©Z¿ˆ¿‹Ah1s–Ì!oâ9)ù–¹ÁÓʦ«:#Ç¥Ä-~·Ê endstream endobj 363 0 obj << /Length 159 /Filter /FlateDecode >> stream xÚ33Ð3°T0P0bS3Ss…C®B.S# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÁ¬CýfÅPÿLÉC(~ÅŽB1£PŒX© ª‚Å€Dý@¦!;˜úÿ7UÓ€j š ø(ÚP °ÅEq¹zrrco©· endstream endobj 364 0 obj << /Length 262 /Filter /FlateDecode >> stream xڽѱNÃ0à«2Dº%à{p<¸-“¥R$2 ÁÄ€˜€‘súh~”> stream xÚ37Ñ37V0Pas#Ss…C®B.3 ßÄI$çr9yré‡+˜Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÿ‡H|ÀÃ`¨ÿÁÀÀøÿÃÐdüŒ!íAœ b"—ËÕ“+ ¸0Õ endstream endobj 366 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ36Ó32T0P0aSs…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…h 1±\ž. ÿÿÿÿƒŒê0 uŒî'.WO®@.•õy9 endstream endobj 367 0 obj << /Length 138 /Filter /FlateDecode >> stream xÚ35×31V0PaScSs…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þVŠ¡þÃ0¤ØRüPŠ %BÙ£Põê?˜b„PÌŠÿ˜ªÿÝÿ8(.WO®@.‹† endstream endobj 368 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}Ò±jÃ0à·è ì{‚ʦIëBÀ¦P…vÊP:µ;´´ÒÁ~°~?‚Æ &×S !HÁßIËwWÅÙÅœ :—[U4¿¤—ß±šI_„6|<¿á²A·¦j†îV^Ñ5wôùñõŠnyM%º=–T> stream xÚeѽJÄ@ÀñYR¦É#džÀMü¸\·pž` A+ ±RK EA±ˆ¾™¾I|ƒ³Sˆgwv/'W,üfþÅn³¿ÓìQEþ4»tÐÐuw8›Ë\ùÑ/®nqÑ¢=§Ùí±Ü¢mOèáþñíâôj´Kº¨©ºÄvIÌ@ƼÚÀ˜À èøU´Á;€é=zÅ‹¬ž'|+ž|1 #G”R (¤ø¹¤2))€RT¸58BÒ )*¤¨¢BŠ ˜0Dtc„㈒ß(rþTd¾†À¿á±<\B¹…"!OÈL¬ÑmÁ%”‚Á£è!ü)ä Y‚Ùµx†n«Äº endstream endobj 370 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚµ‘1NÃ@EQ Mã#ì\Ì*Š •¥$\D‚*J(SAíÍGñ\º°2üñÈ "JË»Ïþ£ïÿÍã]>‘{™Êm”,—éƒ|DÞr!B~ôÊzó’Ó¥d‘ÓÈœ– ùþúùätöú$Pçòϊ˹‘vdW¢º3Vª-p¥uèÁµ›/ˆ «Æ—=›:Ô`Nzº¸wÏèʼn¬8røöØ,œÍVÃpÚž£¯Ý¥xèçóœðdnÿ¿&8둉ç°;æb9©•ßÞ³µ0ÔrEÓªõUXîЂyjóÖA‡^ªýŸó:œŸŸ'?—üÆ¿°ÛÈI endstream endobj 371 0 obj << /Length 233 /Filter /FlateDecode >> stream xڥѽ Â0ð‡Â->Bï4bÛ­àØAÐÉAAëækù(>BG‡Ð3͇‚uP=¤òAYý‡Ú¯K]¹k̵ÚpÍ&ŽËœÛÈ…MšÊgd ŸÎoç°Úk|x–¯pÿ +‡Â@Zä/0ƒ´d73(Mº\5|¢³3¿WU =e0ƒ>¬ß endstream endobj 372 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚeϱNÃ@ à?êÉyƒÆ/iJ"•¥‘J‘È€D'ÄŒ X{÷hy”^åc¡¯êŠ™D5‡=îþÙü:þé§“ÎÇ|ñ_.þ(Ø_’ IŸ˜4B±±ÌCjÑz8½–nZ:Ð7¡6 endstream endobj 373 0 obj << /Length 152 /Filter /FlateDecode >> stream xÚ33Ó31V0Pa3cS3…C®B.SK ßÄI$çr9yré‡+˜Zré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿƒANúÃÿÌÿêi†úõ Zþ@ˆæ‡Ó5`šNW€ifœôýà˜fÄI3€i0™4?(pÓ\®ž\\wG³æ endstream endobj 374 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚíÑ1‚P Ð’.^@?'ILtr0Nêè ÑÍGã(ÑP[ˆ‰““£Cû_Û´Ë‚Á0$êûy4Šhïã CmJ9î&»#&š5…!š¹´Ñd ºœ¯4ÉrJ>š”6>y[ÌRbæ\æò €[B§øãgpq ‰¸þD¬…b¢ ¤û7 ›%é¸ÇXzÂ’¯²+pîC‘7 M=$¿©¯¬qÓ˜«ŽÀY†+|œ¼T endstream endobj 375 0 obj << /Length 271 /Filter /FlateDecode >> stream xÚ}нNÃ0ÀqG"Ý’GȽ8‰DÃÔH¥Hd@‚‰uFlU›GË£¸o©‹‡¨ÇÝÅ|4RâülK§¿\•ç%æXâYUŽ>ð³Šy{9Þ<½Â¢û€³ ì ƒmnñãýóìâî °K|,0_A³D"êMLäþá¿1 /äΘ­¢c Œô/jEË802F¦x©åZ0WðýFf ÖÇàa2+x…3‘ ô .Hbìþ‰‚[¥TS'J &f N”@MüA­àÖy@»Qpâ: œèÜ7v#"Úõû†ö.€¶ÔBMíúŠGH'‘ SÄ~ }J× ÜÃ2ÿš` endstream endobj 376 0 obj << /Length 345 /Filter /FlateDecode >> stream xÚÑÁJÃ@à 9ö’7èî hšÒÒZÁ=yOêу¢ÐC1yŸÄCÄYðrkKÆ™ÝMEÛƒ·YþÙ?[Ï'j¬&ê(UÙ\Íæê."›Òp¬f ÷rû –¥H®T6ÉERž«ç§—{‘,/NT*’•ºNÕøF”+…ˆZ"(ÐüǶ…€Wëžœ;ËÁ÷ b#yí6ì sû"¶ßÇü¾ô£s¨Ý>‰Âæ·yGA¡¢Ú9ß¹±ŽÉ!yCacp^Wƒµµ$ä–ެÛéà ¥°¹·–ƒ;ë »êBú9>׺‰vݱ Õ°µî,û˜ü¡½)”7²?­c”䝯yD¿‘·Ö¾S¨míL?h:ƒ3E©öX÷ÞCÛà›7ÞÜÈWìΛÛ9à‚i÷-ÙÚ›CyÛvø,qZŠKñ ydõ• endstream endobj 377 0 obj << /Length 199 /Filter /FlateDecode >> stream xÚuν Â0ð+„[ò¹'0­~€ÄIí›™Gé#tì =猪‹!ùAþ¹—úù€RÊÉG4Ó!Ã3vYªW}ØŸpR ßP>@¿}±¤ëåvD?YM)C?£mFé‹AhÀ0W–¹pµ•(Ô†Å&áRŽ_ïÕGW«¶RM©Êú1|šŠw5áFò—ú«ýö ]Ÿ÷æ·ñ¯¬5IW¦†º'C»§{p´Ü:ކ«ƒV†#Î \ã 8.y endstream endobj 378 0 obj << /Length 191 /Filter /FlateDecode >> stream xڵϱ Â0ÐH†Â-ýï L«–ºj3:9ˆ“::(:·ŸÖOÉ'dìP{^ŠCEœÄ<¸Ü%¹$“Q”`„c^ Ïc¸À4å¸ }âp†Ì€Úâ4µä]Pf…·ëý*[Ï1•ã.Æh&GA‚}1è”t@%’c55lË)É1•’¬(*ÉÚúzí¼Ãºgã û¶?øqÛÛ[®ë„­Da_½=@ÖMÐ é4ÕBÚ3²ò'`a`Otí„€ endstream endobj 379 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ•Î; Â@à )ÓäBænbÄ*#¸… •…X©¥…¢­Ù£å(9BÊKÆY#X[Ìó‚?›M³ŒbJ]-(Ó9Á¦¹ô±kÝâtÅR£ÚSš£ZË•ÞÐãþ¼ *·KJPUtH(>¢®> stream xÚµ= Â@FR¦É2'p³$!vÁ-­,ÄJ--­o–£è ´‹dœ±ò¯æÁ·3ì<6{AŒ†\±Æ¸+ [ˆÎDi,7P3ŒP#¾eƸßÖ ²É5¨çƒ˜->E) ït´ÿD›ŽL®Ì”Z&U¼×!˧Òm,—J¯¿–yÿ"LŸXœÞI?ðåµ]ìÀ&^-Vìæ±gÇž·Zêø¿n$ù̴ɦ†¦p h¥Á endstream endobj 381 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚ]ν Â0àS:wÉ#ä>m©Ð± ì èä Nêè (¸¥à‹õQò3ã­ þ\È'›3ʇEÁ)çrFçï2:RÞߥ}ì¶×”¬$S2{ZÏù|ºì)/&œQRñ:ãtCuňCèà:DávG|‡iÊFy”­öÐV;¡tPo¼0ðáƒÌ7ÀæÙ÷âª{äKxÕNÄ. P¡5­ô €’’ÒÒ‚¦5-éQle€ endstream endobj 382 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ3²Ô3´P0P0a S …C®B.c ßÄI$çr9yré‡+›pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä?000þÿÃÀÀþÿ?÷£¾ÁþÁÿ†ÿÿŒÿ¡óFÁð¿FØ1 bˆÿ ÓÑbõÒøÿÿÁåêÉÈŽXo5 endstream endobj 383 0 obj << /Length 264 /Filter /FlateDecode >> stream xÚ…½NÄ0 Ç]1Dòropõ @ZµU™ˆt`b81#æô x¥lŒ¼B$€Ž7œbì´Bb"Š~±ì¿?â¶?é;ª¨¡ãº§¶§æ”j|ƶoE]·„îŸp3 ½¥¶A{)~´Ã½¾¼=¢Ý\ŸSvK»šª;¶rJ“€xþâP0ów4Éð{\í .c9ØNø]ÿ”"ÿßY¹pÒ&Zm­¬m¥1¬˜÷BÏ`­XëX Ï2ÝÌ1Ï2s–Pª)£Ö—àH˜²r”Á€—L¥5ø1ýÒýáU¥—Wôš[$ÜtUòÝ’ŒáYņ'¼ðr˜Ô endstream endobj 384 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#S …C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ3Á$;˜d¦%YH2ÿÿ$ùÿÿ’ò@Aæÿ6Œÿ˜ÿW€É òÃÿÌÿ ‘ H$Ã’ÿÿÿ±ÿÿ“ärõä ä WžH endstream endobj 385 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ32Ó35V0Pa#SSK…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒØÿ0ðÿ!ùÿ("”ªÁþ3Ô#!öÿ ÌÔFÿÿÿ€#.WO®@.Nq endstream endobj 386 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32Ó35V0Pa#3S …C®B.## ßÄI$çr9yré‡+qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ3üGBìÿ˜úÿÿq¹zrrÊWù endstream endobj 387 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚÝÍ= Â` àˆC!‹GhNà×"Ú ‚ ì èä Nêè (¸µÒÁkyo =Â7:”¾¦ÅÉÁ8„<ù! úín(žt4BMl}>pÐÓº.«ÁfÏ£˜ÍR‚›©vÙÄ39Ï;6£ùX|6‘¬|ñÖGB%%9µ "” 4Dªrr•{Ef‡V5 ÜR×’S^r_Ô,µÿ¬¥»IQiâNÉë[)%ö[ôyü/ Èû[<‰yÁo¨Rµ€ endstream endobj 388 0 obj << /Length 151 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#cs…C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ1Ô`øÿùÿ Éÿÿ”gþ$mÿ7°ÿ«’Ìÿ>0Éÿþ`þ‰l@"üÿÿýÿÿ˜$—«'W Žá‰ endstream endobj 389 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ31×37U0P0bScs…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Œÿ000ðÿÿ$ëÿÿ’ÿþ700ÿc°ÀÀþ‡Aþÿ2 \ i$Á €Êêäò?ˆl •Ä4b>Ä.dÛ!îp!îdræ~ùÿ€$Ø_\®ž\\-in« endstream endobj 390 0 obj << /Length 193 /Filter /FlateDecode >> stream xڭп‚0ðš$·ðÞ h[I;˜èä`œÔÑA£3>Â#02Î+šhÔM‡þ†ûúçK£`¨#Ô8Âc¤1ˆqgàaÌSQðˆ¶H-¨†1¨ÏAÙ9žO—=¨t1A*õA½›¡ ]‘O›Pö±’JA…äy)Iˆ¼r&õÓ~ó®ßþàÇmý—·’ªkÂ]Ÿ{77”Ôx­Ü¿f}N$¹nýCâù&L-,á‹ endstream endobj 391 0 obj << /Length 144 /Filter /FlateDecode >> stream xÚ3¶Ô36V0P0bcsJ1ä*ä26òÁ" ‰ä\.'O.ýpc.} (—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹Ã?æ ÿÿñÿöÿDM}Ãÿ?þ`ÿ÷áÿæÿ@Ä8ÑPß$쀈` 4'þÿÿ‡Ap¹zrr8WÖ endstream endobj 392 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚ%Œ= ÂP„7¤¶ñÙ˜„‡Æ.à˜BÐÊB¬ÔÒBQ°“£y”á•[„ŒûHñÁÎÌθb2+$˜Š+ä’ó]n: 2ç/*NârN7ærZmåùx]9]ì–bîJŽV9qµ*ý> stream xÚ36×34Q0P0bc#Sc…C®B.#K ßÄI$çr9yré‡+Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ø0°<¶‡âz þÁŒ@ÌÄòÿÿ?ø„™bTÂðÆÿ ÿ7~`øøƒýÿ@Ç400ÿcàrõä äÎpR endstream endobj 394 0 obj << /Length 149 /Filter /FlateDecode >> stream xÚ35Ö30U0P0bS#cs…C®B. ßÄI$çr9yré‡+˜Xpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ30ØøÿŸÁþ?’ý?ãÿÌ@5J2"‘Ì0’ñ?;ˆlàÿÿ¨Ìèâúÿ€¤üÿÿA*þÿçrõä äðŒ endstream endobj 395 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚuαJÄ@à9R,L³opÙ'p=…póSZYˆÕ¥…¢pE ûhû(û{]Ä#ãÌZ˜F˜ácfø«Ë³«Ú朻ªÍEmö%¾aµâ¹Q»WÜthMµB{Ë[´Ýùxÿ|A»¹¿6%Ú­y*MñŒÝÖ‰\Kÿ©&Ð#d!#P¬OIÇ*¿ —M «D // R2h‚``ÝRÌ“m\®ùÕ‹ãzð=@>6m8ˆ}F}:ä1Μ¢>²Šý ,EýÍfù¹œ‘]ˆîO Î sSq0€iî ›TxÓáþ¦‹j endstream endobj 396 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚeͱjÃ@ `-~„ÓôìÆ&lpˆ‡B2e™ÚŒZš-?šó&†¾ÀA–Œé– î㤻_*³—‚2z•S¼ÑbI_9þ`QJi©ŸßØthwT”h×ÒEÛ}Ðßï鈶ټS޶¥}NÙ»–˜a÷lÌ}ì!â!xHĢ µK{Ñ0S%¦ÓYLæIŒÙ±„4¬^½vA:ÓCžõÿ5ûÏ2?¹j,TÓkØ„pÂgÙ àe3D^63ÔìŸÅU‡[¼}l* endstream endobj 397 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚeϱJÄ@€áYR¦ÉÜÎ è&^¢‡óSZYˆ•ZZ( Wœ$/%ñEò[nnœYäÚ|Å,ü3[åû%åt@{Å!•Ç4?¢ûŸ°¬dšS5ÿ}º{ÄeƒîšÊ ݹÌÑ5ôòüú€nyyJºÝ”ßb³"fo8ü7a êLìàŒ¸{؈kq€ÐàEoÄÚ›A ª I¿sLÅlL;q›‰é6‘­˜ð,ú)þˆŽ"pøkë'ëaÒö“šß “6ª«jùTº…vûMtÕ%ü¥yþÖpû®É7«±šc%^–Æ ð¬Á+üš~oì endstream endobj 398 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31×37U0P0bCS…C®B.cc ßÄI$çr9yré‡+sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€ÀDübvQ$þÿG%úAüȨÿÿÿÁåêÉÈB•\ endstream endobj 399 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚmÏÏJÄ0ð¯,Ì%ÐZ%c‹ã7¢â!¿02I†ñ|ÜøÖÛz¿ü¾“éGÆ­…Vx|–í,ÍïGi®˜•f¾ö‡×ã“4Û› ßI³ó÷odÞy¸A# ÕŒJõ—&E½8]&”ÃRj ©Ð¤ šÙõKXÿ™"9ãØß°öC¯ú"‚ãƒùÊÞáN¤¶¶šàžç‚ +–o¨q‘Ô ™€ï@æF2ŠÌÏh.ÊpFmLF IÿA.g¹•OÕ¬—´ endstream endobj 400 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿbaš> stream xڕϱ Â@ à– Yú6O`[¼Ò¥T¨¼AÐÉAœÔÑAQèP°ÖGé#tt«—ªtò $áB¢ÓyšpÄ :áDó%¦;騿‘¤Ò8ߨ0XÇnl•B³åçãu¥°Ø­ØVK>Ú/'2%;ŽãµÇÀ%|ÃAtG*èA0‡¬`/ºPu°½Fô19€9¬a{ÑíDíªb#úØj3XÃä5S¯øS… imhO_o`{ endstream endobj 402 0 obj << /Length 229 /Filter /FlateDecode >> stream xڅϱNÃ@ `G"yh_éüp’([+•"5:T #Ö^í%pcó»He``ùÛ÷û\·wm# iä¶”º’¦–ç’߸jQD¹ùéœ^yݱßKղߢ̾{”÷Ïöë§{)ÙoäPÊâÈÝFnˆ(ºžŠèF Ñ©j…Àd|ÉŒL@Àä6ììmБÜT /åˆõ¤sg`À|¸®Œ¿8c†Â¨Ò’5 MñÃÙâ—”i\Qn+ ¥yrŠevœEs¬á‡Žwü Ô4„s endstream endobj 403 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÏ=NÄ0à¥Mã#x.N´ŽV[YZ‰HPQ * ¤Aíp³%G0¢ÀE”a²» ÍgûYš¿<]6\±ç“š½çÆóCMÏ´XiXqÓì~îŸhÝ’»áÅŠÜ…ÆäÚK~}y{$·¾:ãšÜ†ok®î¨Ý0`2™€R¤Ó—é†r@ìŠI…ÀærBÈG£b¶dÅþ2lRÌ“V;äxFïò!#äSòÕI§gìµk4I±Yòžñ€;ý!þGøaÜbóžÝ¸óài^aÐeb_È»î+:‚¶‡ÑÚ(4¢ó–®é–•™ endstream endobj 404 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚϱ ‚`ðáÁ{2As‰3È!¨©!šª±¡(hˆôÑzÁñĺïŒt©¡~Ãÿ8îÎûa@ ¨ç‘R0¤‡Gô=9›Îö€qŠîŠ|ÝÇè¦s:Ÿ.{tãÅ„8MhÍ3L®±â“+ÿ"dL-V¢K±x{°pprm î%@%*­!š¥ÞiÉfúÈ£ú1ƒÖºÕh¬´fG«£Ý¨ZŸFéȶ> stream xÚEÐ;N1 `G)Fr“#Œ/³£Ñj«HË"1Tˆ ()@PgŽ–£ä)S„{Aló)Çù“iw¹›iC]Œ4M4Oô2â;n÷²¸¡yþÝy~ÃÂÃm÷8ÜÈ2Ë-}~|½âp¸»¢‡#=Ž´yÂåH`xpœv ú$¸ä"¸,t¹?“”¬¥JIÏRÜsTR/´°vÌ „ –å6£#`f€ÀÁ3G&û-Û]\\ò\´Eõ«åV>R®ô­tŠUÌ?p¦²"ÅFÏ ¶ø¿Ìò¢!ÚS‚S¯`% ^/x?}Ï“… endstream endobj 406 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚmÐ1NÃ@Ðo¹°4°s°­ØŠR­‚„ $¨(U ¤A½¾ WñMØ#¸ÜšapJ‘æ³Úù·]_®;®¹å‹†Û–»–Ÿz£ÕƆ5wÝádÿJÛžª^m¨º±1Uý-¼¾Pµ½»â†ª?6\?Q¿cä Ài‚&dš r¢˜†2!Œ.ÁG?pS8’ôÈ|9‡]ó'ø?‚XP‹T)æL%—ü[2Õ/±jNl¥›þ§”>9Û’¼5þ‰FX ü”éà¢=Ø … Œ–W¨UÊUG@—˜ºîéž~Uí–Ž endstream endobj 58 0 obj << /Type /Font /Subtype /Type3 /Name /F29 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 0 -17 97 59 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 121 /Widths 407 0 R /Encoding 408 0 R /CharProcs 409 0 R >> endobj 407 0 obj [47.75 0 0 0 0 0 0 53.05 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 31.83 26.53 0 0 47.75 47.75 47.75 47.75 47.75 47.75 47.75 47.75 47.75 0 0 0 0 0 0 0 72.2 67.93 68.97 73.23 62.74 60.09 75.08 74.73 36.21 0 0 57.43 90.65 74.73 71.73 0 0 71.62 53.05 66.43 73.46 72.2 98.72 0 0 0 0 0 0 0 0 0 46.42 53.05 42.44 53.05 43.77 29.18 47.75 53.05 26.53 0 0 26.53 79.58 53.05 47.75 53.05 0 39.33 37.67 37.14 53.05 0 68.97 50.4 50.4 ] endobj 408 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 28/a28 29/.notdef 45/a45/a46 47/.notdef 49/a49/a50/a51/a52/a53/a54/a55/a56/a57 58/.notdef 65/a65/a66/a67/a68/a69/a70/a71/a72/a73 74/.notdef 76/a76/a77/a78/a79 80/.notdef 82/a82/a83/a84/a85/a86/a87 88/.notdef 97/a97/a98/a99/a100/a101/a102/a103/a104/a105 106/.notdef 108/a108/a109/a110/a111/a112 113/.notdef 114/a114/a115/a116/a117 118/.notdef 119/a119/a120/a121] >> endobj 409 0 obj << /a21 356 0 R /a28 357 0 R /a45 355 0 R /a46 354 0 R /a49 398 0 R /a50 399 0 R /a51 400 0 R /a52 401 0 R /a53 402 0 R /a54 403 0 R /a55 404 0 R /a56 405 0 R /a57 406 0 R /a65 358 0 R /a66 359 0 R /a67 360 0 R /a68 361 0 R /a69 362 0 R /a70 363 0 R /a71 364 0 R /a72 365 0 R /a73 366 0 R /a76 367 0 R /a77 368 0 R /a78 369 0 R /a79 370 0 R /a82 371 0 R /a83 372 0 R /a84 373 0 R /a85 374 0 R /a86 375 0 R /a87 376 0 R /a97 377 0 R /a98 378 0 R /a99 379 0 R /a100 380 0 R /a101 381 0 R /a102 382 0 R /a103 383 0 R /a104 384 0 R /a105 385 0 R /a108 386 0 R /a109 387 0 R /a110 388 0 R /a111 389 0 R /a112 390 0 R /a114 391 0 R /a115 392 0 R /a116 393 0 R /a117 394 0 R /a119 395 0 R /a120 396 0 R /a121 397 0 R >> endobj 410 0 obj << /Length 327 /Filter /FlateDecode >> stream xÚ•Ó¿j„0Àq%C ‹`ž *½B]®W¨C¡:”NmÇ-ív¨–GÉ#dt—&æ—?RiDø¨ ~ýi]_\V´¤;½×WôzGß*òIê’šMš ¯dß‘â‰Ö%)îôYRt÷ôûëçû‡Z‘â@Ÿõm^Hw ‰YmVìaܶb«Nß4RbÕXM›Î”\u®N›n•ònbÁý |ä± –mˆœbçÞ©¶‹LEæ´]$â±±7æ!3äi»ÈlŒzçÚ.2Ob'Þzº>¸Ñƒtî!ò¸´—Æ9™7Ê ×˜CîÒ.Ík&) 7L³Èʬ ¦k–üÓùì“ËõÁóÇ Á͹!¾·!×Kk¹KÛøÌ!×#°€Ü¥m<æá“ÆÌþçÎFkó(­°¿4J@?û¯ÉmGÉ/ðc ¥ endstream endobj 411 0 obj << /Length 267 /Filter /FlateDecode >> stream xÚµ“=nƒ@…Ç¢@šfà9Al%"’C$SX²+V*;eŠDI£pJ ÄzÖ°òÚîÌŠÕ·üì›y^çOÏ‘=“Jftˆñ“ˆìॽ±ÿÂEŽzKI„zÉWQç+úýùûD½X¿QŒ:£]LÑæ™óÑ@G¦j…ÌQ¨P¦˜ÚϘº§‰iz‚ÿVÈ8Jy›Ž¦<_’â­oSÈr¡ûºãJ^CoC¿âÁàK(®¥vR“ਾB,á|.ÅÝÚWK¥uÅÉ¡Ë`DuO6®KNý™‡‘¯6‘_i JGãT+É­”´ ç¤KP±„û²¡J¨ðÿ~ ßsÜà uÍyë endstream endobj 412 0 obj << /Length 338 /Filter /FlateDecode >> stream xÚÍ“?N…@ÆgC±É6½€QãÚ¸Éó™Ha¢•…±RK vF8Þä%^€’‚0Îì ‘¼Z ø-;;3|óqvrX”ºÐ§ú ÔÆhs¤ŸJõªL¡ù6Ç~çñEm*•ßiS¨üŠ^«¼ºÖïoÏ*ßÜ\èRå[}O‰TµÕ@W‚€dªR‰ˆ;Ȉ,Q–ˆG¨9ÛCi ì7rXKËä0—Aà@$ˆs;’²º:ñ>GOÔ11PV¨GG’ª à{ ré(µëÜ‘  J}1*7S(»$;SheIÙLõ>âoúCø¨^¥f­i0Ó¤ÚÙIñ™Î§ÉÌô¬ð§ Cœ4ôqú¢ŽHºèG®¹‹nJÛè°¬‰®³œcÔC +{ç7ZÛÎÛ¶>»ƒ Úà¿¢‹*E!¼Õe¥nÕ/ÙÏíã endstream endobj 413 0 obj << /Length 258 /Filter /FlateDecode >> stream xÚÕÓ1nƒ0`£ ‘ÞÂx'¨¡b€ ‰¦R"5S†ªSÛ±C¢d†£õ(9BF†ˆcWæGµR¦Z}lÀþ_ÇYÂ1§æÈSÎù#¡=e¹éÇ}·¿ñþEeEzÇYNzm®’®6|<œ>I—/Oœ^ñ«™æª‹kªo?nÁ‚>ƒíCK¹(Iç¸ÖªoïÐv^سs`'rVr\wƒ Iã‚—ý˼ÏÞ‹‘/ÞÁÈí¤íýênp=g¹ÇÍ?ôÿ;³†¸ÎØ—¹=Å  13èr…Ù‹ “E7™ÛòŒ™ÇZ€1µÓŒk kmªgjÖ.=W´¥€Ms³ endstream endobj 414 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚ•Ò= ð×t y G('«Æv3ñ#±ƒ‰NÆI4:—£õ(ÁÑIÓ¾ú¤H~…þi¿ÕE[ôLK;¶nc<`’˜ïgØìq˜¡\Š$A95½(³™8Ï;”ÃùHÄ(Çbe–Yc6º,wh*àúÀ´.9)"1RH HP+wh ¾yÅ›(¸/*±†øPè#qRDÒ¥LùSõÜ×õ¸c_ÿÿ½Ÿè擽®²éPèÒå[Ì+^« —& ÊIº ¬)J¢¢t*Jl)sŪJ¶SàN2\àîÀU\ endstream endobj 415 0 obj << /Length 192 /Filter /FlateDecode >> stream xÚ³0Ò33S0P0bs  #…C®B.sc ßÄI$çr9yré‡+˜sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þCÁbY ìÿ?00ðÿÿe1 Xòp?œÅg1ÃYŒp‚UgÕÃYöxYò¤³À,æ üD²p²Øñ²øá,y8ËÆbüe‰,„^$óìà'Ò}ÌTaAÀf“õRX\®ž\\1=# endstream endobj 416 0 obj << /Length 349 /Filter /FlateDecode >> stream xÚÕ“±NÄ0 †]u¨”¥P¿´U‘®"‡D$˜02€`ny³ãMNâ¸ñ†ªÆIÜ»´EÀJ÷“ã8vâ?ÏŠã¢Â x”cµÀ²Àû\=©Ò83,OÜÊÝ£ZÖ*½Æ²Ré9»UZ_àËóëƒJ——§˜«t…79f·ª^!ðÒ û5D±Åˆˆ6XÖÌ;Ж©‡Æí¤uH@†cýN.|ÍŽrá.m@µÎ³Û¯F|Ž=›Mb¶š Ö´`]ƒÃœb{)Ð$èÀU2¤ئç¿ô' ÄcW˜¾|–rƬÇ,eŽ9sóýÃôOx^cf¥u=þÌzÆ.‡–{6œü‡·›òðÖS–1´Œ¸;ôAýe&oVýögÛ›ù`¦_#œˆ7ÄŸ¢)ÒNG¼¼ èöÝYmv¢M£Ù­è×Üf !ˆ&\oê¬VWê ?¦! endstream endobj 417 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bS #…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿA ÉÀþÿÃ(9THü±ÉåêÉÈ’:Õ° endstream endobj 418 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ3·Ô30T0P0bs #…C®B.3K ßÄI$çr9yré‡+˜Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü Ä0ø!Ô(c2~f0ÂH`0ãf°c0øáŒP†<Ãƨ‡1þCŒ0;ŒÁcÔCÌÀ¤ø Ãàrõä ä6n6 endstream endobj 419 0 obj << /Length 311 /Filter /FlateDecode >> stream xÚÔ±N„0Àñ’oé#´O ”\<'HÎ3‘ÁD'㤎ÝHàÉ ÆÁÑGð‘áBýú•Iû%)ð+,ÿ¦`ÊÕÑz­ ½ÂaJ£OJ}oà Œ9Æ™ÂÙ=º{„MùµÆyÈÏqòæB¿<¿>@¾¹<Õò­¾1º¸…f«­µ£ #q·8&ÏtáÞ3ûŸxž=%Ýüæ·õT]ˆ_¶'V1ü´± òÃîˆSï>8ƒ|º‹bGýx ²¦~Ù‡©¨_‰(Jê¯fÔß2L©Šcâ–# ןî8º~w‰¢[ÙstýJptýU,Ýr´,]ÿÄû±ž#öc},»=Ö3Ö³Tëc)íÛfôÑrLi‡G’vKA;+DEï ñß1¥]þ*Y÷‡¨ÄB8kà ~oˆ§L endstream endobj 420 0 obj << /Length 316 /Filter /FlateDecode >> stream xÚuÓ1NÃ0ÆqG"yÉâ¤êÐL–J‘È€bFÌé ¸Rc@n@G†*Æï9~ýÈðäßóò,×Õâdµ4•¡i³Z˜ûZ?é†öŠVÂÝ£^·º¼6ÍR—çþV—í…yy~}ÐåúòÔԺܘ›ÚT·ºÝçÜR*ñç<‚ÝV™s[¿(;(rOηì¼wþäpô(þàXð;¸áàŽÃуØr,¸çÎ8=ŠSpÂá`ÅáÉb æðdOæ°x§`Oæp4…ÄLáh }S8:S8šÂà^ìÃb öa±ƒb§`ûØx'îÜ·Ø‚ ~›à|Æ8'`5çlÁ8ŸqNÁ X‘‹½xúƒ> ¶àœÿµ>kõ•þJÔ@ endstream endobj 421 0 obj << /Length 325 /Filter /FlateDecode >> stream xÚÍ“±NÄ0 @ÝPÉK?¡þh H×›*‡D$˜02€`¾û´~J?¡c†ª&±ãrœNldH^âØŽ{U.+,p‰'%®Î°:ÇçÞ ºð‡ú…%O¯°n ¿÷_óÜÜàÇûç äëÛK,!ßàC‰Å#44~d´32DCÄšˆZAOÔ3%ä,F•¢b= _&gŒåË2‡½·dõÀ‚FL¤dtæ½Èêˆ^c;È“ºh†MZE=°p¡8È}ÃÚ‰âèÝ´1ª˜M¸Ótøµž°=Š[’l¥ÔýiÂþÿâìéñq<”3Mu;Ëúo˜ê†Ïš0Ñï÷q¯fUËȱ„±çšà:ëØ „Æåq’ñÌ×Ä·€•ZwÑ»¾$D#ÌB·HÜIè!iÐýh²Dåß W ÜÁxkD— endstream endobj 422 0 obj << /Length 290 /Filter /FlateDecode >> stream xÚµÓ±NÄ `H‡&ÿÒGèÿJk×NMÎ3±ƒ‰NÆIMÔèÜ{4¥ÀØá"R ÜßÈ%)ù ~ø¡Ùœo®°ÀK<+±©±¾À×>¡©Lcuåz^ÞaÛxĦqkšAtwøýõób{%ˆ>•X> stream xÚ}ѱJÄ@à?¤l“v_@“pÞ] !pž` A+ ±RK E;!÷hñMÎ7H¹à’qfwO ¦ù`vv23»œ•µ)ÍÒVf±0õÌÜWêIÍ%Xšú8œÜ=ªU«Šk3¯UqÎaU´æåùõA«ËSS©bmn*SÞªvm€| 82"‡7@бï, }8$´þtHIR2>JØÜJ =°MT;4[6ÿ±ùR׳éÄÄ~“û íD©Ï}~k£.:Âíì£6ʃH«¬Ï±¥DÎJ†wðkñ©8ÊÌ1ÁÛ‡=Iszÿ‚‰6üÑWÎBðJIľ7ìl¢:šÇa²hJ½Ý7ùCÞ¦ûßÍ8‘ÂýðˆþÝÆðâÞ5,φýkV›Ôqœ<ò Òöè÷Ã/™„µXY×dã|…ËvRJµêJ}áI± endstream endobj 424 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ³4Ô31W0P0b 3 C…C®B. rAɹ\Nž\úá \ú@Q.}O_…’¢ÒT.}§g ßE!ÚPÁ –ËÓEÁþ?ü!žu€¡þ?3õ‡Äb°ÿSÿÂâÿWÿÂbÿWÂbþWßa1þ«g€°Xu0V6V ŒeG,ëŒeÿÆ’'Åc1Œ²†%‹’œÍârõä äãCì< endstream endobj 425 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚ퓱 Â@ †S:Y|„æô]ª‚ÄIÝÄöÑú(>BGñLÓZD''—|ü¹ÿr7œÑ¦©;¤©M CA‡º>­ î0ðYÔÔmÕÃ՜՘eTÑ„ûãU8A5¤…!½ÄhH–ãàpɾe¨Û ä§P±þóï¸Vrÿ…{ÂÙŸy¹%ŸÞرWáÛ K¶¹Žp,ìŠ+¾ç¹&ûÂuaÏJNE±IÞM ºœ4y0犉%®Þ­àØ^žÃù ŽâAlæH 4È—¬6eOæ†E8Ã`ò| endstream endobj 426 0 obj << /Length 347 /Filter /FlateDecode >> stream xÚ•Ò±JÄ0Àñ YúÉ h¯w v¹Ày‚ÄIÝŽkÁÁ×êæx¯Ð7ðÆ ‡Ÿù¾/ׄë¡Hû#MHYO =ÖS}TèòDŸNôC!Ÿe9q‹c}:å/÷Or^ÉüF—™_¸e™W—úõåíQæó«3]È|¡oÝAw²Zhpà !j€Í- ´GÝ ¡ #gM°rÎÜ>²6n¦Þ3²xåf[ò22>GÞ–üÑ_Þt2À¾r º NɆݲñ•‘»aw{VdS"Ø9ræm÷¼"sØ22Çq˜ æDŽä,‹xc'²SoŒäDŽÌ¼1’³8,¶òÆ0NdoŒœõ¶> c¬Ïâ°Ø[o ³Á»DŒÜeaXì¤w ï]ðGoŸm𺷂uüzg|UNùj ¼»–¿yö l»îþ¶i[5ËóJ^Ë÷ûø· endstream endobj 427 0 obj << /Length 459 /Filter /FlateDecode >> stream xÚ­Ó±nÛ0Æq pá#/8ŠÀ“$)PÚ©CÑ©íØ¡E³ ²ß,z=GPħ£íZ™êáðáçNþëõÝõæÎݸ[wU»zýÆmnÝ·ZÿÔõº¾q›u~ïë}¿Ó«OðCµ^½׫Ý{÷û×Ów½ºÿðà@Ýgø¥/z÷è"¼‚ØÃEwø lì…€;ÀiŸ€åi24> stream xÚ…¿J1‡gÙ"0M!óº·`D«Ày‚[ZYˆ•ZZ(Úºy´}”<•aÇ™¹ãôP1|ðå—?üâéáIO :¢ƒžâ1ÅH=>cT¹Pc;÷O¸°»¡Øcw!»á’^_Þ±[^‘ØÝÊ™;Và8ƒŒ‘?dm˜gPÇj·\R…q :“dÄ„*Á |…Vbn¶;ƒg³Eó çd˜ö1Öo( Ø÷aãhDBÿcü³!ýD[Áo˜¬1¿En¥ ¹±¦ä%iêÝînª6N:ó\ÒZÛ` æ]H›_ÙI<ð?yë­œ endstream endobj 429 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚíѱ‚@ à& &]xúÞÜHLtr0Nêè ÑUy´{ጃ „zwÀ¡Í×6ÿÔd4”’™JBG´ñ„qlfiG{Ø1+P¬)ŽQÌÍE± Ëùz@‘-§¢Èi’Üb‘¤‚˜µ©ÒÁc®|æÚ!P÷Æái à±®!`{èø.ÿT¼ÊV6ß¡ýAÓõ_°yÍÀ4Õ8+p…o âøš endstream endobj 430 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚµ‘±‚0†kHná¼Ђ±0’ &2˜èä`œÔÑA£3<šÂ#02Î^KL%!_sý{½þ¬æI‚!.qa¼@¥ðÁCT±Ý9ß +@P% 7º ²Øâóñº‚Ìv+Œ@æxŒ0> stream xÚ]Ð1NÃ@Ð¥°4¾;ÛŠBƒ¥$\ ‘ŠQ%Ú¬æ£ì\¦°v˜Y)¢yÒî·çÝT—ëk.¹æ‹Šë57 ¿UôIõJ/Kn®æäõƒ6O\¯¨¸×k*ºþþúy§bóxË[~®¸|¡nËXÊp8™ÎÙë…HDÑFä#ò°Ô々Ú~Àþ¨¨7ö'ÉQÈ”´^;LKZ+45qj@.dêtÜÇv“ù!¤¸Ç"iíÐÄÌôehÖ”ôÁjÛ]ˆÿdVçµ³½ÍSuž‡è ±ýõ?h©›ÓêgåcfKxýºëhG¿Á•¡Z endstream endobj 432 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ35Ô34S0P0RÐ5T01Q07SH1ä*ä21 (˜›Cd’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.O†ÀOþÁN2bÌH$;É&åÁ¤=˜¬“ÿA$3˜äÿÿÿÿ?†ÿ8H¨úANò7PJÊÃç‚”ÿÇ`$ÿƒHþÿ ÀØ`ÿð(Èþßÿ ýß E` q¹zrr:é“p endstream endobj 433 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ33Õ37W0P04¦æ æ )†\…\&f  ,“œËåäÉ¥®`bÆ¥ïæÒ÷ôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQ```c;0ùD0ƒI~0Y"ÙÿIæÿ ò?&ù¤æDå(I²ôÿÿà"¹\=¹¹VI¢” endstream endobj 434 0 obj << /Length 301 /Filter /FlateDecode >> stream xÚ}ÑMJÅ0à)Y²é’Ø–G_]x>Á.]¹WêÒ…¢ëôh=JŽe¥ãüˆ? Ú¯if¦“tߟ ChÞ¯6 §á±s/®ßÑ\¦¼ððì£knC¿sÍ%½uÍxÞ^ߟ\s¸>kŽá® í½Ào@£B,D¸'€DdZš"-š,-ÚB/6¨3"x‰š¢äç”™œ®—ÓÊ®k‰í ƒËpÞ7q|Ì$pãFúæš¿È »ùdíL™@ÚAvüZ´H¥ÙFÓ¬¦YM«5Þk|,ZdÖìI³eb4Ðj`Môä³g!@Tt¶«`[ÈBÍ».àA8ã²EþõËwÌ•b«ÔŠW¢’üÉü'îbt7î}tû” endstream endobj 435 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚ‘½N„@LJlA² À¼€ÅgErž‰&ZY+µ´ÐhÍ=Ú> @IA烋 á·ì|ýgf.ëK xQá®Âz¯•ÿð!ðe‰õ•Y^Þý¡õÅ#†à‹[¾öE{‡_Ÿßo¾8Ü_cå‹#>UX>ûöˆ)Eà§£‰¿ŽˆN£ÈGG#›"ˆqhfHøÔ8¾ÏéäfEÊAEIÅÈ=¿ÿ„Å-ˆÎ’%$©#쵂H\ÀÕWèfä¹  Íhg™…™cgݺi†¹8iZþG«`©s+´¤É,25×ô\iÜ`2[Ì[¸¨ÈE3)Dä/ˆþbZÁ1.8Gƒ ƒ•I¬³éUuužR¯áÍ:îXÔ&¼oÝ´í]Ö¯"MºÎÝß´þÁÿéýëo endstream endobj 436 0 obj << /Length 225 /Filter /FlateDecode >> stream xڽнjÃ0ð ‚[ôº'ˆìPÛt±!têP2µ;´4›qüh~?‚G‚$ÎýÅC»õ@ú¡Bw—&ó,㈮+]pöÈo1}R2æ¢ñ8^¼~в$ÿÌIF~{Í’/wüýu|'¿Ü¯8&¿æ—˜£•kžnûLMÔÐ@;ÑÁž&žEõD-twñ>‡5 pU/jh:ØŠ¶,PW+D5À^Ôh ma#:ôYÀVpÔ=ìDÓŠºb~9¬a€g‰æ/ÌÿŸuøÿwiSÒ]]Óq endstream endobj 437 0 obj << /Length 285 /Filter /FlateDecode >> stream xڭѽJÄ@ðY l“Gȼ€&áH¢ ç ¦´²+µ´P´N-²°`“b¹u>r‡"X?²ÙLæ¿Ó6']‡¶x\c[awŠOµ}µÍšéñLß<¾ØMoË;lÖ¶¼¢e[ö×øþöñlËÍÍÖ¶Üâ}Õƒí·hF8ˆs0;àÛ¤Ž¡+*³¯Lʨ€•Yñ ‘ iþŸŒk›àäï!%Nó¹4tíaà(.JÚ‚bÒî> stream xÚ’=NÄ0…'ÚÂ’›!sHRd ‘–E"Tˆ ()@ Qa-GÙ#¤Lyxcó´‘•Oòóx~ž×ÍaÛrÅ Ô¼®¹=âûÚ>Ù¦ÁfÅíqRîí¦·å57-ϱmËþ‚_ž_l¹¹<åÚ–[¾©¹ºµý–‰ÈÒOdÀ%2…È ¸9SQväTòÔy2ÙSÁ Tà» 2NXFvY òŒø_ȹèíC!š‹"Þˆº%R­î/ºQ‘‰(Œ¶"!×V$ÞMÀ x#$“0"»W ­ ÎˆPrÂ(¨ì$Ó7´Ày?â Âîßèö"^Ò\æ%òˆI‘Éd¾«^EÀ€AíÈRɯiP7ë@tÊê4F¦¾Ã}œÒ·  CÔGƒÉžõöÊ~†\ö endstream endobj 439 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­Ò±jÃ0`™[ü¾he…ÚÎTAš@=š)Cé”dÌÐnÁò£ùQü5˜8²þ@mp CoÐ'¸ÓJ“§,ã˜3~Tœ>óLñVÑ’Ô%cžMq³ÙÓ<'¹æ$%ùæÒ$ówþ>þìHÎ?^Y‘\ð§âø‹òGÂGT‚ ´%ð1Šîs °à< (G˜®Ï‹(ºnhÄÉõ<œA홀°OîÐÂS€ÆiüX+ÒÃé"¬]ö1¨Õö n\PrÀ䚇cDôÆÞ§ý+Á"ZlÎ`eºúý1´ÌiEWÂÁL endstream endobj 440 0 obj << /Length 339 /Filter /FlateDecode >> stream xÚU‘1NÄ0E'JÉMŽ`_²)²ÊÒ²H¤@‚ŠQ-” ¨£…›øéHayøcARäIñÿù?ûî¼ïÍÎtæ¬5ûÖôæ¹UoªëðqgúË|rzU‡A5¦ëTsƒÏªnÍÇûç‹jwW¦UÍÑ<¶f÷¤†£!*y"<–Þ3Dà‰ê@¼àȓơ©ŠD,#DQÄc!C<– S 1¹©úŸ`}½EØ fðŠQæjÙÀM5ÏA°˜øcÁ²¦Ç.%ó‚Í€€ %‚Æ ç œ9æd’QÿÅœrè™’t‘pI#xÙï$u_"E`—-5KˆfXÊz‘ qv, /&Áy¹6:)z…‹©veÒuFµA¹EøÅ”àVxXVˆ;Õ³]äß‘^KFƒùa9 ÔjcªG²ëÜY•ëAEJ˜¨ëAÝ«D© endstream endobj 56 0 obj << /Type /Font /Subtype /Type3 /Name /F28 /FontMatrix [0.00836 0 0 0.00836 0 0] /FontBBox [ 2 -1 134 84 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 49 /LastChar 116 /Widths 441 0 R /Encoding 442 0 R /CharProcs 443 0 R >> endobj 441 0 obj [65.77 65.77 65.77 65.77 65.77 65.77 65.77 65.77 0 0 0 0 0 0 0 0 99.31 93.5 95.01 100.81 86.31 82.66 103.39 0 48.44 0 0 79.01 124.77 102.84 98.78 0 0 97.76 73.08 91.47 101.07 99.31 135.85 0 0 0 0 0 0 0 0 0 0 0 0 0 59.81 0 0 0 0 0 0 0 0 73.08 65.77 0 0 0 51.89 51.16 ] endobj 442 0 obj << /Type /Encoding /Differences [49/a49/a50/a51/a52/a53/a54/a55/a56 57/.notdef 65/a65/a66/a67/a68/a69/a70/a71 72/.notdef 73/a73 74/.notdef 76/a76/a77/a78/a79 80/.notdef 82/a82/a83/a84/a85/a86/a87 88/.notdef 101/a101 102/.notdef 110/a110/a111 112/.notdef 115/a115/a116] >> endobj 443 0 obj << /a49 433 0 R /a50 434 0 R /a51 435 0 R /a52 436 0 R /a53 437 0 R /a54 438 0 R /a55 439 0 R /a56 440 0 R /a65 410 0 R /a66 411 0 R /a67 412 0 R /a68 413 0 R /a69 414 0 R /a70 415 0 R /a71 416 0 R /a73 417 0 R /a76 418 0 R /a77 419 0 R /a78 420 0 R /a79 421 0 R /a82 422 0 R /a83 423 0 R /a84 424 0 R /a85 425 0 R /a86 426 0 R /a87 427 0 R /a101 428 0 R /a110 429 0 R /a111 430 0 R /a115 431 0 R /a116 432 0 R >> endobj 444 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÐÁjÂ@à ƒ4׊ÁSµ`B{êAA{,ØÒž“GË£ôrô ngvÜ]vù˜]Øaþb:™Î•QOt ·O9~ᬠڕüpüÄe‰ú]Í ÔºE]nÕÏ÷ïêåëJå¨×j—+³Çr­€Ö€Ç(àYXU€õ‰zj&®|’€aOÃd pèùcš1uÔŽ¸Æ-1H[7c(< ¤bÆgá Xk;®>É÷èN`$ŸŽ³„Ö:¢‹ -åomc)¾ŠZ¶ç†/%¾á?OFi° endstream endobj 445 0 obj << /Length 245 /Filter /FlateDecode >> stream xÚ}бNÃ@ `W"yé#ÄOÀ% í©‰ Htb@LÀÈ@ÕÎÍ£åQînìåøí‹ e@Ê铳å³_^-¯¥’¿+ï5±÷ˆ+ õÇÛ'¯[vÏâ=»dÙµ²ß>Ø­Ÿî¤f·‘—ZªWn7BÇ”R$c̤Ž(õÔ„•Ñ(NHN͇ÌxÎì‡ÙÄø—ù%ƒ•ƒõCke2Mo胵ŭB/ç©•ð›Äpè·8Yi¹RN„L4pʉ`Eÿ¡ËÀMôÓ¢s‚Ñd޽~Fgû:5ЗêTúŒŽšHºi¬Ù só}Ë[þL[œæ endstream endobj 446 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚÐÁJÃ@àYh`Í ”f^@“[ …ZÁ zò ‚ …* =É£åQò9î!tÝ™¤‡âAO;»³Ìü¶8-Î)£‚NÎhaÉô’›wcm(f´È‡›ç7³*MzOÖšô&”MZnèóãëÕ¤«Û+ ç5=ä”=šrM¢“@åë) ¼oç\SÝ%´Ø}‡«³ØqÝKK䄸´ã‡PËFïF왎»m4â„øˆ¤cž´ÂRÀ1Uó'~¤þú@õ›h`"[bzÄ ÉOv˜ÙJ:Y³åœ ¨°»®‡8!áÎy¥»@ì4÷h? î%<$ü¹.ÍùD‰pj endstream endobj 447 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚѽnƒ0àC"ÝÂ#pOƒ(TLH ‘ÂP©:D™ÚŒZ53<Â#02 ßÙ$i¤(Aœ>l#ÝÓxñSHiLÉ+}GøƒIfÖ!/ùàë€ËÕ'%ªÙEU¾Ñßïqjù¾¢UAۈ–A¥µîÄÑ©kó¡~ÍF AkóæpÖ³Þ`…Ñ9EåÌkð&Çkkpk ³Éá9ç“\SþX¿·ù}iúžõÙÀõ,3ÐðO®ùZ®)g{I!9ÅÎê·VÓ®ÈQ5’Fb´)e¬<îþR‚gJàëàÛ‘)›gpò-áºÄ<[?—Ò endstream endobj 448 0 obj << /Length 230 /Filter /FlateDecode >> stream xÚmпJÄ@ð „´bæ ÜD؈ œ'˜B8+ µT´5y´> stream xڅн Â@ àÁB]ó^«=ì þ€ÄI¡}´>ŠàØ¡´&ZÚŠã#¹§N—,êñÑ.é>íl<¢v8·$•‹íGªiÕŒ«¨¼9O—=ªÑbL6ª ­m²6èMü”#Îi ÆÀx7.2>´Ê12¦VFS¨0•ªBÌ@‘ú3–ù`F²[ˆ…×cs4"#p}ãþ¢ýK¸—_†á_üŒà'Fújá¾À©‡K|ÒÐqj endstream endobj 450 0 obj << /Length 270 /Filter /FlateDecode >> stream xÚ…Ð?JÄPð/¤ b.°ìÎ4‰°‚XW0Å‚Vb¥–ŠÂ²ÉÑr”=BÊ!Ï™I\ˆ ¾æG&óþÌ—¥§IÆ1/ù䌳”Ós~NèR-Æœ%ß§WZÝsšQt#eŠŠ ¼¾P´º½bù^óCÂñ#kôð…ÜUà9·µæµs`Ñàâ(+Ìw€z;#h¿GØÈž‹½œÐ!¯ éW¤øñze«»e0Òá¹TV<%× ä‘Êú_ÜHõ'Ëèo@Ûííeõ7®²)Àˆ%pÀb9 czCr™&!j.Ç; w¶³‘¶uØùÍLÚœ«ô$ – ]tGßPÄ< endstream endobj 451 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0bc Ss…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿÿ!êAC=3Ø€õ`¢ñL0`'ÁÄ?3˜øƒƒ`?pü`âBL<ÀAØ£úA€=ÿÿÿñDp¹zrr¾aZ¡ endstream endobj 452 0 obj << /Length 196 /Filter /FlateDecode >> stream xڅн Â0Àñ ‚…Côï LC[T?À ‚N⤎Š‚›>šÒGèØAŒEl ù‘Ëø'ªÙ¡"ÞIDI‹Ö wÛYh¯öaµÅ¾F9§¸ƒrÌS”zB‡ýqƒ²?B9¤…¢p‰zHp6&øÌÕžp¾|b¿-j8 endstream endobj 453 0 obj << /Length 285 /Filter /FlateDecode >> stream xÚeÑAK„@Àñ' Èk‡Àù©Úv¶ ò°P§KTÇ`‹:;}³‰û ó òèÁvzÏ]Å=èüFaü;“ON&S™ÈSºòs™ÉÇ_0Ïhžð”_<<ã¬ÄøVæÆWôãr!ß^ߟ0ž]_Èã¹\¦2¹Ãr.¡²„µjÀÊ5ƒn¡rh„߯á‡à3¾Û1¾ÖÒè}Z‡ÂCÑG¨tc‚P…ÙG¢zŒ°é1Ž Ú>#é ÖcxÖ,¬ ‹³ŠA•ºwÐÅÆ!2´EÕ *kíÐ8;´âAqÂ2¨À³jØGÅXmÁ Á'ñÎmA?N¼i¿ƒÞ/K¼Á¨‡xƒ endstream endobj 454 0 obj << /Length 262 /Filter /FlateDecode >> stream xÚ…‘1NÅ0 †]e¨ä%Gˆ/m©xS¤ÇC¢L ˆ ßð¬´GëQz„ŒªÛdè"Jò)ËþÓ^žû+ªiGgÔzò;zmð„Þ³XSÛüܼqßaõHÞcuË2VÝ}¼¾aµ¿¿&>è©¡ú»€]@ƺ¼›ÙN¢ff¹üÒYÌ*˜à('‰’ ü‚Q‚ BФùŠ Id“!Ù‹¥T$·pÓa“¨èÿ‡6U.ÃοÀÅ~‹I2FE?h+(¸QÊ©š[/¹UöB–€éÃÄ oÄ\öLrƒD’Š5éßÑð¦ÃüÖ¼ˆ„ endstream endobj 455 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚнNÃ0`G,Ý@¡÷à8UÚ2E*E"L ¨tìPsüh~”> stream xÚuнNÃ0ðä¡Ò-YÙz/IÀTt!R)`b@LÀˆ&PãGó£øÌV¤¨æÎa¨øÈðS|gûîlg{Í×lywŸíœç|×ÐY+Ášg͘¹} EGÕ[KÕ™„©êÎùåùõžªÅÅ ËzÉ× ×7Ô-0j`šÜ#ЧQ æ#ÀD¼LÚ€Òc0u(e ‹+9í1ü´ _¬E—ÿÿrùŠ4ê²A)'RòÐvd/Ú”F½¶™¢”NI/ÏJB7™,ú|z’5[%°m_‰«¾}תŒ¦£G9Ð;}ŒÞ£tøŒúBq)[m0”:˜Ï}ÐiG—ôy?x endstream endobj 457 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ…ÐÍ ‚@àÂyõ 5OÐ*h&‚ä!¨S‡‚êØ¡¨³>šâ#tô°d»µDFäÀð1?00~8r(9ôÈhïâ }OÔŽ,å`wÄ8E¶"ßC6]déœ.çëY¼˜‹,¡µKÎÓ„ŒZÿ¢‚¬Ô¹Y@T7sɸ z‚l»õbô¤ãÔ x³ýÄR I´;Èø‡®à­ŠªSqk¥¯([‰Å²µ\ÑŧÅy£NS\âwpmõ endstream endobj 458 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚ}ÐÁJÃ@à ¸0HsõPè¼€nHLO…ZÁ=yBA= * ÞÌ£åQò9öP:Îvô 9}à 3Uœ5gœ|Zp5çòœsz¥²ÒnÆå<ŽžiÙ»ã²"w¥}rÍ5¿¿}<‘[Þ\pNnÅ÷9gkjV,"­ùVöFZે˜áÀ&²WŽG˜"‰ì”“jØÈVÉFxA”Í=f‘^éþÇtXD:¥ýƒ$‚ߨÀQ`¢uþõÓ@ ¤ºú3 çØF«d@âma5_³óÙjέ ñ"btÙÐ-}”^p endstream endobj 459 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚ]ÐÍJÃ@Àñ †@¯½9/ » ÄF„ZÁ„zò …Bõ(¨èMÌ>Ú>J¡Ç$ë~LµÙÃòcfØóê¬jHRYÒiE Iõ‚žJ|ÃÚmíxÁ§Ý .[T7(níE{GïŸÏ(–ëk*Q¬è±$¹ÁvEƌѱ©Q³y‰]CªÃœ*Ö>gY8U°³Î#å±`k½²ö¬&•³÷98ù7‹,¼ûàlïsÇJﯬËB>ø¬S}òŸƒ>éŸÙÔ±˜˜Œs¶aeÐø¬ý˜-«#ÕÔ¦~G~±—lÆÞ´x¿+%eÒ endstream endobj 460 0 obj << /Length 318 /Filter /FlateDecode >> stream xÚmÑAK„@ð'‚ ëU(p¾@©™äÒAØ6ÈCP§Õ1¨¨³³ßl– Sb?‚ÑEXqz㨛ëžüñÈûó&ŽÃcêÓ  GtÒè„>ä•Ħ>¦íèá™ÌRâÝÐ8 ÞæÄK/éûÛÇñfWgÓ9½ÅŸîH:§BTºÁ†4‘Ò ÜÀ-AÇ]˜+ÅÉ@kS]Ñ”„žÆNZC E$«ž6ÒÑEfŠ{œ"92gÖ=ƒ4¦x? vl¸ìÈ% É„k‹0QÔq£µá¾¢t6Œ®,¤¬ ®${Qtpc6¢äÛ,2Ȳ.Þ¹lÉ!ÿ„ŽIËÉ׈¿Øã[qÝÓÄÓ$eO·e%7ŽXÊJÛÔqèòžvKÚl'A‘8Q”ÒÈyJ®Éj㬠endstream endobj 461 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚmÁJ1EïÐÅÀ[˜?°ï4N‡Ùˆµ‚³tåB\©ËB Ý%Ÿ–OÉ'ÌreâKBEÄEáææÝ›¬ªËfÉ nøbÉ«š›†ß*ú ºQä6Ÿ¼niÝ“~âº%}'2éþž¿>÷ï¤×7\‘ÞðsÅ‹ê7 ¨€™€"‹r˜;(«<Îe+”c†I°‚ð Ôˆë<+aî#œ K°1D޲Š1ÚÄ1“D?i˜pò¥ÝÏ€<ïRÐp&–Aì7N~ø +Õ¤«Äxv˜qˆ¯J½•“œ2~AbÇNè¶§Gúé«jp endstream endobj 462 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚeνŠÂ@à Ñ6…ûN²1’NðL!hµÅ"v·\6ŠÖæM|ßDÁÒBϱÐÂóÁ{¦—t³µÇ¤šõõ'‘•¤9æ˜#ß2,Ä~jš‹âVl1ÓÍzû+v8i"v¬_‰ÆK)Æjpª'gÄ#> N ý$"òOÜÝ#ð÷$ Ò$á 6&')Éx5ðÍ“éĤ47tGü4HÓxWtAN*²sÎ] î‚¿\ÌÁ‹ó;mçN/dRÈB\ endstream endobj 463 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚuϱJAà± ¢­•7/ {›Üy¸Dð A+ „ÄRPQ°òÖ7[ð|ûW¦8¼Ì$Ml¾…ÙÝf w\9ç>rQpYòÜÑ3*)æ\V››Ù#k²7<ªÈ^H™l}ɯ/odÇWvd§|ë8¿£zÊØKdiÐ"ëû¤D%(€ï;¥œ”Û<)÷ÿ‘”Ø_ŒïOIY Ó~0-Î`> stream xÚ]Ð1NÄ0Ð¥ˆ4à¹$Ù]C*,-‹D $¨¶@T@I‚aÍ7 ¥ â)]D˜I²H@᧑ǶþxUï›W|À{ ^6†ojº§e#››Ã¹s}Gë–Ê-/*Oe›ÊöŒžn©\ŸsMå†/k®®¨Ý0€$«HЩ"² òŠNjòÚ ‚Cñ52 ûëEÿƒšèÝYý‘:èÏa_ñ ûŽ#Ø7yÑFyÛö‚“APÁ¹9ãgô/þc'‚ûË‹Lã'Ü8—…¤Þ‘ME(/YUPA2KÈ,Ÿ‘†)4@'-]Ð70¥oÈ endstream endobj 465 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚuν Â0ð“…ìÚ¡Ð{MÒZɤàØAÐÉAA]ÅGë£ô:vjNLÄÁ ?È%÷¿ë©n–$¥¨“P&)ëÓ^áSmªæª?O»#Žr+J5Š™©£Èçt½Ü(F‹1)Z+’Ì'ä9þ›‚išæüPdžŠ)™"ðš›$@›‰` 2š9I*MX‹½‡Ðf"‡fNLÅ¿ …[†[&Ë0wÇÓÒrxµÅÿ%¨þ¿)-[§9.ñ†©O‡ endstream endobj 466 0 obj << /Length 260 /Filter /FlateDecode >> stream xÚm±JÄ@†ÿ°E`š}ƒd^@s¹\ˆ…8O0…àUb¥–Š‚ÅAòhû(û[¦7Î(‚,|Åìÿ;ì¦>m×¼â–OÖ¼i¸mù©¦Wj:ê¸û¹y|¡í@Õ7U×:¦j¸á÷·gª¶·—\SµãûšW4ìÈ€þ¨™à’ȃ‹ðÈ á˜q|êùEú‹Ù"³…«‘EȤ y€D?aœK`\TÖ‹&K‰€—  ˆ*2›yY€b5–2eɛ™"“  ‰ªèã…¶£z|.Îóü¾¡‘|2@kÞP@U”ú”Ê|„³/€Øg”Ú¡«öôé8p endstream endobj 55 0 obj << /Type /Font /Subtype /Type3 /Name /F30 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 2 -2 93 60 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 51 /LastChar 87 /Widths 467 0 R /Encoding 468 0 R /CharProcs 469 0 R >> endobj 467 0 obj [41.52 41.52 41.52 41.52 41.52 41.52 0 0 0 0 0 0 0 0 62.28 58.82 59.97 63.43 56.51 54.2 65.16 0 29.99 0 0 51.9 0 62.28 64.58 0 0 61.12 46.13 59.97 62.28 62.28 85.34 ] endobj 468 0 obj << /Type /Encoding /Differences [51/a51/a52/a53/a54/a55/a56 57/.notdef 65/a65/a66/a67/a68/a69/a70/a71 72/.notdef 73/a73 74/.notdef 76/a76 77/.notdef 78/a78/a79 80/.notdef 82/a82/a83/a84/a85/a86/a87] >> endobj 469 0 obj << /a51 461 0 R /a52 462 0 R /a53 463 0 R /a54 464 0 R /a55 465 0 R /a56 466 0 R /a65 444 0 R /a66 445 0 R /a67 446 0 R /a68 447 0 R /a69 448 0 R /a70 449 0 R /a71 450 0 R /a73 451 0 R /a76 452 0 R /a78 453 0 R /a79 454 0 R /a82 455 0 R /a83 456 0 R /a84 457 0 R /a85 458 0 R /a86 459 0 R /a87 460 0 R >> endobj 470 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ1 Â@E°L¡70sÝì ’@°ˆÜBÐÊB„€ZZ( 9ZŽ’#XZ:IV›t«þ 3ïOÌØÄrÄ#²‰xjø¨éBºN%7nt8SjImYǤ–’“²+¾]ï'RézΚTÆ;ÍážlÆ@TðJô ø@ ðhxÁ«jze/¨ š]aöåÙáýÝ;¿íÇÎAdDÉ/ak+ÚÎ?i¶¥”T“‚RSÊ"§…¥ }G«@ endstream endobj 471 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ1 Â@E¿¤L/ :ÐÍ®A"ˆEŒà‚Vb¥–‚Š‚…EŽ–£äÁÍ$±ÐNxÕÌgæý¡˜1‡qß„l">hº.§!Ǧ^íO”XRÖcR 7'e—|»Þ¤’ÕŒ5©”·šÃÙ”s Î@ t€h~//i¹ÝKxO`L®Ð“tIVãçßxÅ?üÞù¼¨>ö‡©(=C±uÚ•¿/ñ@ªÅRÓr•iniMoEËBs endstream endobj 472 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ52T02R03RH1ä*ä24Š(XC¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿÿüÿó‡a0C ¹\=¹¹¶ h endstream endobj 473 0 obj << /Length 102 /Filter /FlateDecode >> stream xÚÍŽ;@PÕggÜwAí“x…„J!*” Âî%>‰EÈt3ÍØ00 •¾UjÌØrR¬Ð豆iø¥qAæ 5‚T‡¸šûv̬ɩ‚½Ò p¯ó:½_ó¢thq_þh endstream endobj 474 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Œ?øØ¾á„ËüýóƒðÚcyn€8£žáÐ@§Ô­ÿÏ¡A|8X¤¤^þ}ÜÇÿ& ð…(¼À…ã.WO®@.QåXÙ endstream endobj 475 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. þ```ÿÀÀÀâÔ±=700ȃ0P’ŸøÐ aþäy û]ɃÔÔƒôÑÃ} p…(\ìàN9~ ×r¹zrr°Wß endstream endobj 476 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 477 0 obj << /Length 130 /Filter /FlateDecode >> stream xÚ-ɱ Â0…á gð 2œ'0¹-¥™k3:9ˆ TGAEçæÑòfÚ¢|Ûÿ—ÕÒ7ôlXUÔÀ:ð¢x@='eý;ý m„;P=ÜfÌpqË×ó}…kw+*\Ç£ÒŸ;Zä“Fy2d›åÏd“L*R!s™ÉB¬¹ËY°ŽØã ,P#Œ endstream endobj 478 0 obj << /Length 164 /Filter /FlateDecode >> stream xÚ31Ô35R0P0U02S06W03RH1ä*ä26 (›Ad’s¹œ<¹ôÃŒ ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæö8qsƒÍ憺Ì ÿê››ÿØnÿÁÿ¸ÿóïý ÿÿ10Øÿ``àÁ 6P $RR ÒÒ 2d>»@nárõä äT¶Dí endstream endobj 479 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 480 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ-É1 Â@EÑ?^á ¦xЙ‰‰mŒà‚V"ÑRPÑ:³´Ù™&Nwo¾\ø’ž%红V\ó¦xA=y1žö:À¨n×w¸°ççý½ÃÕ‡ ®áYé/ ­tò‹½4è’M22ÉD³˜ÉT&2+•<å*ØñBÛ#´ endstream endobj 481 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsK…C®B.K Ïȉ&çr9yré‡+Xré{€O_…’¢ÒT.}§gC.}…hCƒX.O†z†ÿ 0XÏ ÃÀåêÉÈ[\w endstream endobj 482 0 obj << /Length 153 /Filter /FlateDecode >> stream xڅ̽AÅñ ɉ¨ŠóÌ—eëµSH¨"‘ ” ôÍ£xw³ÓN¦ø5çæþgvZ8œ8K¿àÜñbñ€·²–>žÎ7TzOo¡×²C‡ _Ï÷ºÚ.)k̓<j*¥zÑP ¢±‰R˜è.NÑO|[ƧÕmÈÜÏdSéL6•Îeé\6•NdV;üxÔ*Æ endstream endobj 483 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsc3…C®B.K ×ĉ'çr9yré‡+Xré{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]dêþ7À`=ƒ 1S—«'W fp"¸ endstream endobj 484 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ54S0´P06SH1ä*ä24PAS#¨Tr.—“'—~¸‚¡—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEA†¡žá Ö3È0຀`ý™ PÈx€±±¹™¨Ò‚¡€!ËÕ“+ &,• endstream endobj 485 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0U04T03P06TH1ä*ä25 (Ae’s¹œ<¹ôÃLM¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿAà˜üÿ‡Îj-Ô\®ž\\~,Ü endstream endobj 486 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 487 0 obj << /Length 90 /Filter /FlateDecode >> stream xÚ31Ô35R0B#C##c…C®B.Cˆ D"9—ËÉ“K?\ÁÄKßCÁˆKßÓW¡¤¨4•Kß)ÀY(è¢ ÔËåé¢ð $—«'W Rˆ endstream endobj 488 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31Ô35R0P°T0²T06V0µTH1ä*ä22 (Ce’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. 5 5ÿþýg„" Õ1ü*Êl*,,0‘ƒ—«'W /¨67 endstream endobj 489 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚµ‘½ Â0ǯ,ÒÙÁá^@ÓH[ëZ+˜AÐÉAA…*:ÛGË£ø&õ-8d¨ —áIøpéd8¢ˆȔҘ’ŒÏÈŒøŒã÷Óþ„¹B±æ(æ|B-èz¹QäË)Im$E[T@¼ >Øß²>¸˜A`AÇÉBË+ºø`3šô4;V¬è ‡+-¢ƒq€{m§z¡Öß×l[·]ý&G“ëG5Á˜jCãàØîŸ·Œ3…+|¯rPË endstream endobj 490 0 obj << /Length 295 /Filter /FlateDecode >> stream xÚ¥Q±JÄ@}a‹ÀîÚÁìh6± œ'˜B8+ j)DQlDîÓ⟠ø)-qf·ÑÚdáM^&/oÞlª“º±ÎÖö¸´ÁS{_ÒÕ•Î3úæî‘¶×¶®¨¸šŠîÒ¾<¿>P±ÝŸÙ’н)­»¥ng³@¯|a…Yn b Ä=Z F˜Á-µ;C4 ¬`Ú £ FŠhj…x‘†¹1føo8ý}}‹Èà¢IDœ3Ö솘sÓ{Hûõø ØC6æb‰“BKú¿à›i°”ªÁœSµÛr£æßØé(_Ó ƒ}NìÇ\F?t"@!„°Bzéï>a3û„óÉ'¼tíìס²¡é¼£+ú®E}d endstream endobj 491 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bSK…C®B.# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ø0Aý? Áøƒ½ýãù† ö@CÿùA2þ€’@5@’±D‚!™dþÀðPI¸ùÌCdþÃÀþƒ¡þÿƒÿÿ “\®ž\\^åˆÓ endstream endobj 492 0 obj << /Length 175 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bScSK…C®B.SßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.Oþ êÿ³ÿg``üÁ~¿ùûÆÿüäØÿÉ?`°gàÿ¤êàÔ õN}`o`üÁÀþ¤›™ÚÔøFÑ¢¢˜ÿ0°ÿÿƒÿÿ? Q\®ž\\à  endstream endobj 493 0 obj << /Length 154 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bSK…C®B.# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]øÿ0AýÿÆÌذIù~ iÏ"ëÈ?P¨†ñ3õÈÿ@€JR×|Z“ÌÀ0ù Çÿÿ@&¹\=¹¹)“ endstream endobj 494 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚåѱŠÂ@à?¤X˜f!ó·FHÄJð"˜BÐÊâ¸J--îÐÖ|1}_aaËÁu=ÎÒÎe¿Ùýg›Mû]îp,+íqÒçeL?”&Òwš¶¹X¬i˜“™sšË)™|›ßíŠÌpúÉ1™Œ¿$ùMyÆ€vˆ¤Š3|-{Pé½ÓeƒÓ!,¨„GpPghÁºFdPCWTíÓ-”k¦¡Cˆðj( ­g¸f"{¿!ªý—Â[ïÞ—ÿA£œftàùËC endstream endobj 495 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚÌ1 Â@…á· LàœÀMŒÀBŒà‚Vb¥–‚Šv¢9ZŽ’#¤L!êÄ‚ºËWÌü0aÔíìs_„D¼hO¡Ïõ—±«-%–ôœCŸôX¶¤í„‡Ó†t2r@:å…œY’M¦€zÜáæ&óÐÎc¸¥§ÜÁ©ÎPÕêöøp±t¼¸e£] 0.â,$+IJ’“‹¬áâ­õ§_ÏFn_óoõ^:,Íè Àv;r endstream endobj 496 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚmÐÁj1à é^=;OÐd-‘õ$¨…îAhO=”‚ÐöX¨ÒÞ„Í£í£ø{ô°˜N"¸Q6>fB&?™Nî'izàmf4Õô™ãáZûÒ||ã¢DõJÆ zâ.ªrM¿»¿/T‹ç%å¨Vô–“~ÇrEP@X×ìû8õ \²²IU{ó˜»ùÁ3ÌbÆYã¥1Ezôè$æ'i=SË©†LÂB„p6Pu Ž–8ç:R†£ ²Ž÷›[4ß9Þ²áéí…ÃŽ&ÎÈ&üZÚú'­ãXήÁÇ_ð%°m¼ endstream endobj 497 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ•±‚0†0Üâ#pO`Amd3ALd0ÑÉÁ8©£ƒFgúh< ÀÈ@¨…«Ú´_®íÝýýe4fÐÜ,¹ ¹¤kˆ”µÓ„íÅåŽqŠâH2@±5§(Ò½žïŠx¿¦EB§‚3¦ i3 €5C8ZA–›À/:LÊ^ÕÁ­ûpšôXpžÛôkÚF¶­±bIF°Ü2ÕéqžËUœNÐC¨™E>ª_…ñ÷c‹ð+v·d¯ó¯åínÔâ&Å~VŸP endstream endobj 498 0 obj << /Length 260 /Filter /FlateDecode >> stream xڭѱJÄ@à? LaZ áæ4‰Üª[-œ'˜BÐÊB¬ÔRPÑÖÌ›ø*¾‰yË+Äuv²g!–Bà#“ÍÌî¿ÎïúnÙñÎ;ÇÎóMG4÷Zly¿›¾\ßÑ¢§æ‚çžš-SÓŸòÓãó-5‹³#Ö÷%_vÜ^Q¿d ˆRPDZT†¸R´öR ÊOÔµ þ@ù*˜(ÞAWEÁ],øR‚º˜IµRê5ú7P­Ñ&?”2oÆ(~#FLØàgÈü5=dF#ïzv¢L;mf–Ä&,—mXJ[°Ìa Þ#å }Rº:%e-vÁvS½•Ô=U:î霾šes– endstream endobj 499 0 obj << /Length 194 /Filter /FlateDecode >> stream xÚ33Ö31V0PaS Ss…C®B.S ßÄI$çr9yré‡+˜špé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÁõBýc``üßD@.ƒý0ÅÿL1ÿSŒÀÃ?UBÙ7@¨`JJ=SüPêŠýê (<ö¡9ÅñP¯@=ómrüC%h˜ACž  !@ y`> stream xÚuб Â0Ð  ·ô¼/0­ µ‚Dª£ƒ¢³ý4?Å/iLsqˆð’»INÍÆª œ&vª)©9 ¼¢‹åý¶O4¬4Ê©åÊFQê5Ýo3Êj³ ­ioK¨k2ýè D˜ÒÀ€§dFLƤ1’(­C8^Qˆ€„ÉÆDð¹ïɰ|pÃ1ÆÛ½Ó.þ"bøÿyÒ€Œ)™gëºk¸×¿àRã?UŸ’~ endstream endobj 501 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚ35Ñ3R0P0bSCSs…C®B.s ßÄI$çr9yré‡+˜˜sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÀd’ñƒü†ÿ Œ`’ᘬ“6`R‰äÁAòI68ÉØ€L2`%™‘Hv0)"ÿÿG'!âP5Ⱥ‰ A€J$ãÿ `G@%¹\=¹¹Mÿx× endstream endobj 502 0 obj << /Length 254 /Filter /FlateDecode >> stream xڭѱJÄ@à?l˜&yM"&`µpž` A+ ±:--­7`ákMgé+ä ¼òŠãÖÙÍ& XšæKf’Íì¿]{Üt\ó)p×p{Æ =SŠu¨ÄÎæ‰V=U·ÜvT]j™ªþŠ__Þ©Z]Ÿ³>¯ù®áúžú5ð(ü6S¬ßü`À쑊-Ì— oÕ¶¸áÖë¥d‡ˆ¾¯ I¾Sòý03a‘™LlB".€¿Ñ!1ÍúOx½&ÂpcÄJÂ&ÆHù‹¸£…¸Û…˜„rI)¥ÌÜ” _ò,v0Ÿšõù{lØtéT–‰é¢§úî”Û endstream endobj 503 0 obj << /Length 125 /Filter /FlateDecode >> stream xÚ33Ò3²P0P0bSKSs…C®B.SS ßÄI$çr9yré‡+˜šré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÏøÿÿ?TŠñó bü78) À¤¯s‘)hèb y.WO®@.!»¥7 endstream endobj 504 0 obj << /Length 106 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0aKSs…C®B.#3 ßÄI$çr9yré‡+™qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿ†€ˆ¡¾aècWüÅåêÉÈ3v\‚ endstream endobj 505 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ35Ô³T0P0bKSs…C®B.S ßÄI$çr9yré‡+˜˜ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÿ€™dü€þ3 eR/i& 0È ò‚d“Ì`’LÊ?`üßÀðÿÁ@!¹\=¹¹Afl÷ endstream endobj 506 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚuÑ?kÂPð{<0p² Þ'ð%œÿ€ ur(Ávt°ÔÙ€«ê•]ÝÌGÈè|½¨X#yîøÝ=8. [~›< 8¢€:½û¸Ä°ËµW”ÅÇ|ýÕ”Â.ª1wQÅÏôõ¹ú@ÕjH¯>yoÉà瘣1 ýƒ¸ 8hFãx‡]Ê*ñ›1æ•øá8§¾yºØTBŸ¤,a P³ —À“M õ2Ü< œ fepÒˆ\$ÀIÂÖ5+zÛG4÷V¸Y5D NZ@fWðí¤'c´ÔÒÇýoÊÀQŒü¦Â! endstream endobj 507 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚUпJÄ@ð/.0…ûfŸÀMNÖ?óSge!Vji¡hkRù\AKÁTÖ©$EØuwöŠM1üøf`Šï`¹·<’…Üw£¥>”w%=’Ö.>úÃí­jRWRkRçnKª¾ÏO/÷¤V›SY’ZËëR7T¯¥µ@fµm óÀ¦‡í¼ÅÏ0 à{d¾¦˜üۘÎ=õ4]LÕ3ùȦ€aÒ@b·´liº@ÏT|`Ä“MLjbËÀ¾Å4ŸLõ“ÿ1ÂÄdtFÀœW$®Gœ á*Ã.|ר™±ÕtIÿ6D†c endstream endobj 508 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­‘±‚0†Ï8˜ÜÂ#ô^@D'ÔDŒ“::htGáxWÚœmš~éÝßöú_LÂyÒxJsNgoô(ò»ÌéŠIŠîžÂÝ5‡ÑM7ô¸?/è&Ûñ~IŸ¼#¦K¶ Cµ¥ Ô¼*x1F%¨À)dBœÃè ñ‘Š…¬ªA«ÑŸ8çEÅjGîU…Ò(ßNk¼ûÈ4ª,— ~ÐjÔ…}Á<ÛC¿2[|Žþfa?­-ÈÖžÆ3ë ñ“­oŒ×œÈ¾}°]Ñ=ÂUŠ;ü”K‰É endstream endobj 509 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ35Ó35T0P0bS#Ss…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü‚ ê„úÏÀÀø¿,ÊÀ ÿLñSÌ? Ô0Åø™adªT Y;ªÑPû ¶CÝuP7ÈÙÿÀÔˆ ƒ™….ĵ˜—«'W ŽK€¿ endstream endobj 510 0 obj << /Length 221 /Filter /FlateDecode >> stream xڕѽ Â0ð–‚ì#x/ i*Uœ ~€ÄIí£ù(}„ŽJãÙK Í"&…äHrÿt¢F*ÄÇ8 q¢0šâYÁ È€f4ãÊé óäžê ×´ 2Ùàãþ¼€œo¨@.ñ 08B²D­uåÐ uf,HW§‚ ô¥lüfëç¬(ºz¥eõ§Ö~ûüæÞ¦Øô§¹_Qš@™ñÍëõ6Ò+L®6ŸñeålóZ¹šÿ«›v,X¿ÕKéP~ï‡ÞEÔºe¯Ö©úN=â’¹«vð™<›Â endstream endobj 511 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚUϱNÄ0 à¿Ê)K¡~h{=îÄB¤ãè€Ó ˆ @°!ZÞ̉èF%Psw ²|Jì8¶ç‹Ãª¦’æt0£ùŒŽŽé®r®^j°¤EµËÜ>¸U㊠ÕKWœkØÍ=?½Ü»buyJz_ÓuEåkÖ?€ÆŒ!òÎf°l#>Ù3ZÎ;@Î'€ç7Àîx ïÉ&Œ&È–Nm9ƒR0—!¡G/aEïFD+E$½ÑŒµ²MX‰¿„^É>a‡-úÆü‘Mˆÿèû=¦×:upÇ´–¤-µiÞ}õèGŒˆA§Š^{s¦ywÖ¸+÷=Ÿ†# endstream endobj 512 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ3µÔ³4W0P0bSsJ1ä*ä2ñÁ" Fr.—“'—~¸‚©1—¾P”KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÁþ?<@£0ÿg`ÇÀøùA ˆbüP¢>€©T*L`¥€)‹`J+ŦF Åþ¿Hʃ‚ârõä äWÎr° endstream endobj 513 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚåÐ= Â@àÑÖBÈ\@7‰¬ÆJðL!he!Vj)¨h«9šGÉ,SˆëlÅ3X,ßòf˜âu¢VsÀmnFlzlº¼ é@ÆH¸¤˜¬w4HH/ØÒ‰I'S>Ï[ÒƒÙCÒ#^†¬(±µÊ>ñl \3X~ZPCAù©J'BEH?4€þ—ºôuâ7{©-'¿ROrï%ËxºVÝ™‹Ã·¹CÙ ï qBszØxaº endstream endobj 514 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚmÐ1jÃ0Æñg1> stream xÚuÑ1KÄ0àW „ãºv8ÈûÚôÎb ç vtrá@ÿ…?'â)ΤC¹ø’£âMHøH^ÂK^Yì/Pá÷æX.°8ÄÛ\<ˆR¡ëÅÑvçæ^,k‘]b©DvJË"«ÏðéñùNdËócÌE¶Â«Õµ¨WhíÀ­í"kÿ·ä@öŒæ¤àmDâ$f~¤#; Hl ¿¥½8@£ÁŠwdFUšì¨%[pù¤^q(é`J7)¯Iˆ’›ÑMk¯T¢äRÙñRI JN%}¤½Ö<=“Dt2l¥IÜ©yÑÑ&ôFš:Uï; ôAš9ÉOŠ} ô5*¡¿­ºÿÄÿ‰°­ ÄœŒE'"'íEÑ<´¾¦®_g'µ¸ßÑÆ©Ñ endstream endobj 516 0 obj << /Length 279 /Filter /FlateDecode >> stream xÚ]ÑAJÄ0àC»…МÀ¦Ç.„Â8‚]ãÊ…êÒ…¢ëöÁ«ô&æuW°ôù’<3‹ôãÑ¿ù».OËÊXSÒZ[svnž ýªIkÂè_<¾èM£ó;šu~žÍyûxÖùfwi oÍ}aìƒn¶¦E„'8p…@ë@Òµ1Ù±=™Ž h¨ $«3,ØÄ+N¼€ÝŠ­‚moƒµÛ³.˜ }0ý颿Q…£’x(`ÜO‡b<¾£âkˆç|ŽÑ4ºPS0á€%»â€ ¢–ƒöàØÞW¾œÌÈCeàË  »ä›PIÂ{Á7™½]øоiՈݱúªÑ·úR}Ý endstream endobj 517 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚÍαJAàYÈÁL›"y÷.p1©b¯L•BAS¦P´Î=’p²2EÈ8»n@ô,†ofgÙ§“ËÉŒK®´¦×WüRÑ+ÕsË8ÆÅó– ¹5×sr·zJ®¹ã÷· ¹Åý5Wä–ü 7©Y²È ð~k%…öÒvìT²Z^{ÓcÝÙ³ ÷ÃâôU«o²CÕ0Ë–*¤ÅSTB¶‹ú`ζÑñÞ&‡í%‹ãE¶Ÿ´§QÒÈ0›b4è3¾Ýe}÷¿Íÿô"Ý_馡}Èl® endstream endobj 518 0 obj << /Length 232 /Filter /FlateDecode >> stream xÚUÐ1JÄ@Æñ/¤¼&GØw“@B,ÄuSZYˆ ¨¥ ¢`—-GÙ#liv|ß‹ÜÀü`fÈŸ™iÊ“¶ÖRu«M«Ï•¼K]Ù¼ä”O¯²î¤¸Óº’âÊV¥è®õóãëEŠõÍ…ÚêFïí—é6¢}8rB²G‘š² ç g@þãîp ¬vøÂoûÑðDšD,ZŒN€Çà±E‹Ñ- ®Å-FIâ2vpŽeDZdøÓbt¤½k±Ùt`ÌÜÓÔel6óXÆË"÷ó­üdÁí=yÙ<"ú»ýW.;¹•_µštó endstream endobj 519 0 obj << /Length 204 /Filter /FlateDecode >> stream xÚmÌ; Â@à . ´Vf. ›´1àL!he!Vji¡(X›£å({„”Á8ë£—åø‡ùÝéÅQ—Úš’˜º}Úi<"ÏÈŃ÷f{ÀQ†jÅ{T3ŽQes:Ÿ.{T£Å˜4ª ­5EÌ&¡€º6äü¥…°%/_x÷/PAP02gøýÁ0Ò¦–yp&îî¬dBw›:Œ+0ðÁüâ}¨AT¾yóMÞ6Ó¢5lö–¢.Ë5²Ài†K|¤øT£ endstream endobj 520 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01V0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃT‚D0S$ê00|`ÇÀü¹A¾ù;ÿæ ì˜ÿå˜00þ* àÄ?8Q"êI&êPMÊøbÛ½`Ëßœq ä ã ò Ìê˜þÿ:]þ—«'W ÈckA endstream endobj 521 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚÎA ‚`à'?( ‘œ ”ýüºÌ A­ZD«jXÔ.Ì£yàÒ…Tcu€ßæ 7f: 5ÙðP³™° ø éL¦ %¿—ý‰â”ü MþBbòÓ%_/·#ùñjÆ’&¼•ÎŽÒ„¡ZÀ{ÈUe5ÈTÆ©¬Ö-Õ‡W¨6êÀj@-ÐÉÅóOù¯Ó‰;*`{ú^‰ž[bàTd7“ý w§”§ÍSZÓ»= endstream endobj 522 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0VÐ5T01Q0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÿó‚ÁþT‚zó !ÿHÔ±÷`øÁøþó†ú쀶¤ „|P±=˜i«‡u âÉDª)öph‘<„ÚkrF=ÈAï?0þ`<ÿŸ¡†½ÿ?ƒü?þÿ ì@‡s¹zrroXhI endstream endobj 523 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ]Î1 Â@Ð\˜B/ 8ÐM²(ÚЦ´²+µT´“èÑr”!åbI qáÁ23ü;èö9änÀ¶ÏvÈû€ÎdC)úlGUgw¤IBfÍ6$3—2™dÁ×Ëí@f²œr@&æm)‰Ú¸·2Ï©\^¡sϵ2¸Î÷¯HÅøQ‰RñþQÖOþø—Ö5ÉQÑJrµìhè M£íÂá„TårL¼@³„Vô½£@ endstream endobj 524 0 obj << /Length 141 /Filter /FlateDecode >> stream xÚ32Õ36W0P0bcSK…C®B.# ÌI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ê˜ÿ70ð|À ßþ€ÁžÿCÿ`ÆÌ00ŠÿÿÿÇäè§3ÿa`¨ÿÿ޹\=¹¹¢&[ endstream endobj 525 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ¿J1Æ¿00…ñ v^@³9ïäŠÃ…ó·´²+µT´[¸}´> stream xÚ31Ó34V0P0bS …C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ì€à?É&™iN‚ìaþ`ÿD~°’È700nà?ÀÀüDþ“ØÀÈä‡$Ù€‚ëÿÿƒÿÿ7 “\®ž\\y endstream endobj 527 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS3…C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜ø0È@A@ 8~Àüá? ±q©ŽØ0üÿ‚¸\=¹¹(CE` endstream endobj 528 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ32Õ36W0PÐ5QÐ54W0´P05SH1ä*ä22 (˜Ãä’s¹œ<¹ôÃŒ ¹ô=€\úž¾ %E¥©\úNÎ @Q…h ®X.OÆ ìø   P?`üÁð†Ø€¸ôE6Œ?êügüðŸ‚üc?PÃ~À†Ÿÿó.WO®@.ÿ§Wõ endstream endobj 529 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚµÍ1 Â@Еir3'p.#˜BÐÊB¬ÔRPQ°ÍÑr±0EÈ:? êdÙ³3ó7èuÂ.{Œô¸òʧãH‰ÆrCqJzÆGz$¯¤Ó1öÇ5éx2`ŸtÂsŸ½¥ […RÊüâë?´LõºæÝ3Ø‚ærÁÊkm‚¨„;xÔÂ3êH†Kv¤Ø@%¯â.êýoÔ nn—**ŒÉù@Ô¦ôDr endstream endobj 530 0 obj << /Length 108 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS …C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?0ü‡!þ ̃±ÿ`øÿÿq¹zrrÆ‚Q. endstream endobj 531 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ3³Ô3R0Pa3scs…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?ð`Àðÿƒý†ú@úƒ=ãƒ:†ÿÈ77Ø3ðnà?Î ßÀüÿˆþÇÀDÿa`ÿÁÀNÿ``ÿ€þÀÀþ`Ð O€âÿÿƒÿÿ7ÿÿNs¹zrr#߈ endstream endobj 532 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bcs…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ìø?00üÿ`ÿD~°’È70ðnà?ÀÀüDþ“ØÀÈä‡$Ù0½ñÿÿÁÿÿI.WO®@.‡e% endstream endobj 533 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚŽ1‚@E¿¡ ™†#0Ðeƒ6 &na¢•…±RK v9Gá”Tâd)H¬ÌN^fþîþù‘žÌ¦ð”Çš£€Ã9Ÿ5Ý(ŒE”qÑßœ®”R{cRk‘I™ ?îÏ ©l»dM*çƒæàH&g8^W‰S­œQƒdHàVðá•R¾ ò!J*¨- Ài~ nNû/†ooñkg»Íîõ$AéÖHåŠ> éáwlzZÚÑIKÚ endstream endobj 534 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚα Â@ àH†B¡y½ž­uj;:9ˆ“::(ºÚ>Z¥p"ØŠç]qÐQ |CB’?Šû2ä€Ü“1G!‡#ÞI:R°«aøm”d$V$f¶O"›óùtÙ“H–$R^K6”¥ŒÊ¯À¨\ƒ¹UW0÷Â/¼º%>Á«°T¨5*è´4hy~“ÿÌ÷ö²¥ý¦Ýß> stream xÚ31Ö³0R0P0VÐ54S01Q06WH1ä*ä21PASc¨Tr.—“'—~¸‚‰—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃùŒêØ0üa<|€ùÃãìÊð?`0?À€Áþ€> stream xÚ36Ò35R0PacCcs…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ØÈ3üPàÿÃÇþ?nÿÀÿœýó3 ~Äo˜0ÿah`þÁÀ€‚?P³Íüÿÿs¹zrrjÙF„ endstream endobj 537 0 obj << /Length 195 /Filter /FlateDecode >> stream xÚ=αJÄ@à¶X˜fßÀÌ x{›`TñSwÕ‡•Z * Wî£í£ÄÊ6`“"8Î%GŠ™ùÿfŠ|q~ÆK.ø4p¡ó‚½R^j¨çåÔ<> stream xÚ36Ò3²T0P0TÐ5T0²P05TH1ä*ä22 (˜Ad’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  Ø W á Œ@Ì Äì@,ÿÿ?Ã(f„ÊQ „þ0‚pC sC3ƒ=;ÿ?°f.WO®@.uH– endstream endobj 539 0 obj << /Length 153 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01Q06WH1ä*ä21 ([@d’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæ ìþ`üJò`À‘p’ƒºBþ`°ÀÀðƒ¡üÆçÿì™Iùÿí@’ùÐ.WO®@.1c endstream endobj 540 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚU̱ ‚PÆñ#‘k[çêªWJ'Á rjjˆ ¨Æ†¢¶ˆûh>Š`›Ph—º—jù ÿ¾@ BŸ\ò©ïQà“ÒÎÃ#ŠHE—Äè³l˜dÈ—$"äS•‘g3:Ÿ.{äÉ|Lò”V¹kÌRj×_œ œÒ.Á.X ,g0i)à <¡¥©¡pƒ¶&†®A†=éjœ|c(v‘kØ]þb=ÀÐ(Ô¿áúO¨ÁI† |F£?ê endstream endobj 541 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÎ=KÃPÅñs Xx³v(æùzËíËb ­`A' ÖQ|A7©‘|±€Ð~Lïx‡`¼7UÓN?8gù«áá°Ï!ñAÄjÀÝÏ"z$¥ìr·¿~nîh”¼d¥HžÚ™drÆÏO/·$GçcŽHNø*âðš’ WUPñ÷6¾Aß´4æðŠ5¹§q ‘þ" bxØ%âtÇq¿Á_ù®cùGˆÅ²h;²š÷L€ Ëtè5Â<þfúOk…2·|âµÁ+ñ–ZlECÝdÑ ±ï(°ç˜ÂÑIBô¥Y_™ endstream endobj 542 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚMν Â@ ð)(¡«ƒÐ> stream xÚUÎÁjÂ@àYi® Î èn²Zõ$¨sÚSE¨GÁ½‰æÑöQ|„x ‰³²Iéå;üÃüü=ÝF¤(¢N8 ^DúÖ!þ qª¨¯ÝiµÅIŒò‹ôåœs”ñ‚ö¿‡ ÊÉÇ”B”3úI-1žQY¦ãâàAægà//7ˆœŽ4gËZŽvª*Ì 0‰Ã¿˜Š+ã]S‡¸CEÉ@QsüϰFÕì,IqSn/¼'¶’gCþbŸ^m‘mjg`ç1øã'>ÚŸKø endstream endobj 544 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ%Î1 Â@„á‘@„‡$|'0‰+AA¢‚)­,D¨¥ ¢æQ<‚eŠ`œÅ_ìì·°&î# µÇL_M¬‡H.bìÚ£½ØŸ$I%ب‰$Xp• ]êíz?J¬¦Êu¦[>ÙI:ÓIU•uO§Ã)Fh~ðß!;£ó:còÌÛዬQÖ‘‚ôŸÿ)HÿåpIëH]R·YÀ#õH[¤mé(œ²âl2Oe-?uàC endstream endobj 545 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚµ1 Â@EH!L“#d. ›ÍºˆBŒ` A+ ±RK EÁBb޶GÉR¦R×l´6¯˜˜ÿþPtÌ+îǬƬ5$Ii;ŒXÜf¢$#±a¥I,ì˜D¶äëåv$‘¬f,I¤¼•í(K~ |[äj¿„W¢‚opGÏà ÀÄ!´—S‹¢E¦ /‹òèzù´ÌO¾6x+Ó¸YÛ~åÕÎÜuдñí…æ­éÂÕ`ú endstream endobj 546 0 obj << /Length 121 /Filter /FlateDecode >> stream xÚ31Ô35R0P0bc3SS…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]0001;Ëñÿ ÿaX*6T°ý†úÿÿ?À0—«'W ¾NÚ endstream endobj 547 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚmαJÄ@ÆñoÙ"0M^ป'p÷WóSZYˆ ¨¥ ¢`eòh>JáÊ+ŽŒóé5‚E~°;ÿY²¬šc­té_^iÓèC-/’³Ÿ+9¸’u'éZs–tî·’º }{}”´¾<ÕZÒFoj­n¥Û(Ê-€~‚Ù€8¶#J^ÎQì0CÜc…0áùîÈDÌ_úŸžÓÁïø:ßsöNüaçü™r$_΂[-> ³À,°ˆ, %‡s„'äƒlÏ"³ÈÌñ¥™aAZÒ›M°¿ÈY'Wò TŸc| endstream endobj 548 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÐ1NÄ0ЉRXšß`3', ZiY$R AE¨€ ´ØGóQr„”[¬0¼„‰"OÊŒóÇ“ãîÈ/¥•^—ÒŸ‰÷òØñ+÷ÅVüɾóðÌëÝ­ôžÝ%Êì†+yûxb·¾>—ŽÝFî:iïyØ™-­2È9QµµÕ EëPõE6‚f¤LÍôV»&‘ÆàðÌÔb&e6‚€§Ñf“õÕŽó‘òY (yâ/ifU ý°Å_ cBüÔ¨M>Õ‹ý‚¸Ÿ™°y¥ÿ€‚޵¸2_ |ÃßÇ›jh endstream endobj 549 0 obj << /Length 188 /Filter /FlateDecode >> stream xڕν Â@ ð+ At-(˜'ð®¶µkotr¡P?ÁQðÅ_ÄÇè èý‹­³ù‘äIàõÃ+FŠÃ!¯=Ú“™º,ñ‘o)Ñ$ìG$'¦KROùt8oH&³{$S^z¬V¤SBĢ⊠ØÀ©iƒèA«äf°1ë€h‚.p;»Áö`¯Z  \2ðoóŠß›ÿÂy™³54Ö4§òý`ö endstream endobj 550 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚ•Ï¿jAðïnaÜ ˆÎ ˜½s=b!j W¦J!‚`R ìnÍG¹G°´8ÜÌœEH:›_1;ödÏyŸSp¯ÏnÈyΟíÉ9)¦œ¿Ü_6[šd?Ø9²oR&[Ìùð}ü";YL9#;ãeÆéŠŠÇÀŒÇæÒºÂ„ÐpQ*Å+j .+xsº7á”xÄ•‘Íç–Üð‘\ƒ }µrÓþ† ”¿ø´•R þ/:tK­¬uéîNTc¨'Û¼‰Ä'ò¡jìiT”2ƒ®D¥×‚Þé+XÑ endstream endobj 551 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚm½JÄ@…OØ"p›¼ÁÎ}d³ƒÚXW0… •… j)¨hëäÑò(ó)S„ÏD…m>†{çüÜuuìVZj­G+­ÏÔ9}ªäMjÇa©îägóø"›VìÖNìÇbÛkýxÿ|»¹¹ÐJìVï+-¤Ý*Ðô@ P„sŽºø‚&¾³¾[ D>#E@ƒ¢Ç†r˜Iõ~2û> stream xڕα Â@ àHÁB}Ѽ€Þ]õ¤“…ª`A'uª(¸ÙGóQî|ƒšTZèàà‘û†?$w#3°i²ÔhdÈŽéhð‚CË!Çá·s8cœ ÚÐТZpŒ*YÒíz?¡ŠWS2¨f´5¤w˜ÌHŸP˜Qžç®ÎëY’ 4aÐ:B@à ¸Ç8 ‚—1¾ìn -¡SQ¼üRá-8­ð d“_Ñ®Ó+ÈJ¢_<ÿ!’¯tùâ<Á5~lúQ- endstream endobj 553 0 obj << /Length 265 /Filter /FlateDecode >> stream xÚMÁJÃ@Eo˜ÅÀ[8мÐ$A„ÒB­`B]¹WêÒ…¢ÐEÁù´ù” ;#Ç›*ÖÍyóî{wæÎquÔLµÔZ§ZŸjÓè}%OR7KmN~&w²l¥¸Öº‘₲í¥¾<¿>H±\Ÿi%ÅJo*-o¥])L OÄ[ À`;d1ëa¶°3X`LpÀM6{ä{xÖSÏœ˜°Hpžî|tO¥0£1l¹6Ì ùi4ÈþÓ,ìÀe3zŸÓáw™gRÒô¦SÅß@v伕+ùÿcå endstream endobj 554 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚuÏ1NÄ0бRDšÆ@ò\œlÖBT––E"Tˆ ¶¤AKr®â›ì!eŠ3³ ˆšgiÿ_×'aE5t¼¢æŒB ÇŸ± 2¬(œÎ_žpÓ¢¿¥& ¿”1úöŠ^_Þvè7×çT£ßÒ]MÕ=¶[‚b—….'0SÉ2*(ÙŒ`&p ÞÁõBì!Ît ç¼àÒð_èÝ_èR¥c§Ø™%Éž 6{6Cñ!I¬cˆ“Ä)A×ô?€Ö«ÌÁ“ôXZ1IÁØËN+éOVë”ùÀäqY‰-Þàú m9 endstream endobj 41 0 obj << /Type /Font /Subtype /Type3 /Name /F15 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -4 -21 83 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 125 /Widths 555 0 R /Encoding 556 0 R /CharProcs 557 0 R >> endobj 555 0 obj [41.52 0 0 0 0 0 48.44 46.13 46.13 69.2 0 0 0 41.52 69.2 0 0 0 23.07 32.29 32.29 41.52 64.58 23.07 27.68 23.07 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 41.52 23.07 23.07 0 64.58 0 39.21 64.58 62.28 58.82 59.97 63.43 56.51 54.2 65.16 62.28 29.99 0 0 51.9 76.12 62.28 64.58 56.51 0 61.12 46.13 59.97 62.28 62.28 85.34 62.28 62.28 50.74 23.07 0 23.07 0 64.58 0 41.52 46.13 36.91 46.13 36.91 25.37 41.52 46.13 23.07 25.37 43.82 23.07 69.2 46.13 41.52 46.13 43.82 32.52 32.75 32.29 46.13 43.82 59.97 43.82 43.82 36.91 41.52 0 41.52 ] endobj 556 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 27/a27/a28/a29/a30 31/.notdef 34/a34/a35 36/.notdef 39/a39/a40/a41/a42/a43/a44/a45/a46/a47/a48/a49/a50/a51/a52/a53/a54/a55/a56/a57/a58/a59 60/.notdef 61/a61 62/.notdef 63/a63/a64/a65/a66/a67/a68/a69/a70/a71/a72/a73 74/.notdef 76/a76/a77/a78/a79/a80 81/.notdef 82/a82/a83/a84/a85/a86/a87/a88/a89/a90/a91 92/.notdef 93/a93 94/.notdef 95/a95 96/.notdef 97/a97/a98/a99/a100/a101/a102/a103/a104/a105/a106/a107/a108/a109/a110/a111/a112/a113/a114/a115/a116/a117/a118/a119/a120/a121/a122/a123 124/.notdef 125/a125] >> endobj 557 0 obj << /a21 487 0 R /a27 492 0 R /a28 491 0 R /a29 493 0 R /a30 494 0 R /a34 488 0 R /a35 489 0 R /a39 477 0 R /a40 470 0 R /a41 471 0 R /a42 478 0 R /a43 479 0 R /a44 480 0 R /a45 486 0 R /a46 481 0 R /a47 482 0 R /a48 545 0 R /a49 546 0 R /a50 547 0 R /a51 548 0 R /a52 549 0 R /a53 550 0 R /a54 551 0 R /a55 552 0 R /a56 553 0 R /a57 554 0 R /a58 483 0 R /a59 484 0 R /a61 485 0 R /a63 495 0 R /a64 490 0 R /a65 496 0 R /a66 497 0 R /a67 498 0 R /a68 499 0 R /a69 500 0 R /a70 501 0 R /a71 502 0 R /a72 503 0 R /a73 504 0 R /a76 505 0 R /a77 506 0 R /a78 507 0 R /a79 508 0 R /a80 509 0 R /a82 510 0 R /a83 511 0 R /a84 512 0 R /a85 513 0 R /a86 514 0 R /a87 515 0 R /a88 516 0 R /a89 517 0 R /a90 518 0 R /a91 472 0 R /a93 473 0 R /a95 476 0 R /a97 519 0 R /a98 520 0 R /a99 521 0 R /a100 522 0 R /a101 523 0 R /a102 524 0 R /a103 525 0 R /a104 526 0 R /a105 527 0 R /a106 528 0 R /a107 529 0 R /a108 530 0 R /a109 531 0 R /a110 532 0 R /a111 533 0 R /a112 534 0 R /a113 535 0 R /a114 536 0 R /a115 537 0 R /a116 538 0 R /a117 539 0 R /a118 540 0 R /a119 541 0 R /a120 542 0 R /a121 543 0 R /a122 544 0 R /a123 474 0 R /a125 475 0 R >> endobj 558 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ32×3°P0PaCKC…C®B. ‚†‰ä\.'O.ýp ŸKßLzú*”•¦ré;8+ré»(D*Äryº(È1Ô7Ô7ü? ¶—«'W Ë endstream endobj 559 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚ3±Ð37U0P0UÐ52U01QòR ¹ ¹Œ-€¢ †0¹ä\.'O.ýpc .}—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ðÀ !',@„ˆ( pâˆ8#ÁD` 0‚D°Á >\–!ì¡…e8=…×2„=ø-ã#2Ñ,Ãå)êX†7¸\=¹¹(o0› endstream endobj 560 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32×3°P0PaCKc…C®B.CrAɹ\Nž\úá †\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O9†ú†ú†ÿ Ä–c `3ËÕ“+ ö…( endstream endobj 561 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ36Ò3U0P0T0´P0"…C®B.#3  ‚D"9—ËÉ“K?\ÁÈŒKßCHxú*”•¦ré;8+ré»(D*Äryº(üÿÿÿ6ÌåêÉÈ#ˆ'ï endstream endobj 562 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚuÏ1jÃ0àg<þÅ7ˆÿ 4²‘ã1'…z(¤S‡$ MH×XGÓQ|„ŒJÝW\(TˆôúŸ 7uN3uúk‘i1Ó}.Gq%CËáf÷&u#öU])ö‰±ØæYϧƒØzµÐ\ìR×¹fi–Šè €éÆWà‚Op_ÝPIÓ!õ I@Ò*¤#f %×#ý¸~á,üK{ÇT#ç¼³¶,„ΰq`É(°nìYÜsLøâ¾Þ–ÇF^䃷V2 endstream endobj 563 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ¿NÃ0Æ?+C$/~„Ü @pK§V*E"L02€`«÷ÉÈ£Dâ`ž”7Ѭ$7ëãî¨d¸¬*¦ ¯:}§¿$ X endstream endobj 564 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚÍα Â@ à;:ò’'ðzxµ: µ‚7:9ˆ“: *:{ÖGñ;œs]úÈù“!¹éë3pç‡cÜk8ƒ‰YǸØ¡´ Öh PsNAÙ^/·¨r9E ªÂÆl ¶BéuL[“Vùeˆ¦T³½ôÉŽdÞø@ú‡`_µ¬‹’wV| ýÿšð‡äˆš …oafaosKƒ endstream endobj 565 0 obj << /Length 125 /Filter /FlateDecode >> stream xÚ32×3°P0P0b#S3s…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒØ€ÿ‚ˆ¥ˆŒþÃûæ? : æ ÿÿÿ€ .WO®@.»P endstream endobj 566 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ32×3°P0P0b#S3K…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒþÃûæ? ŒC 1ÿcøÿÿq¹zrrp^Ú endstream endobj 567 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ= Â@…GR¦É2ÐMtý©bSZYˆ•ZZ(Ú‰ÉÑr2EH|›((vÂðí̛ݷ«Ga_<éIÛ=Ý—½Ï'Ö]ˆžQêÎîÈAÄj-ºËj™U´Ëùz`,§â³ eã‹·å(¢8!"«Ê@'-À1¹à4r²Sjed=L A Ñ‹]l»ÓŒßÄñ V0ùee˜þǯÛ̬äsnãÄ…«òíž ²Áœ¬Ì”/óÍKÝ´í*ëßàYÄ+~PûZ> endstream endobj 568 0 obj << /Length 218 /Filter /FlateDecode >> stream xڭнŽÂ0 p[*yé#à€4"€øè€t7Ýpº ‘Á }4¥Ð±CHpH'n¼[~ƒ­8{`zzÄ9÷¹«Ç<Ðl o5É„jÎÃ~ÛÚìiVúb3"µ’:©bÍçÓeGjö1gMjÁßšó*Œ6±Þf¾'i%°ôQ|”p”Þ´Dй£+”7Y´¦Ñ&˜Dí»èþêï™ñÇÖºÍã^ÙÜ+­džF˰ÅU6ºƒ´uÒˆ“¬;Ò‰wþÛĽoÞ¤eAŸô$”Šš endstream endobj 569 0 obj << /Length 144 /Filter /FlateDecode >> stream xÚ36׳4R0P0a3…C®B.c˜ˆ ’HÎåròäÒW06âÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(0ÿ`þðÿ‡üŸÿ?lìþÿ(¨gÿñà?óÏÿ6ügü  u@lÃøŸñþC{Ì ´÷ÿÿpÌåêÉÈÈöPê endstream endobj 570 0 obj << /Length 160 /Filter /FlateDecode >> stream xÚ36׳4R0P0RÐ5T06V03TH1ä*ä26PA3#ˆLr.—“'—~¸‚±—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEó¡a9$lÄuPüˆÙXþÿÿÿ¡$N#ÌC®ca¨gc{ ùù ì00þ?À”àrõä äùJm endstream endobj 571 0 obj << /Length 202 /Filter /FlateDecode >> stream xÚ]Í= Â@àYÑ6sݬ®+Á0… •…‚Z *Z»G²´ÌQr„”!ënÄ5Ø|Å›7¼¾èȈBêR[ìÑ^àË0$)?—ÝG1òÉùÌÄÈã9]/·òÑbLù„Ö‚Â ÆÒ:c:¯êk€{ê-Ŭ`m8ë¦8•u¨ t&p2 l©µ™Bâ̘ÑϘúê½> stream xÚeɱJÄ@…á; $p ¤M!æ¾€ÎdÍF 1°®` A+ ÔÒBÑv362°eЏãì]X'ñqι>­g¤iF'5TŸÑk…ØÌè©®÷ÏË;.:TÔÌQ݆UwG_Ÿßo¨÷×T¡ZÒSEú»%yïB­7ÿ‘zÈ· CÇD`AlÙ`Áï^Ѓ\ƒ„Fö´&i!‰QÚ¤5#+§È]VÚ‚QäS¤›"wš¡Ó)ä ÓÍŠ±’SˆÑÉÁ2¬8`ܼ?†aàÏè€ÁÅhÖŒ+.Æ1À%ãˆûÞtø€¿ƒ}z= endstream endobj 573 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚ½½ ÂP F¿Ò¡¥Ð¼€ÞVn«“‚?`A'qRGE7Áúf}”>BÇÅšÞ‚Šè*3$|9º×î†ì³æV‡uÈQÄÛ€¤}®+ê5“Íž†1©%kŸÔTڤ⟎ç©á|Ä©1¯öר8Ux·èã”À*à%V7±38©“ÂÎ \Aî&°rOP ådeyÜ¿¡>Xý ?c\%éý#øë£æË'q¶(I£©fÔ‰µNšÄ´ ƒ…) endstream endobj 574 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ3±Ð37U0P°bC33…C®B.c# ßÄI$çr9yré‡+qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<] >00013Ëñÿ ÿAø9³ùà óÿúóCýÿÿÿa˜ËÕ“+ Ìt^@ endstream endobj 575 0 obj << /Length 259 /Filter /FlateDecode >> stream xÚ]ÐÁJ…@ÆñOf!"·."ç åÚÍE0p»A.‚Zµˆ ¨vµ ôÑ|Á¥‹ËÎgH0?˜ñ?p´¬NÎNmn¹ÊÒ®×ö¹wYUºÏ¹å‹§7ÙÔâîìªw¥§âêkûùñõ"nssa q[{_ØüAê­…ÙÈB´aD4%;˜>Ú#îp¨§Ýà{%*eÌdl”鈧W”]èHÿ‹ùOË·ž¦…dfä 3Âױt¢KÒ‡óF¼oæû¼³MØfl=³oÂ,"†EÌ"pLΉ~WІh–Fš¥F³*Ö4×€& !Œ3ž´DWþËZnåÎvj endstream endobj 576 0 obj << /Length 238 /Filter /FlateDecode >> stream xڭбJÄ@à?ìÂ4y1󺉗‹[8O0… •…‚Z *Úš<Ú>Ê=BÊKÖD¸Òæ+f™™¶ö‡Ç+.yÅG\×Ü4üPÑ -½Knü÷Ëý­;r×¼ôäÎ¥L®»à·×÷GrëËS®Èmø¦âò–º ÁØ`#úÁ¦” ÌJT&e« 0m´ã?H‚M¦ÈF3âC‚ …P J°@¤#ßJ“ÿ2 ‹_â.N”^‘v2%5+w:ù‹gY9–º×Cbì)û@;ä@¯ùf,B‘M¥—B‘~2ÑYGWô îøeß endstream endobj 577 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚuпJÄ@ðoÙ"0…y!óšDr1•óSZ)ˆ ¨¥ ¢­É£åQò[¦X2ÎæN¼²ð[˜ý÷ÍÕñéŠ3.øè„‹—%?çôNEÆa”Õvåé•Ö ¥·\d”^j™ÒæŠ??¾^(]_ŸsNé†ïsΨÙ0yµ("=¬·¢I 5p‡oI—àu·ë~ѽvŒ§ œÚ§î´„©5âÐF‡à rˆ¤“ q/ošAz½ ¹FÅÌxé¶`Úcο¤ý=!õ‚)Ùa¦$¼ï°ãÜ ¹Ðï íkÙkRý—:ô5±Œ€•ðš†.º¡Ö̈% endstream endobj 40 0 obj << /Type /Font /Subtype /Type3 /Name /F17 /FontMatrix [0.01004 0 0 0.01004 0 0] /FontBBox [ 1 -25 68 75 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 45 /LastChar 119 /Widths 578 0 R /Encoding 579 0 R /CharProcs 580 0 R >> endobj 578 0 obj [32.5 27.08 48.75 48.75 48.75 48.75 0 0 48.75 48.75 0 0 0 27.08 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 43.33 0 48.75 54.17 27.08 0 0 27.08 0 0 48.75 54.17 0 37.92 0 37.92 0 51.46 70.42 ] endobj 579 0 obj << /Type /Encoding /Differences [45/a45/a46/a47/a48/a49/a50 51/.notdef 53/a53/a54 55/.notdef 58/a58 59/.notdef 101/a101 102/.notdef 103/a103/a104/a105 106/.notdef 108/a108 109/.notdef 111/a111/a112 113/.notdef 114/a114 115/.notdef 116/a116 117/.notdef 118/a118/a119] >> endobj 580 0 obj << /a45 561 0 R /a46 558 0 R /a47 559 0 R /a48 573 0 R /a49 574 0 R /a50 575 0 R /a53 576 0 R /a54 577 0 R /a58 560 0 R /a101 562 0 R /a103 563 0 R /a104 564 0 R /a105 565 0 R /a108 566 0 R /a111 567 0 R /a112 568 0 R /a114 569 0 R /a116 570 0 R /a118 571 0 R /a119 572 0 R >> endobj 581 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×31R0P0F¦ :Å« Ì ƒYɹ\Nž\úá@—¾˜ôôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàg°?Pÿàÿ¬`€ŸËÕ“+ è±"g endstream endobj 582 0 obj << /Length 118 /Filter /FlateDecode >> stream xÚ3±Ð33T0P0b#K …C®B.c ßÄI$çr9yré‡+›pé{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü‚hCýÿù üF‰¡C€£ yØb•ËÕ“+ À¹—— endstream endobj 583 0 obj << /Length 316 /Filter /FlateDecode >> stream xÚÔ±JÄ0Àñ„ ½¨4O`µÐ[,œ'ØAð&qRG¡ŠâØn¾V|‚ƒëmÞp\üò¥Šp9óÚä—–JôÁá~q¤r5…KëBMKu«åƒÔy;¹µ}ts/gµÌ.ìËì ¶eVŸ«§Çç;™Í.N”–Ù\]i•_Ëz®ŒY37RcºÿµUØupû•]ì™Q/ë-%öu;>ƒj{ªPÑkPé%„G“*K¸0IX‘ S†Å]¦Æ'æÂ aÞ„a¢Ž Ì$˜W&¦ˆ>a˜’"ÌÔø…a’ ïI‚0QGdl‡ LLÌ M¦¤ 254A¦a§Ú·ž¨ê£#*ýbDM6~ÿ,> stream xÚÓ1KÃ@Àñ 7´_ Øûš¤CI P¨Ì èÔAœÔQ¨¢s#~±lý·¹IÆ !ÏÜ»{w5‰Ö Ç—„ð?.qŸEs‰™8‰4i"bþÌS5ŒD™[÷O|•ñp#Ò9/Õœ‡Ù•x}y{äáêú\Ä<\‹ÛXDw<[ ¨™ºvÿ1ÈÑc(Ù²A2¿-õ#ÌkgSrí̪öC›wYÉX@–­ÁÙ7öŠ®skÏØÏ».БÕÒy§=ê¹DŸ¨e©=AW=/Ô2ÕNе³ ÞöÜPºÇ¯›ø{Ro0åR¼¶öó¾ J7ñÞ=Œ7ÆàÑ€KgŒŸW/´1>1®1x;à†ÒM¼4†Ÿö$.ÊÕñd¬s».(ãM.Æ[·Á£A—ÎmüdÐ¥c|b];·ÁÛA7”ŽñÒíYû@¹ÊïÖ|äÃÞ[3Ø3çOçÝ×/nœéþËæØ÷<.;Çí=ó‹ŒßðoZÎ) endstream endobj 585 0 obj << /Length 287 /Filter /FlateDecode >> stream xڕѽNÃ0à‹> stream xÚ‘±J1†'lq0…ûÞ¼€f̰pžà‚Vb¥–Š‚]òhy”}„-¯86ÎL¢œ‡• Ù/Ìü;“üq«Ó5äè¤%×QwFO-¾¢kHfçræñ×Ú;r Ú+£®éýíãíúæ‚Z´ºo©yÀaCÕ 2–i¤´å¯™5º˜À€z„>‚¬%k<&rš¥,«¶`vŒìd+q3Ëß’1«^+ü ô\úoxE<@ØG*Ðqˆ ÷ù/|AüýoŒÙ¸=˜¨×,¨¢8U(`‡Ø´ fA-©‘pœûžçÚŸ¹Ú¤Pjí"ê{mœ¤ÔIš€‘ƒã倷øYRŽ endstream endobj 587 0 obj << /Length 142 /Filter /FlateDecode >> stream xÚ36×31R0P0bcCKS…C®B.#ßÄ1’s¹œ<¹ôÃŒL¹ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  Œÿ˜ÿ30°ÿoÀŠAr 5 µTì ü@;þ£af f€áú!Žÿ``üÿè¯ÿ ȘËÕ“+ > stream xÚ36×31R0P0bc#C…C®B.#3 €˜’JÎåròäÒW02ãÒ÷ sé{ú*”•¦ré;8+ré»(D*Äryº(0°70ðÿo`ø†™˜†ëG1Õñÿ ŒÿÃúÿdÌåêÉȸ§‰ô endstream endobj 589 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚíÑ¡Â0à[*–œÙ#pO@·@ ¨%0&H@! $¸ñh%Ø#L"Çu€…D´ùþ¶—KzzµÙ¢ê²™Í"\¢1’CÝÅtíõˆŒAÝ“SÔiŸÖ«Íu{СuBãˆÂ ¦ ²åà³U|0Û€ù‰Ø–ØB%/Q@Px¼·à_åQvØïʲ#€rˆO‚û ^‰Ëç7\©ëŸ‘†ýãgpÓ÷x'A~^ɼ™¹P²Ù/ÀnŠC|U¸ý endstream endobj 590 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚ­‘±NÃ@ †}êÉK!~¸5Ç©©*ÁÔ1#æÜ£õQú3T9l× êÈÝIßɾü±‡Ûë5•TÓUEá†Âš^+üÀ:p°¤PŸ3/ï¸éÐï©è·Fßíèëóû ýæáŽ*ô-=UT>c×€Kxåiôi$Þ«Š@v”#W@Áø!ç'=rå4à8 E\)™æGCÎ †B1Š:‹6ŠÓ½bê¥:wZ¹KÿŠ??²"XÖi=Ì1w«½fùbpêYœ4?Í]óšeä[›ƒã©ÄßÙÄt~xßá#þ°´”ð endstream endobj 591 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚÝÏ? ÂP ð¯,d°«ƒÐœÀ×ÚVt*øì èä ‚ Ž‚ŠÎ¯GëQzÇNÆ÷:ˆƒx‡üÈ—@ i¿—Drj*ñ æCDJb“Cíb¢qNjÍILjn¦¤òß®÷#©ñr©)oÌ™-åS†¯†/ž–ÂX¥ˆSeF·Ô•+^¡+ˆkÛª»d%ôA¢è3ðv×X}Xþ´øÅ~äÈö"õ7i–ÓŠ^¤Ds. endstream endobj 592 0 obj << /Length 281 /Filter /FlateDecode >> stream xÚuÐ1NÄ0Ð¥ˆäÆGð\’o$"-‹D $¨(PR€ [mr®â›#¸Lv˜q v š'Ù3þ3Éêì´n¨"O'5ùsj<=׿Íx/—5«¥òôjÖ)ïÉ{S^˵)»úxÿ|1åúö’jSn衦êÑt8ä€å©zÞ[dŒö yDñbDΰƒtÁ‰=Z¨b‹è°M΢ýÇûyqPû¡©“Újë•e^Œ5X*³>ìYëŽYžÌ:#•õB´IjÆ!¥MlGÕ-ƨéÉâH]$?r>Pçäcš6òŸA§Ù ÓìÖ~¢þ¥I"v˜¶ÈfD7¸ˆ(Ÿ0æºl@/]æª3wæׄŒœ endstream endobj 593 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚ35Ò31T0P0RÐ5T01U°°PH1ä*ä21 (XXBd’s¹œ<¹ôÃLŒ¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. Ñ@ƒb¹<] @€ò>’ƒdF"Ù‘H~$RLÚƒÉz0ùD2ƒIþÿ@ÀðƒD1aˆ’Œ¨L²ÿ``n@'Ù˜ÿ0°3€H~`¼ücà1ƒ(¸l@Aÿà(ÀáÍþÿ8¸\=¹¹~@‡Ø endstream endobj 594 0 obj << /Length 203 /Filter /FlateDecode >> stream xÚíÒ¿Aðïr Éî$7/ÀÞÆeQIüI\!¡Rˆ ¥¡æÑîQ<‚ReÌž V÷Ûùv¶ù¶™Ö[mN8åšå¦e×॥-9§Ã„]úHkêfd¦ì™¡ŽÉd#Þï+2Ýq-™>Ï,'sÊúŒ0eQĈ"”ïüå²ÇÜŸÞÑñþñ3‚Ï?£(%V” œÊUè… Ð’“n(6áÁY4nú+|×<>èÈ­h‘\Ð ºEƒŒ&tj8­Ú endstream endobj 595 0 obj << /Length 328 /Filter /FlateDecode >> stream xÚ’±JÄ@†'¤XØ&oàÎ h.r98œ'˜BÐÊB¬ÔÒBQ°2y´{”<•[„Œ»ó¯ÁÂòÁÌÎÏ?›¿>;Yò‚k>>åºâõ’+ûbW±¸àuÎóݶ¶¼åÕÒ–—¡lËöŠß^ߟl¹½>çÊ–;¾«xqoÛ¡ø4rßLd¢X鉜ÏdZ=5¡ù Dá-FÊBÁL”‡v.dú8šÐQOöÅx…ºÁMÿEãÙ  Hÿ…žÔÍOs˜Q¡¶ åZDæç3½è „EÊ!Iàösiãçg’‰ä,¹þÞ¡K€™óÍoø9\˜`5àFøøÿ¡ñºUÀ PSÍá–6ð¹ù#Àá) ˆF>hP2Ć&˜7·t>«Ç¸!|ºH‡kÕ`Ú‹ÖÞØ/U=Å¡ endstream endobj 596 0 obj << /Length 246 /Filter /FlateDecode >> stream xÚÍÒÁJÄ0€á† sè¾@©yÓ¢]+ÖìAГÙÓêQ¨¢°7û&¾JßÄ>Bž\ó´¸wÂÇ$2™ŸëLÛ5?Ò§…¾ËåQŠrÌ3›ÚƒÍƒ,k17º(Å\Œ»bêKýüôr/fyu¦s1+}›ël-õJ6† ø©Âpb„³‰ø:q÷[õî ½oÎÈË}1¦˜`…[lpÀÞ©0ì°uF^úŽ1Å+ÜbƒöN…a‡­3òò>1¦˜`…%68`ïT8–q¶ÎÈËf˜b‚–Øà€;Ý>ÿš÷qñÁÿúüž³í·Ý§œ×r-_³c·Å endstream endobj 597 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚ½ÑÁJÃ@à-9æ`^ ˜yÝDL×@h ­`‚ž<ˆ'õXh‹…œj-²c¥uÍþ-f¡<8—f–º¼æˆ_\ñ áTñ[LsJ”IFœ¦¶ò:¥QAò‰EòΤI÷ü±X¾“=Œ9&9á瘣*&|&lœÃpo×p×FuÌÜ*ºnáæà°½­YëLÜ´6&c¢§am*&<èWPXh­¿íà –p†aKOÃÚêA³ú88Ò‡,q½ÐÝ6žvÚ8íÇÐYA‡Ž+Ç-Ü ý½½ë®þ ƒ†ÍïæôóŸÌ±¦°þ¹º-葾YïšÓ endstream endobj 598 0 obj << /Length 380 /Filter /FlateDecode >> stream xÚ’¿NÃ0ÆÏò`ÉK!~HƒÚ N‘J‘È€bF¬M-’GðèÁÄÜw.*$D駞Ͼᄏæôxé®qG'®©ÝzéjûlW.ܺÉ'÷OvÓÙêÆ­–¶ºà°­ºK÷úòöh«ÍÕ™«mµu·µ[ÜÙnëˆt"üÊä”"!–5Q¥‘&|ÔdÑŽ9‡?5“â1p·'ÍYœf€r0#0@ñ…˜JÀüñS¾'KŸ ß(‡b΀ò–L ɤ ’5º‹¤¸;–¬ÒLÚ£Y‚Ö>‰º6MÜ"v(™Þ÷Nì}N~˜U¤ÿÍù •UTã[¤²Tä°ðµåçfñ‹SUÄ•AT §H#ä°dÈQ)÷ž¼Ò{ˆ£6´R2ô"@¤òX:î!rTŒ¿Aÿ\§ü¦ú„ÔS^ªë¬EŽj,òp ŸÇdØïŠtÌS‘Ž'BZIÌÊë¦òò±â®,¦=ïìµýÖYÙá endstream endobj 39 0 obj << /Type /Font /Subtype /Type3 /Name /F16 /FontMatrix [0.00697 0 0 0.00697 0 0] /FontBBox [ 2 -2 115 100 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 46 /LastChar 117 /Widths 599 0 R /Encoding 600 0 R /CharProcs 601 0 R >> endobj 599 0 obj [37.42 0 0 0 0 67.4 67.4 0 0 67.4 67.4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 48.61 0 0 0 123.54 0 0 0 0 0 0 0 0 101.06 0 0 0 0 0 0 0 0 0 0 67.4 0 0 0 59.9 0 0 0 37.42 0 0 37.42 0 74.89 67.4 0 0 52.41 53.16 52.41 74.89 ] endobj 600 0 obj << /Type /Encoding /Differences [46/a46 47/.notdef 51/a51/a52 53/.notdef 55/a55/a56 57/.notdef 73/a73 74/.notdef 77/a77 78/.notdef 86/a86 87/.notdef 97/a97 98/.notdef 101/a101 102/.notdef 105/a105 106/.notdef 108/a108 109/.notdef 110/a110/a111 112/.notdef 114/a114/a115/a116/a117] >> endobj 601 0 obj << /a46 581 0 R /a51 595 0 R /a52 596 0 R /a55 597 0 R /a56 598 0 R /a73 582 0 R /a77 583 0 R /a86 584 0 R /a97 585 0 R /a101 586 0 R /a105 587 0 R /a108 588 0 R /a110 589 0 R /a111 590 0 R /a114 591 0 R /a115 592 0 R /a116 593 0 R /a117 594 0 R >> endobj 602 0 obj << /Length1 1438 /Length2 6052 /Length3 0 /Length 7022 /Filter /FlateDecode >> stream xÚwTÓ}Û?RÂPI‘f*pÝÝ)’c ±m#é’îTR¥DBR@¥ABBEéx‡z?Ïs?ÿÿ9ï{vÎö»úú|¯Ïõ=¿qÞ¼kįh´ƒ©!X~°H ¨¬«« A aHÀÉi ǺÂþÖ8Mah ‰úe4 ‚ÅëT X¼£.Ôzà  ÁbR`q)(IþíˆDKU p{ ®P ‰€aœÊH”7îè„Å×ùûÈ å‚%%Åïü *ºÁÐp(Ô…``nøŠPˆ+Ð …ðÞÿHÁ-ã„Å¢¤=== n$ÚQŽçÐŽuÂ00´Ìx¨qƒý&à;Á1¿ FH¬' â®p( Á‡<@ØÃÐ@|u ‘¦PCüvÖùípøçp€`ð¿Òý‰¾HGü †@¡H7á G8à®0 ¾šŽÖ {AØ_8B\1H|<Äw…Øá~µª)!x„ða h8 ‹ÀÀ]/0 ^¤Á³*Â^éæC`1€‹þTàhîÞ‚†ë‚@z"|þ–à{‡ öP‚&¸û˜¦Ê¼ ðo# Iˆ Kˆaî@˜ÔI𢀱7 ö˾Pã1øù ( ÌîÃÿ|0‹~óóùOÃ?% ´‡C±@;˜#øwv¼æð[ÆÏ ÷Z€ðôAŸ=YáfD¸zÿÛý׈î©ÝU2åûù_F%%¤Ї_XÈ/$ ‚A"@qüƒß?óüëþFÿK{ÿÓÝdÔD8 %.Pàïo$¨Áýgox€ÿ,¡‡Ääþ7ÿ-A¢ (þ üÞ‚_!ÿ?ò_dù_ùÿß©=puýeçþíðÿØ!npWï?xB?Àâ—C‰_Ä»šÁ~o´.ÌþÀí¿­šX~IŽx¢óƒE@"¿õpŒÜ fŽ…:ý&ÓßÓÀ×p…#`w‘øÅŃþˆß=¨ þrÁàgöÛÁàûk¼2 ¿jÿìCEÚ_줨‚FC¼xJà%Q ¿¼ö0¯_œ X|Ùè€D.-&t¼¸áðÇ€7üÖ€‚®M\(þQ úÆ·ó‹&øVþ–]0˜ ˜œ@B¥ƒ«ƒ[+™=ùW†dH¶ÒÍ…ø‡ ¬É°Ýª£6‹ FÙYSÚÏÕ&»ÀjÖÎmzJî‡9sv|–kØk½EöùÙÕÖÙíâ&Î÷/'ú°Üš l$xb–¢Ä&UŒî&¸ËEÕN.oïØmÄIéûWuçÇDO.º5q­½ÖöÊ’,zIÓ/Ÿ ±Mv}Æ+¢» å~r‹ ZжŒHÕ˸¥-ÓzHð¬ Zèíîbíˆ Ôòx´ò#K­*ÝÇ¢"r¹ÂtæéµŸ¹Å›4>vê´ ›öÝ/æyR«õ¶–·7­nr'µ‹;Ù&9Dƒ¿àŽX©Q3tJiè¼üÕHûéœ0v¢†^¹ÄŒig:\ãõ\Ù'V­°mï©ñΑ…Ÿ´S5-†{‚¹ïè&Èž•.ñ«ã|ãáJØüWe õ²*}φŸCÐÓ×ì™}îq3! ‰4§c¹¢Éàæsjaá«ð´r“k‚uŸ{/ÞÛ÷Á‰œ=ÝimUâšr¯ˆBÄÐDãjf|3 žoßÔBÓ«¢•qžn‹û¾^‹V:½nÈB¿2\‹›è×…Ô£‘R@öœgm‘Á1 ͷʦ—ºÂ÷ØJ ãì Jôò^ïÒ¿íA¶Ù .Ð 9Èó¸7=S)Ôèñ“€ªÞÍÍÌÖ¸iz0h_³>@Ú^äi¾q!夨ԥcºÛPíXÞ™ i>ÜðõËæÑ4¸«.ÀcóžÝr÷;±pŒæqÓ6Wˆ<ìÝûƒxÙ𠇦z™ïÎÚ?q¸4ºîÏqÚìºqXQ¥K.ñwå­Üpè GmÊÇÎøÕ`‹i觯ye>:£›\áíí€~ólÉ¥þ¢…ãƒouórò´S˵Æyûß =3Æ¥al™°¦-€à6yDó+K½÷Éׯk~ÁyaØÕ)ó§AͷĶݱÁ Ç~í4«#I<•¡ÄF†cæÉÞ7hd²0µBÎÉúÖ-‹AÍTœíWbM²›C|äÆcóJ+ž)»!çW@Cœ¥~OPÓ7ì?û8Ñ‹ÈEÒD^¶öT)ú®3ص¿ÖE´Ûß±^Ph«“'C] K³T*u7)²ÂNNØzw÷®Ü*Ó†®¯Ú»r?ßü4FŽÈð²Ð6¾8ö.˜¼¢%åH7bTd‹Ý–bÈn`§>â><‡šj2V‰qÛ uoF`Cì‚fŸëm† YAáÅ}‘sÙ-Ö·èô—ÞÓNÖ¼Ú“U¾–»ïExÒÖ1énæ ßá­ëŠôõx^(Yt£2÷–¤¥–úìÞz†_‘Ø3!?í Ð7ÓJú¡—Ñ—§‹ÅÚý"@Û.J á=g®ßä<æÌ7d>iÜ‹©ì!öò yEë°¬ÆÏ‘y+ÓŽî&wÎEÅÀÐ+]Ó{mݹ ±+Û…bYq_¤lŒTä(}w¾fæÜY‘7ÓÖq4ÌàyU59wÑgéÀJƒ«&ìÁÊ(»µ· ҇ʒ°u.5 î(ÀÓŸ!GqGEòC 1h‚ȯi-Í6»å!—©GôÉÌæÞ.•ä–<8ÍÄǸ&”sUˆî]y3ZrT÷þ#y`ÿ¼Î=ÓûÏí¾ˆ˜çX ‚ :ÓË©Ž»TTß4ïn׉k­?|Òo’Z¹Ÿ¹Ô s=6Ö`éCŒžygvÁLzzÎbB‰g²"‘!ÂìC¾VìÀ «ôåUf\Sà¬^9W2S’ú{°B]¨€ $¡tïˆæ¥a5\GQk€ÉGAmB"×b^î y¬äÞ€jO¿ªG‚5¼œÇÓvÉ.‰?ïUy#½ÞÕ;—Kõʯ6z•Fdé]ǃ¸!ßœcºöH«ž‘툔½Ù’gA›tH«  Iýà É;káÀ(K¨KC/<ÆÃÙòãY9U¢ûóòz}n’6Kþû7£Ùr6µ:<,hƒý¸:VÑýü‡Æ v:~‚rC¢.4_d <ŸêŸ‰Ó‹þ ¿Í,•üáÎSz»òñu½ý7ô”ËWt÷ß÷Þ_’K¾FÝ3|¾reå‡0ïçÛfÙ*kQÛc¾Û97Ô"çû#Ϙ֧t¥mì R´49ê›S:ïõqd w3t_£=Èײ`Hðw˜ "’¼“òB¬æÓ ðqþ˜¿'âåæ3£;$òàXù 2Š ÅñîyoWîGK:—š†±/󨉶Lâh¾}Y#og|á¦0ÊKgL'7­ÚDXh¦ïÈ?•2ÑMY©±ŽZe¸Ñ e»Ef‰+8}M%8:ƬêlJâ“ ŽØW%›êœŽŠz›iûâFw–R¿ûNÕc/8+Ù¯‡˜Ê–ã&…§Ú'´ü[V-ª[ëÎÞ Ûžzä¡è “+º¦fÏ3÷>ÓÞãÇ®¥§­W–U á²ßÿˆ.$ȉaÁu®]³¶/í2V# r› 47éGXmx²ï§ïŒÛÀ¨T¯a¯š@E¿¼U^Tˆz„ì¥êõÒQyÛ¦˜Yÿð´[¯ˆõ!P'êk–Cת wÊ£AD^õÔDÖ4|&æùðȳhÌÕÎÉ–˜ OÇè9²J"¶U‹güD¥§ _ö®­•â^¥¬Ä¢ËI(7F9 •žSè FÆ}–jT¢ßNÌ}à PgÎ?Yal »É¾͉ÜUô"¹óÅÜëß•ªOù©]Z^6åô¤¸.îž¼Ôf+w‹šU˜³)PükõCûýæ±v²;†0r·q ¢²˜ö”ÿÀ÷òï¤æ3‰Š§nЏɽÏYÄö­zÒ·–ÓýHGJZQó-û©×•Õ‹®$ê½Ë­|Ü5ï+ Ô¾üMŒª]qþ`¼×Öv¹ÕYJ‚ðÁýšØ€ó3“"NÞc1fË;õJ«‹‰Sñ2ý+w£9PDÎeí=ëžØ>xɼ¼@ëùxNÃÏqà+“Âî{ÍÙÎ!~O–¯±Ê—·úØÒ*‹+À—ýä>pX×Ò•t¢R™'Ì­羯|R¡•a®‡ ÇùáÜÅôS•ÉÒø¾½eid™¼ßx†ârý ‚SÖr¨>OPÓˆq#à™¿1W LRŠ7\gºr€8½\nž*§KH®¶âéçâ¯3¢ðùkéë«ê²]Ö/œ>nð¸Td6ÁÉ%ìÆâ0Ö7½ÔÏâCÉ(7ôB3îG}s®XR£3žiywõd+ˆÉpºòãT›_ðÑÒ-êFVñ­>$ \'èPݳۊº£\î¾ÓÉzjN»©™ŸÙ3žFŒ~e9]ÿúÑ›óO'†0¤­GÂb3ÚþJþËðxyE–Ã{å¡ë¤UÏ&šÌHöQ¡ã;.¤Oƒ†ú󨩏'­t—?PS’SÑíÏÄY–¼×O®r~ç-˲[bUdÄqœ=€~ ¸E¢b_)~'t*Fc(B^…Û’h½Mp†ƒòeWUã*š“¶„¬Ð5…R¹Ü¬r¥°µ©»ƒ³5ãÒ{?< ös3ËZçÿQ§»¨8„ÃØbìüâr¢'O;1 t6‰˜AÂÔœ%µð¶`JýÕ×/R]¿EÍ9YªÛÚ]Ú‡°Id4ppÏm÷Y›ÓV¸gÔŽïm-í(“ÜzqîÑÕ¸ç|FM#Ÿ–{<3 È:Ö°**P‚‘jµêe–Ö*yU-ïÚV[ ¥£Y>#¸[x°{F–?½Á?þ(È$Øo'šœ8sêr"¸â3Oº>’„ÌÊ£ Ž}ÛC´ô¥PB“:5Ôòf³§A÷‡ÔXò1âô5Ô(`“Yôæó„œfPrä§)…›)õþË*äc·%¤¯<|²]{¾ƒ!f͵ި”uTþþ4¾6pVþhmóî²tŒUb ÚÿP#±"Bû“¢sgMLù™¸ºã㦴£7ÌR”GJ²’{—ôn2pdò6ˆÅï÷9¡)÷n‘³ÃJ¥×®Œšu ”Øû¨ŸTÓ‡È æÀËõ…1^ðÊHÓçîWâ+^$•QM >;è]òô¶šŸ°ÌšÁ¹»};“ÏøX¨]¼/í³·gÜ$òˆ*´=÷ul±ÞÓ­qªÒV—Í….û¯M'UÙÞ âðB«+4Ð8¡Ýïjó7ÍG'_3…fËo_- #N?Ûè¶ ¯L¼O€>8õn21 tY ŠÃ¿‘ÔõG0¿xØìÛb~w<ÏôU7÷:nndÃÍÇãÕãN=,oîà (JzÕ S…4Öe|Ž?3{C„•³¸¸žD­äh+ñÊáì×j¦KDŠú¹Ü塘7UœÜ3'¨!•i[B\$iü¨H í-ÿÊ»¥]ᛲTw Ö“Rɸ7Ud¤kœ+»úŽç'5WŽ„0t¬OëçOkCÕßêõFB{„Æ6@Ó„Î.‰¿W~l­¬”·µVI';‹Ž±MÙ¦Ëru/㲚mK׃1gk¯%jX¿È¢À)?(¬cÒ¶¯Ñ]§¶½ëotÎ.«={.¯z´ªÍœ™ÉU÷‘¶ä"ç°ø-è5n%ØütÏäI©{I/¡møì@‘¢,ÑD¢§·Ç‹Â\a9ºªZ¸ïêRl§€0àÛ”6ŒFä$Dy‡VÐOÖû±½\Ó^ÿ¨mjtû…ÓbtN2JUªÕ³?;g„^JC‘˜ÛYÚ)«¹·Q¬ÕkûýM’9¡×Ö\ÂzQ—¹èˆÀ”SÉm²f ÆÜIP!´Î¿£‰^«ðÊRhãV`¡”;1}OŸ“·öl홚´Ì½óÜw!?ý;}·_4Ì“SÓî ¢ÛN‹Ø+¶»ì6ZzókO–]K9]q»  ˆ?æs¢Ê]e=mËúÙíUyÕÛ? £É·6]nÏæî&(åûjQðœïjX3“ÒùÝIõ0‘W‘á HÙ²*È<-ø–üò{Bé§¹uõw½Ô‰$ Ækšºû‹ÞQô"‚º¬¾• m·semŘzHIâ±Wi‡$\úÙàO×He쎒³r›.–rÂùؤe¯f«O?|ˆ“ 7B£¸B«9"\ö–ß*,‘Õ¥EAtÂ_§Ü »Ý_ ó=IÛµ«øÄ–Nq«&1RJí÷ÛhÕgã™w·B¥–Œ%OÑÏ%Ì—õª.lî&‰šºú±Èfµ[ö<‘ê”/µbT_r%TÑoá‰%Å¢·5åY/›èŽ&$/cÛ矈铅9+M-IȇÈ^Q!yCÏbñx×[%i²í²›Y‘Íí»(ÈyН'µ¦íeY'ñ…ô`^ñ he£n ÷)*p­z+¼úJÿiì‘ )ia{ Rp?;ÂDáE‘¼³Ç7HÏ+^¿¥1lsh ³ËöÀè4_ª™vy/šjoŽ9NÑx\dïb†_q÷6•ée[ô¢ÝåÏò'þ©>LçWy¯éš>¾[1ÌÏ'üáf:1Ï]ª“‘²dæõìÒzHV°Š² ¬fì§jõ£EøÉ|±' —n£wLþ=å‚$r»£¥Æ¢>rEÏëÚù€ƒW@–²ø,ò|U±eVW3t˜ ©ÈÙ¡n¿ “•qxºÿ_i¬'òÞç…w9‹I;(Ò|ù+¡:TÄÁ»µÆÄÔ¹ßpþ}ÔÔ„YçÌ:ÇL¡âã…eê|÷Ûr•¢«æ#Û6dÉx¹Å_Hø? ‹»6ºÐÓæšüZ‚ýz={u÷«F'­“†¢Ž<–§ÜÎ1çv+¼ô²¾Øhæ;ÐÑDM7ȵa«²ö-FÆ´Ù“ ´<štð„—=V1h;•¿¤sºæˆú!)ÔW8󢯾”ˆJõaâI?W'Ý£¤=ŇušäAµ³üï—¦Œl•¯<w‡gÐËØR PØê†¹ÑJ¬±™¾m(Ëèw}/¯¯ÏÔ?š72æ•8Jh«ÓÙ|ÕÜ œ@îâŠÌ‚¾À¥zIÍZø¶‰SµkZÚ~N{~~†q3.muz$†žÚØÖIä’2»ÙÕ’\r|^P§c/F¨}9óªÂ‰ð{ËoFzROòéÿr$^/š'3‘ŸãY7´ã9™BF7¤­ÉEŠ]]êêõçI#×O¼xÖkî)úVðÖÀ¢¯Kz 7Œ‘CaNëE«:EãB"[ï^G HwyÛ 5b¼ÎÙµ½r‰ß0[®wè˜|´äKŸh¸SËÚV³¯¦€èƒ[ƒ»ùxl> endobj 92 0 obj << /Type /Font /Subtype /Type1 /BaseFont /SYFPBV+CMMI10 /FontDescriptor 603 0 R /FirstChar 60 /LastChar 62 /Widths 156 0 R >> endobj 42 0 obj << /Type /Pages /Count 6 /Parent 604 0 R /Kids [34 0 R 52 0 R 60 0 R 66 0 R 74 0 R 79 0 R] >> endobj 93 0 obj << /Type /Pages /Count 6 /Parent 604 0 R /Kids [87 0 R 95 0 R 102 0 R 107 0 R 113 0 R 118 0 R] >> endobj 129 0 obj << /Type /Pages /Count 5 /Parent 604 0 R /Kids [126 0 R 131 0 R 135 0 R 140 0 R 149 0 R] >> endobj 604 0 obj << /Type /Pages /Count 17 /Kids [42 0 R 93 0 R 129 0 R] >> endobj 605 0 obj << /Type /Outlines /First 3 0 R /Last 31 0 R /Count 8 >> endobj 31 0 obj << /Title 32 0 R /A 29 0 R /Parent 605 0 R /Prev 27 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 605 0 R /Prev 23 0 R /Next 31 0 R >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 605 0 R /Prev 19 0 R /Next 27 0 R >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 605 0 R /Prev 15 0 R /Next 23 0 R >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 605 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 605 0 R /Prev 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 605 0 R /Prev 3 0 R /Next 11 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R /Parent 605 0 R /Next 7 0 R >> endobj 606 0 obj << /Names [(Doc-Start) 38 0 R (Item.12) 90 0 R (Item.13) 91 0 R (Item.14) 98 0 R (Item.28) 143 0 R (Item.29) 144 0 R] /Limits [(Doc-Start) (Item.29)] >> endobj 607 0 obj << /Names [(Item.30) 145 0 R (Item.31) 146 0 R (page.1) 37 0 R (page.10) 109 0 R (page.11) 115 0 R (page.12) 120 0 R] /Limits [(Item.30) (page.12)] >> endobj 608 0 obj << /Names [(page.13) 128 0 R (page.14) 133 0 R (page.15) 137 0 R (page.16) 142 0 R (page.17) 151 0 R (page.2) 54 0 R] /Limits [(page.13) (page.2)] >> endobj 609 0 obj << /Names [(page.3) 62 0 R (page.4) 68 0 R (page.5) 76 0 R (page.6) 81 0 R (page.7) 89 0 R (page.8) 97 0 R] /Limits [(page.3) (page.8)] >> endobj 610 0 obj << /Names [(page.9) 104 0 R (section*.1) 57 0 R (section*.10) 84 0 R (section*.11) 85 0 R (section*.15) 99 0 R (section*.16) 100 0 R] /Limits [(page.9) (section*.16)] >> endobj 611 0 obj << /Names [(section*.17) 105 0 R (section*.19) 110 0 R (section*.20) 111 0 R (section*.21) 116 0 R (section*.23) 122 0 R (section*.24) 123 0 R] /Limits [(section*.17) (section*.24)] >> endobj 612 0 obj << /Names [(section*.25) 124 0 R (section*.26) 138 0 R (section*.32) 147 0 R (section*.5) 64 0 R (section*.6) 69 0 R (section*.7) 77 0 R] /Limits [(section*.25) (section*.7)] >> endobj 613 0 obj << /Names [(section*.9) 82 0 R (section.18) 18 0 R (section.2) 2 0 R (section.22) 22 0 R (section.27) 26 0 R (section.3) 6 0 R] /Limits [(section*.9) (section.3)] >> endobj 614 0 obj << /Names [(section.33) 30 0 R (section.4) 10 0 R (section.8) 14 0 R] /Limits [(section.33) (section.8)] >> endobj 615 0 obj << /Kids [606 0 R 607 0 R 608 0 R 609 0 R 610 0 R 611 0 R] /Limits [(Doc-Start) (section*.24)] >> endobj 616 0 obj << /Kids [612 0 R 613 0 R 614 0 R] /Limits [(section*.25) (section.8)] >> endobj 617 0 obj << /Kids [615 0 R 616 0 R] /Limits [(Doc-Start) (section.8)] >> endobj 618 0 obj << /Dests 617 0 R >> endobj 619 0 obj << /Type /Catalog /Pages 604 0 R /Outlines 605 0 R /Names 618 0 R /PageMode/UseOutlines/PageLabels<>1<>]>> /OpenAction 33 0 R >> endobj 620 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.10)/Keywords() /CreationDate (D:20150606134849-04'00') /ModDate (D:20150606134849-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-1.40.10-2.2 (TeX Live 2009/Debian) kpathsea version 5.0.0) >> endobj xref 0 621 0000000000 65535 f 0000000015 00000 n 0000005311 00000 n 0000181017 00000 n 0000000060 00000 n 0000000084 00000 n 0000005366 00000 n 0000180933 00000 n 0000000129 00000 n 0000000161 00000 n 0000005423 00000 n 0000180847 00000 n 0000000206 00000 n 0000000237 00000 n 0000014139 00000 n 0000180759 00000 n 0000000283 00000 n 0000000322 00000 n 0000025491 00000 n 0000180671 00000 n 0000000369 00000 n 0000000397 00000 n 0000029954 00000 n 0000180583 00000 n 0000000444 00000 n 0000000474 00000 n 0000039568 00000 n 0000180495 00000 n 0000000521 00000 n 0000000562 00000 n 0000040883 00000 n 0000180420 00000 n 0000000609 00000 n 0000000642 00000 n 0000000969 00000 n 0000001191 00000 n 0000000692 00000 n 0000001077 00000 n 0000001135 00000 n 0000171372 00000 n 0000164585 00000 n 0000156801 00000 n 0000179937 00000 n 0000001942 00000 n 0000002092 00000 n 0000002241 00000 n 0000002392 00000 n 0000002543 00000 n 0000002695 00000 n 0000002847 00000 n 0000002999 00000 n 0000003267 00000 n 0000001766 00000 n 0000001285 00000 n 0000003151 00000 n 0000133433 00000 n 0000124793 00000 n 0000003209 00000 n 0000112167 00000 n 0000005539 00000 n 0000005145 00000 n 0000003373 00000 n 0000005253 00000 n 0000096064 00000 n 0000005481 00000 n 0000008764 00000 n 0000008540 00000 n 0000005645 00000 n 0000008648 00000 n 0000008706 00000 n 0000083512 00000 n 0000061669 00000 n 0000051587 00000 n 0000011681 00000 n 0000011457 00000 n 0000008894 00000 n 0000011565 00000 n 0000011623 00000 n 0000014369 00000 n 0000013973 00000 n 0000011787 00000 n 0000014081 00000 n 0000014196 00000 n 0000043480 00000 n 0000014254 00000 n 0000014312 00000 n 0000017828 00000 n 0000017546 00000 n 0000014523 00000 n 0000017654 00000 n 0000017712 00000 n 0000017770 00000 n 0000179795 00000 n 0000180047 00000 n 0000020702 00000 n 0000020361 00000 n 0000017946 00000 n 0000020469 00000 n 0000020527 00000 n 0000020585 00000 n 0000020643 00000 n 0000023085 00000 n 0000022854 00000 n 0000020844 00000 n 0000022965 00000 n 0000023025 00000 n 0000025668 00000 n 0000025320 00000 n 0000023204 00000 n 0000025431 00000 n 0000025548 00000 n 0000025608 00000 n 0000027719 00000 n 0000027488 00000 n 0000025799 00000 n 0000027599 00000 n 0000027659 00000 n 0000030193 00000 n 0000029783 00000 n 0000027850 00000 n 0000029894 00000 n 0000041277 00000 n 0000030013 00000 n 0000030073 00000 n 0000030133 00000 n 0000032518 00000 n 0000032346 00000 n 0000030349 00000 n 0000032458 00000 n 0000180161 00000 n 0000035482 00000 n 0000035310 00000 n 0000032649 00000 n 0000035422 00000 n 0000037421 00000 n 0000037190 00000 n 0000035613 00000 n 0000037302 00000 n 0000037362 00000 n 0000039927 00000 n 0000039396 00000 n 0000037540 00000 n 0000039508 00000 n 0000039627 00000 n 0000039687 00000 n 0000039747 00000 n 0000039807 00000 n 0000039867 00000 n 0000040940 00000 n 0000040711 00000 n 0000040058 00000 n 0000040823 00000 n 0000041047 00000 n 0000041526 00000 n 0000041552 00000 n 0000041615 00000 n 0000041652 00000 n 0000041687 00000 n 0000041993 00000 n 0000042299 00000 n 0000042663 00000 n 0000042914 00000 n 0000043222 00000 n 0000043729 00000 n 0000043813 00000 n 0000043962 00000 n 0000044068 00000 n 0000044245 00000 n 0000044420 00000 n 0000044746 00000 n 0000045097 00000 n 0000045333 00000 n 0000045705 00000 n 0000045994 00000 n 0000046330 00000 n 0000046625 00000 n 0000046937 00000 n 0000047230 00000 n 0000047497 00000 n 0000047815 00000 n 0000048089 00000 n 0000048399 00000 n 0000048667 00000 n 0000048996 00000 n 0000049249 00000 n 0000049596 00000 n 0000049902 00000 n 0000050173 00000 n 0000050492 00000 n 0000050755 00000 n 0000051036 00000 n 0000051295 00000 n 0000051836 00000 n 0000052161 00000 n 0000052540 00000 n 0000052915 00000 n 0000053099 00000 n 0000053265 00000 n 0000053494 00000 n 0000053668 00000 n 0000053959 00000 n 0000054266 00000 n 0000054543 00000 n 0000054731 00000 n 0000055044 00000 n 0000055374 00000 n 0000055623 00000 n 0000055948 00000 n 0000056212 00000 n 0000056473 00000 n 0000056733 00000 n 0000057001 00000 n 0000057275 00000 n 0000057489 00000 n 0000057804 00000 n 0000058026 00000 n 0000058202 00000 n 0000058479 00000 n 0000058649 00000 n 0000058895 00000 n 0000059113 00000 n 0000059384 00000 n 0000059654 00000 n 0000059868 00000 n 0000060137 00000 n 0000060351 00000 n 0000060559 00000 n 0000060822 00000 n 0000061139 00000 n 0000061440 00000 n 0000061918 00000 n 0000062223 00000 n 0000062586 00000 n 0000063084 00000 n 0000063297 00000 n 0000063570 00000 n 0000063838 00000 n 0000064086 00000 n 0000064329 00000 n 0000064524 00000 n 0000064721 00000 n 0000064977 00000 n 0000065229 00000 n 0000065414 00000 n 0000065666 00000 n 0000065863 00000 n 0000066080 00000 n 0000066260 00000 n 0000066498 00000 n 0000066686 00000 n 0000066922 00000 n 0000067113 00000 n 0000067297 00000 n 0000067495 00000 n 0000067744 00000 n 0000068076 00000 n 0000068396 00000 n 0000068661 00000 n 0000068932 00000 n 0000069231 00000 n 0000069495 00000 n 0000069723 00000 n 0000069949 00000 n 0000070257 00000 n 0000070446 00000 n 0000070745 00000 n 0000070949 00000 n 0000071207 00000 n 0000071482 00000 n 0000071733 00000 n 0000071988 00000 n 0000072266 00000 n 0000072583 00000 n 0000072788 00000 n 0000073036 00000 n 0000073306 00000 n 0000073584 00000 n 0000073857 00000 n 0000074129 00000 n 0000074397 00000 n 0000074660 00000 n 0000074934 00000 n 0000075216 00000 n 0000075451 00000 n 0000075785 00000 n 0000076027 00000 n 0000076240 00000 n 0000076490 00000 n 0000076769 00000 n 0000076965 00000 n 0000077217 00000 n 0000077453 00000 n 0000077717 00000 n 0000077998 00000 n 0000078290 00000 n 0000078529 00000 n 0000078795 00000 n 0000079031 00000 n 0000079260 00000 n 0000079527 00000 n 0000079782 00000 n 0000080065 00000 n 0000080383 00000 n 0000080640 00000 n 0000080924 00000 n 0000081146 00000 n 0000081449 00000 n 0000081756 00000 n 0000082018 00000 n 0000082306 00000 n 0000082628 00000 n 0000082892 00000 n 0000083186 00000 n 0000083762 00000 n 0000084288 00000 n 0000084847 00000 n 0000085936 00000 n 0000086122 00000 n 0000086296 00000 n 0000086668 00000 n 0000086984 00000 n 0000087371 00000 n 0000087681 00000 n 0000087935 00000 n 0000088316 00000 n 0000088501 00000 n 0000088872 00000 n 0000089138 00000 n 0000089470 00000 n 0000089713 00000 n 0000090002 00000 n 0000090385 00000 n 0000090698 00000 n 0000091008 00000 n 0000091303 00000 n 0000091605 00000 n 0000091912 00000 n 0000092160 00000 n 0000092522 00000 n 0000092770 00000 n 0000092982 00000 n 0000093170 00000 n 0000093413 00000 n 0000093707 00000 n 0000094015 00000 n 0000094257 00000 n 0000094561 00000 n 0000094815 00000 n 0000095062 00000 n 0000095359 00000 n 0000095716 00000 n 0000096313 00000 n 0000096675 00000 n 0000097079 00000 n 0000097574 00000 n 0000097757 00000 n 0000097934 00000 n 0000098108 00000 n 0000098359 00000 n 0000098696 00000 n 0000098985 00000 n 0000099329 00000 n 0000099606 00000 n 0000099871 00000 n 0000100111 00000 n 0000100454 00000 n 0000100657 00000 n 0000100839 00000 n 0000101058 00000 n 0000101392 00000 n 0000101734 00000 n 0000102064 00000 n 0000102378 00000 n 0000102722 00000 n 0000102955 00000 n 0000103232 00000 n 0000103584 00000 n 0000104010 00000 n 0000104290 00000 n 0000104562 00000 n 0000104827 00000 n 0000105104 00000 n 0000105376 00000 n 0000105612 00000 n 0000105957 00000 n 0000106195 00000 n 0000106398 00000 n 0000106584 00000 n 0000106853 00000 n 0000107085 00000 n 0000107342 00000 n 0000107615 00000 n 0000107840 00000 n 0000108108 00000 n 0000108339 00000 n 0000108569 00000 n 0000108886 00000 n 0000109181 00000 n 0000109507 00000 n 0000109710 00000 n 0000110022 00000 n 0000110340 00000 n 0000110609 00000 n 0000110919 00000 n 0000111235 00000 n 0000111516 00000 n 0000111849 00000 n 0000112416 00000 n 0000112846 00000 n 0000113279 00000 n 0000114009 00000 n 0000114417 00000 n 0000114765 00000 n 0000115184 00000 n 0000115523 00000 n 0000115832 00000 n 0000116105 00000 n 0000116535 00000 n 0000116721 00000 n 0000116959 00000 n 0000117351 00000 n 0000117748 00000 n 0000118154 00000 n 0000118525 00000 n 0000118952 00000 n 0000119209 00000 n 0000119523 00000 n 0000119951 00000 n 0000120491 00000 n 0000120816 00000 n 0000121081 00000 n 0000121393 00000 n 0000121733 00000 n 0000122000 00000 n 0000122218 00000 n 0000122600 00000 n 0000122986 00000 n 0000123292 00000 n 0000123658 00000 n 0000124053 00000 n 0000124373 00000 n 0000125042 00000 n 0000125327 00000 n 0000125616 00000 n 0000126047 00000 n 0000126361 00000 n 0000126687 00000 n 0000127034 00000 n 0000127356 00000 n 0000127667 00000 n 0000127954 00000 n 0000128305 00000 n 0000128547 00000 n 0000128824 00000 n 0000129190 00000 n 0000129533 00000 n 0000129863 00000 n 0000130210 00000 n 0000130489 00000 n 0000130810 00000 n 0000131134 00000 n 0000131533 00000 n 0000131854 00000 n 0000132149 00000 n 0000132472 00000 n 0000132804 00000 n 0000133092 00000 n 0000133680 00000 n 0000133864 00000 n 0000134083 00000 n 0000134405 00000 n 0000134675 00000 n 0000134944 00000 n 0000135129 00000 n 0000135312 00000 n 0000135570 00000 n 0000135825 00000 n 0000136009 00000 n 0000136220 00000 n 0000136465 00000 n 0000136651 00000 n 0000136863 00000 n 0000137038 00000 n 0000137272 00000 n 0000137454 00000 n 0000137675 00000 n 0000137863 00000 n 0000138038 00000 n 0000138209 00000 n 0000138412 00000 n 0000138693 00000 n 0000139069 00000 n 0000139322 00000 n 0000139578 00000 n 0000139812 00000 n 0000140101 00000 n 0000140367 00000 n 0000140683 00000 n 0000140973 00000 n 0000141314 00000 n 0000141589 00000 n 0000141851 00000 n 0000142098 00000 n 0000142433 00000 n 0000142639 00000 n 0000142826 00000 n 0000143047 00000 n 0000143372 00000 n 0000143696 00000 n 0000144016 00000 n 0000144264 00000 n 0000144566 00000 n 0000144903 00000 n 0000145134 00000 n 0000145406 00000 n 0000145727 00000 n 0000146115 00000 n 0000146475 00000 n 0000146787 00000 n 0000147100 00000 n 0000147385 00000 n 0000147664 00000 n 0000147927 00000 n 0000148206 00000 n 0000148476 00000 n 0000148698 00000 n 0000149016 00000 n 0000149252 00000 n 0000149455 00000 n 0000149686 00000 n 0000149963 00000 n 0000150152 00000 n 0000150410 00000 n 0000150638 00000 n 0000150907 00000 n 0000151184 00000 n 0000151467 00000 n 0000151688 00000 n 0000151964 00000 n 0000152196 00000 n 0000152430 00000 n 0000152694 00000 n 0000153008 00000 n 0000153299 00000 n 0000153599 00000 n 0000153863 00000 n 0000154132 00000 n 0000154334 00000 n 0000154643 00000 n 0000154959 00000 n 0000155228 00000 n 0000155535 00000 n 0000155859 00000 n 0000156137 00000 n 0000156483 00000 n 0000157051 00000 n 0000157616 00000 n 0000158194 00000 n 0000159347 00000 n 0000159523 00000 n 0000159770 00000 n 0000159956 00000 n 0000160131 00000 n 0000160422 00000 n 0000160778 00000 n 0000161026 00000 n 0000161232 00000 n 0000161423 00000 n 0000161713 00000 n 0000162012 00000 n 0000162237 00000 n 0000162478 00000 n 0000162761 00000 n 0000163088 00000 n 0000163376 00000 n 0000163588 00000 n 0000163928 00000 n 0000164247 00000 n 0000164834 00000 n 0000165083 00000 n 0000165370 00000 n 0000165664 00000 n 0000165841 00000 n 0000166040 00000 n 0000166437 00000 n 0000166892 00000 n 0000167260 00000 n 0000167608 00000 n 0000167831 00000 n 0000168035 00000 n 0000168323 00000 n 0000168653 00000 n 0000168919 00000 n 0000169281 00000 n 0000169553 00000 n 0000169837 00000 n 0000170246 00000 n 0000170573 00000 n 0000170911 00000 n 0000171622 00000 n 0000171853 00000 n 0000172154 00000 n 0000172420 00000 n 0000179562 00000 n 0000180270 00000 n 0000180346 00000 n 0000181088 00000 n 0000181258 00000 n 0000181426 00000 n 0000181593 00000 n 0000181749 00000 n 0000181936 00000 n 0000182138 00000 n 0000182333 00000 n 0000182516 00000 n 0000182641 00000 n 0000182756 00000 n 0000182847 00000 n 0000182928 00000 n 0000182966 00000 n 0000183133 00000 n trailer << /Size 621 /Root 619 0 R /Info 620 0 R /ID [ ] >> startxref 183459 %%EOF verilator-3.874/src/0000775000177100017500000000000012534632371014320 5ustar wsnyderwsnyderverilator-3.874/src/V3AstConstOnly.h0000664000177100017500000000260412525171733017304 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ast node structure // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3ASTCONSTONLY_H_ #define _V3ASTCONSTONLY_H_ 1 // Include only in visitors that do not not edit nodes, so should use constant iterators #define iterateAndNext error_use_iterateAndNextConst #define iterateChildren error_use_iterateChildrenConst #define addNext error_no_addNext_in_ConstOnlyVisitor #define replaceWith error_no_replaceWith_in_ConstOnlyVisitor #define deleteTree error_no_deleteTree_in_ConstOnlyVisitor #define unlinkFrBack error_no_unlinkFrBack_in_ConstOnlyVisitor #endif // Guard verilator-3.874/src/V3LinkLevel.cpp0000664000177100017500000001415012525171733017123 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Resolve module/signal name references // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LINKTOP TRANSFORMATIONS: // Utility functions // Sort cells by depth // Create new MODULE TOP with connections to below signals //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3LinkLevel.h" #include "V3Ast.h" //###################################################################### // Levelizing class functions struct CmpLevel { inline bool operator () (const AstNodeModule* lhsp, const AstNodeModule* rhsp) const { return lhsp->level() < rhsp->level(); } }; void V3LinkLevel::modSortByLevel() { // Sort modules by levels, root down to lowest children // Calculate levels again in case we added modules UINFO(2,"modSortByLevel()\n"); // level() was computed for us in V3LinkCells typedef vector ModVec; ModVec vec; AstNodeModule* topp = NULL; for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) { if (nodep->level()<=2) { if (topp) { nodep->v3warn(E_MULTITOP, "Unsupported: Multiple top level modules: " <prettyName()<<" and "<prettyName()); nodep->v3warn(E_MULTITOP, "Fix, or use --top-module option to select which you want."); } topp = nodep; } vec.push_back(nodep); } stable_sort(vec.begin(), vec.end(), CmpLevel()); // Sort the vector UINFO(9,"modSortByLevel() sorted\n"); // Comment required for gcc4.6.3 / bug666 for (ModVec::iterator it = vec.begin(); it != vec.end(); ++it) { AstNodeModule* nodep = *it; nodep->clearIter(); // Because we didn't iterate to find the node pointers, may have a stale m_iterp() needing cleanup nodep->unlinkFrBack(); } if (v3Global.rootp()->modulesp()) v3Global.rootp()->v3fatalSrc("Unlink didn't work"); for (ModVec::iterator it = vec.begin(); it != vec.end(); ++it) { AstNodeModule* nodep = *it; v3Global.rootp()->addModulep(nodep); } UINFO(9,"modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666 V3Global::dumpCheckGlobalTree("cells.tree", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } //###################################################################### // Wrapping void V3LinkLevel::wrapTop(AstNetlist* netlistp) { UINFO(2,__FUNCTION__<<": "<modulesp(); if (!oldmodp) netlistp->v3fatalSrc("No module found to process"); AstNodeModule* newmodp = new AstModule(oldmodp->fileline(), (string)"TOP_"+oldmodp->name()); // Make the new module first in the list oldmodp->unlinkFrBackWithNext(); newmodp->addNext(oldmodp); newmodp->level(1); newmodp->modPublic(true); netlistp->addModulep(newmodp); // TODO the module creation above could be done after linkcells, but // the rest must be done after data type resolution wrapTopCell(netlistp); wrapTopPackages(netlistp); } void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) { AstNodeModule* newmodp = netlistp->modulesp(); if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process"); AstNodeModule* oldmodp = newmodp->nextp()->castNodeModule(); if (!oldmodp) netlistp->v3fatalSrc("No module found to process"); // Add instance AstCell* cellp = new AstCell(newmodp->fileline(), (v3Global.opt.l2Name() ? "v" : oldmodp->name()), oldmodp->name(), NULL, NULL, NULL); cellp->modp(oldmodp); newmodp->addStmtp(cellp); // Add pins for (AstNode* subnodep=oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) { if (AstVar* oldvarp=subnodep->castVar()) { UINFO(8,"VARWRAP "<isIO()) { AstVar* varp = oldvarp->cloneTree(false); newmodp->addStmtp(varp); varp->sigPublic(true); // User needs to be able to get to it... if (oldvarp->isIO()) { oldvarp->primaryIO(true); varp->primaryIO(true); } if (varp->isIO() && v3Global.opt.systemC()) { varp->sc(true); // User can see trace one level down from the wrapper // Avoids packing & unpacking SC signals a second time varp->trace(false); } AstPin* pinp = new AstPin(oldvarp->fileline(),0,oldvarp->name(), new AstVarRef(varp->fileline(), varp, oldvarp->isOutput())); // Skip length and width comp; we know it's a direct assignment pinp->modVarp(oldvarp); cellp->addPinsp(pinp); } } } } void V3LinkLevel::wrapTopPackages(AstNetlist* netlistp) { // Instantiate all packages under the top wrapper // This way all later SCOPE based optimizations can ignore packages AstNodeModule* newmodp = netlistp->modulesp(); if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process"); for (AstNodeModule* modp = netlistp->modulesp(); modp; modp=modp->nextp()->castNodeModule()) { if (modp->castPackage()) { AstCell* cellp = new AstCell(modp->fileline(), // Could add __03a__03a="::" to prevent conflict // with module names/"v" modp->name(), modp->name(), NULL, NULL, NULL); cellp->modp(modp); newmodp->addStmtp(cellp); } } } verilator-3.874/src/V3Broken.h0000664000177100017500000000237212525171733016126 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Find broken links in tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3BROKEN_H_ #define _V3BROKEN_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Broken { public: static void brokenAll(AstNetlist* nodep); static void addNewed(AstNode* nodep); static void deleted(AstNode* nodep); }; #endif // Guard verilator-3.874/src/V3Combine.cpp0000664000177100017500000004064112525171733016616 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Combine common code into functions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Combine's Transformations: // // For every function that we spit out // Examine code to find largest common blocks // Hash each node depth first // Hash includes varp name and operator type, and constants // Form lookup table based on hash of each statement w/ nodep and next nodep // GO through table // Lookup in hash, while next of each statement match, grow that common block // Foreach common block // If common block large enough (> 20 statements) & used 2x or more // Make new function // Move common block to function // Replace each common block ref with funccall // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Combine.h" #include "V3Hashed.h" #include "V3Stats.h" #include "V3Ast.h" //###################################################################### #define COMBINE_MIN_STATEMENTS 50 // Min # of statements to be worth making a function //###################################################################### class CombBaseVisitor : public AstNVisitor { protected: // STATE // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual ~CombBaseVisitor() {} //***** optimization levels static bool emptyFunctionDeletion() { return true; } static bool duplicateFunctionCombine() { return true; } // Note this is disabled, it still needed work // Also repair it for DPI functions; when make __common need to insure proper // flags get inherited from the old to new AstCFunc, and that AstText doesn't // get split between functions causing the text to have a danginling reference. bool statementCombine() { return false && duplicateFunctionCombine(); } }; //###################################################################### // Combine replacement function class CombCallVisitor : CombBaseVisitor { // Find all CCALLS of each CFUNC, so that we can later rename them private: // NODE STATE bool m_find; // Find mode vs. delete mode typedef multimap CallMmap; CallMmap m_callMmap; // Associative array of {function}{call} // METHODS public: void replaceFunc (AstCFunc* oldfuncp, AstCFunc* newfuncp) { if (oldfuncp==newfuncp) return; if (newfuncp) { UINFO(4, " Replace "< "< eqrange = m_callMmap.equal_range(oldfuncp); for (CallMmap::iterator nextit = eqrange.first; nextit != eqrange.second;) { CallMmap::iterator eqit = nextit++; AstCCall* callp = eqit->second; if (!callp->user3()) { // !already done UINFO(4, " Called "<funcp() != oldfuncp) callp->v3fatalSrc("Call list broken, points to call w/different func"); if (newfuncp) { AstCCall* newp = new AstCCall(callp, newfuncp); // Special new AstCCall form above transfers children of callp to newfuncp callp->replaceWith(newp); addCall(newp); // Fix the table } else { // Just deleting empty function callp->unlinkFrBack(); } callp->user3(true); // Dead now pushDeletep(callp); callp=NULL; m_callMmap.erase(eqit); // Fix the table } } } // METHODS void addCall(AstCCall* nodep) { m_callMmap.insert(make_pair(nodep->funcp(), nodep)); } void deleteCall(AstCCall* nodep) { pair eqrange = m_callMmap.equal_range(nodep->funcp()); for (CallMmap::iterator nextit = eqrange.first; nextit != eqrange.second;) { CallMmap::iterator eqit = nextit++; AstCCall* callp = eqit->second; if (callp==nodep) { m_callMmap.erase(eqit); return; } } nodep->v3fatalSrc("deleteCall node not found in table"); } private: // VISITORS virtual void visit(AstCCall* nodep, AstNUser*) { addCall(nodep); } // Speed things up virtual void visit(AstNodeAssign* nodep, AstNUser*) {} virtual void visit(AstNodeMath* nodep, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS CombCallVisitor() { m_find = false; } virtual ~CombCallVisitor() {} void main(AstNetlist* nodep) { nodep->accept(*this); } }; //###################################################################### // Combine marking function class CombMarkVisitor : CombBaseVisitor { // Mark all nodes under specified one. private: // OUTPUT: // AstNode::user3() -> bool. True to indicate duplicated // VISITORS virtual void visit(AstNode* nodep, AstNUser*) { nodep->user3(true); nodep->iterateChildren(*this); } public: // CONSTRUCTORS CombMarkVisitor(AstNode* nodep) { nodep->accept(*this); } virtual ~CombMarkVisitor() {} }; //###################################################################### // Combine state, as a visitor of each AstNode class CombineVisitor : CombBaseVisitor { private: // NODE STATE // Entire netlist: // AstNodeStmt::user() -> bool. True if iterated already // AstCFunc::user3p() -> AstCFunc*, If set, replace ccalls to this func with new func // AstNodeStmt::user3() -> AstNode*. True if to ignore this cell // AstNodeStmt::user4() -> V3Hashed::V3Hash. Hash value of this node (hash of 0 is illegal) AstUser1InUse m_inuser1; AstUser3InUse m_inuser3; //AstUser4InUse part of V3Hashed // STATE typedef enum {STATE_IDLE, STATE_HASH, STATE_DUP} CombineState; V3Double0 m_statCombs; // Statistic tracking CombineState m_state; // Major state AstNodeModule* m_modp; // Current module AstCFunc* m_funcp; // Current function V3Hash m_lowerHash; // Hash of the statement we're building CombCallVisitor m_call; // Tracking of function call users int m_modNFuncs; // Number of functions made AstNode* m_walkLast1p; // Final node that is the same in duplicate list AstNode* m_walkLast2p; // Final node that is the same in duplicate list V3Hashed m_hashed; // Hash for every node in module // METHODS void hashStatement(AstNode* nodep) { // Compute hash on entire tree of this statement m_hashed.hashAndInsert(nodep); //UINFO(9," stmthash "<user4()<<" "<accept(*this); } m_state = oldState; } void walkEmptyFuncs() { for (V3Hashed::iterator it = m_hashed.begin(); it != m_hashed.end(); ++it) { AstNode* node1p = it->second; AstCFunc* oldfuncp = node1p->castCFunc(); if (oldfuncp && oldfuncp->emptyBody() && !oldfuncp->dontCombine()) { UINFO(5," EmptyFunc "<user4p())<<" "<unlinkFrBack(); pushDeletep(oldfuncp); oldfuncp=NULL; } } } void walkDupFuncs() { for (V3Hashed::iterator it = m_hashed.begin(); it != m_hashed.end(); ++it) { V3Hash hashval = it->first; AstNode* node1p = it->second; if (!node1p->castCFunc()) continue; if (hashval.isIllegal()) node1p->v3fatalSrc("Illegal (unhashed) nodes\n"); for (V3Hashed::iterator eqit = it; eqit != m_hashed.end(); ++eqit) { AstNode* node2p = eqit->second; if (!(eqit->first == hashval)) break; if (node1p==node2p) continue; // Identical iterator if (node1p->user3p() || node2p->user3p()) continue; // Already merged if (node1p->sameTree(node2p)) { // walk of tree has same comparison // Replace AstCCall's that point here replaceFuncWFunc(node2p->castCFunc(), node1p->castCFunc()); // Replacement may promote a slow routine to fast path if (!node2p->castCFunc()->slow()) node1p->castCFunc()->slow(false); } } } } void replaceFuncWFunc(AstCFunc* oldfuncp, AstCFunc* newfuncp) { UINFO(5," DupFunc "<user4p())<<" "<user4p())<<" "<unlinkFrBack(); pushDeletep(oldfuncp); oldfuncp=NULL; } void replaceOnlyCallFunc(AstCCall* nodep) { if (AstCFunc* oldfuncp = nodep->backp()->castCFunc()) { //oldfuncp->dumpTree(cout,"MAYDEL: "); if (nodep->nextp()==NULL && oldfuncp->initsp()==NULL && oldfuncp->stmtsp()==nodep && oldfuncp->finalsp()==NULL) { UINFO(9," Function only has call "<funcp()); nodep=NULL; } } } void walkDupCodeStart(AstNode* node1p) { V3Hash hashval (node1p->user4p()); //UINFO(4," STMT "< eqrange = m_hashed.mmap().equal_range(hashval); for (V3Hashed::iterator eqit = eqrange.first; eqit != eqrange.second; ++eqit) { AstNode* node2p = eqit->second; if (node1p==node2p) continue; // // We need to mark iteration to prevent matching code inside code (abab matching in ababab) AstNode::user1ClearTree(); // user1p() used on entire tree m_walkLast1p = NULL; m_walkLast2p = NULL; int depth = walkDupCodeNext(node1p, node2p, 1); if (depth>COMBINE_MIN_STATEMENTS && depth>bestDepth) { bestDepth = depth; bestNode2p = node2p; bestLast1p = m_walkLast1p; bestLast2p = m_walkLast2p; } } if (bestDepth) { // Found a replacement UINFO(5," Duplicate of depth "<user1p() || node2p->user1p()) return 0; // Already iterated if (node1p->user3p() || node2p->user3p()) return 0; // Already merged if (!m_hashed.sameNodes(node1p,node2p)) return 0; // walk of tree has same comparison V3Hash hashval(node1p->user4p()); //UINFO(9," wdup1 "<user4p())<<" "<user4p())<<" "<user1(true); node2p->user1(true); if (node1p->nextp() && node2p->nextp()) { return hashval.depth()+walkDupCodeNext(node1p->nextp(), node2p->nextp(), level+1); } return hashval.depth(); } void walkReplace(AstNode* node1p, AstNode* node2p, AstNode* last1p, AstNode* last2p) { // Final node in linked list, maybe null if all statements to be grabbed // Make new function string oldname = m_funcp->name(); string::size_type pos; if ((pos=oldname.find("_common")) != string::npos) { oldname.erase(pos); } if ((pos=oldname.find("__")) != string::npos) { oldname.erase(pos); } AstCFunc* newfuncp = new AstCFunc(node1p->fileline(), oldname+"_common"+cvtToStr(++m_modNFuncs), NULL); m_modp->addStmtp(newfuncp); // Create calls AstCCall* call1p = new AstCCall(node1p->fileline(), newfuncp); AstCCall* call2p = new AstCCall(node2p->fileline(), newfuncp); // Grab statement bodies AstNRelinker relink1Handle; AstNRelinker relink2Handle; for (AstNode* nextp, *walkp = node1p; 1; walkp = nextp) { nextp = walkp->nextp(); if (walkp==node1p) walkp->unlinkFrBack(&relink1Handle); else { walkp->unlinkFrBack(); node1p->addNext(walkp); } if (walkp==last1p) break; } for (AstNode* nextp, *walkp = node2p; 1; walkp = nextp) { nextp = walkp->nextp(); if (walkp==node2p) walkp->unlinkFrBack(&relink2Handle); else { walkp->unlinkFrBack(); node2p->addNext(walkp); } if (walkp==last2p) break; } // Move node1 statements to new function newfuncp->addStmtsp(node1p); //newfuncp->dumpTree(cout," newfunctree: "); // Mark node2 statements as dead CombMarkVisitor visitor(node2p); pushDeletep(node2p); // Delete later // Link in new function relink1Handle.relink(call1p); relink2Handle.relink(call2p); // Hash the new function hashFunctions(newfuncp); m_call.addCall(call1p); m_call.addCall(call2p); // If either new statement makes a func with only a single call, replace // the above callers to call it directly replaceOnlyCallFunc(call1p); call1p=NULL; replaceOnlyCallFunc(call2p); call2p=NULL; } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { // Track all callers of each function m_call.main(nodep); // //In V3Hashed AstNode::user4ClearTree(); // user4p() used on entire tree // Iterate modules backwards, in bottom-up order. // Required so that a module instantiating another can benefit from collapsing. nodep->iterateChildrenBackwards(*this); } virtual void visit(AstNodeModule* nodep, AstNUser*) { UINFO(4," MOD "<iterateChildren(*this); m_state = STATE_IDLE; if (debug()>=9) { m_hashed.dumpFilePrefixed("combine"); } // Walk the hashes removing empty functions if (emptyFunctionDeletion()) { walkEmptyFuncs(); } // Walk the hashes looking for duplicate functions if (duplicateFunctionCombine()) { walkDupFuncs(); } // Walk the statements looking for large replicated code sections if (statementCombine()) { m_state = STATE_DUP; nodep->iterateChildren(*this); m_state = STATE_IDLE; } m_modp = NULL; } virtual void visit(AstCFunc* nodep, AstNUser*) { m_funcp = nodep; if (!nodep->dontCombine()) { if (m_state == STATE_HASH) { hashStatement(nodep); // Hash the entire function - it might be identical } else if (m_state == STATE_DUP) { nodep->iterateChildren(*this); } } m_funcp = NULL; } virtual void visit(AstNodeStmt* nodep, AstNUser*) { if (m_state == STATE_HASH && m_funcp) { hashStatement(nodep); } else if (m_state == STATE_DUP && m_funcp) { walkDupCodeStart(nodep); } } //-------------------- // Default: Just iterate virtual void visit(AstVar*, AstNUser*) {} virtual void visit(AstTraceDecl*, AstNUser*) {} virtual void visit(AstTraceInc*, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS CombineVisitor(AstNetlist* nodep) { m_modp=NULL; m_funcp = NULL; m_state = STATE_IDLE; nodep->accept(*this); } virtual ~CombineVisitor() { V3Stats::addStat("Optimizations, Combined CFuncs", m_statCombs); } }; //###################################################################### // Combine class functions void V3Combine::combineAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Name.cpp0000664000177100017500000001132012525171733016112 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Change names for __PVT__'s // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Name's Transformations: // // Cell/Var's // Prepend __PVT__ to variable names //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Name.h" #include "V3Ast.h" #include "V3LanguageWords.h" //###################################################################### // Name state, as a visitor of each AstNode class NameVisitor : public AstNVisitor { private: // NODE STATE // Cleared on Netlist // AstCell::user1() -> bool. Set true if already processed // AstScope::user1() -> bool. Set true if already processed // AstVar::user1() -> bool. Set true if already processed AstUser1InUse m_inuser1; // STATE AstNodeModule* m_modp; V3LanguageWords m_words; // Reserved word detector // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void rename(AstNode* nodep, bool addPvt) { if (!nodep->user1()) { // Not already done if (addPvt) { string newname = (string)"__PVT__"+nodep->name(); nodep->name(newname); } else { string rsvd = m_words.isKeyword(nodep->name()); if (rsvd != "") { nodep->v3warn(SYMRSVDWORD,"Symbol matches "+rsvd+": '"<prettyName()<<"'"); string newname = (string)"__SYM__"+nodep->name(); nodep->name(newname); } } nodep->user1(1); } } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } // Add __PVT__ to names of local signals virtual void visit(AstVar* nodep, AstNUser*) { // Don't iterate... Don't need temps for RANGES under the Var. rename(nodep, (!m_modp->isTop() && !nodep->isSigPublic() && !nodep->isFuncLocal() // Isn't exposed, and would mess up dpi import wrappers && !nodep->isTemp())); // Don't bother to rename internal signals } virtual void visit(AstCFunc* nodep, AstNUser*) { if (!nodep->user1()) { nodep->iterateChildren(*this); rename(nodep, false); } } virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->varp()) { nodep->varp()->iterate(*this); nodep->name(nodep->varp()->name()); } } virtual void visit(AstCell* nodep, AstNUser*) { if (!nodep->user1()) { rename(nodep, !nodep->modp()->modPublic()); nodep->iterateChildren(*this); } } virtual void visit(AstMemberDType* nodep, AstNUser*) { if (!nodep->user1()) { rename(nodep, false); nodep->iterateChildren(*this); } } virtual void visit(AstMemberSel* nodep, AstNUser*) { if (!nodep->user1()) { rename(nodep, false); nodep->iterateChildren(*this); } } virtual void visit(AstScope* nodep, AstNUser*) { if (!nodep->user1SetOnce()) { if (nodep->aboveScopep()) nodep->aboveScopep()->iterate(*this); if (nodep->aboveCellp()) nodep->aboveCellp()->iterate(*this); // Always recompute name (as many level above scope may have changed) // Same formula as V3Scope nodep->name(nodep->isTop() ? "TOP" : (nodep->aboveScopep()->name()+"."+nodep->aboveCellp()->name())); nodep->iterateChildren(*this); } } //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS NameVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~NameVisitor() {} }; //###################################################################### // Name class functions void V3Name::nameAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.874/src/V3Ast.cpp0000664000177100017500000011774512525171733016003 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ast node structures // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include #include #include #include "V3Ast.h" #include "V3File.h" #include "V3Global.h" #include "V3Broken.h" //====================================================================== // Statics vluint64_t AstNode::s_editCntLast=0; vluint64_t AstNode::s_editCntGbl=0; // Hot cache line // To allow for fast clearing of all user pointers, we keep a "timestamp" // along with each userp, and thus by bumping this count we can make it look // as if we iterated across the entire tree to set all the userp's to null. int AstNode::s_cloneCntGbl=0; uint32_t AstUser1InUse::s_userCntGbl=0; // Hot cache line, leave adjacent uint32_t AstUser2InUse::s_userCntGbl=0; // Hot cache line, leave adjacent uint32_t AstUser3InUse::s_userCntGbl=0; // Hot cache line, leave adjacent uint32_t AstUser4InUse::s_userCntGbl=0; // Hot cache line, leave adjacent uint32_t AstUser5InUse::s_userCntGbl=0; // Hot cache line, leave adjacent bool AstUser1InUse::s_userBusy=false; bool AstUser2InUse::s_userBusy=false; bool AstUser3InUse::s_userBusy=false; bool AstUser4InUse::s_userBusy=false; bool AstUser5InUse::s_userBusy=false; int AstNodeDType::s_uniqueNum = 0; //###################################################################### // V3AstType ostream& operator<<(ostream& os, AstType rhs); //###################################################################### // Creators void AstNode::init() { editCountInc(); m_fileline = NULL; m_nextp = NULL; m_backp = NULL; m_headtailp = this; // When made, we're a list of only a single element m_op1p = NULL; m_op2p = NULL; m_op3p = NULL; m_op4p = NULL; m_iterpp = NULL; m_dtypep = NULL; m_clonep = NULL; m_cloneCnt = 0; // Attributes m_didWidth = false; m_doingWidth = false; m_user1p = NULL; m_user1Cnt = 0; m_user2p = NULL; m_user2Cnt = 0; m_user3p = NULL; m_user3Cnt = 0; m_user4p = NULL; m_user4Cnt = 0; m_user5p = NULL; m_user5Cnt = 0; } string AstNode::encodeName(const string& namein) { // Encode signal name raw from parser, then not called again on same signal const char* start = namein.c_str(); string out; for (const char* pos = start; *pos; pos++) { if ((pos==start) ? isalpha(pos[0]) // digits can't lead identifiers : isalnum(pos[0])) { out += pos[0]; } else if (pos[0]=='_') { if (pos[1]=='_') { out += "_"; out += "__05F"; // hex(_) = 0x5F pos++; } else { out += pos[0]; } } else { // Need the leading 0 so this will never collide with // a user identifier nor a temp we create in Verilator. // We also do *NOT* use __DOT__ etc, as we search for those // in some replacements, and don't want to mangle the user's names. char hex[10]; sprintf(hex,"__0%02X",pos[0]); out += hex; } } return out; } string AstNode::encodeNumber(vlsint64_t num) { if (num < 0) { return "__02D"+cvtToStr(-num); // 2D=- } else { return cvtToStr(num); } } string AstNode::shortName() const { string pretty = name(); string::size_type pos; while ((pos=pretty.find("__PVT__")) != string::npos) { pretty.replace(pos, 7, ""); } return pretty; } string AstNode::dedotName(const string& namein) { string pretty = namein; string::size_type pos; while ((pos=pretty.find("__DOT__")) != string::npos) { pretty.replace(pos, 7, "."); } if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,""); return pretty; } string AstNode::vcdName(const string& namein) { // VCD tracing expects space to separate hierarchy // Dots are reserved for dots the user put in the name string pretty = namein; string::size_type pos; while ((pos=pretty.find("__DOT__")) != string::npos) { pretty.replace(pos, 7, " "); } while ((pos=pretty.find(".")) != string::npos) { pretty.replace(pos, 1, " "); } // Now convert escaped special characters, etc return prettyName(pretty); } string AstNode::prettyName(const string& namein) { string pretty; pretty = ""; for (const char* pos = namein.c_str(); *pos; ) { if (0==strncmp(pos,"__BRA__",7)) { pretty += "["; pos += 7; } else if (0==strncmp(pos,"__KET__",7)) { pretty += "]"; pos += 7; } else if (0==strncmp(pos,"__DOT__",7)) { pretty += "."; pos += 7; } else if (0==strncmp(pos,"->",2)) { pretty += "."; pos += 2; } else if (0==strncmp(pos,"__PVT__",7)) { pretty += ""; pos += 7; } else if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0' && isxdigit(pos[3]) && isxdigit(pos[4])) { char value = 0; value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10)); value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10)); pretty += value; pos += 5; } else { pretty += pos[0]; pos++; } } if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,""); if (pretty.substr(0,5) == "TOP->") pretty.replace(0,5,""); return pretty; } string AstNode::prettyTypeName() const { if (name()=="") return typeName(); return string(typeName())+" '"+prettyName()+"'"; } //###################################################################### // Insertion inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next) { #ifdef VL_DEBUG // Called on all major tree changers. // Only for use for those really nasty bugs relating to internals // Note this may be null. //if (debug()) cout<<"-treeChange: V3Ast.cpp:"<"<dumpTree(cout,"-treeChange: "); // if (next||1) this->dumpTreeAndNext(cout, prefix); // else this->dumpTree(cout, prefix); // this->checkTree(); // v3Global.rootp()->checkTree(); //} #endif } AstNode* AstNode::addNext(AstNode* newp) { // Add to m_nextp, returns this UASSERT(newp,"Null item passed to addNext\n"); this->debugTreeChange("-addNextThs: ", __LINE__, false); newp->debugTreeChange("-addNextNew: ", __LINE__, true); if (this == NULL) { return (newp); } else { // Find end of old list AstNode* oldtailp = this; if (oldtailp->m_nextp) { if (oldtailp->m_headtailp) { oldtailp = oldtailp->m_headtailp; // This=beginning of list, jump to end UASSERT(!oldtailp->m_nextp, "Node had next, but headtail says it shouldn't"); } else { // Though inefficent, we are occasionally passed a addNext in the middle of a list. while (oldtailp->m_nextp != NULL) oldtailp = oldtailp->m_nextp; } } // Link it in oldtailp->m_nextp = newp; newp->m_backp = oldtailp; // New tail needs the head AstNode* newtailp = newp->m_headtailp; AstNode* headp = oldtailp->m_headtailp; oldtailp->m_headtailp = NULL; // May be written again as new head newp->m_headtailp = NULL; // May be written again as new tail newtailp->m_headtailp = headp; headp->m_headtailp = newtailp; newp->editCountInc(); if (oldtailp->m_iterpp) *(oldtailp->m_iterpp) = newp; // Iterate on new item } this->debugTreeChange("-addNextOut:", __LINE__, true); return this; } AstNode* AstNode::addNextNull(AstNode* newp) { if (!newp) return this; return addNext(newp); } void AstNode::addNextHere(AstNode* newp) { // Add to m_nextp on exact node passed, not at the end. // This could be at head, tail, or both (single) // New could be head of single node, or list UASSERT(newp,"Null item passed to addNext"); UASSERT(this,"Null base node"); UASSERT(newp->backp()==NULL,"New node (back) already assigned?"); this->debugTreeChange("-addHereThs: ", __LINE__, false); newp->debugTreeChange("-addHereNew: ", __LINE__, true); newp->editCountInc(); AstNode* addlastp = newp->m_headtailp; // Last node in list to be added UASSERT(!addlastp->m_nextp, "Headtailp tail isn't at the tail"); // Forward links AstNode* oldnextp = this->m_nextp; this->m_nextp = newp; addlastp->m_nextp = oldnextp; // Perhaps null if 'this' is not list // Backward links if (oldnextp) oldnextp->m_backp = addlastp; newp->m_backp = this; // Head/tail AstNode* oldheadtailp = this->m_headtailp; // (!oldheadtailp) // this was&is middle of list // (oldheadtailp==this && !oldnext)// this was head AND tail (one node long list) // (oldheadtailp && oldnextp) // this was&is head of list of not just one node, not tail // (oldheadtailp && !oldnextp) // this was tail of list, might also be head of one-node list // newp->m_headtailp = NULL; // Not at head any longer addlastp->m_headtailp = NULL; // Presume middle of list // newp might happen to be head/tail after all, if so will be set again below if (oldheadtailp) { // else in middle of list, no change if (oldheadtailp==this) { // this was one node this->m_headtailp = addlastp; // Was head/tail, now a tail addlastp->m_headtailp = oldheadtailp; // Tail needs to remember head (or NULL) } else if (!oldnextp) { // this was tail this->m_headtailp = NULL; // No longer a tail oldheadtailp->m_headtailp = addlastp; // Head gets new tail addlastp->m_headtailp = oldheadtailp; // Tail needs to remember head (or NULL) } // else is head, and we're inserting into the middle, so no other change } if (this->m_iterpp) *(this->m_iterpp) = newp; // Iterate on new item this->debugTreeChange("-addHereOut: ", __LINE__, true); } void AstNode::setOp1p(AstNode* newp) { UASSERT(newp,"Null item passed to setOp1p\n"); UDEBUGONLY(if (m_op1p) this->v3fatalSrc("Adding to non-empty, non-list op1");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1");); this->debugTreeChange("-setOp1pThs: ", __LINE__, false); newp->debugTreeChange("-setOp1pNew: ", __LINE__, true); m_op1p = newp; newp->editCountInc(); newp->m_backp = this; this->debugTreeChange("-setOp1pOut: ", __LINE__, false); } void AstNode::setOp2p(AstNode* newp) { UASSERT(newp,"Null item passed to setOp2p\n"); UDEBUGONLY(if (m_op2p) this->v3fatalSrc("Adding to non-empty, non-list op2");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2");); this->debugTreeChange("-setOp2pThs: ", __LINE__, false); newp->debugTreeChange("-setOp2pNew: ", __LINE__, true); m_op2p = newp; newp->editCountInc(); newp->m_backp = this; this->debugTreeChange("-setOp2pOut: ", __LINE__, false); } void AstNode::setOp3p(AstNode* newp) { UASSERT(newp,"Null item passed to setOp3p\n"); UDEBUGONLY(if (m_op3p) this->v3fatalSrc("Adding to non-empty, non-list op3");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3");); this->debugTreeChange("-setOp3pThs: ", __LINE__, false); newp->debugTreeChange("-setOp3pNew: ", __LINE__, true); m_op3p = newp; newp->editCountInc(); newp->m_backp = this; this->debugTreeChange("-setOp3pOut: ", __LINE__, false); } void AstNode::setOp4p(AstNode* newp) { UASSERT(newp,"Null item passed to setOp4p\n"); UDEBUGONLY(if (m_op4p) this->v3fatalSrc("Adding to non-empty, non-list op4");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4");); this->debugTreeChange("-setOp4pThs: ", __LINE__, false); newp->debugTreeChange("-setOp4pNew: ", __LINE__, true); m_op4p = newp; newp->editCountInc(); newp->m_backp = this; this->debugTreeChange("-setOp4pOut: ", __LINE__, false); } void AstNode::addOp1p(AstNode* newp) { UASSERT(newp,"Null item passed to addOp1p\n"); if (!m_op1p) { op1p(newp); } else { m_op1p->addNext(newp); } } void AstNode::addOp2p(AstNode* newp) { UASSERT(newp,"Null item passed to addOp2p\n"); if (!m_op2p) { op2p(newp); } else { m_op2p->addNext(newp); } } void AstNode::addOp3p(AstNode* newp) { UASSERT(newp,"Null item passed to addOp3p\n"); if (!m_op3p) { op3p(newp); } else { m_op3p->addNext(newp); } } void AstNode::addOp4p(AstNode* newp) { UASSERT(newp,"Null item passed to addOp4p\n"); if (!m_op4p) { op4p(newp); } else { m_op4p->addNext(newp); } } void AstNode::replaceWith(AstNode* newp) { // Replace oldp with this // Unlike a unlink/relink, children are changed to point to the new node. AstNRelinker repHandle; this->unlinkFrBack(&repHandle); repHandle.relink(newp); } void AstNRelinker::dump(ostream& str) const { str<<" BK="<<(uint32_t*)m_backp; str<<" ITER="<<(uint32_t*)m_iterpp; str<<" CHG="<<(m_chg==RELINK_NEXT?"[NEXT] ":""); str<<(m_chg==RELINK_OP1?"[OP1] ":""); str<<(m_chg==RELINK_OP2?"[OP2] ":""); str<<(m_chg==RELINK_OP3?"[OP3] ":""); str<<(m_chg==RELINK_OP4?"[OP4] ":""); } AstNode* AstNode::unlinkFrBackWithNext(AstNRelinker* linkerp) { this->debugTreeChange("-unlinkWNextThs: ", __LINE__, true); AstNode* oldp = this; UASSERT(oldp->m_backp,"Node has no back, already unlinked?\n"); oldp->editCountInc(); AstNode* backp = oldp->m_backp; if (linkerp) { linkerp->m_oldp = oldp; linkerp->m_backp = backp; linkerp->m_iterpp = oldp->m_iterpp; if (backp->m_nextp == oldp) linkerp->m_chg = AstNRelinker::RELINK_NEXT; else if (backp->m_op1p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP1; else if (backp->m_op2p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP2; else if (backp->m_op3p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP3; else if (backp->m_op4p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP4; else oldp->v3fatalSrc("Unlink of node with back not pointing to it."); } if (backp->m_nextp== oldp) { backp->m_nextp= NULL; // Old list gets truncated // New list becomes a list upon itself // Most common case is unlinking a entire operand tree // (else we'd probably call unlinkFrBack without next) // We may be in the middle of a list; we have no way to find head or tail! AstNode* oldtailp = oldp; while (oldtailp->m_nextp) oldtailp=oldtailp->m_nextp; // Create new head/tail of old list AstNode* oldheadp = oldtailp->m_headtailp; oldheadp->m_headtailp = oldp->m_backp; oldheadp->m_headtailp->m_headtailp = oldheadp; // Create new head/tail of extracted list oldp->m_headtailp = oldtailp; oldp->m_headtailp->m_headtailp = oldp; } else if (backp->m_op1p == oldp) backp->m_op1p = NULL; else if (backp->m_op2p == oldp) backp->m_op2p = NULL; else if (backp->m_op3p == oldp) backp->m_op3p = NULL; else if (backp->m_op4p == oldp) backp->m_op4p = NULL; else this->v3fatalSrc("Unlink of node with back not pointing to it."); // Relink oldp->m_backp = NULL; // Iterator fixup if (oldp->m_iterpp) *(oldp->m_iterpp) = NULL; oldp->m_iterpp = NULL; oldp->debugTreeChange("-unlinkWNextOut: ", __LINE__, true); return oldp; } AstNode* AstNode::unlinkFrBack(AstNRelinker* linkerp) { this->debugTreeChange("-unlinkFrBkThs: ", __LINE__, true); AstNode* oldp = this; UASSERT(oldp->m_backp,"Node has no back, already unlinked?\n"); oldp->editCountInc(); AstNode* backp = oldp->m_backp; if (linkerp) { linkerp->m_oldp = oldp; linkerp->m_backp = backp; linkerp->m_iterpp = oldp->m_iterpp; if (backp->m_nextp == oldp) linkerp->m_chg = AstNRelinker::RELINK_NEXT; else if (backp->m_op1p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP1; else if (backp->m_op2p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP2; else if (backp->m_op3p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP3; else if (backp->m_op4p == oldp) linkerp->m_chg = AstNRelinker::RELINK_OP4; else this->v3fatalSrc("Unlink of node with back not pointing to it."); } if (backp->m_nextp== oldp) { // This node gets removed from middle (or tail) of list // Not head, since then oldp wouldn't be a next of backp... backp->m_nextp= oldp->m_nextp; if (backp->m_nextp) backp->m_nextp->m_backp = backp; // If it was a tail, back becomes new tail if (oldp->m_headtailp) { backp->m_headtailp = oldp->m_headtailp; backp->m_headtailp->m_headtailp = backp; } } else { if (backp->m_op1p == oldp) backp->m_op1p = oldp->m_nextp; else if (backp->m_op2p == oldp) backp->m_op2p = oldp->m_nextp; else if (backp->m_op3p == oldp) backp->m_op3p = oldp->m_nextp; else if (backp->m_op4p == oldp) backp->m_op4p = oldp->m_nextp; else this->v3fatalSrc("Unlink of node with back not pointing to it."); if (oldp->m_nextp) { AstNode* newheadp = oldp->m_nextp; newheadp->m_backp = backp; newheadp->m_headtailp = oldp->m_headtailp; newheadp->m_headtailp->m_headtailp = newheadp; } } // Iterator fixup if (oldp->m_iterpp) *(oldp->m_iterpp) = oldp->m_nextp; // Relink oldp->m_nextp = NULL; oldp->m_backp = NULL; oldp->m_headtailp = this; oldp->m_iterpp = NULL; oldp->debugTreeChange("-unlinkFrBkOut: ", __LINE__, true); return oldp; } void AstNode::relink(AstNRelinker* linkerp) { if (debug()>8) { UINFO(0," EDIT: relink: "); dumpPtrs(); } AstNode* newp = this; UASSERT(linkerp && linkerp->m_backp, "Need non-empty linker\n"); UASSERT(newp->backp()==NULL, "New node already linked?\n"); newp->editCountInc(); if (debug()>8) { linkerp->dump(cout); cout<m_backp; this->debugTreeChange("-relinkNew: ", __LINE__, true); backp->debugTreeChange("-relinkTre: ", __LINE__, true); switch (linkerp->m_chg) { case AstNRelinker::RELINK_NEXT: backp->addNextHere(newp); break; case AstNRelinker::RELINK_OP1: relinkOneLink(backp->m_op1p /*ref*/, newp); break; case AstNRelinker::RELINK_OP2: relinkOneLink(backp->m_op2p /*ref*/, newp); break; case AstNRelinker::RELINK_OP3: relinkOneLink(backp->m_op3p /*ref*/, newp); break; case AstNRelinker::RELINK_OP4: relinkOneLink(backp->m_op4p /*ref*/, newp); break; default: this->v3fatalSrc("Relink of node without any link to change."); break; } // Relink newp->m_backp = backp; linkerp->m_backp = NULL; // Iterator fixup if (linkerp->m_iterpp) { // If we're iterating over a next() link, we need to follow links off the // NEW node. Thus we pass iteration information via a pointer in the node. // This adds a unfortunate hot 8 bytes to every AstNode, but is faster than passing // across every function. // If anyone has a cleaner way, I'd be grateful. *(linkerp->m_iterpp) = newp; newp->m_iterpp = linkerp->m_iterpp; } // Empty the linker so not used twice accidentally linkerp->m_backp = NULL; this->debugTreeChange("-relinkOut: ", __LINE__, true); } void AstNode::relinkOneLink(AstNode*& pointpr, // Ref to pointer that gets set to newp AstNode* newp) { if (pointpr) { // We know there will be at least two elements when we are done, // (newp & the old list). // We *ALLOW* the new node to have its own next list. // Likewise there may be a old list. // Insert the whole old list following the new node's list. // Thus a unlink without next, followed by relink, gives the same list. AstNode* newlistlastp=newp->m_headtailp; if (newlistlastp->m_nextp && newlistlastp!=newp) newp->v3fatalSrc("Headtailp tail isn't at the tail"); AstNode* oldlistlastp = pointpr->m_headtailp; if (oldlistlastp->m_nextp && oldlistlastp!=pointpr) newp->v3fatalSrc("Old headtailp tail isn't at the tail"); // Next links newlistlastp->m_nextp = pointpr; pointpr->m_backp = newlistlastp; // Head/tail pointpr->m_headtailp = NULL; // Old head newlistlastp->m_headtailp = NULL; // Old tail newp->m_headtailp = oldlistlastp; // Head points to tail oldlistlastp->m_headtailp = newp; // Tail points to head } pointpr = newp; } void AstNode::addHereThisAsNext (AstNode* newp) { // {old}->this->{next} becomes {old}->new->this->{next} AstNRelinker handle; this->unlinkFrBackWithNext(&handle); newp->addNext(this); handle.relink(newp); } void AstNode::swapWith (AstNode* bp) { AstNRelinker aHandle; AstNRelinker bHandle; this->unlinkFrBack(&aHandle); bp->unlinkFrBack(&bHandle); aHandle.relink(bp); bHandle.relink(this); } //====================================================================== // Clone AstNode* AstNode::cloneTreeIter() { if (!this) return NULL; AstNode* newp = this->clone(); newp->op1p(this->m_op1p->cloneTreeIterList()); newp->op2p(this->m_op2p->cloneTreeIterList()); newp->op3p(this->m_op3p->cloneTreeIterList()); newp->op4p(this->m_op4p->cloneTreeIterList()); newp->m_iterpp = NULL; newp->clonep(this); // Save pointers to/from both to simplify relinking. this->clonep(newp); // Save pointers to/from both to simplify relinking. return newp; } AstNode* AstNode::cloneTreeIterList() { // Clone list of nodes, set m_headtailp if (!this) return NULL; AstNode* newheadp = NULL; AstNode* newtailp = NULL; for (AstNode* oldp = this; oldp; oldp=oldp->m_nextp) { AstNode* newp = oldp->cloneTreeIter(); newp->m_headtailp = NULL; newp->m_backp = newtailp; if (newtailp) newtailp->m_nextp = newp; if (!newheadp) newheadp = newp; newtailp = newp; } newheadp->m_headtailp = newtailp; newtailp->m_headtailp = newheadp; return newheadp; } AstNode* AstNode::cloneTree(bool cloneNextLink) { if (!this) return NULL; this->debugTreeChange("-cloneThs: ", __LINE__, cloneNextLink); cloneClearTree(); AstNode* newp; if (cloneNextLink && this->m_nextp) { newp = cloneTreeIterList(); } else { newp = cloneTreeIter(); newp->m_nextp = NULL; newp->m_headtailp = newp; } newp->m_backp = NULL; newp->cloneRelinkTree(); newp->debugTreeChange("-cloneOut: ", __LINE__, true); return newp; } //====================================================================== // Delete void AstNode::deleteNode() { if (!this) return; UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n"); editCountInc(); // Change links of old node so we coredump if used this->m_nextp = (AstNode*)1; this->m_backp = (AstNode*)1; this->m_headtailp = (AstNode*)1; this->m_op1p = (AstNode*)1; this->m_op2p = (AstNode*)1; this->m_op3p = (AstNode*)1; this->m_op4p = (AstNode*)1; #if !defined(VL_DEBUG) || defined(VL_LEAK_CHECKS) delete this; // Leak massively, so each pointer is unique and we can debug easier #endif } AstNode::~AstNode() { } void AstNode::deleteTreeIter() { if (!this) return; for (AstNode* nodep=this, *nnextp; nodep; nodep=nnextp) { nnextp = nodep->m_nextp; // MUST be depth first! nodep->m_op1p->deleteTreeIter(); nodep->m_op2p->deleteTreeIter(); nodep->m_op3p->deleteTreeIter(); nodep->m_op4p->deleteTreeIter(); nodep->m_nextp = NULL; nodep->m_backp = NULL; nodep->deleteNode(); } } void AstNode::deleteTree() { // deleteTree always deletes the next link, because you must have called // unlinkFromBack or unlinkFromBackWithNext as appropriate before calling this. if (!this) return; UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n"); this->debugTreeChange("-delTree: ", __LINE__, true); this->editCountInc(); // MUST be depth first! deleteTreeIter(); } //====================================================================== // Memory checks #ifdef VL_LEAK_CHECKS void* AstNode::operator new(size_t size) { AstNode* objp = static_cast(::operator new(size)); V3Broken::addNewed(objp); return objp; } void AstNode::operator delete(void* objp, size_t size) { if (!objp) return; AstNode* nodep = static_cast(objp); V3Broken::deleted(nodep); ::operator delete(objp); } #endif //====================================================================== // Iterators void AstNode::iterateChildren(AstNVisitor& v, AstNUser* vup) { // This is a very hot function if (!this) return; ASTNODE_PREFETCH(m_op1p); ASTNODE_PREFETCH(m_op2p); ASTNODE_PREFETCH(m_op3p); ASTNODE_PREFETCH(m_op4p); // if () not needed since iterateAndNext accepts null this, but faster with it. if (m_op1p) m_op1p->iterateAndNext(v, vup); if (m_op2p) m_op2p->iterateAndNext(v, vup); if (m_op3p) m_op3p->iterateAndNext(v, vup); if (m_op4p) m_op4p->iterateAndNext(v, vup); } void AstNode::iterateChildrenConst(AstNVisitor& v, AstNUser* vup) { // This is a very hot function if (!this) return; ASTNODE_PREFETCH(m_op1p); ASTNODE_PREFETCH(m_op2p); ASTNODE_PREFETCH(m_op3p); ASTNODE_PREFETCH(m_op4p); // if () not needed since iterateAndNext accepts null this, but faster with it. if (m_op1p) m_op1p->iterateAndNextConst(v, vup); if (m_op2p) m_op2p->iterateAndNextConst(v, vup); if (m_op3p) m_op3p->iterateAndNextConst(v, vup); if (m_op4p) m_op4p->iterateAndNextConst(v, vup); } void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) { // This is a very hot function // IMPORTANT: If you replace a node that's the target of this iterator, // then the NEW node will be iterated on next, it isn't skipped! // if (!this) return; // Part of for() // Future versions of this function may require the node to have a back to be iterated; // there's no lower level reason yet though the back must exist. AstNode* nodep=this; #ifdef VL_DEBUG // Otherwise too hot of a function for debug if (VL_UNLIKELY(nodep && !nodep->m_backp)) nodep->v3fatalSrc("iterateAndNext node has no back"); #endif while (nodep) { AstNode* niterp = nodep; // This address may get stomped via m_iterpp if the node is edited ASTNODE_PREFETCH(nodep->m_nextp); // Desirable check, but many places where multiple iterations are OK //if (VL_UNLIKELY(niterp->m_iterpp)) niterp->v3fatalSrc("IterateAndNext under iterateAndNext may miss edits"); // cppcheck-suppress nullPointer niterp->m_iterpp = &niterp; niterp->accept(v, vup); // accept may do a replaceNode and change niterp on us... //if (niterp != nodep) UINFO(1,"iterateAndNext edited "<<(void*)nodep<<" now into "<<(void*)niterp<m_iterpp = NULL; if (VL_UNLIKELY(niterp!=nodep)) { // Edited node inside accept nodep = niterp; } else { // Unchanged node, just continue loop nodep = niterp->m_nextp; } } } void AstNode::iterateListBackwards(AstNVisitor& v, AstNUser* vup) { if (!this) return; AstNode* nodep=this; while (nodep->m_nextp) nodep=nodep->m_nextp; while (nodep) { // Edits not supported: nodep->m_iterpp = &nodep; nodep->accept(v, vup); if (nodep->backp()->m_nextp == nodep) nodep=nodep->backp(); else nodep = NULL; // else: backp points up the tree. } } void AstNode::iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup) { if (!this) return; this->op1p()->iterateListBackwards(v,vup); this->op2p()->iterateListBackwards(v,vup); this->op3p()->iterateListBackwards(v,vup); this->op4p()->iterateListBackwards(v,vup); } void AstNode::iterateAndNextConst(AstNVisitor& v, AstNUser* vup) { // Keep following the current list even if edits change it if (!this) return; for (AstNode* nodep=this; nodep; ) { AstNode* nnextp = nodep->m_nextp; ASTNODE_PREFETCH(nnextp); nodep->accept(v, vup); nodep = nnextp; } } AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) { // Some visitors perform tree edits (such as V3Const), and may even // replace/delete the exact nodep that the visitor is called with. If // this happens, the parent will lose the handle to the node that was // processed. // To solve this, this function returns the pointer to the replacement node, // which in many cases is just the same node that was passed in. AstNode* nodep = this; // Note "this" may point to bogus point later in this function if (nodep->castNetlist()) { // Calling on top level; we know the netlist won't get replaced nodep->accept(v, vup); } else if (!nodep->backp()) { // Calling on standalone tree; insert a shim node so we can keep track, then delete it on completion AstBegin* tempp = new AstBegin(nodep->fileline(),"[EditWrapper]",nodep); { tempp->stmtsp()->accept(v, vup); nodep=NULL; // nodep to null as may be replaced } nodep = tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp=NULL; } else { // Use back to determine who's pointing at us (IE assume new node grafts into same place as old one) AstNode** nextnodepp = NULL; if (this->m_backp->m_op1p == this) nextnodepp = &(this->m_backp->m_op1p); else if (this->m_backp->m_op2p == this) nextnodepp = &(this->m_backp->m_op2p); else if (this->m_backp->m_op3p == this) nextnodepp = &(this->m_backp->m_op3p); else if (this->m_backp->m_op4p == this) nextnodepp = &(this->m_backp->m_op4p); else if (this->m_backp->m_nextp == this) nextnodepp = &(this->m_backp->m_nextp); if (!nextnodepp) this->v3fatalSrc("Node's back doesn't point to forward to node itself"); { nodep->accept(v, vup); nodep=NULL; // nodep to null as may be replaced } nodep = *nextnodepp; // Grab new node from point where old was connected } return nodep; } //====================================================================== void AstNode::cloneRelinkTree() { if (!this) return; for (AstNode* nodep=this; nodep; nodep=nodep->m_nextp) { if (m_dtypep && m_dtypep->clonep()) { m_dtypep = m_dtypep->clonep()->castNodeDType(); } nodep->cloneRelink(); nodep->m_op1p->cloneRelinkTree(); nodep->m_op2p->cloneRelinkTree(); nodep->m_op3p->cloneRelinkTree(); nodep->m_op4p->cloneRelinkTree(); } } //====================================================================== // Comparison bool AstNode::sameTreeIter(AstNode* node2p, bool ignNext, bool gateOnly) { // Return true if the two trees are identical if (this==NULL && node2p==NULL) return true; if (this==NULL || node2p==NULL) return false; if (this->type() != node2p->type() || this->dtypep() != node2p->dtypep() || !this->same(node2p) || (gateOnly && !this->isGateOptimizable())) { return false; } return (this->op1p()->sameTreeIter(node2p->op1p(),false,gateOnly) && this->op2p()->sameTreeIter(node2p->op2p(),false,gateOnly) && this->op3p()->sameTreeIter(node2p->op3p(),false,gateOnly) && this->op4p()->sameTreeIter(node2p->op4p(),false,gateOnly) && (ignNext || this->nextp()->sameTreeIter(node2p->nextp(),false,gateOnly)) ); } //====================================================================== // Static utilities ostream& operator<<(ostream& os, V3Hash rhs) { return os<backp()) { this->v3fatalSrc("Back node inconsistent"); } if (castNodeTermop() || castNodeVarRef()) { // Termops have a short-circuited iterateChildren, so check usage if (op1p()||op2p()||op3p()||op4p()) this->v3fatalSrc("Terminal operation with non-terminals"); } if (op1p()) op1p()->checkTreeIterList(this); if (op2p()) op2p()->checkTreeIterList(this); if (op3p()) op3p()->checkTreeIterList(this); if (op4p()) op4p()->checkTreeIterList(this); } void AstNode::checkTreeIterList(AstNode* backp) { // Check a (possible) list of nodes, this is always the head of the list if (!this) v3fatalSrc("Null nodep"); AstNode* headp = this; AstNode* tailp = this; for (AstNode* nodep=headp; nodep; nodep=nodep->nextp()) { nodep->checkTreeIter(backp); if (headp!=this && nextp()) this->v3fatalSrc("Headtailp should be null in middle of lists"); tailp=nodep; backp=nodep; } if (headp->m_headtailp != tailp) headp->v3fatalSrc("Tail in headtailp is inconsistent"); if (tailp->m_headtailp != headp) tailp->v3fatalSrc("Head in headtailp is inconsistent"); } void AstNode::checkTree() { if (!this) return; if (!debug()) return; if (this->backp()) { // Linked tree- check only the passed node this->checkTreeIter(this->backp()); } else { this->checkTreeIterList(this->backp()); } } void AstNode::dumpGdb() { // For GDB only if (!this) { cout<<"This=NULL"<dumpTreeFile(filename); } void AstNode::checkIter() const { if (m_iterpp) { dumpPtrs(cout); // Perhaps something forgot to clear m_iterpp? this->v3fatalSrc("Iteration link should be NULL"); } } void AstNode::dumpPtrs(ostream& os) const { os<<"This="<8) { os<nextp()) { nodep->dumpTree(os,indent+"1:",maxDepth-1); } for (AstNode* nodep=op2p(); nodep; nodep=nodep->nextp()) { nodep->dumpTree(os,indent+"2:",maxDepth-1); } for (AstNode* nodep=op3p(); nodep; nodep=nodep->nextp()) { nodep->dumpTree(os,indent+"3:",maxDepth-1); } for (AstNode* nodep=op4p(); nodep; nodep=nodep->nextp()) { nodep->dumpTree(os,indent+"4:",maxDepth-1); } } } void AstNode::dumpTreeAndNext(ostream& os, const string& indent, int maxDepth) { if (!this) return; for (AstNode* nodep=this; nodep; nodep=nodep->nextp()) { nodep->dumpTree(os, indent, maxDepth); } } void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) { if (doDump) { { // Write log & close UINFO(2,"Dumping "< logsp (V3File::new_ofstream(filename, append)); if (logsp->fail()) v3fatalSrc("Can't write "<"; *logsp<<" to "<=9)) { *logsp<castNetlist()) V3Broken::brokenAll(netp); } // Next dump can indicate start from here editCountSetLast(); } void AstNode::v3errorEnd(ostringstream& str) const { if (this && m_fileline) { ostringstream nsstr; nsstr<dump(nsstr); nsstr<v3errorEnd(nsstr); } else { V3Error::v3errorEnd(str); } } string AstNode::warnMore() const { if (this) return this->fileline()->warnMore(); else return V3Error::warnMore(); } //====================================================================== // Data type conversion void AstNode::dtypeChgSigned(bool flag) { if (!dtypep()) this->v3fatalSrc("No dtype when changing to (un)signed"); dtypeChgWidthSigned(dtypep()->width(), dtypep()->widthMin(), flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); } void AstNode::dtypeChgWidth(int width, int widthMin) { if (!dtypep()) this->v3fatalSrc("No dtype when changing width"); // Use ChgWidthSigned(...UNSIGNED) otherwise dtypeChgWidthSigned(width, widthMin, dtypep()->numeric()); } void AstNode::dtypeChgWidthSigned(int width, int widthMin, AstNumeric numeric) { if (!dtypep()) { // We allow dtypep() to be null, as before/during widthing dtypes are not resolved dtypeSetLogicSized(width, widthMin, numeric); } else { if (width==dtypep()->width() && widthMin==dtypep()->widthMin() && numeric==dtypep()->numeric()) return; // Correct already // FUTURE: We may be pointing at a two state data type, and this may // convert it to logic. Since the AstVar remains correct, we // work OK but this assumption may break in the future. // Note we can't just clone and do a widthForce, as if it's a BasicDType // the msb() indications etc will be incorrect. dtypeSetLogicSized(width, widthMin, numeric); } } AstNodeDType* AstNode::findBasicDType(AstBasicDTypeKwd kwd) const { // For 'simple' types we use the global directory. These are all unsized. // More advanced types land under the module/task/etc return v3Global.rootp()->typeTablep() ->findBasicDType(fileline(), kwd); } AstNodeDType* AstNode::findBitDType(int width, int widthMin, AstNumeric numeric) const { return v3Global.rootp()->typeTablep() ->findLogicBitDType(fileline(), AstBasicDTypeKwd::BIT, width, widthMin, numeric); } AstNodeDType* AstNode::findLogicDType(int width, int widthMin, AstNumeric numeric) const { return v3Global.rootp()->typeTablep() ->findLogicBitDType(fileline(), AstBasicDTypeKwd::LOGIC, width, widthMin, numeric); } AstNodeDType* AstNode::findLogicRangeDType(VNumRange range, int widthMin, AstNumeric numeric) const { return v3Global.rootp()->typeTablep() ->findLogicBitDType(fileline(), AstBasicDTypeKwd::LOGIC, range, widthMin, numeric); } AstBasicDType* AstNode::findInsertSameDType(AstBasicDType* nodep) { return v3Global.rootp()->typeTablep() ->findInsertSameDType(nodep); } //###################################################################### // AstNVisitor void AstNVisitor::doDeletes() { for (vector::iterator it = m_deleteps.begin(); it != m_deleteps.end(); ++it) { (*it)->deleteTree(); } m_deleteps.clear(); } verilator-3.874/src/V3Trace.cpp0000664000177100017500000006527612525171733016313 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Trace's Transformations: // Pass 1: // For each TRACE // Add to list of traces, Mark where traces came from, unlink it // Look for duplicate values; if so, cross reference // Make vertex for each var it references // Pass 2: // Go through _eval; if there's a call on the same flat statement list // then all functions for that call can get the same activity code. // Likewise, all _slow functions can get the same code. // CFUNCs that are public need unique codes, as does _eval // // For each CFUNC with unique callReason // Make vertex // For each var it sets, make vertex and edge from cfunc vertex // // For each CFUNC in graph // Add ASSIGN(SEL(__Vm_traceActivity,activityNumber++),1) // Create __Vm_traceActivity vector // Sort TRACEs by activityNumber(s) they come from (may be more than one) // Each set of activityNumbers // Add IF (SEL(__Vm_traceActivity,activityNumber),1) // Add traces under that activity number. // Assign trace codes: // If from a VARSCOPE, record the trace->varscope map // Else, assign trace codes to each variable // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Trace.h" #include "V3EmitCBase.h" #include "V3Graph.h" #include "V3Hashed.h" #include "V3Stats.h" //###################################################################### // Graph vertexes class TraceActivityVertex : public V3GraphVertex { AstNode* m_insertp; // Insert before this statement vlsint32_t m_activityCode; bool m_activityCodeValid; bool m_slow; // If always slow, we can use the same code public: enum { ACTIVITY_NEVER =((1UL<<31) - 1) }; enum { ACTIVITY_ALWAYS=((1UL<<31) - 2) }; enum { ACTIVITY_SLOW=0 }; TraceActivityVertex(V3Graph* graphp, AstNode* nodep, bool slow) : V3GraphVertex(graphp), m_insertp(nodep) { m_activityCode = 0; m_activityCodeValid = false; m_slow = slow; } TraceActivityVertex(V3Graph* graphp, vlsint32_t code) : V3GraphVertex(graphp), m_insertp(NULL) { m_activityCode = code; m_activityCodeValid = true; m_slow = false; } virtual ~TraceActivityVertex() {} // Accessors AstNode* insertp() const { if (!m_insertp) v3fatalSrc("Null insertp; probably called on a special always/slow."); return m_insertp; } virtual string name() const { if (activityAlways()) return "*ALWAYS*"; else return ((string)(slow()?"*SLOW* ":""))+insertp()->name(); } virtual string dotColor() const { return slow()?"yellowGreen":"green"; } bool activityCodeValid() const { return m_activityCodeValid; } vlsint32_t activityCode() const { return m_activityCode; } bool activityAlways() const { return activityCode()==ACTIVITY_ALWAYS; } void activityCode(vlsint32_t code) { m_activityCode=code; m_activityCodeValid=true;} bool slow() const { return m_slow; } void slow(bool flag) { if (!flag) m_slow=false; } }; class TraceCFuncVertex : public V3GraphVertex { AstCFunc* m_nodep; public: TraceCFuncVertex(V3Graph* graphp, AstCFunc* nodep) : V3GraphVertex(graphp), m_nodep(nodep) { } virtual ~TraceCFuncVertex() {} // Accessors AstCFunc* nodep() const { return m_nodep; } virtual string name() const { return nodep()->name(); } virtual string dotColor() const { return "yellow"; } }; class TraceTraceVertex : public V3GraphVertex { AstTraceInc* m_nodep; // TRACEINC this represents TraceTraceVertex* m_duplicatep; // NULL, or other vertex with the real code() that duplicates this one public: TraceTraceVertex(V3Graph* graphp, AstTraceInc* nodep) : V3GraphVertex(graphp), m_nodep(nodep), m_duplicatep(NULL) {} virtual ~TraceTraceVertex() {} // Accessors AstTraceInc* nodep() const { return m_nodep; } virtual string name() const { return nodep()->declp()->name(); } virtual string dotColor() const { return "red"; } TraceTraceVertex* duplicatep() const { return m_duplicatep; } void duplicatep(TraceTraceVertex* dupp) { if (duplicatep()) nodep()->v3fatalSrc("Assigning duplicatep() to already duplicated node"); m_duplicatep=dupp; } }; class TraceVarVertex : public V3GraphVertex { AstVarScope* m_nodep; public: TraceVarVertex(V3Graph* graphp, AstVarScope* nodep) : V3GraphVertex(graphp), m_nodep(nodep) {} virtual ~TraceVarVertex() {} // Accessors AstVarScope* nodep() const { return m_nodep; } virtual string name() const { return nodep()->name(); } virtual string dotColor() const { return "skyblue"; } }; //###################################################################### // Trace state, as a visitor of each AstNode class TraceVisitor : public EmitCBaseVisitor { private: // NODE STATE // V3Hashed // Ast*::user4() // V3Hashed calculation // Cleared entire netlist // AstCFunc::user1() // V3GraphVertex* for this node // AstTraceInc::user1() // V3GraphVertex* for this node // AstVarScope::user1() // V3GraphVertex* for this node // AstCCall::user2() // bool; walked next list for other ccalls // Ast*::user3() // TraceActivityVertex* for this node AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; //AstUser4InUse In V3Hashed // STATE AstNodeModule* m_topModp; // Module to add variables to AstScope* m_highScopep; // Scope to add variables to AstCFunc* m_funcp; // C function adding to graph AstTraceInc* m_tracep; // Trace function adding to graph AstCFunc* m_initFuncp; // Trace function we add statements to AstCFunc* m_fullFuncp; // Trace function we add statements to AstCFunc* m_fullSubFuncp; // Trace function we add statements to (under full) int m_fullSubStmts; // Statements under function being built AstCFunc* m_chgFuncp; // Trace function we add statements to AstCFunc* m_chgSubFuncp; // Trace function we add statements to (under full) AstNode* m_chgSubParentp;// Which node has call to m_chgSubFuncp int m_chgSubStmts; // Statements under function being built AstVarScope* m_activityVscp; // Activity variable uint32_t m_code; // Trace ident code# being assigned V3Graph m_graph; // Var/CFunc tracking TraceActivityVertex* m_alwaysVtxp; // "Always trace" vertex bool m_finding; // Pass one of algorithm? int m_funcNum; // Function number being built V3Double0 m_statChgSigs; // Statistic tracking V3Double0 m_statUniqSigs; // Statistic tracking V3Double0 m_statUniqCodes;// Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void detectDuplicates() { UINFO(9,"Finding duplicates\n"); // Note uses user4 V3Hashed hashed; // Duplicate code detection // Hash all of the values the traceIncs need for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (TraceTraceVertex* vvertexp = dynamic_cast(itp)) { AstTraceInc* nodep = vvertexp->nodep(); if (nodep->valuep()) { if (nodep->valuep()->backp() != nodep) nodep->v3fatalSrc("Trace duplicate back needs consistency, so we can map duplicates back to TRACEINCs"); hashed.hashAndInsert(nodep->valuep()); UINFO(8, " Hashed "<valuep())<<" "<verticesNextp()) { if (TraceTraceVertex* vvertexp = dynamic_cast(itp)) { AstTraceInc* nodep = vvertexp->nodep(); if (nodep->valuep() && !vvertexp->duplicatep()) { V3Hashed::iterator dupit = hashed.findDuplicate(nodep->valuep()); if (dupit != hashed.end()) { AstTraceInc* dupincp = hashed.iteratorNodep(dupit)->backp()->castTraceInc(); if (!dupincp) nodep->v3fatalSrc("Trace duplicate of wrong type"); TraceTraceVertex* dupvertexp = dynamic_cast(dupincp->user1p()->castGraphVertex()); UINFO(8," Orig "<duplicatep(vvertexp); // Remove node from comparison so don't hit it again hashed.erase(dupit); } } } } hashed.clear(); } void graphSimplify() { // Remove all variable nodes for (V3GraphVertex* nextp, *itp = m_graph.verticesBeginp(); itp; itp=nextp) { nextp = itp->verticesNextp(); if (TraceVarVertex* vvertexp = dynamic_cast(itp)) { vvertexp->rerouteEdges(&m_graph); vvertexp->unlinkDelete(&m_graph); } } // Remove multiple variables connecting funcs to traces // We do this twice, as then we have fewer edges to multiply out in the below expansion. m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); // Remove all Cfunc nodes for (V3GraphVertex* nextp, *itp = m_graph.verticesBeginp(); itp; itp=nextp) { nextp = itp->verticesNextp(); if (TraceCFuncVertex* vvertexp = dynamic_cast(itp)) { vvertexp->rerouteEdges(&m_graph); vvertexp->unlinkDelete(&m_graph); } } // Remove multiple variables connecting funcs to traces m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); // If there are any edges from a always, keep only the always for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (TraceTraceVertex* vvertexp = dynamic_cast(itp)) { V3GraphEdge* alwaysEdgep = NULL; for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { TraceActivityVertex* actVtxp = dynamic_cast(edgep->fromp()); if (!actVtxp) vvertexp->nodep()->v3fatalSrc("Tracing a node with FROM non activity"); if (actVtxp->activityAlways()) { alwaysEdgep = edgep; break; } } if (alwaysEdgep) { for (V3GraphEdge* nextp, *edgep = vvertexp->inBeginp(); edgep; edgep=nextp) { nextp = edgep->inNextp(); if (edgep!=alwaysEdgep) edgep->unlinkDelete(); } } } } // Activity points with no outputs can be removed for (V3GraphVertex* nextp, *itp = m_graph.verticesBeginp(); itp; itp=nextp) { nextp = itp->verticesNextp(); if (TraceActivityVertex* vvertexp = dynamic_cast(itp)) { if (!vvertexp->outBeginp()) { vvertexp->unlinkDelete(&m_graph); } } } } void assignActivity() { // Select activity numbers and put into each CFunc vertex uint32_t activityNumber = 1; // Note 0 indicates "slow" for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (TraceActivityVertex* vvertexp = dynamic_cast(itp)) { if (!vvertexp->activityCodeValid()) { if (vvertexp->slow()) { // If all functions in the calls are slow, we'll share the same code. // This makes us need less activityNumbers and so speeds up the fast path. vvertexp->activityCode(TraceActivityVertex::ACTIVITY_SLOW); } else { vvertexp->activityCode(activityNumber++); } } } } // Insert global variable if (!activityNumber) activityNumber++; // For simplicity, always create it int activityBits = VL_WORDS_I(activityNumber)*VL_WORDSIZE; // For tighter code; round to next 32 bit point. AstVar* newvarp = new AstVar (m_chgFuncp->fileline(), AstVarType::MODULETEMP, "__Vm_traceActivity", VFlagBitPacked(), activityBits); m_topModp->addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope(newvarp->fileline(), m_highScopep, newvarp); m_highScopep->addVarp(newvscp); m_activityVscp = newvscp; // Insert activity setter for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (TraceActivityVertex* vvertexp = dynamic_cast(itp)) { if (!vvertexp->activityAlways()) { FileLine* fl = vvertexp->insertp()->fileline(); uint32_t acode = vvertexp->activityCode(); vvertexp->insertp()->addNextHere (new AstAssign (fl, new AstSel (fl, new AstVarRef(fl, m_activityVscp, true), acode, 1), new AstConst (fl, AstConst::LogicTrue()))); } } } } AstCFunc* newCFunc(AstCFuncType type, const string& name, AstCFunc* basep) { AstCFunc* funcp = new AstCFunc(basep->fileline(), name, basep->scopep()); funcp->slow(basep->slow()); funcp->argTypes(EmitCBaseVisitor::symClassVar() +", "+v3Global.opt.traceClassBase()+"* vcdp, uint32_t code"); funcp->funcType(type); funcp->symProlog(true); basep->addNext(funcp); UINFO(5," Newfunc "<name()+"__"+cvtToStr(++m_funcNum); AstCFunc* funcp = NULL; if (basep->funcType()==AstCFuncType::TRACE_FULL) { funcp = newCFunc(AstCFuncType::TRACE_FULL_SUB, name, basep); } else if (basep->funcType()==AstCFuncType::TRACE_CHANGE) { funcp = newCFunc(AstCFuncType::TRACE_CHANGE_SUB, name, basep); } else { basep->v3fatalSrc("Strange base function type"); } AstCCall* callp = new AstCCall(funcp->fileline(), funcp); callp->argTypes("vlSymsp, vcdp, code"); if (callfromp->castCFunc()) { callfromp->castCFunc()->addStmtsp(callp); } else if (callfromp->castIf()) { callfromp->castIf()->addIfsp(callp); } else { callfromp->v3fatalSrc("Unknown caller node type"); // Where to add it?? } return funcp; } void addToChgSub(AstNode* underp, AstNode* stmtsp) { if (!m_chgSubFuncp || (m_chgSubParentp != underp) || (m_chgSubStmts && v3Global.opt.outputSplitCTrace() && m_chgSubStmts > v3Global.opt.outputSplitCTrace())) { m_chgSubFuncp = newCFuncSub(m_chgFuncp, underp); m_chgSubParentp = underp; m_chgSubStmts = 0; } m_chgSubFuncp->addStmtsp(stmtsp); m_chgSubStmts += EmitCBaseCounterVisitor(stmtsp).count(); } void putTracesIntoTree() { // Form a sorted list of the traces we are interested in UINFO(9,"Making trees\n"); typedef set ActCodeSet; // All activity numbers applying to a given trace typedef multimap TraceVec; // For activity set, what traces apply TraceVec traces; // Form sort structure // If a trace doesn't have activity, it's constant, and we don't need to track changes on it. for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (TraceTraceVertex* vvertexp = dynamic_cast(itp)) { ActCodeSet actset; UINFO(9," Add to sort: "<=9) vvertexp->nodep()->dumpTree(cout,"- trnode: "); for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { TraceActivityVertex* cfvertexp = dynamic_cast(edgep->fromp()); if (!cfvertexp) vvertexp->nodep()->v3fatalSrc("Should have been function pointing to this trace"); UINFO(9," Activity: "<activityAlways()) { // If code 0, we always trace; ignore other codes actset.clear(); actset.insert(TraceActivityVertex::ACTIVITY_ALWAYS); break; } else { uint32_t acode = cfvertexp->activityCode(); if (actset.find(acode) == actset.end()) { actset.insert(acode); } } } // If a trace doesn't have activity, it's constant, and we don't need to track changes on it. // We put constants and non-changers last, as then the prevvalue vector is more compacted if (actset.empty()) actset.insert(TraceActivityVertex::ACTIVITY_NEVER); traces.insert(make_pair(actset, vvertexp)); } } // Our keys are now sorted to have same activity number adjacent, // then by trace order. (Better would be execution order for cache efficiency....) // Last are constants and non-changers, as then the last value vector is more compact // Put TRACEs back into the tree const ActCodeSet* lastactp = NULL; AstNode* ifnodep = NULL; for (TraceVec::iterator it = traces.begin(); it!=traces.end(); ++it) { const ActCodeSet& actset = it->first; TraceTraceVertex* vvertexp = it->second; UINFO(9," Done sort: "<nodep(), needChg); if (addp) { // Else no activity or duplicate if (actset.find(TraceActivityVertex::ACTIVITY_NEVER) != actset.end()) { vvertexp->nodep()->v3fatalSrc("If never, needChg=0 and shouldn't need to add."); } else if (actset.find(TraceActivityVertex::ACTIVITY_ALWAYS) != actset.end()) { // Must always set it; add to base of function addToChgSub(m_chgFuncp, addp); } else if (lastactp && actset == *lastactp && ifnodep) { // Add to last statement we built addToChgSub(ifnodep, addp); } else { // Build a new IF statement FileLine* fl = addp->fileline(); AstNode* condp = NULL; for (ActCodeSet::const_iterator csit = actset.begin(); csit!=actset.end(); ++csit) { uint32_t acode = *csit; AstNode* selp = new AstSel (fl, new AstVarRef(fl, m_activityVscp, false), acode, 1); if (condp) condp = new AstOr (fl, condp, selp); else condp = selp; } AstIf* ifp = new AstIf (fl, condp, NULL, NULL); ifp->branchPred(AstBranchPred::BP_UNLIKELY); m_chgFuncp->addStmtsp(ifp); lastactp = &actset; ifnodep = ifp; addToChgSub(ifnodep, addp); } } } // Set in initializer // Clear activity after tracing completes FileLine* fl = m_chgFuncp->fileline(); AstNode* clrp = new AstAssign (fl, new AstVarRef(fl, m_activityVscp, true), new AstConst(fl, V3Number(fl, m_activityVscp->width()))); m_fullFuncp->addFinalsp(clrp->cloneTree(true)); m_chgFuncp->addFinalsp(clrp); } uint32_t assignDeclCode(AstTraceDecl* nodep) { if (!nodep->code()) { nodep->code(m_code); m_code += nodep->codeInc(); m_statUniqCodes += nodep->codeInc(); ++m_statUniqSigs; } return nodep->code(); } AstNode* assignTraceCode(TraceTraceVertex* vvertexp, AstTraceInc* nodep, bool needChg) { // Assign trace code, add to tree, return node for change tree or null // Look for identical copies uint32_t codePreassigned = 0; //if (debug()>=9) nodep->dumpTree(cout,"- assnnode: "); // Find non-duplicated node; note some nodep's maybe null, as they were deleted below TraceTraceVertex* dupvertexp = vvertexp; while (dupvertexp->duplicatep()) { dupvertexp = dupvertexp->duplicatep(); UINFO(9," dupOf "<<((void*)dupvertexp)<<" "<<((void*)dupvertexp->nodep()) <<" "<nodep()->declp()); nodep->declp()->code(codePreassigned); } else { assignDeclCode(nodep->declp()); } UINFO(8," Created code="<declp()->code() <<" "<<(codePreassigned?"[PREASS]":"") <<" "<<(needChg?"[CHG]":"")<<" "<cloneTree(true); } if (!m_fullSubFuncp || (m_fullSubStmts && v3Global.opt.outputSplitCTrace() && m_fullSubStmts > v3Global.opt.outputSplitCTrace())) { m_fullSubFuncp = newCFuncSub(m_fullFuncp, m_fullFuncp); m_fullSubStmts = 0; } m_fullSubFuncp->addStmtsp(nodep); m_fullSubStmts += EmitCBaseCounterVisitor(nodep).count(); } else { // Duplicates don't need a TraceInc pushDeletep(nodep); nodep=NULL; } return incAddp; } TraceCFuncVertex* getCFuncVertexp(AstCFunc* nodep) { TraceCFuncVertex* vertexp = dynamic_cast(nodep->user1p()->castGraphVertex()); if (!vertexp) { vertexp = new TraceCFuncVertex(&m_graph, nodep); nodep->user1p(vertexp); } return vertexp; } TraceActivityVertex* getActivityVertexp(AstNode* nodep, bool slow) { TraceActivityVertex* vertexp = dynamic_cast(nodep->user3p()->castGraphVertex()); if (!vertexp) { vertexp = new TraceActivityVertex(&m_graph, nodep, slow); nodep->user3p(vertexp); } vertexp->slow(slow); return vertexp; } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { m_code = 1; // Multiple TopScopes will require fixing how code#s // are assigned as duplicate varscopes must result in the same tracing code#. // Make a always vertex m_alwaysVtxp = new TraceActivityVertex(&m_graph, TraceActivityVertex::ACTIVITY_ALWAYS); // Add vertexes for all TRACES, and edges from VARs each trace looks at m_finding = false; nodep->iterateChildren(*this); // Add vertexes for all CFUNCs, and edges to VARs the func sets m_finding = true; nodep->iterateChildren(*this); m_finding = false; // Detect and remove duplicate values detectDuplicates(); // Simplify it if (debug()>=6) m_graph.dumpDotFilePrefixed("trace_pre"); graphSimplify(); if (debug()>=6) m_graph.dumpDotFilePrefixed("trace_opt"); // Create new TRACEINCs assignActivity(); putTracesIntoTree(); } virtual void visit(AstNodeModule* nodep, AstNUser*) { if (nodep->isTop()) m_topModp = nodep; nodep->iterateChildren(*this); } virtual void visit(AstTopScope* nodep, AstNUser*) { AstScope* scopep = nodep->scopep(); if (!scopep) nodep->v3fatalSrc("No scope found on top level"); m_highScopep = scopep; nodep->iterateChildren(*this); } virtual void visit(AstCCall* nodep, AstNUser*) { UINFO(8," CCALL "<user2()) { // See if there are other calls in same statement list; // If so, all funcs might share the same activity code TraceActivityVertex* activityVtxp = getActivityVertexp(nodep, nodep->funcp()->slow()); for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) { if (AstCCall* ccallp = nextp->castCCall()) { ccallp->user2(true); // Processed UINFO(8," SubCCALL "<funcp()); activityVtxp->slow(ccallp->funcp()->slow()); new V3GraphEdge (&m_graph, activityVtxp, ccallFuncVtxp, 1); } } } nodep->iterateChildren(*this); } virtual void visit(AstCFunc* nodep, AstNUser*) { UINFO(8," CFUNC "<funcType() == AstCFuncType::TRACE_INIT) { m_initFuncp = nodep; } else if (nodep->funcType() == AstCFuncType::TRACE_FULL) { m_fullFuncp = nodep; } else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE) { m_chgFuncp = nodep; } V3GraphVertex* funcVtxp = getCFuncVertexp(nodep); if (!m_finding) { // If public, we need a unique activity code to allow for sets directly in this func if (nodep->funcPublic() || nodep->dpiExport() || nodep->name() == "_eval") { // Need a non-null place to remember to later add a statement; make one if (!nodep->stmtsp()) nodep->addStmtsp(new AstComment(nodep->fileline(), "Tracing activity check")); V3GraphVertex* activityVtxp = getActivityVertexp(nodep->stmtsp(), nodep->slow()); new V3GraphEdge (&m_graph, activityVtxp, funcVtxp, 1); } } m_funcp = nodep; nodep->iterateChildren(*this); m_funcp = NULL; } virtual void visit(AstTraceInc* nodep, AstNUser*) { UINFO(8," TRACE "<v3fatalSrc("Traces should have been removed in prev step."); nodep->unlinkFrBack(); V3GraphVertex* vertexp = new TraceTraceVertex(&m_graph, nodep); nodep->user1p(vertexp); if (!m_funcp || (!m_chgFuncp || !m_fullFuncp)) nodep->v3fatalSrc("Trace not under func"); m_tracep = nodep; nodep->iterateChildren(*this); m_tracep = NULL; } virtual void visit(AstVarRef* nodep, AstNUser*) { if (m_tracep) { if (!nodep->varScopep()) nodep->v3fatalSrc("No var scope?"); if (nodep->lvalue()) nodep->v3fatalSrc("Lvalue in trace? Should be const."); V3GraphVertex* varVtxp = nodep->varScopep()->user1p()->castGraphVertex(); if (!varVtxp) { varVtxp = new TraceVarVertex(&m_graph, nodep->varScopep()); nodep->varScopep()->user1p(varVtxp); } V3GraphVertex* traceVtxp = m_tracep->user1p()->castGraphVertex(); new V3GraphEdge(&m_graph, varVtxp, traceVtxp, 1); if (nodep->varp()->isPrimaryIn() // Always need to trace primary inputs || nodep->varp()->isSigPublic()) { // Or ones user can change new V3GraphEdge(&m_graph, m_alwaysVtxp, traceVtxp, 1); } } else if (m_funcp && m_finding && nodep->lvalue()) { if (!nodep->varScopep()) nodep->v3fatalSrc("No var scope?"); V3GraphVertex* funcVtxp = getCFuncVertexp(m_funcp); V3GraphVertex* varVtxp = nodep->varScopep()->user1p()->castGraphVertex(); if (varVtxp) { // else we're not tracing this signal new V3GraphEdge(&m_graph, funcVtxp, varVtxp, 1); } } } //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS TraceVisitor(AstNetlist* nodep) { m_funcp = NULL; m_tracep = NULL; m_topModp = NULL; m_highScopep = NULL; m_finding = false; m_activityVscp = NULL; m_alwaysVtxp = NULL; m_initFuncp = NULL; m_fullFuncp = NULL; m_fullSubFuncp = NULL; m_fullSubStmts = 0; m_chgFuncp = NULL; m_chgSubFuncp = NULL; m_chgSubParentp = NULL; m_chgSubStmts = 0; m_funcNum = 0; nodep->accept(*this); } virtual ~TraceVisitor() { V3Stats::addStat("Tracing, Unique changing signals", m_statChgSigs); V3Stats::addStat("Tracing, Unique traced signals", m_statUniqSigs); V3Stats::addStat("Tracing, Unique trace codes", m_statUniqCodes); } }; //###################################################################### // Trace class functions void V3Trace::traceAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Hashed.cpp0000664000177100017500000001554412525171733016442 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Hashed common code into functions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Hashed's Transformations: // // Hash each node depth first // Hash includes varp name and operator type, and constants // Form lookup table based on hash of each statement w/ nodep and next nodep // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3Hashed.h" #include "V3Ast.h" #include "V3File.h" //###################################################################### // Hashed state, as a visitor of each AstNode class HashedVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstNodeStmt::user4() -> V3Hash. Hash value of this node (hash of 0 is illegal) //AstUser4InUse in V3Hashed.h // STATE V3Hash m_lowerHash; // Hash of the statement we're building static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // METHODS void nodeHashIterate(AstNode* nodep) { if (!nodep->user4()) { if (nodep->backp()->castCFunc() && !(nodep->castNodeStmt() || nodep->castCFunc())) { nodep->v3fatalSrc("Node "<prettyTypeName()<<" in statement position but not marked stmt (node under function)"); } V3Hash oldHash = m_lowerHash; { m_lowerHash = nodep->sameHash(); if (m_lowerHash.isIllegal()) { nodep->v3fatalSrc("sameHash function undefined (returns 0) for node under CFunc."); } // For identical nodes, the type should be the same thus dtypep should be the same too m_lowerHash = V3Hash(m_lowerHash, V3Hash(nodep->type()<<6, V3Hash(nodep->dtypep()))); // Now update m_lowerHash for our children's (and next children) contributions nodep->iterateChildren(*this); // Store the hash value nodep->user4(m_lowerHash.fullValue()); //UINFO(9, " hashnode "<user4p()) { HashedVisitor visitor (nodep); } } bool V3Hashed::sameNodes(AstNode* node1p, AstNode* node2p) { if (!node1p->user4p()) node1p->v3fatalSrc("Called isIdentical on non-hashed nodes"); if (!node2p->user4p()) node2p->v3fatalSrc("Called isIdentical on non-hashed nodes"); return (node1p->user4p() == node2p->user4p() // Same hash && node1p->sameTree(node2p)); } void V3Hashed::erase(iterator it) { AstNode* nodep = iteratorNodep(it); UINFO(8," erase "<user4p()) nodep->v3fatalSrc("Called removeNode on non-hashed node"); m_hashMmap.erase(it); nodep->user4p(NULL); // So we don't allow removeNode again } void V3Hashed::dumpFilePrefixed(const string& nameComment, bool tree) { if (v3Global.opt.dumpTree()) { dumpFile(v3Global.debugFilename(nameComment)+".hash", tree); } } void V3Hashed::dumpFile(const string& filename, bool tree) { const auto_ptr logp (V3File::new_ofstream(filename)); if (logp->fail()) v3fatalSrc("Can't write "< dist; V3Hash lasthash; int num_in_bucket = 0; for (HashMmap::iterator it=begin(); 1; ++it) { if (lasthash != it->first || it==end()) { if (it!=end()) lasthash = it->first; if (num_in_bucket) { if (dist.find(num_in_bucket)==dist.end()) { dist.insert(make_pair(num_in_bucket,1)); } else { ++dist[num_in_bucket]; } } num_in_bucket = 0; } if (it==end()) break; num_in_bucket++; } *logp <<"\n*** STATS:\n"<::iterator it=dist.begin(); it!=dist.end(); ++it) { *logp<<" "<first<<" "<second<first) { lasthash = it->first; *logp <<" "<first<second<second->dumpTree(*logp,"\t\t"); } } V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep) { UINFO(8," findD "<user4p()) nodep->v3fatalSrc("Called findDuplicate on non-hashed node"); pair eqrange = mmap().equal_range(nodeHash(nodep)); for (HashMmap::iterator eqit = eqrange.first; eqit != eqrange.second; ++eqit) { AstNode* node2p = eqit->second; if (nodep != node2p && sameNodes(nodep, node2p)) { return eqit; } } return end(); } V3Hashed::iterator V3Hashed::findDuplicate(AstNode* nodep, V3HashedUserCheck* checkp) { UINFO(8," findD "<user4p()) nodep->v3fatalSrc("Called findDuplicate on non-hashed node"); pair eqrange = mmap().equal_range(nodeHash(nodep)); for (HashMmap::iterator eqit = eqrange.first; eqit != eqrange.second; ++eqit) { AstNode* node2p = eqit->second; if (nodep != node2p && checkp->check(nodep,node2p) && sameNodes(nodep, node2p)) { return eqit; } } return end(); } verilator-3.874/src/V3Life.cpp0000664000177100017500000004307212525171733016122 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Lifelicate variable assignment elimination // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LIFE TRANSFORMATIONS: // Build control-flow graph with assignments and var usages // All modules: // ASSIGN(x,...), ASSIGN(x,...) => delete first one // We also track across if statements: // ASSIGN(X,...) IF( ..., ASSIGN(X,...), ASSIGN(X,...)) => deletes first // We don't do the opposite yet though (remove assigns in if followed by outside if) // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Life.h" #include "V3Stats.h" #include "V3Ast.h" #include "V3Const.h" //###################################################################### // Structure for global state class LifeState { // NODE STATE // See below AstUser1InUse m_inuser1; // STATE public: V3Double0 m_statAssnDel; // Statistic tracking V3Double0 m_statAssnCon; // Statistic tracking vector m_unlinkps; public: // CONSTRUCTORS LifeState() {} ~LifeState() { V3Stats::addStat("Optimizations, Lifetime assign deletions", m_statAssnDel); V3Stats::addStat("Optimizations, Lifetime constant prop", m_statAssnCon); for (vector::iterator it = m_unlinkps.begin(); it != m_unlinkps.end(); ++it) { (*it)->unlinkFrBack(); (*it)->deleteTree(); } } // METHODS void pushUnlinkDeletep(AstNode* nodep) { m_unlinkps.push_back(nodep); } }; //###################################################################### // Structure for each variable encountered class LifeVarEntry { AstNodeAssign* m_assignp; // Last assignment to this varscope, NULL if no longer relevant AstConst* m_constp; // Known constant value bool m_setBeforeUse; // First access was a set (and thus block above may have a set that can be deleted bool m_everSet; // Was ever assigned (and thus above block may not preserve constant propagation) inline void init (bool setBeforeUse) { m_assignp = NULL; m_constp = NULL; m_setBeforeUse = setBeforeUse; m_everSet = false; } public: class SIMPLEASSIGN {}; class COMPLEXASSIGN {}; class CONSUMED {}; LifeVarEntry(SIMPLEASSIGN, AstNodeAssign* assp) { init(true); simpleAssign(assp); } LifeVarEntry(COMPLEXASSIGN) { init(false); complexAssign(); } LifeVarEntry(CONSUMED) { init(false); consumed(); } ~LifeVarEntry() {} inline void simpleAssign(AstNodeAssign* assp) { // New simple A=.... assignment m_assignp = assp; m_constp = NULL; m_everSet = true; if (assp->rhsp()->castConst()) m_constp = assp->rhsp()->castConst(); } inline void complexAssign() { // A[x]=... or some complicated assignment m_assignp = NULL; m_constp = NULL; m_everSet = true; } inline void consumed() { // Rvalue read of A m_assignp = NULL; } AstNodeAssign* assignp() const { return m_assignp; } AstConst* constNodep() const { return m_constp; } bool setBeforeUse() const { return m_setBeforeUse; } bool everSet() const { return m_everSet; } }; //###################################################################### // Structure for all variables under a given meta-basic block class LifeBlock { // NODE STATE // Cleared each AstIf: // AstVarScope::user1() -> int. Used in combining to detect duplicates // LIFE MAP // For each basic block, we'll make a new map of what variables that if/else is changing typedef std::map LifeMap; LifeMap m_map; // Current active lifetime map for current scope LifeBlock* m_aboveLifep; // Upper life, or NULL LifeState* m_statep; // Current global state static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } public: LifeBlock(LifeBlock* aboveLifep, LifeState* statep) { m_aboveLifep = aboveLifep; // Null if top m_statep = statep; } ~LifeBlock() {} // METHODS void checkRemoveAssign(const LifeMap::iterator& it) { AstVar* varp = it->first->varp(); LifeVarEntry* entp = &(it->second); if (!varp->isSigPublic()) { // Rather than track what sigs AstUCFunc/AstUCStmt may change, // we just don't optimize any public sigs // Check the var entry, and remove if appropriate if (AstNode* oldassp = entp->assignp()) { UINFO(7," PREV: "<4) oldassp->dumpTree(cout, " REMOVE/SAMEBLK "); entp->complexAssign(); m_statep->pushUnlinkDeletep(oldassp); oldassp=NULL; ++m_statep->m_statAssnDel; } } } void simpleAssign(AstVarScope* nodep, AstNodeAssign* assp) { // Do we have a old assignment we can nuke? UINFO(4," ASSIGNof: "<second.simpleAssign(assp); } else { m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::SIMPLEASSIGN(), assp))); } //lifeDump(); } void complexAssign(AstVarScope* nodep) { UINFO(4," clearof: "<second.complexAssign(); } else { m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::COMPLEXASSIGN()))); } } void varUsageReplace (AstVarScope* nodep, AstVarRef* varrefp) { // Variable rvalue. If it references a constant, we can simply replace it LifeMap::iterator it = m_map.find(nodep); if (it != m_map.end()) { if (AstConst* constp = it->second.constNodep()) { if (!varrefp->varp()->isSigPublic()) { // Aha, variable is constant; substitute in. // We'll later constant propagate UINFO(4," replaceconst: "<replaceWith(constp->cloneTree(false)); varrefp->deleteTree(); varrefp=NULL; ++m_statep->m_statAssnCon; return; // **DONE, no longer a var reference** } } UINFO(4," usage: "<second.consumed(); } else { m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::CONSUMED()))); } } void complexAssignFind(AstVarScope* nodep) { LifeMap::iterator it = m_map.find(nodep); if (it != m_map.end()) { UINFO(4," casfind: "<first<second.complexAssign(); } else { m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::COMPLEXASSIGN()))); } } void consumedFind(AstVarScope* nodep) { LifeMap::iterator it = m_map.find(nodep); if (it != m_map.end()) { it->second.consumed(); } else { m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::CONSUMED()))); } } void lifeToAbove() { // Any varrefs under a if/else branch affect statements outside and after the if/else if (!m_aboveLifep) v3fatalSrc("Pushing life when already at the top level"); for (LifeMap::iterator it = m_map.begin(); it!=m_map.end(); ++it) { AstVarScope* nodep = it->first; m_aboveLifep->complexAssignFind(nodep); if (it->second.everSet()) { // Record there may be an assignment, so we don't constant propagate across the if. complexAssignFind(nodep); } else { // Record consumption, so we don't eliminate earlier assignments consumedFind(nodep); } } } void dualBranch (LifeBlock* life1p, LifeBlock* life2p) { // Find any common sets on both branches of IF and propagate upwards //life1p->lifeDump(); //life2p->lifeDump(); AstNode::user1ClearTree(); // user1p() used on entire tree for (LifeMap::iterator it = life1p->m_map.begin(); it!=life1p->m_map.end(); ++it) { // When the if branch sets a var before it's used, mark that variable if (it->second.setBeforeUse()) it->first->user1(1); } for (LifeMap::iterator it = life2p->m_map.begin(); it!=life2p->m_map.end(); ++it) { // When the else branch sets a var before it's used AstVarScope* nodep = it->first; if (it->second.setBeforeUse() && nodep->user1()) { // Both branches set the var, we can remove the assignment before the IF. UINFO(4,"DUALBRANCH "<lifeDump(); } // DEBUG void lifeDump() { UINFO(5, " LifeMap:"<second.setBeforeUse()?"[F] ":" ") <first<second.assignp()) { UINFO(5, " Ass: "<second.assignp()< LifeMap; // cppcheck-suppress memleak // cppcheck bug - it is deleted LifeBlock* m_lifep; // Current active lifetime map for current scope // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { // Consumption/generation of a variable, // it's used so can't elim assignment before this use. if (!nodep->varScopep()) nodep->v3fatalSrc("NULL"); // AstVarScope* vscp = nodep->varScopep(); if (!vscp) nodep->v3fatalSrc("Scope not assigned"); if (nodep->lvalue()) { m_lifep->complexAssign(vscp); } else { m_lifep->varUsageReplace(vscp, nodep); nodep=NULL; } } virtual void visit(AstNodeAssign* nodep, AstNUser*) { // Collect any used variables first, as lhs may also be on rhs // Similar code in V3Dead vluint64_t lastEdit = AstNode::editCountGbl(); // When it was last edited m_sideEffect = false; nodep->rhsp()->iterateAndNext(*this); if (lastEdit != AstNode::editCountGbl()) { // We changed something, try to constant propagate, but don't delete the // assignment as we still need nodep to remain. V3Const::constifyEdit(nodep->rhsp()); // rhsp may change } // Has to be direct assignment without any EXTRACTing. if (nodep->lhsp()->castVarRef() && !m_sideEffect && !m_noopt) { AstVarScope* vscp = nodep->lhsp()->castVarRef()->varScopep(); if (!vscp) nodep->v3fatalSrc("Scope lost on variable"); m_lifep->simpleAssign(vscp, nodep); } else { nodep->lhsp()->iterateAndNext(*this); } } virtual void visit(AstAssignDly* nodep, AstNUser*) { // Don't treat as normal assign; V3Life doesn't understand time sense nodep->iterateChildren(*this); } //---- Track control flow changes virtual void visit(AstNodeIf* nodep, AstNUser*) { UINFO(4," IF "<condp()->iterateAndNext(*this); LifeBlock* prevLifep = m_lifep; LifeBlock* ifLifep = new LifeBlock (prevLifep, m_statep); LifeBlock* elseLifep = new LifeBlock (prevLifep, m_statep); { m_lifep = ifLifep; nodep->ifsp()->iterateAndNext(*this); m_lifep = prevLifep; } { m_lifep = elseLifep; nodep->elsesp()->iterateAndNext(*this); m_lifep = prevLifep; } UINFO(4," join "<dualBranch (ifLifep, elseLifep); // For the next assignments, clear any variables that were read or written in the block ifLifep->lifeToAbove(); elseLifep->lifeToAbove(); delete ifLifep; delete elseLifep; } virtual void visit(AstWhile* nodep, AstNUser*) { // While's are a problem, as we don't allow loops in the graph. We // may go around the cond/body multiple times. Thus a // lifelication just in the body is ok, but we can't delete an // assignment in the body that's used in the cond. (And otherwise // would because it only appears used after-the-fact. So, we model // it as a IF statement, and just don't allow elimination of // variables across the body. LifeBlock* prevLifep = m_lifep; LifeBlock* condLifep = new LifeBlock (prevLifep, m_statep); LifeBlock* bodyLifep = new LifeBlock (prevLifep, m_statep); { m_lifep = condLifep; nodep->precondsp()->iterateAndNext(*this); nodep->condp()->iterateAndNext(*this); m_lifep = prevLifep; } { m_lifep = bodyLifep; nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); m_lifep = prevLifep; } UINFO(4," joinfor"<lifeToAbove(); bodyLifep->lifeToAbove(); delete condLifep; delete bodyLifep; } virtual void visit(AstJumpLabel* nodep, AstNUser*) { // As with While's we can't predict if a JumpGo will kill us or not // It's worse though as an IF(..., JUMPGO) may change the control flow. // Just don't optimize blocks with labels; they're rare - so far. LifeBlock* prevLifep = m_lifep; LifeBlock* bodyLifep = new LifeBlock (prevLifep, m_statep); bool prev_noopt = m_noopt; { m_lifep = bodyLifep; m_noopt = true; nodep->stmtsp()->iterateAndNext(*this); m_lifep = prevLifep; m_noopt = prev_noopt; } UINFO(4," joinjump"<lifeToAbove(); delete bodyLifep; } virtual void visit(AstCCall* nodep, AstNUser*) { //UINFO(4," CCALL "<iterateChildren(*this); // Enter the function and trace it if (!nodep->funcp()->entryPoint()) { // else is non-inline or public function we optimize separately nodep->funcp()->accept(*this); } } virtual void visit(AstCFunc* nodep, AstNUser*) { //UINFO(4," CCALL "<dpiImport() && !nodep->pure()) { m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment } nodep->iterateChildren(*this); } virtual void visit(AstUCFunc* nodep, AstNUser*) { m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment nodep->iterateChildren(*this); } virtual void visit(AstCMath* nodep, AstNUser*) { m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment nodep->iterateChildren(*this); } virtual void visit(AstVar*, AstNUser*) {} // Don't want varrefs under it virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS LifeVisitor(AstNode* nodep, LifeState* statep) { UINFO(4," LifeVisitor on "<accept(*this); delete m_lifep; m_lifep=NULL; } } virtual ~LifeVisitor() {} }; //###################################################################### class LifeTopVisitor : public AstNVisitor { // Visit all top nodes searching for functions that are entry points we want to start // finding code within. private: // STATE LifeState* m_statep; // Current state // VISITORS virtual void visit(AstCFunc* nodep, AstNUser*) { if (nodep->entryPoint()) { // Usage model 1: Simulate all C code, doing lifetime analysis LifeVisitor visitor (nodep, m_statep); } } virtual void visit(AstAlways* nodep, AstNUser*) { // Usage model 2: Cleanup basic blocks LifeVisitor visitor (nodep, m_statep); } virtual void visit(AstInitial* nodep, AstNUser*) { // Usage model 2: Cleanup basic blocks LifeVisitor visitor (nodep, m_statep); } virtual void visit(AstFinal* nodep, AstNUser*) { // Usage model 2: Cleanup basic blocks LifeVisitor visitor (nodep, m_statep); } virtual void visit(AstVar*, AstNUser*) {} // Accelerate virtual void visit(AstNodeStmt*, AstNUser*) {} // Accelerate virtual void visit(AstNodeMath*, AstNUser*) {} // Accelerate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS LifeTopVisitor(AstNetlist* nodep, LifeState* statep) { m_statep = statep; nodep->accept(*this); } virtual ~LifeTopVisitor() {} }; //###################################################################### // Life class functions void V3Life::lifeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Trace.h0000664000177100017500000000222712525171733015743 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves Tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3TRACE_H_ #define _V3TRACE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Trace { public: static void traceAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Stats.h0000664000177100017500000000713612525171733016007 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Collect and print statistics // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3STATS_H_ #define _V3STATS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" class AstNetlist; //============================================================================ class V3Double0 { // Double counter, initializes to zero for easy use double m_d; ///< Count of occurrences/ value public: // METHODS V3Double0() : m_d(0) {} ~V3Double0() {} // Implicit conversion operators: inline V3Double0 (const vluint64_t v) : m_d(v) { } inline operator double () const { return m_d; } // Explicit operators: inline V3Double0& operator++() { ++m_d; return *this; } // prefix inline V3Double0 operator++(int) { V3Double0 old=*this; m_d++; return old; } // postfix inline V3Double0& operator= (const double v) { m_d = v; return *this; } inline V3Double0& operator+=(const double v) { m_d += v; return *this; } inline V3Double0& operator-=(const double v) { m_d -= v; return *this; } }; //============================================================================ class V3Statistic { // A statistical entry we want published into the database string m_name; ///< Nameiption of this statistic double m_count; ///< Count of occurrences/ value string m_stage; ///< Runtime stage bool m_sumit; ///< Do summation of similar stats bool m_printit; ///< Print the results public: // METHODS string stage() const { return m_stage; } string name() const { return m_name; } double count() const { return m_count; } bool sumit() const { return m_sumit; } bool printit() const { return m_printit; } virtual void dump(ofstream& os) const; void combineWith(V3Statistic* otherp) { m_count += otherp->count(); otherp->m_printit = false; } // CONSTRUCTORS V3Statistic(const string& stage, const string& name, double count, bool sumit=false) : m_name(name), m_count(count), m_stage(stage), m_sumit(sumit) , m_printit(true) {} virtual ~V3Statistic() {} }; //============================================================================ class V3Stats { public: static void addStat(const V3Statistic&); static void addStat(const string& stage, const string& name, double count) { addStat(V3Statistic(stage,name,count)); } static void addStat(const string& name, double count) { addStat(V3Statistic("*",name,count)); } static void addStatSum(const string& name, double count) { addStat(V3Statistic("*",name,count,true)); } /// Called by the top level to collect statistics static void statsStageAll(AstNetlist* nodep, const string& stage, bool fast=false); static void statsFinalAll(AstNetlist* nodep); /// Called by the top level to dump the statistics static void statsReport(); }; #endif // Guard verilator-3.874/src/V3Ast.h0000664000177100017500000025533212525247644015450 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ast node structure // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3AST_H_ #define _V3AST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3FileLine.h" #include "V3Number.h" #include "V3Global.h" #include #include #include #include "V3Ast__gen_classes.h" // From ./astgen // Things like: // class V3AstNode; // Hint class so we can choose constructors class VFlagLogicPacked {}; class VFlagBitPacked {}; class VFlagChildDType {}; // Used by parser.y to select constructor that sets childDType // For broken() function, return error string if have a match #define BROKEN_RTN(test) do { if (VL_UNLIKELY(test)) return # test; } while(0) //###################################################################### class AstType { public: #include "V3Ast__gen_types.h" // From ./astgen // Above include has: // enum en {...}; // const char* ascii() const {...}; enum en m_e; // cppcheck-suppress uninitVar // responsiblity of each subclass inline AstType () {} inline AstType (en _e) : m_e(_e) {} explicit inline AstType (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; inline bool operator== (AstType lhs, AstType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstType lhs, AstType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstType::en lhs, AstType rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, AstType rhs) { return os<(_e)) {} operator en () const { return m_e; } inline bool isSigned() const { return m_e==SIGNED; } inline bool isNosign() const { return m_e==NOSIGN; } // No isUnsigned() as it's ambiguous if NOSIGN should be included or not. }; inline bool operator== (AstNumeric lhs, AstNumeric rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstNumeric lhs, AstNumeric::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstNumeric::en lhs, AstNumeric rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, AstNumeric rhs) { return os<(_e)) {} operator en () const { return m_e; } }; inline bool operator== (AstPragmaType lhs, AstPragmaType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstPragmaType lhs, AstPragmaType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstPragmaType::en lhs, AstPragmaType rhs) { return (lhs == rhs.m_e); } //###################################################################### class AstCFuncType { public: enum en { FT_NORMAL, TRACE_INIT, TRACE_INIT_SUB, TRACE_FULL, TRACE_FULL_SUB, TRACE_CHANGE, TRACE_CHANGE_SUB }; enum en m_e; inline AstCFuncType () : m_e(FT_NORMAL) {} inline AstCFuncType (en _e) : m_e(_e) {} explicit inline AstCFuncType (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } // METHODS bool isTrace() const { return (m_e==TRACE_INIT || m_e==TRACE_INIT_SUB || m_e==TRACE_FULL || m_e==TRACE_FULL_SUB || m_e==TRACE_CHANGE || m_e==TRACE_CHANGE_SUB); } }; inline bool operator== (AstCFuncType lhs, AstCFuncType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstCFuncType lhs, AstCFuncType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstCFuncType::en lhs, AstCFuncType rhs) { return (lhs == rhs.m_e); } //###################################################################### class AstEdgeType { public: // REMEMBER to edit the strings below too enum en { // These must be in general -> most specific order, as we sort by it in V3Const::visit AstSenTre ET_ILLEGAL, // Involving a variable ET_ANYEDGE, // Default for sensitivities; rip them out ET_BOTHEDGE, // POSEDGE | NEGEDGE ET_POSEDGE, ET_NEGEDGE, ET_HIGHEDGE, // Is high now (latches) ET_LOWEDGE, // Is low now (latches) // Not involving anything ET_COMBO, // Sensitive to all combo inputs to this block ET_INITIAL, // User initial statements ET_SETTLE, // Like combo but for initial wire resolutions after initial statement ET_NEVER // Never occurs (optimized away) }; enum en m_e; bool clockedStmt() const { static const bool clocked[] = { false, false, true, true, true, true, true, false, false, false }; return clocked[m_e]; } AstEdgeType invert() const { switch (m_e) { case ET_ANYEDGE: return ET_ANYEDGE; case ET_BOTHEDGE: return ET_BOTHEDGE; case ET_POSEDGE: return ET_NEGEDGE; case ET_NEGEDGE: return ET_POSEDGE; case ET_HIGHEDGE: return ET_LOWEDGE; case ET_LOWEDGE: return ET_HIGHEDGE; default: UASSERT_STATIC(0,"Inverting bad edgeType()"); }; return AstEdgeType::ET_ILLEGAL; } const char* ascii() const { static const char* names[] = { "%E-edge", "ANY", "BOTH", "POS", "NEG", "HIGH", "LOW", "COMBO","INITIAL","SETTLE","NEVER" }; return names[m_e]; }; const char* verilogKwd() const { static const char* names[] = { "%E-edge", "[any]", "edge", "posedge", "negedge", "[high]","[low]", "*","[initial]","[settle]","[never]" }; return names[m_e]; }; inline AstEdgeType () : m_e(ET_ILLEGAL) {} inline AstEdgeType (en _e) : m_e(_e) {} explicit inline AstEdgeType (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; inline bool operator== (AstEdgeType lhs, AstEdgeType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstEdgeType lhs, AstEdgeType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstEdgeType::en lhs, AstEdgeType rhs) { return (lhs == rhs.m_e); } //###################################################################### class AstAttrType { public: enum en { ILLEGAL, // DIM_BITS, // V3Const converts to constant DIM_DIMENSIONS, // V3Width converts to constant DIM_HIGH, // V3Width processes DIM_INCREMENT, // V3Width processes DIM_LEFT, // V3Width processes DIM_LOW, // V3Width processes DIM_RIGHT, // V3Width processes DIM_SIZE, // V3Width processes DIM_UNPK_DIMENSIONS, // V3Width converts to constant // DT_PUBLIC, // V3LinkParse moves to AstTypedef::attrPublic // ENUM_FIRST, // V3Width processes ENUM_LAST, // V3Width processes ENUM_NUM, // V3Width processes ENUM_NEXT, // V3Width processes ENUM_PREV, // V3Width processes ENUM_NAME, // V3Width processes // MEMBER_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes // VAR_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes 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_PUBLIC_FLAT_RD, // V3LinkParse moves to AstVar::sigPublic VAR_PUBLIC_FLAT_RW, // V3LinkParse moves to AstVar::sigPublic VAR_ISOLATE_ASSIGNMENTS, // V3LinkParse moves to AstVar::attrIsolateAssign VAR_SC_BV, // V3LinkParse moves to AstVar::attrScBv VAR_SFORMAT, // V3LinkParse moves to AstVar::attrSFormat VAR_CLOCKER, // V3LinkParse moves to AstVar::attrClocker VAR_NO_CLOCKER // V3LinkParse moves to AstVar::attrClocker }; enum en m_e; const char* ascii() const { static const char* names[] = { "%E-AT", "DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT", "DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS", "DT_PUBLIC", "ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME", "MEMBER_BASE", "VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC", "VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW", "VAR_ISOLATE_ASSIGNMENTS", "VAR_SC_BV", "VAR_SFORMAT", "VAR_CLOCKER", "VAR_NO_CLOCKER" }; return names[m_e]; }; inline AstAttrType () : m_e(ILLEGAL) {} inline AstAttrType (en _e) : m_e(_e) {} explicit inline AstAttrType (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; inline bool operator== (AstAttrType lhs, AstAttrType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstAttrType lhs, AstAttrType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstAttrType::en lhs, AstAttrType rhs) { return (lhs == rhs.m_e); } //###################################################################### class AstBasicDTypeKwd { public: enum en { UNKNOWN, BIT, BYTE, CHANDLE, INT, INTEGER, LOGIC, LONGINT, DOUBLE, SHORTINT, FLOAT, TIME, // Closer to a class type, but limited usage STRING, // Internal types for mid-steps SCOPEPTR, CHARPTR, // Unsigned and two state; fundamental types UINT32, UINT64, // Internal types, eliminated after parsing LOGIC_IMPLICIT, // Leave last _ENUM_MAX }; enum en m_e; const char* ascii() const { static const char* names[] = { "%E-unk", "bit", "byte", "chandle", "int", "integer", "logic", "longint", "real", "shortint", "shortreal", "time", "string", "VerilatedScope*", "char*", "IData", "QData", "LOGIC_IMPLICIT", " MAX" }; return names[m_e]; }; const char* dpiType() const { static const char* names[] = { "%E-unk", "unsigned char", "char", "void*", "int", "int", "svLogic", "long long", "double", "short int", "float", "long long", "const char*", "dpiScope", "const char*", "IData", "QData", "svLogic", // Though shouldn't be needed " MAX" }; return names[m_e]; }; static void test() { UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).ascii()," MAX"),"Enum array mismatch"); UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"Enum array mismatch"); } inline AstBasicDTypeKwd () : m_e(UNKNOWN) {} inline AstBasicDTypeKwd (en _e) : m_e(_e) {} explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } int width() const { switch (m_e) { case BIT: return 1; // scalar, can't bit extract unless ranged case BYTE: return 8; case CHANDLE: return 64; case INT: return 32; case INTEGER: return 32; case LOGIC: return 1; // scalar, can't bit extract unless ranged case LONGINT: return 64; case DOUBLE: return 64; // opaque case FLOAT: return 32; // opaque case SHORTINT: return 16; case TIME: return 64; case STRING: return 64; // opaque // Just the pointer, for today case SCOPEPTR: return 0; // opaque case CHARPTR: return 0; // opaque case UINT32: return 32; case UINT64: return 64; default: return 0; } } bool isSigned() const { return m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER || m_e==DOUBLE || m_e==FLOAT; } bool isUnsigned() const { return m_e==CHANDLE || m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR || m_e==UINT32 || m_e==UINT64; } bool isFourstate() const { return m_e==INTEGER || m_e==LOGIC || m_e==LOGIC_IMPLICIT; } bool isZeroInit() const { // Otherwise initializes to X return (m_e==BIT || m_e==BYTE || m_e==CHANDLE || m_e==INT || m_e==LONGINT || m_e==SHORTINT || m_e==STRING || m_e==DOUBLE || m_e==FLOAT); } bool isIntNumeric() const { // Enum increment supported return (m_e==BIT || m_e==BYTE || m_e==INT || m_e==INTEGER || m_e==LOGIC || m_e==LONGINT || m_e==SHORTINT || m_e==UINT32 || m_e==UINT64); } bool isSloppy() const { // Don't be as anal about width warnings return !(m_e==LOGIC || m_e==BIT); } bool isBitLogic() const { // Bit/logic vector types; can form a packed array return (m_e==LOGIC || m_e==BIT); } bool isDpiUnsupported() const { return (m_e==LOGIC || m_e==TIME); } bool isDpiUnsignable() const { // Can add "unsigned" to DPI return (m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER); } bool isOpaque() const { // IE not a simple number we can bit optimize return (m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR || m_e==DOUBLE || m_e==FLOAT); } bool isDouble() const { return m_e==DOUBLE; } bool isString() const { return m_e==STRING; } }; inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstBasicDTypeKwd::en lhs, AstBasicDTypeKwd rhs) { return (lhs == rhs.m_e); } //###################################################################### class AstVarType { public: enum en { UNKNOWN, GPARAM, LPARAM, GENVAR, VAR, // Reg, integer, logic, etc INPUT, OUTPUT, INOUT, SUPPLY0, SUPPLY1, WIRE, IMPLICITWIRE, TRIWIRE, TRI0, TRI1, PORT, // Temp type used in parser only BLOCKTEMP, MODULETEMP, STMTTEMP, XTEMP, IFACEREF // Used to link Interfaces between modules }; enum en m_e; inline AstVarType () : m_e(UNKNOWN) {} inline AstVarType (en _e) : m_e(_e) {} explicit inline AstVarType (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } const char* ascii() const { static const char* names[] = { "?","GPARAM","LPARAM","GENVAR", "VAR","INPUT","OUTPUT","INOUT", "SUPPLY0","SUPPLY1","WIRE","IMPLICITWIRE", "TRIWIRE","TRI0","TRI1", "PORT", "BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP", "IFACEREF"}; return names[m_e]; } bool isSignal() const { return (m_e==WIRE || m_e==IMPLICITWIRE || m_e==TRIWIRE || m_e==TRI0 || m_e==TRI1 || m_e==SUPPLY0 || m_e==SUPPLY1 || m_e==VAR); } }; inline bool operator== (AstVarType lhs, AstVarType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstVarType lhs, AstVarType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstVarType::en lhs, AstVarType rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, AstVarType rhs) { return os<(_e)) {} operator en () const { return m_e; } AstBranchPred invert() const { if (m_e==BP_UNLIKELY) return BP_LIKELY; else if (m_e==BP_LIKELY) return BP_UNLIKELY; else return m_e; } const char* ascii() const { static const char* names[] = { "","VL_LIKELY","VL_UNLIKELY"}; return names[m_e]; } }; inline bool operator== (AstBranchPred lhs, AstBranchPred rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstBranchPred lhs, AstBranchPred::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstBranchPred::en lhs, AstBranchPred rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, AstBranchPred rhs) { return os<(_e)) {} operator en () const { return m_e; } AstVarAttrClocker invert() const { if (m_e==CLOCKER_YES) return CLOCKER_NO; else if (m_e==CLOCKER_NO) return CLOCKER_YES; else return m_e; } const char* ascii() const { static const char* names[] = { "","clker","non_clker"}; return names[m_e]; } }; inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstVarAttrClocker::en lhs, AstVarAttrClocker rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, AstVarAttrClocker rhs) { return os<(_e)) {} operator en () const { return m_e; } const char* ascii() const { static const char* names[] = { "always","always_ff","always_latch","always_comb"}; return names[m_e]; } }; inline bool operator== (VAlwaysKwd lhs, VAlwaysKwd rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (VAlwaysKwd lhs, VAlwaysKwd::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (VAlwaysKwd::en lhs, VAlwaysKwd rhs) { return (lhs == rhs.m_e); } //###################################################################### class VCaseType { public: enum en { CT_CASE, CT_CASEX, CT_CASEZ, CT_CASEINSIDE }; enum en m_e; inline VCaseType () : m_e(CT_CASE) {} inline VCaseType (en _e) : m_e(_e) {} explicit inline VCaseType (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; inline bool operator== (VCaseType lhs, VCaseType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (VCaseType lhs, VCaseType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (VCaseType::en lhs, VCaseType rhs) { return (lhs == rhs.m_e); } //###################################################################### class AstDisplayType { public: enum en { DT_DISPLAY, DT_WRITE, DT_INFO, DT_ERROR, DT_WARNING, DT_FATAL }; enum en m_e; inline AstDisplayType () : m_e(DT_DISPLAY) {} inline AstDisplayType (en _e) : m_e(_e) {} explicit inline AstDisplayType (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } bool addNewline() const { return m_e!=DT_WRITE; } bool needScopeTracking() const { return m_e!=DT_DISPLAY && m_e!=DT_WRITE; } const char* ascii() const { static const char* names[] = { "display","write","info","error","warning","fatal"}; return names[m_e]; } }; inline bool operator== (AstDisplayType lhs, AstDisplayType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstDisplayType lhs, AstDisplayType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstDisplayType::en lhs, AstDisplayType rhs) { return (lhs == rhs.m_e); } //###################################################################### class AstParseRefExp { public: enum en { PX_NONE, // Used in V3LinkParse only PX_TEXT // Unknown ID component }; enum en m_e; inline AstParseRefExp() : m_e(PX_NONE) {} inline AstParseRefExp (en _e) : m_e(_e) {} explicit inline AstParseRefExp (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } const char* ascii() const { static const char* names[] = { "","TEXT","PREDOT"}; return names[m_e]; } }; inline bool operator== (AstParseRefExp lhs, AstParseRefExp rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstParseRefExp lhs, AstParseRefExp::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (AstParseRefExp::en lhs, AstParseRefExp rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, AstParseRefExp rhs) { return os<= LO int m_lo; // LO union { int mu_flags; struct { bool m_ranged:1; // Has a range bool m_littleEndian:1; // Bit vector is little endian }; }; inline bool operator== (const VNumRange& rhs) const { return m_hi == rhs.m_hi && m_lo == rhs.m_lo && mu_flags == rhs.mu_flags; } inline bool operator< (const VNumRange& rhs) const { if ( (m_hi < rhs.m_hi)) return true; if (!(m_hi == rhs.m_hi)) return false; // lhs > rhs if ( (m_lo < rhs.m_lo)) return true; if (!(m_lo == rhs.m_lo)) return false; // lhs > rhs if ( (mu_flags < rhs.mu_flags)) return true; if (!(mu_flags == rhs.mu_flags)) return false; // lhs > rhs return false; } // VNumRange() : m_hi(0), m_lo(0), mu_flags(0) {} VNumRange(int hi, int lo, bool littleEndian) : m_hi(0), m_lo(0), mu_flags(0) { init(hi,lo,littleEndian); } ~VNumRange() {} // MEMBERS void init(int hi, int lo, bool littleEndian) { m_hi=hi; m_lo=lo; mu_flags=0; m_ranged=true; m_littleEndian=littleEndian; } int hi() const { return m_hi; } int lo() const { return m_lo; } int left() const { return littleEndian()?lo():hi(); } // How to show a declaration int right() const { return littleEndian()?hi():lo(); } int leftToRightInc() const { return littleEndian()?1:-1; } int elements() const { return hi()-lo()+1; } bool ranged() const { return m_ranged; } bool littleEndian() const { return m_littleEndian; } int hiMaxSelect() const { return (lo()<0 ? hi()-lo() : hi()); } // Maximum value a [] select may index bool representableByWidth() const // Could be represented by just width=1, or [width-1:0] { return (!m_ranged || (m_lo==0 && m_hi>=1 && !m_littleEndian)); } void dump(ostream& str) const { if (ranged()) str<<"["< rhs if ( (m_widthMin < rhs.m_widthMin)) return true; if (!(m_widthMin == rhs.m_widthMin)) return false; // lhs > rhs if ( (m_numeric < rhs.m_numeric)) return true; if (!(m_numeric == rhs.m_numeric)) return false; // lhs > rhs if ( (m_keyword < rhs.m_keyword)) return true; if (!(m_keyword == rhs.m_keyword)) return false; // lhs > rhs if ( (m_nrange < rhs.m_nrange)) return true; if (!(m_nrange == rhs.m_nrange)) return false; // lhs > rhs return false; } VBasicTypeKey(int width, int widthMin, AstNumeric numeric, AstBasicDTypeKwd kwd, VNumRange nrange) : m_width(width), m_widthMin(widthMin), m_numeric(numeric), m_keyword(kwd), m_nrange(nrange) {} ~VBasicTypeKey() {} }; //###################################################################### // AstNUser - Generic pointer base class for AST User nodes. // - Also used to allow parameter passing up/down iterate calls class WidthVP; class LinkVP; class OrderBlockNU; class OrderVarNU; class V3GraphVertex; class VSymEnt; struct AstNUser { AstNUser* p() { return this; } // So can take address of temporary: iterate(...,AstNUser(args).p()) // Casters WidthVP* c() { return ((WidthVP*)this); } LinkVP* castLinkVP() { return ((LinkVP*)this); } VSymEnt* castSymEnt() { return ((VSymEnt*)this); } AstNode* castNode() { return ((AstNode*)this); } OrderBlockNU* castOrderBlock() { return ((OrderBlockNU*)this); } OrderVarNU* castOrderVar() { return ((OrderVarNU*)this); } V3GraphVertex* castGraphVertex() { return ((V3GraphVertex*)this); } inline int castInt() { union { AstNUser* up; int ui; } u; u.up = this; return u.ui; } static inline AstNUser* fromInt (int i) { union { AstNUser* up; int ui; } u; u.up=0; u.ui=i; return u.up; } }; //###################################################################### // AstUserResource - Generic pointer base class for tracking usage of user() // // Where AstNode->user2() is going to be used, for example, you write: // // AstUser2InUse m_userres; // // This will clear the tree, and prevent another visitor from clobering // user2. When the member goes out of scope it will be automagically // freed up. class AstUserInUseBase { protected: static void allocate(int id, uint32_t& cntGblRef, bool& userBusyRef) { // Perhaps there's still a AstUserInUse in scope for this? UASSERT_STATIC(!userBusyRef, "Conflicting user use; AstUser"+cvtToStr(id)+"InUse request when under another AstUserInUse"); userBusyRef = true; clearcnt(id, cntGblRef, userBusyRef); } static void free(int id, uint32_t& cntGblRef, bool& userBusyRef) { UASSERT_STATIC(userBusyRef, "Free of User"+cvtToStr(id)+"() not under AstUserInUse"); clearcnt(id, cntGblRef, userBusyRef); // Includes a checkUse for us userBusyRef = false; } static void clearcnt(int id, uint32_t& cntGblRef, bool& userBusyRef) { UASSERT_STATIC(userBusyRef, "Clear of User"+cvtToStr(id)+"() not under AstUserInUse"); // If this really fires and is real (after 2^32 edits???) // we could just walk the tree and clear manually ++cntGblRef; UASSERT_STATIC(cntGblRef, "User*() overflowed!"); } static void checkcnt(int id, uint32_t&, bool& userBusyRef) { UASSERT_STATIC(userBusyRef, "Check of User"+cvtToStr(id)+"() failed, not under AstUserInUse"); } }; // For each user() declare the in use structure // We let AstNode peek into here, because when under low optimization even // an accessor would be way too slow. class AstUser1InUse : AstUserInUseBase { protected: friend class AstNode; static uint32_t s_userCntGbl; // Count of which usage of userp() this is static bool s_userBusy; // Count is in use public: AstUser1InUse() { allocate(1, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } ~AstUser1InUse() { free (1, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void clear() { clearcnt(1, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void check() { checkcnt(1, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; class AstUser2InUse : AstUserInUseBase { protected: friend class AstNode; static uint32_t s_userCntGbl; // Count of which usage of userp() this is static bool s_userBusy; // Count is in use public: AstUser2InUse() { allocate(2, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } ~AstUser2InUse() { free (2, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void clear() { clearcnt(2, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void check() { checkcnt(2, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; class AstUser3InUse : AstUserInUseBase { protected: friend class AstNode; static uint32_t s_userCntGbl; // Count of which usage of userp() this is static bool s_userBusy; // Count is in use public: AstUser3InUse() { allocate(3, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } ~AstUser3InUse() { free (3, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void clear() { clearcnt(3, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void check() { checkcnt(3, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; class AstUser4InUse : AstUserInUseBase { protected: friend class AstNode; static uint32_t s_userCntGbl; // Count of which usage of userp() this is static bool s_userBusy; // Count is in use public: AstUser4InUse() { allocate(4, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } ~AstUser4InUse() { free (4, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void clear() { clearcnt(4, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void check() { checkcnt(4, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; class AstUser5InUse : AstUserInUseBase { protected: friend class AstNode; static uint32_t s_userCntGbl; // Count of which usage of userp() this is static bool s_userBusy; // Count is in use public: AstUser5InUse() { allocate(5, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } ~AstUser5InUse() { free (5, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void clear() { clearcnt(5, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } static void check() { checkcnt(5, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; //###################################################################### // AstNVisitor -- Allows new functions to be called on each node // type without changing the base classes. See "Modern C++ Design". class AstNVisitor { private: vector m_deleteps; // Nodes to delete when we are finished protected: friend class AstNode; public: // Cleaning void pushDeletep(AstNode* nodep) { m_deleteps.push_back(nodep); } void doDeletes(); public: virtual ~AstNVisitor() { doDeletes(); } #include "V3Ast__gen_visitor.h" // From ./astgen // Things like: // virtual void visit(type*) = 0; }; //###################################################################### // AstNRelinker -- Holds the state of a unlink so a new node can be // added at the same point. class AstNRelinker { protected: friend class AstNode; enum RelinkWhatEn { RELINK_BAD, RELINK_NEXT, RELINK_OP1, RELINK_OP2, RELINK_OP3, RELINK_OP4 }; AstNode* m_oldp; // The old node that was linked to this point in the tree AstNode* m_backp; RelinkWhatEn m_chg; AstNode** m_iterpp; public: AstNRelinker() { m_oldp=NULL; m_backp=NULL; m_chg=RELINK_BAD; m_iterpp=NULL;} void relink(AstNode* newp); AstNode* oldp() const { return m_oldp; } void dump(ostream& str=cout) const; }; inline ostream& operator<<(ostream& os, AstNRelinker& rhs) { rhs.dump(os); return os;} //###################################################################### // V3Hash -- Node hashing for V3Combine class V3Hash { // A hash of a tree of nodes, consisting of 8 bits with the number of nodes in the hash // and 24 bit value hash of relevant information about the node. // A value of 0 is illegal uint32_t m_both; static const uint32_t M24 = ((1<<24)-1); void setBoth(uint32_t depth, uint32_t hshval) { if (depth==0) depth=1; if (depth>255) depth=255; m_both = (depth<<24) | (hshval & M24); } public: // METHODS bool isIllegal() const { return m_both==0; } uint32_t fullValue() const { return m_both; } uint32_t depth() const { return (m_both >> 24) & 255; } uint32_t hshval() const { return m_both & M24; } // OPERATORS inline bool operator== (const V3Hash& rh) const { return m_both==rh.m_both; } inline bool operator!= (const V3Hash& rh) const { return m_both!=rh.m_both; } inline bool operator< (const V3Hash& rh) const { return m_bothcastInt(); } V3Hash operator+= (const V3Hash& rh) { setBoth(depth()+rh.depth(), (hshval()*31+rh.hshval())); return *this; }; // Creating from raw data (sameHash functions) V3Hash() { setBoth(1,0); } V3Hash(uint32_t val) { setBoth(1,val); } V3Hash(const void* vp) { setBoth(1,cvtToHash(vp)); } V3Hash(const string& name); V3Hash(V3Hash h1, V3Hash h2) { setBoth(1,h1.hshval()*31+h2.hshval()); } V3Hash(V3Hash h1, V3Hash h2, V3Hash h3) { setBoth(1,(h1.hshval()*31+h2.hshval())*31+h3.hshval()); } V3Hash(V3Hash h1, V3Hash h2, V3Hash h3, V3Hash h4) { setBoth(1,((h1.hshval()*31+h2.hshval())*31+h3.hshval())*31+h4.hshval()); } }; ostream& operator<<(ostream& os, V3Hash rhs); //###################################################################### // AstNode -- Base type of all Ast types // Prefetch a node. // The if() makes it faster, even though prefetch won't fault on null pointers #define ASTNODE_PREFETCH(nodep) \ { if (nodep) { VL_PREFETCH_RD(&(nodep->m_nextp)); VL_PREFETCH_RD(&(nodep->m_iterpp)); }} class AstNode { // v ASTNODE_PREFETCH depends on below ordering of members AstNode* m_nextp; // Next peer in the parent's list AstNode* m_backp; // Node that points to this one (via next/op1/op2/...) AstNode* m_op1p; // Generic pointer 1 AstNode* m_op2p; // Generic pointer 2 AstNode* m_op3p; // Generic pointer 3 AstNode* m_op4p; // Generic pointer 4 AstNode** m_iterpp; // Pointer to node iterating on, change it if we replace this node. // ^ ASTNODE_PREFETCH depends on above ordering of members AstNode* m_headtailp; // When at begin/end of list, the opposite end of the list FileLine* m_fileline; // Where it was declared vluint64_t m_editCount; // When it was last edited static vluint64_t s_editCntGbl; // Global edit counter static vluint64_t s_editCntLast;// Global edit counter, last value for printing * near node #s AstNodeDType* m_dtypep; // Data type of output or assignment (etc) AstNode* m_clonep; // Pointer to clone of/ source of this module (for *LAST* cloneTree() ONLY) int m_cloneCnt; // Mark of when userp was set static int s_cloneCntGbl; // Count of which userp is set // Attributes bool m_didWidth:1; // Did V3Width computation bool m_doingWidth:1; // Inside V3Width // // Space for more bools here // This member ordering both allows 64 bit alignment and puts associated data together AstNUser* m_user1p; // Pointer to any information the user iteration routine wants uint32_t m_user1Cnt; // Mark of when userp was set uint32_t m_user2Cnt; // Mark of when userp was set AstNUser* m_user2p; // Pointer to any information the user iteration routine wants AstNUser* m_user3p; // Pointer to any information the user iteration routine wants uint32_t m_user3Cnt; // Mark of when userp was set uint32_t m_user4Cnt; // Mark of when userp was set AstNUser* m_user4p; // Pointer to any information the user iteration routine wants AstNUser* m_user5p; // Pointer to any information the user iteration routine wants uint32_t m_user5Cnt; // Mark of when userp was set // METHODS void op1p(AstNode* nodep) { m_op1p = nodep; if (nodep) nodep->m_backp = this; } void op2p(AstNode* nodep) { m_op2p = nodep; if (nodep) nodep->m_backp = this; } void op3p(AstNode* nodep) { m_op3p = nodep; if (nodep) nodep->m_backp = this; } void op4p(AstNode* nodep) { m_op4p = nodep; if (nodep) nodep->m_backp = this; } void init(); // initialize value of AstNode void iterateListBackwards(AstNVisitor& v, AstNUser* vup=NULL); AstNode* cloneTreeIter(); AstNode* cloneTreeIterList(); void checkTreeIter(AstNode* backp); void checkTreeIterList(AstNode* backp); bool sameTreeIter(AstNode* node2p, bool ignNext, bool gateOnly); void deleteTreeIter(); void deleteNode(); static void relinkOneLink(AstNode*& pointpr, AstNode* newp); // cppcheck-suppress functionConst void debugTreeChange(const char* prefix, int lineno, bool next); protected: // CONSTUCTORS AstNode() {init(); } AstNode(FileLine* fileline) {init(); m_fileline = fileline; } virtual AstNode* clone() = 0; // Generally, cloneTree is what you want instead virtual void cloneRelink() {} void cloneRelinkTree(); // METHODS void setOp1p(AstNode* newp); // Set non-list-type op1 to non-list element void setOp2p(AstNode* newp); // Set non-list-type op2 to non-list element void setOp3p(AstNode* newp); // Set non-list-type op3 to non-list element void setOp4p(AstNode* newp); // Set non-list-type op4 to non-list element void setNOp1p(AstNode* newp) { if (newp) setOp1p(newp); } void setNOp2p(AstNode* newp) { if (newp) setOp2p(newp); } void setNOp3p(AstNode* newp) { if (newp) setOp3p(newp); } void setNOp4p(AstNode* newp) { if (newp) setOp4p(newp); } void addOp1p(AstNode* newp); // Append newp to end of op1 void addOp2p(AstNode* newp); // Append newp to end of op2 void addOp3p(AstNode* newp); // Append newp to end of op3 void addOp4p(AstNode* newp); // Append newp to end of op4 void addNOp1p(AstNode* newp) { if (newp) addOp1p(newp); } void addNOp2p(AstNode* newp) { if (newp) addOp2p(newp); } void addNOp3p(AstNode* newp) { if (newp) addOp3p(newp); } void addNOp4p(AstNode* newp) { if (newp) addOp4p(newp); } void clonep(AstNode* nodep) { m_clonep=nodep; m_cloneCnt=s_cloneCntGbl; } static void cloneClearTree() { s_cloneCntGbl++; UASSERT_STATIC(s_cloneCntGbl,"Rollover"); } public: // ACCESSORS virtual AstType type() const = 0; const char* typeName() const { return type().ascii(); } // See also prettyTypeName AstNode* nextp() const { return m_nextp; } AstNode* backp() const { return m_backp; } AstNode* op1p() const { return m_op1p; } AstNode* op2p() const { return m_op2p; } AstNode* op3p() const { return m_op3p; } AstNode* op4p() const { return m_op4p; } AstNodeDType* dtypep() const { return m_dtypep; } AstNode* clonep() const { return ((m_cloneCnt==s_cloneCntGbl)?m_clonep:NULL); } AstNode* firstAbovep() const { return ((backp() && backp()->nextp()!=this) ? backp() : NULL); } // Returns NULL when second or later in list bool brokeExists() const; bool brokeExistsAbove() const; // CONSTRUCTORS virtual ~AstNode(); #ifdef VL_LEAK_CHECKS static void* operator new(size_t size); static void operator delete(void* obj, size_t size); #endif // CONSTANT ACCESSORS static int instrCountBranch() { return 4; } ///< Instruction cycles to branch static int instrCountDiv() { return 10; } ///< Instruction cycles to divide static int instrCountDpi() { return 1000; } ///< Instruction cycles to call user function static int instrCountLd() { return 2; } ///< Instruction cycles to load memory static int instrCountMul() { return 3; } ///< Instruction cycles to multiply integers static int instrCountPli() { return 20; } ///< Instruction cycles to call pli routines static int instrCountDouble() { return 8; } ///< Instruction cycles to convert or do floats static int instrCountDoubleDiv() { return 40; } ///< Instruction cycles to divide floats static int instrCountDoubleTrig() { return 200; } ///< Instruction cycles to do triganomics static int instrCountString() { return 100; } ///< Instruction cycles to do string ops static int instrCountCall() { return instrCountBranch()+10; } ///< Instruction cycles to call subroutine static int instrCountTime() { return instrCountCall()+5; } ///< Instruction cycles to determine simulation time // ACCESSORS virtual string name() const { return ""; } virtual void name(const string& name) { this->v3fatalSrc("name() called on object without name() method"); } 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 static string prettyName(const string& namein); // Name for printing out to the user static string encodeName(const string& namein); // Encode user name into internal C representation static string encodeNumber(vlsint64_t numin); // Encode number into internal C representation static string vcdName(const string& namein); // Name for printing out to vcd files string prettyName() const { return prettyName(name()); } string prettyTypeName() const; // "VARREF" for error messages virtual string prettyOperatorName() const { return "operator "+prettyTypeName(); } FileLine* fileline() const { return m_fileline; } void fileline(FileLine* fl) { m_fileline=fl; } bool width1() const; int widthInstrs() const; void didWidth(bool flag) { m_didWidth=flag; } bool didWidth() const { return m_didWidth; } bool didWidthAndSet() { if (didWidth()) return true; didWidth(true); return false;} void doingWidth(bool flag) { m_doingWidth=flag; } bool doingWidth() const { return m_doingWidth; } //TODO stomp these width functions out, and call via dtypep() instead int width() const; int widthMin() const; int widthMinV() const { return v3Global.widthMinUsage()==VWidthMinUsage::VERILOG_WIDTH ? widthMin() : width(); } int widthWords() const { return VL_WORDS_I(width()); } bool isQuad() const { return (width()>VL_WORDSIZE && width()<=VL_QUADSIZE); } bool isWide() const { return (width()>VL_QUADSIZE); } bool isDouble() const; bool isSigned() const; bool isString() const; AstNUser* user1p() const { // Slows things down measurably, so disabled by default //UASSERT_STATIC(AstUser1InUse::s_userBusy, "userp set w/o busy"); return ((m_user1Cnt==AstUser1InUse::s_userCntGbl)?m_user1p:NULL); } void user1p(void* userp) { m_user1p=(AstNUser*)(userp); m_user1Cnt=AstUser1InUse::s_userCntGbl; } int user1() const { return user1p()->castInt(); } void user1(int val) { user1p(AstNUser::fromInt(val)); } int user1Inc() { int v=user1(); user1(v+1); return v; } int user1SetOnce() { int v=user1(); if (!v) user1(1); return v; } // Better for cache than user1Inc() static void user1ClearTree() { AstUser1InUse::clear(); } // Clear userp()'s across the entire tree AstNUser* user2p() const { //UASSERT_STATIC(AstUser2InUse::s_userBusy, "user2p set w/o busy"); return ((m_user2Cnt==AstUser2InUse::s_userCntGbl)?m_user2p:NULL); } void user2p(void* userp) { m_user2p=(AstNUser*)(userp); m_user2Cnt=AstUser2InUse::s_userCntGbl; } int user2() const { return user2p()->castInt(); } void user2(int val) { user2p(AstNUser::fromInt(val)); } int user2Inc() { int v=user2(); user2(v+1); return v; } int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; } static void user2ClearTree() { AstUser2InUse::clear(); } AstNUser* user3p() const { //UASSERT_STATIC(AstUser3InUse::s_userBusy, "user3p set w/o busy"); return ((m_user3Cnt==AstUser3InUse::s_userCntGbl)?m_user3p:NULL); } void user3p(void* userp) { m_user3p=(AstNUser*)(userp); m_user3Cnt=AstUser3InUse::s_userCntGbl; } int user3() const { return user3p()->castInt(); } void user3(int val) { user3p(AstNUser::fromInt(val)); } int user3Inc() { int v=user3(); user3(v+1); return v; } int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; } static void user3ClearTree() { AstUser3InUse::clear(); } AstNUser* user4p() const { //UASSERT_STATIC(AstUser4InUse::s_userBusy, "user4p set w/o busy"); return ((m_user4Cnt==AstUser4InUse::s_userCntGbl)?m_user4p:NULL); } void user4p(void* userp) { m_user4p=(AstNUser*)(userp); m_user4Cnt=AstUser4InUse::s_userCntGbl; } int user4() const { return user4p()->castInt(); } void user4(int val) { user4p(AstNUser::fromInt(val)); } int user4Inc() { int v=user4(); user4(v+1); return v; } int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; } static void user4ClearTree() { AstUser4InUse::clear(); } AstNUser* user5p() const { //UASSERT_STATIC(AstUser5InUse::s_userBusy, "user5p set w/o busy"); return ((m_user5Cnt==AstUser5InUse::s_userCntGbl)?m_user5p:NULL); } void user5p(void* userp) { m_user5p=(AstNUser*)(userp); m_user5Cnt=AstUser5InUse::s_userCntGbl; } int user5() const { return user5p()->castInt(); } void user5(int val) { user5p(AstNUser::fromInt(val)); } int user5Inc() { int v=user5(); user5(v+1); return v; } int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; } static void user5ClearTree() { AstUser5InUse::clear(); } vluint64_t editCount() const { return m_editCount; } void editCountInc() { m_editCount = ++s_editCntGbl; } // Preincrement, so can "watch AstNode::s_editCntGbl=##" static vluint64_t editCountLast() { return s_editCntLast; } static vluint64_t editCountGbl() { return s_editCntGbl; } static void editCountSetLast() { s_editCntLast = editCountGbl(); } // ACCESSORS for specific types // Alas these can't be virtual or they break when passed a NULL bool isZero(); bool isOne(); bool isNeqZero(); bool isAllOnes(); bool isAllOnesV(); // Verilog width rules apply // METHODS - data type changes especially for initial creation void dtypep(AstNodeDType* nodep) { if (m_dtypep != nodep) { m_dtypep = nodep; editCountInc(); } } void dtypeFrom(AstNode* fromp) { if (fromp) { dtypep(fromp->dtypep()); }} void dtypeChgSigned(bool flag=true); void dtypeChgWidth(int width, int widthMin); void dtypeChgWidthSigned(int width, int widthMin, AstNumeric numeric); void dtypeSetBitSized(int width, int widthMin, AstNumeric numeric) { dtypep(findBitDType(width,widthMin,numeric)); } void dtypeSetLogicSized(int width, int widthMin, AstNumeric numeric) { dtypep(findLogicDType(width,widthMin,numeric)); } void dtypeSetLogicBool() { dtypep(findLogicBoolDType()); } void dtypeSetDouble() { dtypep(findDoubleDType()); } void dtypeSetString() { dtypep(findStringDType()); } void dtypeSetSigned32() { dtypep(findSigned32DType()); } void dtypeSetUInt32() { dtypep(findUInt32DType()); } // Twostate void dtypeSetUInt64() { dtypep(findUInt64DType()); } // Twostate // Data type locators AstNodeDType* findLogicBoolDType() { return findBasicDType(AstBasicDTypeKwd::LOGIC); } AstNodeDType* findDoubleDType() { return findBasicDType(AstBasicDTypeKwd::DOUBLE); } AstNodeDType* findStringDType() { return findBasicDType(AstBasicDTypeKwd::STRING); } AstNodeDType* findSigned32DType() { return findBasicDType(AstBasicDTypeKwd::INTEGER); } AstNodeDType* findUInt32DType() { return findBasicDType(AstBasicDTypeKwd::UINT32); } // Twostate AstNodeDType* findUInt64DType() { return findBasicDType(AstBasicDTypeKwd::UINT64); } // Twostate AstNodeDType* findBitDType(int width, int widthMin, AstNumeric numeric) const; AstNodeDType* findLogicDType(int width, int widthMin, AstNumeric numeric) const; AstNodeDType* findLogicRangeDType(VNumRange range, int widthMin, AstNumeric numeric) const; AstNodeDType* findBasicDType(AstBasicDTypeKwd kwd) const; AstBasicDType* findInsertSameDType(AstBasicDType* nodep); // METHODS - dump and error void v3errorEnd(ostringstream& str) const; string warnMore() const; virtual void dump(ostream& str=cout); void dumpGdb(); // For GDB only void dumpGdbHeader() const; // METHODS - Tree modifications AstNode* addNext(AstNode* newp); // Returns this, adds to end of list AstNode* addNextNull(AstNode* newp); // Returns this, adds to end of list, NULL is OK void addNextHere(AstNode* newp); // Adds after speced node void addPrev(AstNode* newp) { replaceWith(newp); newp->addNext(this); } void addHereThisAsNext(AstNode* newp); // Adds at old place of this, this becomes next void replaceWith(AstNode* newp); // Replace current node in tree with new node AstNode* unlinkFrBack(AstNRelinker* linkerp=NULL); // Unlink this from whoever points to it. AstNode* unlinkFrBackWithNext(AstNRelinker* linkerp=NULL); // Unlink this from whoever points to it, keep entire next list with unlinked node void swapWith(AstNode* bp); void relink(AstNRelinker* linkerp); // Generally use linker->relink() instead void cloneRelinkNode() { cloneRelink(); } // Iterate and insert - assumes tree format virtual void addNextStmt(AstNode* newp, AstNode* belowp); // When calling, "this" is second argument virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // When calling, "this" is second argument // METHODS - Iterate on a tree AstNode* cloneTree(bool cloneNextLink); bool sameTree(AstNode* node2p); // Does tree of this == node2p? bool sameGateTree(AstNode* node2p); // Does tree of this == node2p?, not allowing non-isGateOptimizable void deleteTree(); // Always deletes the next link void checkTree(); // User Interface version void checkIter() const; void clearIter() { m_iterpp=NULL; } void dumpPtrs(ostream& str=cout) const; void dumpTree(ostream& str=cout, const string& indent=" ", int maxDepth=0); void dumpTree(const string& indent, int maxDepth=0) { dumpTree(cout,indent,maxDepth); } void dumpTreeGdb(); // For GDB only void dumpTreeAndNext(ostream& str=cout, const string& indent=" ", int maxDepth=0); void dumpTreeFile(const string& filename, bool append=false, bool doDump=true); static void dumpTreeFileGdb(const char* filenamep=NULL); // METHODS - queries virtual bool isPure() const { return true; } // Else a $display, etc, that must be ordered with other displays virtual bool isBrancher() const { return false; } // Changes control flow, disable some optimizations virtual bool isGateOptimizable() const { return true; } // Else a AstTime etc that can't be pushed out virtual bool isGateDedupable() const { return isGateOptimizable(); } // GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf) virtual bool isSubstOptimizable() const { return true; } // Else a AstTime etc that can't be substituted out virtual bool isPredictOptimizable() const { return true; } // Else a AstTime etc which output can't be predicted from input virtual bool isOutputter() const { return false; } // Else creates output or exits, etc, not unconsumed virtual bool isUnlikely() const { return false; } // Else $stop or similar statement which means an above IF statement is unlikely to be taken virtual int instrCount() const { return 0; } virtual V3Hash sameHash() const { return V3Hash(V3Hash::Illegal()); } // Not a node that supports it virtual bool same(AstNode* otherp) const { return true; } virtual bool hasDType() const { return false; } // Iff has a data type; dtype() must be non null virtual AstNodeDType* getChildDTypep() const { return NULL; } // Iff has a non-null childDTypep(), as generic node function virtual bool maybePointedTo() const { return false; } // Another AstNode* may have a pointer into this node, other then normal front/back/etc. virtual const char* broken() const { return NULL; } // INVOKERS virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) = 0; void iterate(AstNVisitor& v, AstNUser* vup=NULL) { this->accept(v,vup); } // Does this; excludes following this->next void iterateAndNext(AstNVisitor& v, AstNUser* vup=NULL); void iterateAndNextConst(AstNVisitor& v, AstNUser* vup=NULL); void iterateAndNextIgnoreEdit(AstNVisitor& v, AstNUser* vup=NULL) { iterateAndNextConst(v, vup); } void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next void iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next void iterateChildrenConst(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next AstNode* acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup=NULL); // Return edited nodep; see comments in V3Ast.cpp // CONVERSION AstNode* castNode() { return this; } #include "V3Ast__gen_interface.h" // From ./astgen // Things like: // AstAlways* castAlways(); }; inline ostream& operator<<(ostream& os, AstNode* rhs) { if (!rhs) os<<"NULL"; else rhs->dump(os); return os; } inline void AstNRelinker::relink(AstNode* newp) { newp->AstNode::relink(this); } //###################################################################### //###################################################################### //=== AstNode* : Derived generic node types #define ASTNODE_BASE_FUNCS(name) \ virtual ~Ast ##name() {} \ Ast ##name * cloneTree(bool cloneNext) { return AstNode::cloneTree(cloneNext)->cast ##name(); } class AstNodeMath : public AstNode { // Math -- anything that's part of an expression tree public: AstNodeMath(FileLine* fl) : AstNode(fl) {} ASTNODE_BASE_FUNCS(NodeMath) // METHODS virtual bool hasDType() const { return true; } virtual string emitVerilog() = 0; /// Format string for verilog writing; see V3EmitV virtual string emitC() = 0; virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() = 0; // True if output has extra upper bits zero // Someday we will generically support data types on every math node // Until then isOpaque indicates we shouldn't constant optimize this node type bool isOpaque() { return castCvtPackString()!=NULL; } }; class AstNodeTermop : public AstNodeMath { // Terminal operator -- a operator with no "inputs" public: AstNodeTermop(FileLine* fl) : AstNodeMath(fl) {} ASTNODE_BASE_FUNCS(NodeTermop) // Know no children, and hot function, so skip iterator for speed // See checkTreeIter also that asserts no children // cppcheck-suppress functionConst void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { } }; class AstNodeUniop : public AstNodeMath { // Unary math public: AstNodeUniop(FileLine* fl, AstNode* lhsp) : AstNodeMath(fl) { dtypeFrom(lhsp); setOp1p(lhsp); } ASTNODE_BASE_FUNCS(NodeUniop) AstNode* lhsp() const { return op1p()->castNode(); } void lhsp(AstNode* nodep) { return setOp1p(nodep); } // METHODS virtual void numberOperate(V3Number& out, const V3Number& lhs) = 0; // Set out to evaluation of a AstConst'ed lhs virtual bool cleanLhs() = 0; virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size virtual bool doubleFlavor() const { return false; } // D flavor of nodes with both flavors? virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors? virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors? virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode*) const { return true; } }; class AstNodeBiop : public AstNodeMath { // Binary math public: AstNodeBiop(FileLine* fl, AstNode* lhs, AstNode* rhs) : AstNodeMath(fl) { setOp1p(lhs); setOp2p(rhs); } ASTNODE_BASE_FUNCS(NodeBiop) AstNode* lhsp() const { return op1p()->castNode(); } AstNode* rhsp() const { return op2p()->castNode(); } void lhsp(AstNode* nodep) { return setOp1p(nodep); } void rhsp(AstNode* nodep) { return setOp2p(nodep); } // METHODS virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) = 0; // Set out to evaluation of a AstConst'ed virtual bool cleanLhs() = 0; // True if LHS must have extra upper bits zero virtual bool cleanRhs() = 0; // True if RHS must have extra upper bits zero virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size virtual bool sizeMattersRhs() = 0; // True if output result depends on rhs size virtual bool doubleFlavor() const { return false; } // D flavor of nodes with both flavors? virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors? virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors? virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode*) const { return true; } }; class AstNodeTriop : public AstNodeMath { // Trinary math public: AstNodeTriop(FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths) : AstNodeMath(fl) { setOp1p(lhs); setOp2p(rhs); setOp3p(ths); } ASTNODE_BASE_FUNCS(NodeTriop) AstNode* lhsp() const { return op1p()->castNode(); } AstNode* rhsp() const { return op2p()->castNode(); } AstNode* thsp() const { return op3p()->castNode(); } void lhsp(AstNode* nodep) { return setOp1p(nodep); } void rhsp(AstNode* nodep) { return setOp2p(nodep); } void thsp(AstNode* nodep) { return setOp3p(nodep); } // METHODS virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) = 0; // Set out to evaluation of a AstConst'ed virtual bool cleanLhs() = 0; // True if LHS must have extra upper bits zero virtual bool cleanRhs() = 0; // True if RHS must have extra upper bits zero virtual bool cleanThs() = 0; // True if THS must have extra upper bits zero virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size virtual bool sizeMattersRhs() = 0; // True if output result depends on rhs size virtual bool sizeMattersThs() = 0; // True if output result depends on ths size virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode*) const { return true; } }; class AstNodeBiCom : public AstNodeBiop { // Binary math with commutative properties public: AstNodeBiCom(FileLine* fl, AstNode* lhs, AstNode* rhs) : AstNodeBiop(fl, lhs, rhs) {} ASTNODE_BASE_FUNCS(NodeBiCom) }; class AstNodeBiComAsv : public AstNodeBiCom { // Binary math with commutative & associative properties public: AstNodeBiComAsv(FileLine* fl, AstNode* lhs, AstNode* rhs) : AstNodeBiCom(fl, lhs, rhs) {} ASTNODE_BASE_FUNCS(NodeBiComAsv) }; class AstNodeCond : public AstNodeTriop { public: AstNodeCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) : AstNodeTriop(fl, condp, expr1p, expr2p) { if (expr1p) dtypeFrom(expr1p); else if (expr2p) dtypeFrom(expr2p); } ASTNODE_BASE_FUNCS(NodeCond) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) { if (lhs.isNeqZero()) out.opAssign(rhs); else out.opAssign(ths); } AstNode* condp() const { return op1p()->castNode(); } // op1 = Condition AstNode* expr1p() const { return op2p()->castNode(); } // op2 = If true... AstNode* expr2p() const { return op3p()->castNode(); } // op3 = If false... virtual string emitVerilog() { return "%k(%l %f? %r %k: %t)"; } virtual string emitC() { return "VL_COND_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; } virtual bool cleanOut() { return false; } // clean if e1 & e2 clean virtual bool cleanLhs() { return true; } virtual bool cleanRhs() { return false; } virtual bool cleanThs() { return false; } // Propagates up virtual bool sizeMattersLhs() { return false; } virtual bool sizeMattersRhs() { return false; } virtual bool sizeMattersThs() { return false; } virtual int instrCount() const { return instrCountBranch(); } }; class AstNodePreSel : public AstNode { // Something that becomes an AstSel public: AstNodePreSel(FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths) : AstNode(fl) { setOp1p(lhs); setOp2p(rhs); setNOp3p(ths); } ASTNODE_BASE_FUNCS(NodePreSel) AstNode* lhsp() const { return op1p()->castNode(); } AstNode* fromp() const { return lhsp(); } AstNode* rhsp() const { return op2p()->castNode(); } AstNode* thsp() const { return op3p()->castNode(); } AstAttrOf* attrp() const { return op4p()->castAttrOf(); } void lhsp(AstNode* nodep) { return setOp1p(nodep); } void rhsp(AstNode* nodep) { return setOp2p(nodep); } void thsp(AstNode* nodep) { return setOp3p(nodep); } void attrp(AstAttrOf* nodep) { return setOp4p((AstNode*)nodep); } // METHODS virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode*) const { return true; } }; class AstNodeStmt : public AstNode { // Statement -- anything that's directly under a function public: AstNodeStmt(FileLine* fl) : AstNode(fl) {} ASTNODE_BASE_FUNCS(NodeStmt) // METHODS virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here }; class AstNodeAssign : public AstNodeStmt { public: AstNodeAssign(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStmt(fl) { setOp1p(rhsp); setOp2p(lhsp); dtypeFrom(lhsp); } ASTNODE_BASE_FUNCS(NodeAssign) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back. // So iteration hits the RHS which is "earlier" in execution order, it's op1, not op2 AstNode* rhsp() const { return op1p()->castNode(); } // op1 = Assign from AstNode* lhsp() const { return op2p()->castNode(); } // op2 = Assign to void rhsp(AstNode* np) { setOp1p(np); } void lhsp(AstNode* np) { setOp2p(np); } virtual bool hasDType() const { return true; } virtual bool cleanRhs() { return true; } virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode*) const { return true; } virtual string verilogKwd() const { return "="; } }; class AstNodeFor : public AstNodeStmt { public: AstNodeFor(FileLine* fileline, AstNode* initsp, AstNode* condp, AstNode* incsp, AstNode* bodysp) : AstNodeStmt(fileline) { addNOp1p(initsp); setOp2p(condp); addNOp3p(incsp); addNOp4p(bodysp); } ASTNODE_BASE_FUNCS(NodeFor) AstNode* initsp() const { return op1p()->castNode(); } // op1= initial statements AstNode* condp() const { return op2p()->castNode(); } // op2= condition to continue AstNode* incsp() const { return op3p()->castNode(); } // op3= increment statements AstNode* bodysp() const { return op4p()->castNode(); } // op4= body of loop virtual bool isGateOptimizable() const { return false; } virtual int instrCount() const { return instrCountBranch(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstNodeIf : public AstNodeStmt { private: AstBranchPred m_branchPred; // Branch prediction as taken/untaken? public: AstNodeIf(FileLine* fl, AstNode* condp, AstNode* ifsp, AstNode* elsesp) : AstNodeStmt(fl) { setOp1p(condp); addNOp2p(ifsp); addNOp3p(elsesp); } ASTNODE_BASE_FUNCS(NodeIf) AstNode* condp() const { return op1p(); } // op1 = condition AstNode* ifsp() const { return op2p(); } // op2 = list of true statements AstNode* elsesp() const { return op3p(); } // op3 = list of false statements void condp(AstNode* newp) { setOp1p(newp); } void addIfsp(AstNode* newp) { addOp2p(newp); } void addElsesp(AstNode* newp) { addOp3p(newp); } virtual bool isGateOptimizable() const { return false; } virtual bool isGateDedupable() const { return true; } virtual int instrCount() const { return instrCountBranch(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } void branchPred(AstBranchPred flag) { m_branchPred = flag; } AstBranchPred branchPred() const { return m_branchPred; } }; class AstNodeCase : public AstNodeStmt { public: AstNodeCase(FileLine* fl, AstNode* exprp, AstNode* casesp) : AstNodeStmt(fl) { setOp1p(exprp); addNOp2p(casesp); } ASTNODE_BASE_FUNCS(NodeCase) virtual int instrCount() const { return instrCountBranch(); } AstNode* exprp() const { return op1p()->castNode(); } // op1 = case condition AstCaseItem* itemsp() const { return op2p()->castCaseItem(); } // op2 = list of case expressions AstNode* notParallelp() const { return op3p()->castNode(); } // op3 = assertion code for non-full case's void addItemsp(AstNode* nodep) { addOp2p(nodep); } void addNotParallelp(AstNode* nodep) { setOp3p(nodep); } }; class AstNodeSenItem : public AstNode { // An AstSenItem or AstSenGate public: AstNodeSenItem(FileLine* fl) : AstNode(fl) {} ASTNODE_BASE_FUNCS(NodeSenItem) virtual bool isClocked() const = 0; virtual bool isCombo() const = 0; virtual bool isInitial() const = 0; virtual bool isSettle() const = 0; virtual bool isNever() const = 0; }; class AstNodeVarRef : public AstNodeMath { // An AstVarRef or AstVarXRef private: bool m_lvalue; // Left hand side assignment AstVar* m_varp; // [AfterLink] Pointer to variable itself AstVarScope* m_varScopep; // Varscope for hierarchy AstPackage* m_packagep; // Package hierarchy string m_name; // Name of variable string m_hiername; // Scope converted into name-> for emitting bool m_hierThis; // Hiername points to "this" function void init(); public: AstNodeVarRef(FileLine* fl, const string& name, bool lvalue) : AstNodeMath(fl), m_lvalue(lvalue), m_varp(NULL), m_varScopep(NULL), m_packagep(NULL), m_name(name), m_hierThis(false) { init(); } AstNodeVarRef(FileLine* fl, const string& name, AstVar* varp, bool lvalue) : AstNodeMath(fl), m_lvalue(lvalue), m_varp(varp), m_varScopep(NULL), m_packagep(NULL), m_name(name), m_hierThis(false) { // May have varp==NULL init(); } ASTNODE_BASE_FUNCS(NodeVarRef) virtual bool hasDType() const { return true; } virtual const char* broken() const; virtual int instrCount() const { return widthInstrs(); } virtual void cloneRelink(); virtual string name() const { return m_name; } // * = Var name virtual void name(const string& name) { m_name = name; } bool lvalue() const { return m_lvalue; } void lvalue(bool lval) { m_lvalue=lval; } // Avoid using this; Set in constructor AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable void varp(AstVar* varp) { m_varp=varp; } AstVarScope* varScopep() const { return m_varScopep; } void varScopep(AstVarScope* varscp) { m_varScopep=varscp; } string hiername() const { return m_hiername; } void hiername(const string& hn) { m_hiername = hn; } bool hierThis() const { return m_hierThis; } void hierThis(bool flag) { m_hierThis = flag; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } // Know no children, and hot function, so skip iterator for speed // See checkTreeIter also that asserts no children // cppcheck-suppress functionConst void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { } }; class AstNodeText : public AstNode { private: string m_text; public: // Node that simply puts text into the output stream AstNodeText(FileLine* fileline, const string& textp) : AstNode(fileline) { m_text = textp; // Copy it } ASTNODE_BASE_FUNCS(NodeText) virtual void dump(ostream& str=cout); virtual V3Hash sameHash() const { return V3Hash(text()); } virtual bool same(AstNode* samep) const { return text()==samep->castNodeText()->text(); } const string& text() const { return m_text; } }; class AstNodeDType : public AstNode { // Ideally width() would migrate to BasicDType as that's where it makes sense, // but it's currently so prevalent in the code we leave it here. // Note the below members are included in AstTypeTable::Key lookups private: int m_width; // (also in AstTypeTable::Key) Bit width of operation int m_widthMin; // (also in AstTypeTable::Key) If unsized, bitwidth of minimum implementation AstNumeric m_numeric; // (also in AstTypeTable::Key) Node is signed // Other members bool m_generic; // Simple globally referenced type, don't garbage collect static int s_uniqueNum; // Unique number assigned to each dtype during creation for IEEE matching public: // CONSTRUCTORS AstNodeDType(FileLine* fl) : AstNode(fl) { m_width=0; m_widthMin=0; m_generic=false; } ASTNODE_BASE_FUNCS(NodeDType) // ACCESSORS virtual void dump(ostream& str); virtual void dumpSmall(ostream& str); virtual bool hasDType() const { return true; } virtual AstBasicDType* basicp() const = 0; // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const = 0; // recurses over typedefs/const/enum to next non-typeref type virtual AstNodeDType* skipRefToConstp() const = 0; // recurses over typedefs to next non-typeref-or-const type virtual AstNodeDType* skipRefToEnump() const = 0; // recurses over typedefs/const to next non-typeref-or-enum/struct type virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... virtual bool maybePointedTo() const { return true; } virtual AstNodeDType* virtRefDTypep() const { return NULL; } // Iff has a non-null refDTypep(), as generic node function virtual void virtRefDTypep(AstNodeDType* nodep) { } // Iff has refDTypep(), set as generic node function // // Changing the width may confuse the data type resolution, so must clear TypeTable cache after use. void widthForce(int width, int sized) { m_width=width; m_widthMin=sized; } // For backward compatibility inherit width and signing from the subDType/base type void widthFromSub(AstNodeDType* nodep) { m_width=nodep->m_width; m_widthMin=nodep->m_widthMin; m_numeric=nodep->m_numeric; } // int width() const { return m_width; } void numeric(AstNumeric flag) { m_numeric = flag; } bool isSigned() const { return m_numeric.isSigned(); } bool isNosign() const { return m_numeric.isNosign(); } AstNumeric numeric() const { return m_numeric; } int widthWords() const { return VL_WORDS_I(width()); } int widthMin() const { return m_widthMin?m_widthMin:m_width; } // If sized, the size, if unsized the min digits to represent it int widthPow2() const; void widthMinFromWidth() { m_widthMin = m_width; } bool widthSized() const { return !m_widthMin || m_widthMin==m_width; } bool generic() const { return m_generic; } void generic(bool flag) { m_generic = flag; } AstNodeDType* dtypeDimensionp(int depth); pair dimensions(bool includeBasic); uint32_t arrayUnpackedElements(); // 1, or total multiplication of all dimensions static int uniqueNumInc() { return ++s_uniqueNum; } }; class AstNodeClassDType : public AstNodeDType { private: // TYPES typedef map MemberNameMap; // MEMBERS bool m_packed; MemberNameMap m_members; public: AstNodeClassDType(FileLine* fl, AstNumeric numericUnpack) : AstNodeDType(fl) { // AstNumeric::NOSIGN overloaded to indicate not packed m_packed = (numericUnpack != AstNumeric::NOSIGN); numeric(numericUnpack.isSigned() ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); } ASTNODE_BASE_FUNCS(NodeClassDType) virtual const char* broken() const; virtual void dump(ostream& str); // For basicp() we reuse the size to indicate a "fake" basic type of same size virtual AstBasicDType* basicp() const { return findLogicDType(width(),width(),numeric())->castBasicDType(); } virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... // op1 = members AstMemberDType* membersp() const { return op1p()->castMemberDType(); } // op1 = AstMember list void addMembersp(AstNode* nodep) { addNOp1p(nodep); } bool packed() const { return m_packed; } bool packedUnsup() const { return true; } // packed() but as don't support unpacked, presently all structs void clearCache() { m_members.clear(); } void repairMemberCache(); AstMemberDType* findMember(const string& name) const { MemberNameMap::const_iterator it = m_members.find(name); return (it==m_members.end()) ? NULL : it->second; } int lsb() const { return 0; } int msb() const { return dtypep()->width()-1; } // Packed classes look like arrays VNumRange declRange() const { return VNumRange(msb(), lsb(), false); } }; class AstNodeArrayDType : public AstNodeDType { // Array data type, ie "some_dtype var_name [2:0]" // Children: DTYPE (moved to refDTypep() in V3Width) // Children: RANGE (array bounds) private: AstNodeDType* m_refDTypep; // Elements of this type (after widthing) AstNode* rangenp() const { return op2p(); } // op2 = Array(s) of variable public: AstNodeArrayDType(FileLine* fl) : AstNodeDType(fl) { m_refDTypep = NULL; } ASTNODE_BASE_FUNCS(NodeArrayDType) virtual void dump(ostream& str); virtual void dumpSmall(ostream& str); virtual const char* broken() const { BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists()) || (!m_refDTypep && childDTypep()))); return NULL; } virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) { m_refDTypep = m_refDTypep->clonep()->castNodeDType(); }} virtual bool same(AstNode* samep) const { AstNodeArrayDType* sp = samep->castNodeArrayDType(); return (msb()==sp->msb() && subDTypep()==sp->subDTypep() && rangenp()->sameTree(sp->rangenp())); } // HashedDT doesn't recurse, so need to check children virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); } AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } AstRange* rangep() const { return op2p()->castRange(); } // op2 = Array(s) of variable void rangep(AstRange* nodep); // METHODS virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return elementsConst() * subDTypep()->widthTotalBytes(); } int msb() const; int lsb() const; int elementsConst() const; VNumRange declRange() const; }; class AstNodeSel : public AstNodeBiop { // Single bit range extraction, perhaps with non-constant selection or array selection public: AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp) :AstNodeBiop(fl, fromp, bitp) {} ASTNODE_BASE_FUNCS(NodeSel) AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing) void fromp(AstNode* nodep) { setOp1p(nodep); } AstNode* bitp() const { return op2p()->castNode(); } // op2 = Msb selection expression void bitp(AstNode* nodep) { setOp2p(nodep); } int bitConst() const; virtual bool hasDType() const { return true; } }; class AstNodeStream : public AstNodeBiop { // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp() public: AstNodeStream(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { if (lhsp->dtypep()) { dtypeSetLogicSized(lhsp->dtypep()->width(), lhsp->dtypep()->width(), AstNumeric::UNSIGNED); } } ASTNODE_BASE_FUNCS(NodeStream) }; //###################################################################### // Tasks/functions common handling class AstNodeFTask : public AstNode { private: string m_name; // Name of task string m_cname; // Name of task if DPI import bool m_taskPublic:1; // Public task bool m_attrIsolateAssign:1;// User isolate_assignments attribute bool m_prototype:1; // Just a prototype bool m_dpiExport:1; // DPI exported bool m_dpiImport:1; // DPI imported bool m_dpiContext:1; // DPI import context bool m_dpiTask:1; // DPI import task (vs. void function) bool m_pure:1; // DPI import pure public: AstNodeFTask(FileLine* fileline, const string& name, AstNode* stmtsp) : AstNode(fileline) , m_name(name), m_taskPublic(false) , m_attrIsolateAssign(false), m_prototype(false) , m_dpiExport(false), m_dpiImport(false), m_dpiContext(false) , m_dpiTask(false), m_pure(false) { addNOp3p(stmtsp); cname(name); // Might be overridden by dpi import/export } ASTNODE_BASE_FUNCS(NodeFTask) virtual void dump(ostream& str=cout); virtual string name() const { return m_name; } // * = Var name virtual bool maybePointedTo() const { return true; } // {AstFunc only} op1 = Range output variable virtual void name(const string& name) { m_name = name; } string cname() const { return m_cname; } void cname(const string& cname) { m_cname = cname; } // op1 = Output variable (functions only, NULL for tasks) AstNode* fvarp() const { return op1p()->castNode(); } void addFvarp(AstNode* nodep) { addNOp1p(nodep); } bool isFunction() const { return fvarp()!=NULL; } // op3 = Statements/Ports/Vars AstNode* stmtsp() const { return op3p()->castNode(); } // op3 = List of statements void addStmtsp(AstNode* nodep) { addNOp3p(nodep); } // op4 = scope name AstScopeName* scopeNamep() const { return op4p()->castScopeName(); } void scopeNamep(AstNode* nodep) { setNOp4p(nodep); } void taskPublic(bool flag) { m_taskPublic=flag; } bool taskPublic() const { return m_taskPublic; } void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; } bool attrIsolateAssign() const { return m_attrIsolateAssign; } void prototype(bool flag) { m_prototype = flag; } bool prototype() const { return m_prototype; } void dpiExport(bool flag) { m_dpiExport = flag; } bool dpiExport() const { return m_dpiExport; } void dpiImport(bool flag) { m_dpiImport = flag; } bool dpiImport() const { return m_dpiImport; } void dpiContext(bool flag) { m_dpiContext = flag; } bool dpiContext() const { return m_dpiContext; } void dpiTask(bool flag) { m_dpiTask = flag; } bool dpiTask() const { return m_dpiTask; } void pure(bool flag) { m_pure = flag; } bool pure() const { return m_pure; } }; class AstNodeFTaskRef : public AstNode { // A reference to a task (or function) private: AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced string m_name; // Name of variable string m_dotted; // Dotted part of scope to task or "" string m_inlinedDots; // Dotted hierarchy flattened out AstPackage* m_packagep; // Package hierarchy public: AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp) :AstNode(fl) , m_taskp(NULL), m_packagep(NULL) { setOp1p(namep); addNOp2p(pinsp); } AstNodeFTaskRef(FileLine* fl, const string& name, AstNode* pinsp) :AstNode(fl) , m_taskp(NULL), m_name(name), m_packagep(NULL) { addNOp2p(pinsp); } ASTNODE_BASE_FUNCS(NodeFTaskRef) virtual const char* broken() const { BROKEN_RTN(m_taskp && !m_taskp->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_taskp && m_taskp->clonep()) { m_taskp = m_taskp->clonep()->castNodeFTask(); }} virtual void dump(ostream& str=cout); virtual string name() const { return m_name; } // * = Var name string dotted() const { return m_dotted; } // * = Scope name or "" string prettyDotted() const { return prettyName(dotted()); } string inlinedDots() const { return m_inlinedDots; } void inlinedDots(const string& flag) { m_inlinedDots = flag; } AstNodeFTask* taskp() const { return m_taskp; } // [After Link] Pointer to variable void taskp(AstNodeFTask* taskp) { m_taskp=taskp; } virtual void name(const string& name) { m_name = name; } void dotted(const string& name) { m_dotted = name; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } // op1 = namep AstNode* namep() const { return op1p(); } // op2 = Pin interconnection list AstNode* pinsp() const { return op2p()->castNode(); } void addPinsp(AstNode* nodep) { addOp2p(nodep); } // op3 = scope tracking AstScopeName* scopeNamep() const { return op3p()->castScopeName(); } void scopeNamep(AstNode* nodep) { setNOp3p(nodep); } }; class AstNodeModule : public AstNode { // A module, package, program or interface declaration; // something that can live directly under the TOP, // excluding $unit package stuff private: string m_name; // Name of the module string m_origName; // Name of the module, ignoring name() changes, for dot lookup bool m_modPublic:1; // Module has public references bool m_modTrace:1; // Tracing this module bool m_inLibrary:1; // From a library, no error if not used, never top level bool m_dead:1; // LinkDot believes is dead; will remove in Dead visitors bool m_internal:1; // Internally created int m_level; // 1=top module, 2=cell off top module, ... int m_varNum; // Incrementing variable number int m_typeNum; // Incrementing implicit type number public: AstNodeModule(FileLine* fl, const string& name) : AstNode (fl) ,m_name(name), m_origName(name) ,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false), m_internal(false) ,m_level(0), m_varNum(0), m_typeNum(0) { } ASTNODE_BASE_FUNCS(NodeModule) virtual void dump(ostream& str); virtual bool maybePointedTo() const { return true; } virtual string name() const { return m_name; } AstNode* stmtsp() const { return op2p()->castNode(); } // op2 = List of statements AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks // METHODS void addInlinesp(AstNode* nodep) { addOp1p(nodep); } void addStmtp(AstNode* nodep) { addOp2p(nodep); } void addActivep(AstNode* nodep) { addOp3p(nodep); } // ACCESSORS virtual void name(const string& name) { m_name = name; } string origName() const { return m_origName; } bool inLibrary() const { return m_inLibrary; } void inLibrary(bool flag) { m_inLibrary = flag; } void level(int level) { m_level = level; } int level() const { return m_level; } bool isTop() const { return level()==1; } int varNumGetInc() { return ++m_varNum; } int typeNumGetInc() { return ++m_typeNum; } void modPublic(bool flag) { m_modPublic = flag; } bool modPublic() const { return m_modPublic; } void modTrace(bool flag) { m_modTrace = flag; } bool modTrace() const { return m_modTrace; } void dead(bool flag) { m_dead = flag; } bool dead() const { return m_dead; } void internal(bool flag) { m_internal = flag; } bool internal() const { return m_internal; } }; //###################################################################### #include "V3AstNodes.h" #include "V3Ast__gen_impl.h" // From ./astgen // Things like: // inline AstAlways* AstNode::castAlways() { return dynamic_cast(this);} //###################################################################### // Inline ACCESSORS inline int AstNode::width() const { return dtypep() ? dtypep()->width() : 0; } inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; } inline bool AstNode::width1() const { return dtypep() && dtypep()->width()==1; } // V3Const uses to know it can optimize inline int AstNode::widthInstrs() const { return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1)); } inline bool AstNode::isDouble() const { return dtypep() && dtypep()->castBasicDType() && dtypep()->castBasicDType()->isDouble(); } inline bool AstNode::isString() const { return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString(); } inline bool AstNode::isSigned() const { return dtypep() && dtypep()->isSigned(); } inline bool AstNode::isZero() { return (this->castConst() && this->castConst()->num().isEqZero()); } inline bool AstNode::isNeqZero() { return (this->castConst() && this->castConst()->num().isNeqZero()); } inline bool AstNode::isOne() { return (this->castConst() && this->castConst()->num().isEqOne()); } inline bool AstNode::isAllOnes() { return (this->castConst() && this->castConst()->isEqAllOnes()); } inline bool AstNode::isAllOnesV() { return (this->castConst() && this->castConst()->isEqAllOnesV()); } inline bool AstNode::sameTree(AstNode* node2p) { return sameTreeIter(node2p, true, false); } inline bool AstNode::sameGateTree(AstNode* node2p) { return sameTreeIter(node2p, true, true); } inline void AstNodeVarRef::init() { if (m_varp) dtypep(m_varp->dtypep()); } inline void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); } inline int AstNodeArrayDType::msb() const { return rangep()->msbConst(); } inline int AstNodeArrayDType::lsb() const { return rangep()->lsbConst(); } inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); } inline VNumRange AstNodeArrayDType::declRange() const { return VNumRange(msb(), lsb(), rangep()->littleEndian()); } inline void AstIfaceRefDType::cloneRelink() { if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep()->castCell(); if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep()->castIface(); if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep()->castModport(); } #endif // Guard verilator-3.874/src/V3Premit.cpp0000664000177100017500000003246012525171733016502 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add temporaries, such as for premit nodes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Premit's Transformations: // // Each module: // For each wide OP, make a a temporary variable with the wide value // For each deep expression, assign expression to temporary. // // Each display (independant transformation; here as Premit is a good point) // If autoflush, insert a flush // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Premit.h" #include "V3Ast.h" //###################################################################### // Structure for global state class PremitAssignVisitor : public AstNVisitor { private: // NODE STATE // AstVar::user4() // bool; occurs on LHS of current assignment AstUser4InUse m_inuser4; // STATE bool m_noopt; // Disable optimization of variables in this block // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstNodeAssign* nodep, AstNUser*) { //AstNode::user4ClearTree(); // Implied by AstUser4InUse // LHS first as fewer varrefs nodep->lhsp()->iterateAndNext(*this); // Now find vars marked as lhs nodep->rhsp()->iterateAndNext(*this); } virtual void visit(AstVarRef* nodep, AstNUser*) { // it's LHS var is used so need a deep temporary if (nodep->lvalue()) { nodep->varp()->user4(true); } else { if (nodep->varp()->user4()) { if (!m_noopt) UINFO(4, "Block has LHS+RHS var: "<iterateChildren(*this); } public: // CONSTRUCTORS PremitAssignVisitor(AstNodeAssign* nodep) { UINFO(4," PremitAssignVisitor on "<accept(*this); } virtual ~PremitAssignVisitor() {} bool noOpt() const { return m_noopt; } }; //###################################################################### // Premit state, as a visitor of each AstNode class PremitVisitor : public AstNVisitor { private: // NODE STATE // AstNodeMath::user() -> bool. True if iterated already // AstShiftL::user2() -> bool. True if converted to conditional // AstShiftR::user2() -> bool. True if converted to conditional // *::user4() -> See PremitAssignVisitor AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // STATE AstNodeModule* m_modp; // Current module AstCFunc* m_funcp; // Current block AstNode* m_stmtp; // Current statement AstWhile* m_inWhilep; // Inside while loop, special statement additions AstTraceInc* m_inTracep; // Inside while loop, special statement additions bool m_assignLhs; // Inside assignment lhs, don't breakup extracts // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } bool assignNoTemp(AstNodeAssign* nodep) { return (nodep->lhsp()->castVarRef() && !AstVar::scVarRecurse(nodep->lhsp()) && nodep->rhsp()->castConst()); } void checkNode(AstNode* nodep) { // Consider adding a temp for this expression. // We need to avoid adding temps to the following: // ASSIGN(x, *here*) // ASSIGN(CONST*here*, VARREF(!sc)) // ARRAYSEL(*here*, ...) (No wides can be in any argument but first, so we don't check which arg is wide) // ASSIGN(x, SEL*HERE*(ARRAYSEL()...) (m_assignLhs==true handles this.) //UINFO(9, " Check: "<isWide()?"Y":"N")<user1()) { // Not already done if (nodep->isWide()) { if (m_assignLhs) { } else if (nodep->firstAbovep() && nodep->firstAbovep()->castNodeAssign() && assignNoTemp(nodep->firstAbovep()->castNodeAssign())) { // Not much point if it's just a direct assignment to a constant } else if (nodep->firstAbovep() && nodep->firstAbovep()->castArraySel()) { // ArraySel's are pointer refs, ignore } else { UINFO(4,"Cre Temp: "<varNumGetInc())); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname, nodep->dtypep()); m_funcp->addInitsp(varp); return varp; } void insertBeforeStmt(AstNode* newp) { // Insert newp before m_stmtp if (m_inWhilep) { // Statements that are needed for the 'condition' in a while actually have to // be put before & after the loop, since we can't do any statements in a while's (cond). m_inWhilep->addPrecondsp(newp); } else if (m_inTracep) { m_inTracep->addPrecondsp(newp); } else if (m_stmtp) { AstNRelinker linker; m_stmtp->unlinkFrBack(&linker); newp->addNext(m_stmtp); linker.relink(newp); } else { newp->v3fatalSrc("No statement insertion point."); } } void createDeepTemp(AstNode* nodep, bool noSubst) { if (debug()>8) nodep->dumpTree(cout,"deepin:"); AstNRelinker linker; nodep->unlinkFrBack(&linker); AstVar* varp = getBlockTemp(nodep); if (noSubst) varp->noSubst(true); // Do not remove varrefs to this in V3Const // Replace node tree with reference to var AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false); linker.relink(newp); // Put assignment before the referencing statement AstAssign* assp = new AstAssign (nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true), nodep); insertBeforeStmt(assp); if (debug()>8) assp->dumpTree(cout,"deepou:"); nodep->user1(true); // Don't add another assignment } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { UINFO(4," MOD "<iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCFunc* nodep, AstNUser*) { m_funcp = nodep; nodep->iterateChildren(*this); m_funcp = NULL; } void startStatement(AstNode* nodep) { m_assignLhs = false; if (m_funcp) m_stmtp = nodep; } virtual void visit(AstWhile* nodep, AstNUser*) { UINFO(4," WHILE "<precondsp()->iterateAndNext(*this); startStatement(nodep); m_inWhilep = nodep; nodep->condp()->iterateAndNext(*this); m_inWhilep = NULL; startStatement(nodep); nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); m_stmtp = NULL; } virtual void visit(AstNodeAssign* nodep, AstNUser*) { startStatement(nodep); { bool noopt = PremitAssignVisitor(nodep).noOpt(); if (noopt && !nodep->user1()) { // Need to do this even if not wide, as e.g. a select may be on a wide operator UINFO(4,"Deep temp for LHS/RHS\n"); createDeepTemp(nodep->rhsp(), false); } } nodep->rhsp()->iterateAndNext(*this); m_assignLhs = true; nodep->lhsp()->iterateAndNext(*this); m_assignLhs = false; m_stmtp = NULL; } virtual void visit(AstNodeStmt* nodep, AstNUser*) { UINFO(4," STMT "<iterateChildren(*this); m_stmtp = NULL; } virtual void visit(AstTraceInc* nodep, AstNUser*) { startStatement(nodep); m_inTracep = nodep; nodep->iterateChildren(*this); m_inTracep = NULL; m_stmtp = NULL; } void visitShift (AstNodeBiop* nodep) { // Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s if (!nodep->user2SetOnce()) { UINFO(4," ShiftFix "<widthMin()<=64 // Else we'll use large operators which work right // C operator's width must be < maximum shift which is based on Verilog width && nodep->width() < (1LL<rhsp()->widthMin())) { AstNRelinker replaceHandle; nodep->unlinkFrBack(&replaceHandle); AstNode* constzerop; int m1value = nodep->widthMin()-1; // Constant of width-1; not changing dtype width if (nodep->signedFlavor()) { // Then over shifting gives the sign bit, not all zeros // Note *NOT* clean output -- just like normal shift! // Create equivalent of VL_SIGNONES_(node_width) constzerop = new AstNegate (nodep->fileline(), new AstShiftR(nodep->fileline(), nodep->lhsp()->cloneTree(false), new AstConst(nodep->fileline(), m1value), nodep->width())); } else { V3Number zeronum (nodep->fileline(), nodep->width(), 0); constzerop = new AstConst(nodep->fileline(), zeronum); } constzerop->dtypeFrom (nodep); // unsigned V3Number widthnum (nodep->fileline(), nodep->rhsp()->widthMin(), m1value); AstNode* constwidthp = new AstConst(nodep->fileline(), widthnum); constwidthp->dtypeFrom (nodep->rhsp()); // unsigned AstCond* newp = new AstCond (nodep->fileline(), new AstGte (nodep->fileline(), constwidthp, nodep->rhsp()->cloneTree(false)), nodep, constzerop); replaceHandle.relink(newp); } } nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstShiftL* nodep, AstNUser*) { visitShift(nodep); } virtual void visit(AstShiftR* nodep, AstNUser*) { visitShift(nodep); } virtual void visit(AstShiftRS* nodep, AstNUser*) { visitShift(nodep); } // Operators virtual void visit(AstNodeTermop* nodep, AstNUser*) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstNodeUniop* nodep, AstNUser*) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstNodeBiop* nodep, AstNUser*) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstUCFunc* nodep, AstNUser*) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstSel* nodep, AstNUser*) { nodep->fromp()->iterateAndNext(*this); { // Only the 'from' is part of the assignment LHS bool prevAssign = m_assignLhs; m_assignLhs = false; nodep->lsbp()->iterateAndNext(*this); nodep->widthp()->iterateAndNext(*this); m_assignLhs = prevAssign; } checkNode(nodep); } virtual void visit(AstConst* nodep, AstNUser*) { nodep->iterateChildren(*this); checkNode(nodep); } virtual void visit(AstNodeCond* nodep, AstNUser*) { nodep->iterateChildren(*this); if (nodep->expr1p()->isWide() && !nodep->condp()->castConst() && !nodep->condp()->castVarRef()) { // We're going to need the expression several times in the expanded code, // so might as well make it a common expression createDeepTemp(nodep->condp(), false); } checkNode(nodep); } // Autoflush virtual void visit(AstDisplay* nodep, AstNUser*) { startStatement(nodep); nodep->iterateChildren(*this); m_stmtp = NULL; if (v3Global.opt.autoflush()) { AstNode* searchp = nodep->nextp(); while (searchp && searchp->castComment()) searchp = searchp->nextp(); if (searchp && searchp->castDisplay() && nodep->filep()->sameGateTree(searchp->castDisplay()->filep())) { // There's another display next; we can just wait to flush } else { UINFO(4,"Autoflush "<addNextHere(new AstFFlush(nodep->fileline(), nodep->filep()->cloneTree(true))); } } } virtual void visit(AstSFormatF* nodep, AstNUser*) { nodep->iterateChildren(*this); // Any strings sent to a display must be var of string data type, // to avoid passing a pointer to a temporary. for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) { if (expp->dtypep()->basicp()->isString() && !expp->castVarRef()) { createDeepTemp(expp, true); } } } //-------------------- // Default: Just iterate virtual void visit(AstVar* nodep, AstNUser*) {} // Don't hit varrefs under vars virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS PremitVisitor(AstNetlist* nodep) { m_modp = NULL; m_funcp = NULL; m_stmtp = NULL; m_inWhilep = NULL; m_inTracep = NULL; nodep->accept(*this); } virtual ~PremitVisitor() {} }; //---------------------------------------------------------------------- // Top loop //###################################################################### // Premit class functions void V3Premit::premitAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Begin.h0000664000177100017500000000225112525171733015726 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Removal of named begin blocks // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3BEGIN_H_ #define _V3BEGIN_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Begin { public: static void debeginAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3FileLine.h0000664000177100017500000001566012525171733016401 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Error handling // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3FileLine_H_ #define _V3FileLine_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Error.h" #include "V3LangCode.h" //###################################################################### class FileLine; //! Singleton class with tables of per-file data. //! This singleton class contains tables of data that are unchanging in each //! source file (each with its own unique filename number). class FileLineSingleton { // TYPES typedef map FileNameNumMap; typedef map FileLangNumMap; // MEMBERS FileNameNumMap m_namemap; // filenameno for each filename deque m_names; // filename text for each filenameno deque m_languages; // language for each filenameno // COSNTRUCTORS FileLineSingleton() { } ~FileLineSingleton() { } protected: friend class FileLine; // METHODS int nameToNumber(const string& filename); const string numberToName(int filenameno) const { return m_names[filenameno]; } const V3LangCode numberToLang(int filenameno) const { return m_languages[filenameno]; } void numberToLang(int filenameno, const V3LangCode& l) { m_languages[filenameno] = l; } void clear() { m_namemap.clear(); m_names.clear(); m_languages.clear(); } void fileNameNumMapDumpXml(ostream& os); static const string filenameLetters(int fileno); }; //! File and line number of an object, mostly for error reporting //! This class is instantiated for every source code line (potentially //! millions). To save space, per-file information (e.g. filename, source //! language is held in tables in the FileLineSingleton class. class FileLine { int m_lineno; int m_filenameno; bitset m_warnOn; private: struct EmptySecret {}; inline static FileLineSingleton& singleton() { static FileLineSingleton s; return s; } inline static FileLine& defaultFileLine() { static FileLine* defFilelinep = new FileLine(FileLine::EmptySecret()); return *defFilelinep; } protected: // User routines should never need to change line numbers // We are storing pointers, so we CAN'T change them after initial reading. friend class FileLineSingleton; friend class V3ParseImp; friend class V3PreLex; friend class V3PreProcImp; void lineno(int num) { m_lineno = num; } void language (V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); } void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); } void lineDirective(const char* textp, int& enterExitRef); void linenoInc() { m_lineno++; } void linenoIncInPlace() { m_lineno++; } FileLine* copyOrSameFileLine(); public: FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filenameno = singleton().nameToNumber(filename); m_warnOn=defaultFileLine().m_warnOn; } FileLine (FileLine* fromp) { m_lineno=fromp->m_lineno; m_filenameno = fromp->m_filenameno; m_warnOn=fromp->m_warnOn; } FileLine (EmptySecret); ~FileLine() { } FileLine* create(const string& filename, int lineno) { return new FileLine(filename,lineno); } FileLine* create(int lineno) { return create(filename(), lineno); } static void deleteAllRemaining(); #ifdef VL_LEAK_CHECKS static void* operator new(size_t size); static void operator delete(void* obj, size_t size); #endif int lineno () const { return m_lineno; } V3LangCode language () const { return singleton().numberToLang(m_filenameno); } string ascii() const; const string filename () const { return singleton().numberToName(m_filenameno); } const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); } const string filebasename () const; const string filebasenameNoExt () const; const string profileFuncname() const; const string xml() const { return "fl=\""+filenameLetters()+cvtToStr(lineno())+"\""; } string lineDirectiveStrg(int enter_exit_level) const; void warnOn(V3ErrorCode code, bool flag) { m_warnOn.set(code,flag); } // Turn on/off warning messages on this line. void warnOff(V3ErrorCode code, bool flag) { warnOn(code,!flag); } bool warnOff(const string& code, bool flag); // Returns 1 if ok bool warnIsOff(V3ErrorCode code) const; void warnLintOff(bool flag); void warnStyleOff(bool flag); void warnStateFrom(const FileLine& from) { m_warnOn=from.m_warnOn; } void warnResetDefault() { warnStateFrom(defaultFileLine()); } // Specific flag ACCESSORS/METHODS bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); } void coverageOn(bool flag) { warnOn(V3ErrorCode::I_COVERAGE,flag); } bool tracingOn() const { return m_warnOn.test(V3ErrorCode::I_TRACING); } void tracingOn(bool flag) { warnOn(V3ErrorCode::I_TRACING,flag); } // METHODS - Global static void globalWarnLintOff(bool flag) { defaultFileLine().warnLintOff(flag); } static void globalWarnStyleOff(bool flag) { defaultFileLine().warnStyleOff(flag); } static void globalWarnOff(V3ErrorCode code, bool flag) { defaultFileLine().warnOff(code, flag); } static bool globalWarnOff(const string& code, bool flag) { return defaultFileLine().warnOff(code, flag); } static void fileNameNumMapDumpXml(ostream& os) { singleton().fileNameNumMapDumpXml(os); } // METHODS - Called from netlist // Merge warning disables from another fileline void modifyStateInherit(const FileLine* fromp); // Change the current fileline due to actions discovered after parsing // and may have side effects on other nodes sharing this FileLine. // Use only when this is intended void modifyWarnOff(V3ErrorCode code, bool flag) { warnOff(code,flag); } // OPERATORS void v3errorEnd(ostringstream& str); string warnMore() const; inline bool operator==(FileLine rhs) const { return (m_lineno==rhs.m_lineno && m_filenameno==rhs.m_filenameno && m_warnOn==rhs.m_warnOn); } }; ostream& operator<<(ostream& os, FileLine* fileline); #endif // Guard verilator-3.874/src/V3Gate.cpp0000664000177100017500000013613712525172076016131 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Gate optimizations, such as wire elimination // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Gate's Transformations: // // Extract a graph of the *entire* netlist with cells expanded // Perform constant optimization across the graph // Create VARSCOPEs for any variables we can rip out // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include "V3Global.h" #include "V3Gate.h" #include "V3Ast.h" #include "V3Graph.h" #include "V3Const.h" #include "V3Stats.h" #include "V3Hashed.h" typedef list GateVarRefList; //###################################################################### class GateBaseVisitor : public AstNVisitor { public: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### class GateLogicVertex; class GateVarVertex; class GateGraphBaseVisitor { public: virtual AstNUser* visit(GateLogicVertex* vertexp, AstNUser* vup=NULL) =0; virtual AstNUser* visit(GateVarVertex* vertexp, AstNUser* vup=NULL) =0; virtual ~GateGraphBaseVisitor() {} }; //###################################################################### // Support classes class GateEitherVertex : public V3GraphVertex { AstScope* m_scopep; bool m_reducible; // True if this node should be able to be eliminated bool m_dedupable; // True if this node should be able to be deduped bool m_consumed; // Output goes to something meaningful public: GateEitherVertex(V3Graph* graphp, AstScope* scopep) : V3GraphVertex(graphp), m_scopep(scopep), m_reducible(true), m_dedupable(true), m_consumed(false) {} virtual ~GateEitherVertex() {} // ACCESSORS virtual string dotStyle() const { return m_consumed?"":"dotted"; } AstScope* scopep() const { return m_scopep; } bool reducible() const { return m_reducible; } bool dedupable() const { return m_dedupable; } void setConsumed(const char* consumedReason) { m_consumed = true; //UINFO(0,"\t\tSetConsumed "<inNextp()) { retp = dynamic_cast(edgep->fromp())->accept(v, vup); } return retp; } }; class GateVarVertex : public GateEitherVertex { AstVarScope* m_varScp; bool m_isTop; bool m_isClock; AstNode* m_rstSyncNodep; // Used as reset and not in SenItem, in clocked always AstNode* m_rstAsyncNodep; // Used as reset and in SenItem, in clocked always public: GateVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : GateEitherVertex(graphp, scopep), m_varScp(varScp), m_isTop(false) , m_isClock(false), m_rstSyncNodep(NULL), m_rstAsyncNodep(NULL) {} virtual ~GateVarVertex() {} // ACCESSORS AstVarScope* varScp() const { return m_varScp; } virtual string name() const { return (cvtToStr((void*)m_varScp)+" "+varScp()->name()); } virtual string dotColor() const { return "blue"; } bool isTop() const { return m_isTop; } void setIsTop() { m_isTop = true; } bool isClock() const { return m_isClock; } void setIsClock() { m_isClock = true; setConsumed("isclk"); } AstNode* rstSyncNodep() const { return m_rstSyncNodep; } void rstSyncNodep(AstNode* nodep) { m_rstSyncNodep=nodep; } AstNode* rstAsyncNodep() const { return m_rstAsyncNodep; } void rstAsyncNodep(AstNode* nodep) { m_rstAsyncNodep=nodep; } // METHODS void propagateAttrClocksFrom(GateVarVertex* fromp) { // Propagate clock and general attribute onto this node varScp()->varp()->propagateAttrFrom(fromp->varScp()->varp()); if (fromp->isClock()) { varScp()->varp()->usedClock(true); setIsClock(); } } AstNUser* accept(GateGraphBaseVisitor& v, AstNUser* vup=NULL) { return v.visit(this,vup); } }; class GateLogicVertex : public GateEitherVertex { AstNode* m_nodep; AstActive* m_activep; // Under what active; NULL is ok (under cfunc or such) bool m_slow; // In slow block public: GateLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstActive* activep, bool slow) : GateEitherVertex(graphp,scopep), m_nodep(nodep), m_activep(activep), m_slow(slow) {} virtual ~GateLogicVertex() {} // ACCESSORS virtual string name() const { return (cvtToStr((void*)m_nodep)+"@"+scopep()->prettyName()); } virtual string dotColor() const { return "yellow"; } AstNode* nodep() const { return m_nodep; } AstActive* activep() const { return m_activep; } bool slow() const { return m_slow; } AstNUser* accept(GateGraphBaseVisitor& v, AstNUser* vup=NULL) { return v.visit(this,vup); } }; //###################################################################### // Is this a simple math expression with a single input and single output? class GateOkVisitor : public GateBaseVisitor { private: // RETURN STATE bool m_isSimple; // Set false when we know it isn't simple GateVarRefList m_rhsVarRefs; // VarRefs on rhs of assignment AstNode* m_substTreep; // What to replace the variable with // STATE bool m_buffersOnly; // Set when we only allow simple buffering, no equations (for clocks) AstNodeVarRef* m_lhsVarRef; // VarRef on lhs of assignment (what we're replacing) bool m_dedupe; // Set when we use isGateDedupable instead of isGateOptimizable // METHODS void clearSimple(const char* because) { if (m_isSimple) { m_isSimple = false; UINFO(9, "Clear simple "<iterateChildren(*this); // We only allow a LHS ref for the var being set, and a RHS ref for something else being read. if (nodep->varScopep()->varp()->isSc()) { clearSimple("SystemC sig"); // Don't want to eliminate the VL_ASSIGN_SI's } if (nodep->lvalue()) { if (m_lhsVarRef) clearSimple(">1 lhs varRefs"); m_lhsVarRef = nodep; } else { if (m_rhsVarRefs.size()>1) { AstNodeVarRef* lastRefp = m_rhsVarRefs.back(); if (0) { // Diable the multiple-input optimization clearSimple(">1 rhs varRefs"); } else { if (m_buffersOnly) clearSimple(">1 rhs varRefs"); if (!nodep->varScopep()->varp()->gateMultiInputOptimizable() // We didn't check multiInput on the first varref, so check it here || !lastRefp->varScopep()->varp()->gateMultiInputOptimizable()) { clearSimple("!gateMultiInputOptimizable"); } } } m_rhsVarRefs.push_back(nodep); } } virtual void visit(AstNodeAssign* nodep, AstNUser*) { m_substTreep = nodep->rhsp(); if (!nodep->lhsp()->castNodeVarRef()) clearSimple("ASSIGN(non-VARREF)"); else nodep->iterateChildren(*this); // We don't push logic other then assignments/NOTs into SenItems // This avoids a mess in computing what exactly a POSEDGE is // V3Const cleans up any NOTs by flipping the edges for us if (m_buffersOnly && !(nodep->rhsp()->castVarRef() // Avoid making non-clocked logic into clocked, // as it slows down the verilator_sim_benchmark || (nodep->rhsp()->castNot() && nodep->rhsp()->castNot()->lhsp()->castVarRef() && nodep->rhsp()->castNot()->lhsp()->castVarRef()->varp()->isUsedClock()) )) { clearSimple("Not a buffer (goes to a clock)"); } } //-------------------- // Default virtual void visit(AstNode* nodep, AstNUser*) { // *** Special iterator if (!m_isSimple) return; // Fastpath if (!(m_dedupe ? nodep->isGateDedupable() : nodep->isGateOptimizable()) || !nodep->isPure() || nodep->isBrancher()) { UINFO(5, "Non optimizable type: "<iterateChildren(*this); } public: // CONSTUCTORS GateOkVisitor(AstNode* nodep, bool buffersOnly, bool dedupe) { m_isSimple = true; m_substTreep = NULL; m_buffersOnly = buffersOnly; m_lhsVarRef = NULL; m_dedupe = dedupe; // Iterate nodep->accept(*this); // Check results if (!m_substTreep) { clearSimple("No assignment found\n"); } for (GateVarRefList::const_iterator it = m_rhsVarRefs.begin(); it != m_rhsVarRefs.end(); ++it) { if (m_lhsVarRef && m_lhsVarRef->varScopep() == (*it)->varScopep()) { clearSimple("Circular logic\n"); // Oh my, we'll get a UNOPTFLAT much later. } } if (debug()>=9 && !m_isSimple) { nodep->dumpTree(cout,"\tgate!Ok: "); } } virtual ~GateOkVisitor() {} // PUBLIC METHODS bool isSimple() const { return m_isSimple; } AstNode* substTree() const { return m_substTreep; } const GateVarRefList& rhsVarRefs() const { return m_rhsVarRefs; } }; //###################################################################### // Gate class functions class GateVisitor : public GateBaseVisitor { private: // NODE STATE //Entire netlist: // AstVarScope::user1p -> GateVarVertex* for usage var, 0=not set yet // {statement}Node::user1p -> GateLogicVertex* for this statement // AstVarScope::user2 -> bool: Signal used in SenItem in *this* always statement // AstVar::user2 -> bool: Warned about SYNCASYNCNET AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // STATE V3Graph m_graph; // Scoreboard of var usages/dependencies GateLogicVertex* m_logicVertexp; // Current statement being tracked, NULL=ignored AstScope* m_scopep; // Current scope being processed AstNodeModule* m_modp; // Current module AstActive* m_activep; // Current active bool m_activeReducible; // Is activation block reducible? bool m_inSenItem; // Underneath AstSenItem; any varrefs are clocks bool m_inSlow; // Inside a slow structure V3Double0 m_statSigs; // Statistic tracking V3Double0 m_statRefs; // Statistic tracking V3Double0 m_statDedupLogic; // Statistic tracking V3Double0 m_statAssignMerged; // Statistic tracking // METHODS void iterateNewStmt(AstNode* nodep, const char* nonReducibleReason, const char* consumeReason) { if (m_scopep) { UINFO(4," STMT "<clearReducibleAndDedupable(nonReducibleReason); } else if (!m_activeReducible) { m_logicVertexp->clearReducible("Block Unreducible"); // Sequential logic is dedupable } if (consumeReason) m_logicVertexp->setConsumed(consumeReason); if (nodep->castSenItem()) m_logicVertexp->setConsumed("senItem"); nodep->iterateChildren(*this); m_logicVertexp = NULL; } } GateVarVertex* makeVarVertex(AstVarScope* varscp) { GateVarVertex* vertexp = (GateVarVertex*)(varscp->user1p()); if (!vertexp) { UINFO(6,"New vertex "<user1p(vertexp); if (varscp->varp()->isSigPublic()) { // Public signals shouldn't be changed, pli code might be messing with them vertexp->clearReducibleAndDedupable("SigPublic"); vertexp->setConsumed("SigPublic"); } if (varscp->varp()->isIO() && varscp->scopep()->isTop()) { // We may need to convert to/from sysc/reg sigs vertexp->setIsTop(); vertexp->clearReducibleAndDedupable("isTop"); vertexp->setConsumed("isTop"); } if (varscp->varp()->isUsedClock()) vertexp->setConsumed("clock"); } return vertexp; } void optimizeSignals(bool allowMultiIn); bool elimLogicOkOutputs(GateLogicVertex* consumeVertexp, const GateOkVisitor& okVisitor); void optimizeElimVar(AstVarScope* varscp, AstNode* logicp, AstNode* consumerp); void warnSignals(); void consumedMark(); void consumedMarkRecurse(GateEitherVertex* vertexp); void consumedMove(); void replaceAssigns(); void dedupe(); void mergeAssigns(); // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { nodep->iterateChildren(*this); //if (debug()>6) m_graph.dump(); if (debug()>6) m_graph.dumpDotFilePrefixed("gate_pre"); warnSignals(); // Before loss of sync/async pointers m_graph.removeRedundantEdgesSum(&V3GraphEdge::followAlwaysTrue); m_graph.dumpDotFilePrefixed("gate_simp"); // Find gate interconnect and optimize m_graph.userClearVertices(); // vertex->user(): bool. True indicates we've set it as consumed // Get rid of buffers first, optimizeSignals(false); // Then propagate more complicated equations optimizeSignals(true); // Remove redundant logic if (v3Global.opt.oDedupe()) dedupe(); if (v3Global.opt.oAssemble()) mergeAssigns(); // Consumption warnings consumedMark(); m_graph.dumpDotFilePrefixed("gate_opt"); // Rewrite assignments consumedMove(); replaceAssigns(); } virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; m_activeReducible = true; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstScope* nodep, AstNUser*) { UINFO(4," SCOPE "<iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstActive* nodep, AstNUser*) { // Create required blocks and add to module UINFO(4," BLOCK "<hasClocked()); // Seq logic outputs aren't reducible m_activep = nodep; AstNode::user2ClearTree(); nodep->iterateChildren(*this); AstNode::user2ClearTree(); m_activep = NULL; m_activeReducible = true; } virtual void visit(AstNodeVarRef* nodep, AstNUser*) { if (m_scopep) { if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block\n"); AstVarScope* varscp = nodep->varScopep(); if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n"); GateVarVertex* vvertexp = makeVarVertex(varscp); UINFO(5," VARREF to "<setIsClock(); // For SYNCASYNCNET if (m_inSenItem) varscp->user2(true); else if (m_activep && m_activep->hasClocked() && !nodep->lvalue()) { if (varscp->user2()) { if (!vvertexp->rstSyncNodep()) vvertexp->rstSyncNodep(nodep); } else { if (!vvertexp->rstAsyncNodep()) vvertexp->rstAsyncNodep(nodep); } } // We use weight of one; if we ref the var more than once, when we simplify, // the weight will increase if (nodep->lvalue()) { new V3GraphEdge(&m_graph, m_logicVertexp, vvertexp, 1); } else { new V3GraphEdge(&m_graph, vvertexp, m_logicVertexp, 1); } } } virtual void visit(AstAlways* nodep, AstNUser*) { iterateNewStmt(nodep, (nodep->isJustOneBodyStmt()?NULL:"Multiple Stmts"), NULL); } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { bool lastslow = m_inSlow; m_inSlow = true; iterateNewStmt(nodep, "AlwaysPublic", NULL); m_inSlow = lastslow; } virtual void visit(AstCFunc* nodep, AstNUser*) { iterateNewStmt(nodep, "User C Function", "User C Function"); } virtual void visit(AstSenItem* nodep, AstNUser*) { // Note we look at only AstSenItems, not AstSenGate's // The gating term of a AstSenGate is normal logic m_inSenItem = true; if (m_logicVertexp) { // Already under logic; presumably a SenGate nodep->iterateChildren(*this); } else { // Standalone item, probably right under a SenTree iterateNewStmt(nodep, NULL, NULL); } m_inSenItem = false; } virtual void visit(AstSenGate* nodep, AstNUser*) { // First handle the clock part will be handled in a minute by visit AstSenItem // The logic gating term is delt with as logic iterateNewStmt(nodep, "Clock gater", "Clock gater"); } virtual void visit(AstInitial* nodep, AstNUser*) { bool lastslow = m_inSlow; m_inSlow = true; iterateNewStmt(nodep, (nodep->isJustOneBodyStmt()?NULL:"Multiple Stmts"), NULL); m_inSlow = lastslow; } virtual void visit(AstAssignAlias* nodep, AstNUser*) { iterateNewStmt(nodep, NULL, NULL); } virtual void visit(AstAssignW* nodep, AstNUser*) { iterateNewStmt(nodep, NULL, NULL); } virtual void visit(AstCoverToggle* nodep, AstNUser*) { iterateNewStmt(nodep, "CoverToggle", "CoverToggle"); } virtual void visit(AstTraceInc* nodep, AstNUser*) { bool lastslow = m_inSlow; m_inSlow = true; iterateNewStmt(nodep, "Tracing", "Tracing"); m_inSlow = lastslow; } virtual void visit(AstConcat* nodep, AstNUser*) { if (nodep->backp()->castNodeAssign() && nodep->backp()->castNodeAssign()->lhsp()==nodep) { nodep->v3fatalSrc("Concat on LHS of assignment; V3Const should have deleted it\n"); } nodep->iterateChildren(*this); } //-------------------- // Default virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); if (nodep->isOutputter() && m_logicVertexp) m_logicVertexp->setConsumed("outputter"); } public: // CONSTUCTORS GateVisitor(AstNode* nodep) { AstNode::user1ClearTree(); m_logicVertexp = NULL; m_scopep = NULL; m_modp = NULL; m_activep = NULL; m_activeReducible = true; m_inSenItem = false; m_inSlow = false; nodep->accept(*this); } virtual ~GateVisitor() { V3Stats::addStat("Optimizations, Gate sigs deleted", m_statSigs); V3Stats::addStat("Optimizations, Gate inputs replaced", m_statRefs); V3Stats::addStat("Optimizations, Gate sigs deduped", m_statDedupLogic); V3Stats::addStat("Optimizations, Gate assign merged", m_statAssignMerged); } }; //---------------------------------------------------------------------- void GateVisitor::optimizeSignals(bool allowMultiIn) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->inEmpty()) { vvertexp->clearReducibleAndDedupable("inEmpty"); // Can't deal with no sources if (!vvertexp->isTop() // Ok if top inputs are driverless && !vvertexp->varScp()->varp()->valuep() && !vvertexp->varScp()->varp()->isSigPublic()) { UINFO(4, "No drivers "<varScp()<varScp()->varp()->v3warn(UNDRIVEN,"Signal has no drivers " <scopep()->prettyName()<<"." <varScp()->varp()->prettyName()); } } } else if (!vvertexp->inSize1()) { vvertexp->clearReducibleAndDedupable("size!1"); // Can't deal with more than one src } // Reduce it? if (!vvertexp->reducible()) { UINFO(8, "SigNotRed "<name()<name()< (vvertexp->inBeginp()->fromp()); UINFO(8, " From "<name()<nodep(); if (logicVertexp->reducible()) { // Can we eliminate? GateOkVisitor okVisitor(logicp, vvertexp->isClock(), false); bool multiInputs = okVisitor.rhsVarRefs().size() > 1; // Was it ok? bool doit = okVisitor.isSimple(); if (doit && multiInputs) { if (!allowMultiIn) doit = false; // Doit if one input, or not used, or used only once, ignoring traces int n=0; for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { GateLogicVertex* consumeVertexp = dynamic_cast(edgep->top()); if (!consumeVertexp->slow()) { // Not tracing or other slow path junk if (edgep->top()->outBeginp()) { // Destination is itself used n += edgep->weight(); } } if (n>1) { doit = false; break; } } } // Process it if (!doit) { if (allowMultiIn && (debug()>=9)) { UINFO(9, "Not ok simp"<outBeginp()<<" on"<<(vvertexp->outBeginp()?vvertexp->outBeginp()->outNextp():0) <<" "<name() <outBeginp(); edgep; edgep = edgep->outNextp()) { GateLogicVertex* consumeVertexp = dynamic_cast(edgep->top()); UINFO(9, " edge "<nodep()<inBeginp(); edgep; edgep = edgep->inNextp()) { GateLogicVertex* consumeVertexp = dynamic_cast(edgep->fromp()); UINFO(9, " edge "<nodep()<=5) logicp->dumpTree(cout,"\telimVar: "); if (debug()>=5) substp->dumpTree(cout,"\t subst: "); ++m_statSigs; bool removedAllUsages = true; for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; ) { GateLogicVertex* consumeVertexp = dynamic_cast(edgep->top()); AstNode* consumerp = consumeVertexp->nodep(); if (!elimLogicOkOutputs(consumeVertexp, okVisitor/*ref*/)) { // Cannot optimize this replacement removedAllUsages = false; edgep = edgep->outNextp(); } else { optimizeElimVar(vvertexp->varScp(), substp, consumerp); // If the new replacement referred to a signal, // Correct the graph to point to this new generating variable const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs(); for (GateVarRefList::const_iterator it = rhsVarRefs.begin(); it != rhsVarRefs.end(); ++it) { AstVarScope* newvarscp = (*it)->varScopep(); UINFO(9," Point-to-new vertex "<propagateAttrClocksFrom(vvertexp); } // Remove the edge edgep->unlinkDelete(); edgep=NULL; ++m_statRefs; edgep = vvertexp->outBeginp(); } } if (removedAllUsages) { // Remove input links while (V3GraphEdge* edgep = vvertexp->inBeginp()) { edgep->unlinkDelete(); edgep=NULL; } // Clone tree so we remember it for tracing, and keep the pointer // to the "ALWAYS" part of the tree as part of this statement // That way if a later signal optimization that retained a pointer to the always // can optimize it further logicp->unlinkFrBack(); vvertexp->varScp()->valuep(logicp); logicp = NULL; // Mark the vertex so we don't mark it as being unconsumed in the next step vvertexp->user(true); logicVertexp->user(true); } } } } } } } bool GateVisitor::elimLogicOkOutputs(GateLogicVertex* consumeVertexp, const GateOkVisitor& okVisitor) { // Return true if can optimize // Return false if the consuming logic has an output signal that the replacement logic has as an input typedef set VarScopeSet; // Use map to find duplicates between two lists VarScopeSet varscopes; // Replacement logic usually has shorter input list, so faster to build list based on it const GateVarRefList& rhsVarRefs = okVisitor.rhsVarRefs(); for (GateVarRefList::const_iterator it = rhsVarRefs.begin(); it != rhsVarRefs.end(); ++it) { AstVarScope* vscp = (*it)->varScopep(); if (varscopes.find(vscp) == varscopes.end()) varscopes.insert(vscp); } for (V3GraphEdge* edgep = consumeVertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { GateVarVertex* consVVertexp = dynamic_cast(edgep->top()); AstVarScope* vscp = consVVertexp->varScp(); if (varscopes.find(vscp) != varscopes.end()) { UINFO(9," Block-unopt, insertion generates input vscp "<verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { // Take the Comments/assigns that were moved to the VarScope and change them to a // simple value assignment AstVarScope* vscp = vvertexp->varScp(); if (vscp->valuep() && !vscp->valuep()->castNodeMath()) { //if (debug()>9) vscp->dumpTree(cout, "-vscPre: "); while (AstNode* delp=vscp->valuep()->castComment()) { delp->unlinkFrBack()->deleteTree(); delp=NULL; } if (AstInitial* delp=vscp->valuep()->castInitial()) { AstNode* bodyp=delp->bodysp(); bodyp->unlinkFrBackWithNext(); delp->replaceWith(bodyp); delp->deleteTree(); delp=NULL; } if (AstAlways* delp=vscp->valuep()->castAlways()) { AstNode* bodyp=delp->bodysp(); bodyp->unlinkFrBackWithNext(); delp->replaceWith(bodyp); delp->deleteTree(); delp=NULL; } if (AstNodeAssign* delp=vscp->valuep()->castNodeAssign()) { AstNode* rhsp=delp->rhsp(); rhsp->unlinkFrBack(); delp->replaceWith(rhsp); delp->deleteTree(); delp=NULL; } //if (debug()>9) {vscp->dumpTree(cout, "-vscDone: "); cout<valuep()->castNodeMath() || vscp->valuep()->nextp()) { vscp->dumpTree(cerr, "vscStrange: "); vscp->v3fatalSrc("Value of varscope not mathematical\n"); } } } } } //---------------------------------------------------------------------- void GateVisitor::consumedMark() { // Propagate consumed signals backwards to all producers into a consumed node m_graph.userClearVertices(); for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { GateEitherVertex* evertexp = (GateEitherVertex*)vertexp; if (!evertexp->user() && evertexp->consumed()) { consumedMarkRecurse(evertexp); } } } void GateVisitor::consumedMarkRecurse(GateEitherVertex* vertexp) { if (vertexp->user()) return; // Already marked vertexp->user(true); if (!vertexp->consumed()) vertexp->setConsumed("propagated"); // Walk sources and mark them too for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { GateEitherVertex* eFromVertexp = (GateEitherVertex*)edgep->fromp(); consumedMarkRecurse(eFromVertexp); } } void GateVisitor::consumedMove() { // Remove unused logic (logic that doesn't hit a combo block or a display statement) // We need the "usually" block logic to do a better job at this for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(vertexp)) { if (!vvertexp->consumed() && !vvertexp->user()) { UINFO(8, "Unconsumed "<varScp()<(vertexp)) { AstNode* nodep = lvertexp->nodep(); AstActive* oldactp = lvertexp->activep(); // NULL under cfunc if (!lvertexp->consumed() && oldactp) { // Eventually: Move the statement to a new active block with "tracing-on" sensitivity UINFO(8," Remove unconsumed "<unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } } } } //---------------------------------------------------------------------- void GateVisitor::warnSignals() { AstNode::user2ClearTree(); for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { AstVarScope* vscp = vvertexp->varScp(); AstNode* sp = vvertexp->rstSyncNodep(); AstNode* ap = vvertexp->rstAsyncNodep(); if (ap && sp && !vscp->varp()->user2()) { // This is somewhat wrong, as marking one flop as ok for sync // may mean a different flop now fails. However it's a pain to // then report a warning in a new place - we should report them all at once. // Instead we'll disable if any disabled if (!vscp->fileline()->warnIsOff(V3ErrorCode::SYNCASYNCNET) && !ap->fileline()->warnIsOff(V3ErrorCode::SYNCASYNCNET) && !sp->fileline()->warnIsOff(V3ErrorCode::SYNCASYNCNET) ) { vscp->varp()->user2(true); // Warn only once per signal vscp->v3warn(SYNCASYNCNET,"Signal flopped as both synchronous and async: "<prettyName()<warnMore()<<"... Location of async usage"<warnMore()<<"... Location of sync usage"<varScopep() == m_elimVarScp) { // Substitute in the new tree // It's possible we substitute into something that will be reduced more later // however, as we never delete the top Always/initial statement, all should be well. m_didReplace = true; if (nodep->lvalue()) nodep->v3fatalSrc("Can't replace lvalue assignments with const var"); AstNode* substp = m_replaceTreep->cloneTree(false); if (nodep->castNodeVarRef() && substp->castNodeVarRef() && nodep->same(substp)) { // Prevent a infinite loop... substp->v3fatalSrc("Replacing node with itself; perhaps circular logic?"); } // Which fileline() to use? // If replacing with logic, an error/warning is likely to want to point to the logic // IE what we're replacing with. // However a VARREF should point to the original as it's otherwise confusing // to throw warnings that point to a PIN rather than where the pin us used. if (substp->castVarRef()) substp->fileline(nodep->fileline()); // Make the substp an rvalue like nodep. This facilitate the hashing in dedupe. if (AstNodeVarRef* varrefp = substp->castNodeVarRef()) varrefp->lvalue(false); nodep->replaceWith(substp); nodep->deleteTree(); nodep=NULL; } } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS virtual ~GateElimVisitor() {} GateElimVisitor(AstNode* nodep, AstVarScope* varscp, AstNode* replaceTreep) { m_didReplace = false; m_elimVarScp = varscp; m_replaceTreep = replaceTreep; nodep->accept(*this); } bool didReplace() const { return m_didReplace; } }; void GateVisitor::optimizeElimVar(AstVarScope* varscp, AstNode* substp, AstNode* consumerp) { if (debug()>=5) consumerp->dumpTree(cout,"\telimUsePre: "); GateElimVisitor elimVisitor (consumerp, varscp, substp); if (elimVisitor.didReplace()) { if (debug()>=9) consumerp->dumpTree(cout,"\telimUseCns: "); //Caution: Can't let V3Const change our handle to consumerp, such as by // optimizing away this assignment, etc. consumerp = V3Const::constifyEdit(consumerp); if (debug()>=5) consumerp->dumpTree(cout,"\telimUseDne: "); } } //###################################################################### // Auxiliary hash class for GateDedupeVarVisitor class GateDedupeHash : public V3HashedUserCheck { private: // NODE STATE // Ast*::user2p -> parent AstNodeAssign* for this rhsp // Ast*::user3p -> AstNode* checked in test for duplicate // Ast*::user5p -> AstNode* checked in test for duplicate // AstUser2InUse m_inuser2; (Allocated for use in GateVisitor) AstUser3InUse m_inuser3; AstUser5InUse m_inuser5; V3Hashed m_hashed; // Hash, contains rhs of assigns void hash(AstNode* nodep) { // !NULL && the object is hashable if (nodep && !nodep->sameHash().isIllegal()) { m_hashed.hash(nodep); } } bool sameHash(AstNode* node1p, AstNode* node2p) { return (node1p && node2p && !node1p->sameHash().isIllegal() && !node2p->sameHash().isIllegal() && m_hashed.sameNodes(node1p,node2p)); } bool same(AstNUser* node1p, AstNUser* node2p) { return node1p == node2p || sameHash((AstNode*)node1p,(AstNode*)node2p); } public: bool check(AstNode* node1p,AstNode* node2p) { return same(node1p->user3p(),node2p->user3p()) && same(node1p->user5p(),node2p->user5p()) && node1p->user2p()->castNode()->type() == node2p->user2p()->castNode()->type() ; } AstNodeAssign* hashAndFindDupe(AstNodeAssign* assignp, AstNode* extra1p, AstNode* extra2p) { AstNode *rhsp = assignp->rhsp(); rhsp->user2p(assignp); rhsp->user3p(extra1p); rhsp->user5p(extra2p); hash(extra1p); hash(extra2p); V3Hashed::iterator inserted = m_hashed.hashAndInsert(rhsp); V3Hashed::iterator dupit = m_hashed.findDuplicate(rhsp, this); // Even though rhsp was just inserted, V3Hashed::findDuplicate doesn't // return anything in the hash that has the same pointer (V3Hashed.cpp::findDuplicate) // So dupit is either a different, duplicate rhsp, or the end of the hash. if (dupit != m_hashed.end()) { m_hashed.erase(inserted); return m_hashed.iteratorNodep(dupit)->user2p()->castNode()->castNodeAssign(); } return NULL; } }; //###################################################################### // Have we seen the rhs of this assign before? class GateDedupeVarVisitor : public GateBaseVisitor { // Given a node, it is visited to try to find the AstNodeAssign under it that can used for dedupe. // Right now, only the following node trees are supported for dedupe. // 1. AstNodeAssign // 2. AstAlways -> AstNodeAssign // (Note, the assign must also be the only node under the always) // 3. AstAlways -> AstNodeIf -> AstNodeAssign // (Note, the IF must be the only node under the always, // and the assign must be the only node under the if, other than the ifcond) // Any other ordering or node type, except for an AstComment, makes it not dedupable private: // STATE GateDedupeHash m_hash; // Hash used to find dupes of rhs of assign AstNodeAssign* m_assignp; // Assign found for dedupe AstNode* m_ifCondp; // IF condition that assign is under bool m_always; // Assign is under an always bool m_dedupable; // Determined the assign to be dedupable // VISITORS virtual void visit(AstNodeAssign* assignp, AstNUser*) { if (m_dedupable) { // I think we could safely dedupe an always block with multiple non-blocking statements, but erring on side of caution here if (!m_assignp) { m_assignp = assignp; } else { m_dedupable = false; } } } virtual void visit(AstAlways* alwaysp, AstNUser*) { if (m_dedupable) { if (!m_always) { m_always = true; alwaysp->bodysp()->iterateAndNext(*this); } else { m_dedupable = false; } } } // Ugly support for latches of the specific form - // always @(...) // if (...) // foo = ...; // or foo <= ...; virtual void visit(AstNodeIf* ifp, AstNUser*) { if (m_dedupable) { if (m_always && !m_ifCondp && !ifp->elsesp()) { //we're under an always, this is the first IF, and there's no else m_ifCondp = ifp->condp(); ifp->ifsp()->iterateAndNext(*this); } else { m_dedupable = false; } } } virtual void visit(AstComment*, AstNUser*) {} // NOP //-------------------- // Default virtual void visit(AstNode*, AstNUser*) { m_dedupable = false; } public: // CONSTUCTORS GateDedupeVarVisitor() { m_assignp = NULL; m_ifCondp = NULL; m_always = false; m_dedupable = true; } // PUBLIC METHODS AstNodeVarRef* findDupe(AstNode* nodep, AstVarScope* consumerVarScopep, AstActive* activep) { m_assignp = NULL; m_ifCondp = NULL; m_always = false; m_dedupable = true; nodep->accept(*this); if (m_dedupable && m_assignp) { AstNode* lhsp = m_assignp->lhsp(); // Possible todo, handle more complex lhs expressions if (AstNodeVarRef* lhsVarRefp = lhsp->castNodeVarRef()) { if (lhsVarRefp->varScopep() != consumerVarScopep) consumerVarScopep->v3fatalSrc("Consumer doesn't match lhs of assign"); if (AstNodeAssign* dup = m_hash.hashAndFindDupe(m_assignp,activep,m_ifCondp)) { return (AstNodeVarRef*) dup->lhsp(); } } } return NULL; } }; //###################################################################### // Recurse through the graph, looking for duplicate expressions on the rhs of an assign class GateDedupeGraphVisitor : public GateGraphBaseVisitor { private: // NODE STATE // AstVarScope::user2p -> bool: already visited // AstUser2InUse m_inuser2; (Allocated for use in GateVisitor) V3Double0 m_numDeduped; // Statistic tracking GateDedupeVarVisitor m_varVisitor; // Looks for a dupe of the logic virtual AstNUser* visit(GateVarVertex *vvertexp, AstNUser*) { // Check that we haven't been here before if (vvertexp->varScp()->user2()) return NULL; vvertexp->varScp()->user2(true); AstNodeVarRef* dupVarRefp = (AstNodeVarRef*) vvertexp->iterateInEdges(*this, (AstNUser*) vvertexp); if (dupVarRefp && vvertexp->inSize1()) { V3GraphEdge* edgep = vvertexp->inBeginp(); GateLogicVertex* lvertexp = (GateLogicVertex*)edgep->fromp(); if (!vvertexp->dedupable()) vvertexp->varScp()->v3fatalSrc("GateLogicVertex* visit should have returned NULL if consumer var vertex is not dedupable."); GateOkVisitor okVisitor(lvertexp->nodep(), false, true); if (okVisitor.isSimple()) { AstVarScope* dupVarScopep = dupVarRefp->varScopep(); GateVarVertex* dupVvertexp = (GateVarVertex*) (dupVarScopep->user1p()); UINFO(4,"replacing " << vvertexp << " with " << dupVvertexp << endl); ++m_numDeduped; // Replace all of this varvertex's consumers with dupVarRefp for (V3GraphEdge* outedgep = vvertexp->outBeginp();outedgep;) { GateLogicVertex* consumeVertexp = dynamic_cast(outedgep->top()); AstNode* consumerp = consumeVertexp->nodep(); GateElimVisitor elimVisitor(consumerp,vvertexp->varScp(),dupVarRefp); outedgep = outedgep->relinkFromp(dupVvertexp); } // Propogate attributes dupVvertexp->propagateAttrClocksFrom(vvertexp); // Remove inputs links while (V3GraphEdge* inedgep = vvertexp->inBeginp()) { inedgep->unlinkDelete(); inedgep=NULL; } // replaceAssigns() does the deleteTree on lvertexNodep in a later step AstNode* lvertexNodep = lvertexp->nodep(); lvertexNodep->unlinkFrBack(); vvertexp->varScp()->valuep(lvertexNodep); lvertexNodep = NULL; vvertexp->user(true); lvertexp->user(true); } } return NULL; } // Returns a varref that has the same logic input virtual AstNUser* visit(GateLogicVertex* lvertexp, AstNUser* vup) { lvertexp->iterateInEdges(*this); GateVarVertex* consumerVvertexpp = (GateVarVertex*) vup; if (lvertexp->dedupable() && consumerVvertexpp->dedupable()) { AstNode* nodep = lvertexp->nodep(); AstVarScope* consumerVarScopep = consumerVvertexpp->varScp(); // TODO: Doing a simple pointer comparison of activep won't work // optimally for statements under generated clocks. Statements under // different generated clocks will never compare as equal, even if the // generated clocks are deduped into one clock. AstActive* activep = lvertexp->activep(); return (AstNUser*) m_varVisitor.findDupe(nodep, consumerVarScopep, activep); } return NULL; } public: GateDedupeGraphVisitor() {} void dedupeTree(GateVarVertex* vvertexp) { vvertexp->accept(*this); } V3Double0 numDeduped() { return m_numDeduped; } }; //---------------------------------------------------------------------- void GateVisitor::dedupe() { AstNode::user2ClearTree(); GateDedupeGraphVisitor deduper; // Traverse starting from each of the clocks for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->isClock()) { deduper.dedupeTree(vvertexp); } } } // Traverse starting from each of the outputs for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->isTop() && vvertexp->varScp()->varp()->isOutput()) { deduper.dedupeTree(vvertexp); } } } m_statDedupLogic += deduper.numDeduped(); } //###################################################################### // Recurse through the graph, try to merge assigns class GateMergeAssignsGraphVisitor : public GateGraphBaseVisitor { private: // NODE STATE AstNodeAssign* m_assignp; AstActive* m_activep; GateLogicVertex* m_logicvp; V3Graph* m_graphp; V3Double0 m_numMergedAssigns; // Statistic tracking // assemble two Sel into one if possible AstSel* merge(AstSel* pre, AstSel* cur) { AstVarRef* preVarRefp = pre->fromp()->castVarRef(); AstVarRef* curVarRefp = cur->fromp()->castVarRef(); if (!preVarRefp || !curVarRefp || !curVarRefp->same(preVarRefp)) return NULL; // not the same var AstConst* pstart = pre->lsbp()->castConst(); AstConst* pwidth = pre->widthp()->castConst(); AstConst* cstart = cur->lsbp()->castConst(); AstConst* cwidth = cur->widthp()->castConst(); if (!pstart || !pwidth || !cstart || !cwidth) return NULL; // too complicated if (cur->lsbConst()+cur->widthConst() == pre->lsbConst()) return new AstSel(curVarRefp->fileline(), curVarRefp->cloneTree(false), cur->lsbConst(), pre->widthConst()+cur->widthConst()); else return NULL; } virtual AstNUser* visit(GateVarVertex *vvertexp, AstNUser*) { for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; ) { V3GraphEdge* oldedgep = edgep; edgep = edgep->inNextp(); // for recursive since the edge could be deleted if (GateLogicVertex* lvertexp = dynamic_cast(oldedgep->fromp())) { if (AstNodeAssign* assignp = lvertexp->nodep()->castNodeAssign()) { //if (lvertexp->outSize1() && assignp->lhsp()->castSel()) { if (assignp->lhsp()->castSel() && lvertexp->outSize1()) { UINFO(9, "assing to the nodep["<lhsp()->castSel()->lsbConst()<<"]"<activep(); if (!m_logicvp) m_logicvp = lvertexp; if (!m_assignp) m_assignp = assignp; // not under the same active if (m_activep != lvertexp->activep()) { m_activep = lvertexp->activep(); m_logicvp = lvertexp; m_assignp = assignp; continue; } AstSel* preselp = m_assignp->lhsp()->castSel(); AstSel* curselp = assignp->lhsp()->castSel(); if (!preselp || !curselp) continue; if (AstSel* newselp = merge(preselp, curselp)) { UINFO(5, "assemble to new sel: "<replaceWith(newselp); preselp->deleteTree(); preselp = NULL; // create new rhs for pre assignment AstNode* newrhsp = new AstConcat(m_assignp->rhsp()->fileline(), m_assignp->rhsp()->cloneTree(false), assignp->rhsp()->cloneTree(false)); AstNode* oldrhsp = m_assignp->rhsp(); oldrhsp->replaceWith(newrhsp); oldrhsp->deleteTree(); oldrhsp = NULL; m_assignp->dtypeChgWidthSigned(m_assignp->width()+assignp->width(), m_assignp->width()+assignp->width(), AstNumeric::fromBool(true)); // don't need to delete, will be handled //assignp->unlinkFrBack(); assignp->deleteTree(); assignp = NULL; // update the graph { // delete all inedges to lvertexp if (!lvertexp->inEmpty()) { for (V3GraphEdge* ledgep = lvertexp->inBeginp(); ledgep; ) { V3GraphEdge* oedgep = ledgep; ledgep = ledgep->inNextp(); GateEitherVertex* fromvp = dynamic_cast(oedgep->fromp()); new V3GraphEdge(m_graphp, fromvp, m_logicvp, 1); oedgep->unlinkDelete(); oedgep = NULL; } } // delete all outedges to lvertexp, only one oldedgep->unlinkDelete(); oldedgep = NULL; } ++m_numMergedAssigns; } else { m_assignp = assignp; m_logicvp = lvertexp; } } } } } return NULL; } virtual AstNUser* visit(GateLogicVertex* lvertexp, AstNUser* vup) { return NULL; } public: GateMergeAssignsGraphVisitor(V3Graph* graphp) { m_assignp = NULL; m_activep = NULL; m_logicvp = NULL; m_numMergedAssigns = 0; m_graphp = graphp; } void mergeAssignsTree(GateVarVertex* vvertexp) { vvertexp->accept(*this); } V3Double0 numMergedAssigns() { return m_numMergedAssigns; } }; //---------------------------------------------------------------------- void GateVisitor::mergeAssigns() { GateMergeAssignsGraphVisitor merger(&m_graph); for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (GateVarVertex* vvertexp = dynamic_cast(itp)) { merger.mergeAssignsTree(vvertexp); } } m_statAssignMerged += merger.numMergedAssigns(); } //###################################################################### // Convert VARSCOPE(ASSIGN(default, VARREF)) to just VARSCOPE(default) class GateDeassignVisitor : public GateBaseVisitor { private: // VISITORS virtual void visit(AstVarScope* nodep, AstNUser*) { if (AstNodeAssign* assp = nodep->valuep()->castNodeAssign()) { UINFO(5," Removeassign "<rhsp(); valuep->unlinkFrBack(); assp->replaceWith(valuep); assp->deleteTree(); assp=NULL; } } // Speedups virtual void visit(AstVar* nodep, AstNUser*) {} virtual void visit(AstActive* nodep, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS GateDeassignVisitor(AstNode* nodep) { nodep->accept(*this); } virtual ~GateDeassignVisitor() {} }; //###################################################################### // Gate class functions void V3Gate::gateAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Parse.h0000664000177100017500000000330212525171733015752 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Reading of Verilog files // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3PARSE_H_ #define _V3PARSE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Global.h" class AstNetlist; class V3InFilter; class V3ParseImp; class V3ParseSym; //============================================================================ class V3Parse { private: V3ParseImp* m_impp; public: // CONSTRUCTORS // We must allow reading multiple files into one parser V3Parse(AstNetlist* rootp, V3InFilter* filterp, V3ParseSym* symp); ~V3Parse(); // METHODS // Preprocess and read the Verilog file specified into the netlist database void parseFile(FileLine* fileline, const string& modname, bool inLibrary, const string& errmsg); // Push preprocessed text to the lexer static void ppPushText(V3ParseImp* impp, const string& text); }; #endif // Guard verilator-3.874/src/Makefile_obj.in0000664000177100017500000001752312525172036017224 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator: Makefile for verilog source # # Code available from: http://www.veripool.org/verilator # #***************************************************************************** # # Copyright 2003-2015 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. # # Verilator is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # #****************************************************************************/ #### Start of system configuration section. #### # Unfortunately configure uses relative paths, and this makefile is called # from a level lower, so we need to move up if it's relative, not if absolute. config_srcdir = @srcdir@ ifeq ($(config_srcdir),.) srcdir = .. else # Run an experiment ifeq ($(wildcard $(config_srcdir)/../Makefile_obj.in),) srcdir = $(config_srcdir) else srcdir = $(config_srcdir)/.. endif endif incdir = $(srcdir)/../include # Bldsrc may differ from srcdir if configure wan't run from the kit top bldsrc = .. # Programs CC = @CC@ CXX = @CXX@ LINK = @CXX@ LEX = @LEX@ LFLAGS = -d PERL = @PERL@ YACC = @YACC@ prefix = @prefix@ # Directory in which to install data across multiple architectures datarootdir = @datarootdir@ # Directory in which to install package specific files # Generally ${prefix}/share/verilator pkgdatadir = @pkgdatadir@ # Compile options CFG_WITH_CCWARN = @CFG_WITH_CCWARN@ CFG_WITH_DEFENV = @CFG_WITH_DEFENV@ CPPFLAGS += @CPPFLAGS@ LDFLAGS += @LDFLAGS@ EXEEXT = @EXEEXT@ CFG_CXXFLAGS_SRC = @CFG_CXXFLAGS_SRC@ CFG_CXXFLAGS_PARSER = @CFG_CXXFLAGS_PARSER@ #### End of system configuration section. #### VPATH += . $(bldsrc) $(srcdir) TGT = ../../verilator_bin ################# ifeq ($(VL_DEBUG),) # Optimize COPT = -O else # Debug COPT = -ggdb -DVL_DEBUG # Debug & Profile: #LDFLAGS += -pg -g #COPT = -ggdb -pg -g endif ################# #LIBS += -ldl #CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl # -lfl not needed as Flex invoked with %nowrap option # -lstdc++ needed for clang, believed harmless with gcc LIBS = -lm -lstdc++ CPPFLAGS += -MMD CPPFLAGS += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir) CPPFLAGS += -DYYDEBUG # Required to get nice error messages #CPPFLAGS += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool CPPFLAGS += $(COPT) CPPFLAGS += -MP # Only works on recent GCC versions ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_SRC) -Werror #CPPFLAGS += -pedantic-errors endif CPPFLAGSWALL = $(CPPFLAGS) CPPFLAGSPARSER = $(CPPFLAGS) $(CFG_CXXFLAGS_PARSER) ifneq ($(SYSTEMPERL),) # Intuit SYSTEMPERL_INCLUDE as it's new SYSTEMPERL_INCLUDE ?= $(SYSTEMPERL)/src #else if set, leave as-is. #else if SYSTEMPERL="" don't set _INCLUDE so source will figure it out endif # Allow RPM builds to specify hardcoded data directories # To do this: ifeq ($(CFG_WITH_DEFENV),yes) CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\" CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\" CPPFLAGS += -DDEFENV_SYSTEMC_INCLUDE=\"$(SYSTEMC_INCLUDE)\" CPPFLAGS += -DDEFENV_SYSTEMC_LIBDIR=\"$(SYSTEMC_LIBDIR)\" CPPFLAGS += -DDEFENV_SYSTEMPERL=\"$(SYSTEMPERL)\" CPPFLAGS += -DDEFENV_SYSTEMPERL_INCLUDE=\"$(SYSTEMPERL_INCLUDE)\" ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\" else CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(VERILATOR_ROOT)\" endif endif HEADERS = $(wildcard V*.h v*.h) ASTGEN = $(srcdir)/astgen BISONPRE = $(srcdir)/bisonpre FLEXFIX = $(srcdir)/flexfix VLCOVGEN = $(srcdir)/vlcovgen ###################################################################### #### Top level all: make_info $(TGT) make_info: @echo " Compile flags: " $(CXX) ${CPPFLAGS} clean mostlyclean distclean maintainer-clean:: -rm -f *.o *.d perlxsi.c *_gen_* -rm -f *__gen* -rm -f obj_* .objcache* distclean maintainer-clean:: clean maintainer-clean:: maintainer-copy:: #### Top executable RAW_OBJS = \ Verilator.o \ V3Active.o \ V3ActiveTop.o \ V3Assert.o \ V3AssertPre.o \ V3Ast.o \ V3AstNodes.o \ V3Begin.o \ V3Branch.o \ V3Broken.o \ V3Case.o \ V3Cast.o \ V3Cdc.o \ V3Changed.o \ V3Clean.o \ V3ClkGater.o \ V3Clock.o \ V3Combine.o \ V3Config.o \ V3Const__gen.o \ V3Coverage.o \ V3CoverageJoin.o \ V3Dead.o \ V3Delayed.o \ V3Depth.o \ V3DepthBlock.o \ V3Descope.o \ V3EmitC.o \ V3EmitCInlines.o \ V3EmitCSyms.o \ V3EmitMk.o \ V3EmitV.o \ V3EmitXml.o \ V3Error.o \ V3Expand.o \ V3File.o \ V3FileLine.o \ V3Gate.o \ V3GenClk.o \ V3Graph.o \ V3GraphAlg.o \ V3GraphAcyc.o \ V3GraphDfa.o \ V3GraphTest.o \ V3Hashed.o \ V3Inline.o \ V3Inst.o \ V3Life.o \ V3LifePost.o \ V3LinkCells.o \ V3LinkDot.o \ V3LinkJump.o \ V3LinkLValue.o \ V3LinkLevel.o \ V3LinkParse.o \ V3LinkResolve.o \ V3Localize.o \ V3Name.o \ V3Number.o \ V3Options.o \ V3Order.o \ V3Os.o \ V3Param.o \ V3PreShell.o \ V3Premit.o \ V3Scope.o \ V3Slice.o \ V3Split.o \ V3SplitAs.o \ V3Stats.o \ V3StatsReport.o \ V3String.o \ V3Subst.o \ V3Table.o \ V3Task.o \ V3Trace.o \ V3TraceDecl.o \ V3Tristate.o \ V3Undriven.o \ V3Unknown.o \ V3Unroll.o \ V3Width.o \ V3WidthSel.o \ # Non-concatable NC_OBJS += \ V3ParseImp.o \ V3ParseGrammar.o \ V3ParseLex.o \ V3PreProc.o \ # verilator_coverage VLCOV_OBJS = \ VlcMain.o \ #### Linking ifeq ($(VL_VLCOV),) PREDEP_H = V3Ast__gen_classes.h OBJS += $(RAW_OBJS) $(NC_OBJS) else PREDEP_H = OBJS += $(VLCOV_OBJS) endif V3__CONCAT.cpp: $(addsuffix .cpp, $(basename $(RAW_OBJS))) $(PERL) $(srcdir)/../bin/verilator_includer $^ > $@ $(TGT): $(PREDEP_H) $(OBJS) @echo " Linking $@..." -rm -rf $@ $@.exe ${LINK} ${LDFLAGS} -o $@ $(OBJS) $(CCMALLOC) ${LIBS} V3Number_test: V3Number_test.o ${LINK} ${LDFLAGS} -o $@ $^ ${LIBS} #### Modules %__gen.cpp: %.cpp $(ASTGEN) V3Ast.h V3AstNodes.h $(PERL) $(ASTGEN) -I$(srcdir) $*.cpp %.o: %.cpp $(OBJCACHE) ${CXX} ${CPPFLAGSWALL} -c $< %.o: %.c $(OBJCACHE) ${CC} ${CPPFLAGSWALL} -c $< V3ParseLex.o: V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c $(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $< V3ParseGrammar.o: V3ParseGrammar.cpp V3ParseBison.c $(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $< V3ParseImp.o: V3ParseImp.cpp V3ParseBison.c $(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $< V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp $(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $< #### Generated files # Target rule called before parallel build to make generated files serial:: V3Ast__gen_classes.h V3ParseBison.c serial_vlcov:: vlcovgen.d vlcovgen.d: $(VLCOVGEN) $(srcdir)/include/verilated_cov_key.h $(PERL) $(VLCOVGEN) --srcdir $(srcdir) touch $@ V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h $(PERL) $(ASTGEN) -I$(srcdir) --classes V3ParseBison.h: V3ParseBison.c # Have only one output file in this rule to prevent parallel make issues 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 $< V3Lexer_pregen.yy.cpp: verilog.l V3ParseBison.h $(HEADERS) ${LEX} --version ${LEX} ${LFLAGS} -o$@ $< V3Lexer.yy.cpp: V3Lexer_pregen.yy.cpp $(FLEXFIX) $(PERL) $(FLEXFIX) V3Lexer <$< >$@ V3PreLex_pregen.yy.cpp: V3PreLex.l $(HEADERS) ${LEX} --version ${LEX} ${LFLAGS} -o$@ $< V3PreLex.yy.cpp: V3PreLex_pregen.yy.cpp $(FLEXFIX) $(PERL) $(FLEXFIX) V3PreLex <$< >$@ ###################################################################### ###################################################################### DEPS := $(wildcard *.d) ifneq ($(DEPS),) include $(DEPS) endif verilator-3.874/src/V3Cdc.cpp0000664000177100017500000006672712525171733015750 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Clock Domain Crossing Lint // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Cdc's Transformations: // // Create V3Graph-ish graph // Find all negedge reset flops // Trace back to previous flop // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include #include "V3Global.h" #include "V3Cdc.h" #include "V3Ast.h" #include "V3Graph.h" #include "V3Const.h" #include "V3EmitV.h" #include "V3File.h" #define CDC_WEIGHT_ASYNC 0x1000 // Weight for edges that feed async logic //###################################################################### class CdcBaseVisitor : public AstNVisitor { public: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### // Graph support classes class CdcEitherVertex : public V3GraphVertex { AstScope* m_scopep; AstNode* m_nodep; AstSenTree* m_srcDomainp; AstSenTree* m_dstDomainp; bool m_srcDomainSet:1; bool m_dstDomainSet:1; bool m_asyncPath:1; public: CdcEitherVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep) : V3GraphVertex(graphp), m_scopep(scopep), m_nodep(nodep) , m_srcDomainp(NULL), m_dstDomainp(NULL) , m_srcDomainSet(false), m_dstDomainSet(false) , m_asyncPath(false) {} virtual ~CdcEitherVertex() {} // Accessors AstScope* scopep() const { return m_scopep; } AstNode* nodep() const { return m_nodep; } AstSenTree* srcDomainp() const { return m_srcDomainp; } void srcDomainp(AstSenTree* nodep) { m_srcDomainp = nodep; } bool srcDomainSet() const { return m_srcDomainSet; } void srcDomainSet(bool flag) { m_srcDomainSet = flag; } AstSenTree* dstDomainp() const { return m_dstDomainp; } void dstDomainp(AstSenTree* nodep) { m_dstDomainp = nodep; } bool dstDomainSet() const { return m_dstDomainSet; } void dstDomainSet(bool flag) { m_dstDomainSet = flag; } bool asyncPath() const { return m_asyncPath; } void asyncPath(bool flag) { m_asyncPath = flag; } }; class CdcVarVertex : public CdcEitherVertex { AstVarScope* m_varScp; int m_cntAsyncRst; bool m_fromFlop; public: CdcVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : CdcEitherVertex(graphp, scopep, varScp), m_varScp(varScp), m_cntAsyncRst(0), m_fromFlop(false) {} virtual ~CdcVarVertex() {} // Accessors AstVarScope* varScp() const { return m_varScp; } virtual string name() const { return (cvtToStr((void*)m_varScp)+" "+varScp()->name()); } virtual string dotColor() const { return fromFlop() ? "green" : cntAsyncRst() ? "red" : "blue"; } int cntAsyncRst() const { return m_cntAsyncRst; } void cntAsyncRst(int flag) { m_cntAsyncRst=flag; } bool fromFlop() const { return m_fromFlop; } void fromFlop(bool flag) { m_fromFlop = flag; } }; class CdcLogicVertex : public CdcEitherVertex { bool m_hazard:1; bool m_isFlop:1; public: CdcLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstSenTree* sensenodep) : CdcEitherVertex(graphp,scopep,nodep) , m_hazard(false), m_isFlop(false) { srcDomainp(sensenodep); dstDomainp(sensenodep); } virtual ~CdcLogicVertex() {} // Accessors virtual string name() const { return (cvtToStr((void*)nodep())+"@"+scopep()->prettyName()); } virtual string dotColor() const { return hazard() ? "black" : "yellow"; } bool hazard() const { return m_hazard; } void setHazard(AstNode* nodep) { m_hazard = true; nodep->user3(true); } void clearHazard() { m_hazard = false; } bool isFlop() const { return m_isFlop; } void isFlop(bool flag) { m_isFlop = flag; } }; //###################################################################### class CdcDumpVisitor : public CdcBaseVisitor { private: // NODE STATE //Entire netlist: // {statement}Node::user3 -> bool, indicating not hazard ofstream* m_ofp; // Output file string m_prefix; virtual void visit(AstNode* nodep, AstNUser*) { *m_ofp<user3()) *m_ofp<<" %%"; else *m_ofp<<" "; *m_ofp<prettyTypeName()<<" "<op1p()->iterateAndNext(*this); m_prefix = lastPrefix + "2:"; nodep->op2p()->iterateAndNext(*this); m_prefix = lastPrefix + "3:"; nodep->op3p()->iterateAndNext(*this); m_prefix = lastPrefix + "4:"; nodep->op4p()->iterateAndNext(*this); m_prefix = lastPrefix; } public: // CONSTUCTORS CdcDumpVisitor(AstNode* nodep, ofstream* ofp, const string& prefix) { m_ofp = ofp; m_prefix = prefix; nodep->accept(*this); } virtual ~CdcDumpVisitor() {} }; //###################################################################### class CdcWidthVisitor : public CdcBaseVisitor { private: int m_maxLineno; size_t m_maxFilenameLen; virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); // Keeping line+filename lengths separate is much faster than calling ascii().length() if (nodep->fileline()->lineno() >= m_maxLineno) { m_maxLineno = nodep->fileline()->lineno()+1; } if (nodep->fileline()->filename().length() >= m_maxFilenameLen) { m_maxFilenameLen = nodep->fileline()->filename().length()+1; } } public: // CONSTUCTORS CdcWidthVisitor(AstNode* nodep) { m_maxLineno = 0; m_maxFilenameLen = 0; nodep->accept(*this); } virtual ~CdcWidthVisitor() {} // ACCESSORS int maxWidth() { size_t width=1; width += m_maxFilenameLen; width += 1; // The : width += cvtToStr(m_maxLineno).length(); width += 1; // Final : return (int)width; } }; //###################################################################### // Cdc class functions class CdcVisitor : public CdcBaseVisitor { private: // NODE STATE //Entire netlist: // AstVarScope::user1p -> CdcVarVertex* for usage var, 0=not set yet // AstVarScope::user2 -> bool Used in sensitivity list // {statement}Node::user1p -> CdcLogicVertex* for this statement // AstNode::user3 -> bool True indicates to print %% (via V3EmitV) AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; // STATE V3Graph m_graph; // Scoreboard of var usages/dependencies CdcLogicVertex* m_logicVertexp; // Current statement being tracked, NULL=ignored AstScope* m_scopep; // Current scope being processed AstNodeModule* m_modp; // Current module AstSenTree* m_domainp; // Current sentree bool m_inDly; // In delayed assign int m_inSenItem; // Number of senitems string m_ofFilename; // Output filename ofstream* m_ofp; // Output file uint32_t m_userGeneration; // Generation count to avoid slow userClearVertices int m_filelineWidth; // Characters in longest fileline // METHODS void iterateNewStmt(AstNode* nodep) { if (m_scopep) { UINFO(4," STMT "<hasClocked()) { // To/from a flop m_logicVertexp->isFlop(true); m_logicVertexp->srcDomainp(m_domainp); m_logicVertexp->srcDomainSet(true); m_logicVertexp->dstDomainp(m_domainp); m_logicVertexp->dstDomainSet(true); } nodep->iterateChildren(*this); m_logicVertexp = NULL; if (0 && debug()>=9) { UINFO(9, "Trace Logic:\n"); nodep->dumpTree(cout, "-log1: "); } } } CdcVarVertex* makeVarVertex(AstVarScope* varscp) { CdcVarVertex* vertexp = (CdcVarVertex*)(varscp->user1p()); if (!vertexp) { UINFO(6,"New vertex "<user1p(vertexp); if (varscp->varp()->isUsedClock()) {} if (varscp->varp()->isPrimaryIO()) { // Create IO vertex - note it's relative to the pointed to var, not where we are now // This allows reporting to easily print the input statement CdcLogicVertex* ioVertexp = new CdcLogicVertex(&m_graph, varscp->scopep(), varscp->varp(), NULL); if (varscp->varp()->isInput()) { new V3GraphEdge(&m_graph, ioVertexp, vertexp, 1); } else { new V3GraphEdge(&m_graph, vertexp, ioVertexp, 1); } } } if (m_inSenItem) { varscp->user2(true); // It's like a clock... // TODO: In the future we could mark it here and do normal clock tree glitch checks also } else if (varscp->user2()) { // It was detected in a sensitivity list earlier // And now it's used as logic. So must be a reset. vertexp->cntAsyncRst(vertexp->cntAsyncRst()+1); } return vertexp; } void warnAndFile(AstNode* nodep, V3ErrorCode code, const string& msg) { static bool told_file = false; nodep->v3warnCode(code,msg); if (!told_file) { told_file = 1; cerr<fileline()<<" "<hasCombo()) { // Source flop logic in a posedge block is OK for reset (not async though) if (m_logicVertexp && !nodep->fileline()->warnIsOff(V3ErrorCode::CDCRSTLOGIC)) { UINFO(8,"Set hazard "<setHazard(nodep); } } } string spaces(int level) { string out; while (level--) out+=" "; return out; } string pad(unsigned column, const string& in) { string out = in; while (out.length()6) m_graph.dump(); if (debug()>6) m_graph.dumpDotFilePrefixed("cdc_pre"); // m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); // This will MAX across edge weights // m_graph.dumpDotFilePrefixed("cdc_simp"); // analyzeReset(); } int filelineWidth() { if (!m_filelineWidth) { CdcWidthVisitor visitor (v3Global.rootp()); m_filelineWidth = visitor.maxWidth(); } return m_filelineWidth; } //---------------------------------------- // RESET REPORT void analyzeReset() { // Find all async reset wires, and trace backwards // userClearVertices is very slow, so we use a generation count instead m_graph.userClearVertices(); // user1: uint32_t - was analyzed generation for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (CdcVarVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->cntAsyncRst()) { m_userGeneration++; // Effectively a userClearVertices() UINFO(8, " Trace One async: "<user()>=m_userGeneration) return NULL; // Processed - prevent loop vertexp->user(m_userGeneration); CdcEitherVertex* mark_outp = NULL; UINFO(9," Trace: "<asyncPath(false); if (CdcLogicVertex* vvertexp = dynamic_cast(vertexp)) { // Any logic considered bad, at the moment, anyhow if (vvertexp->hazard() && !mark_outp) mark_outp = vvertexp; // And keep tracing back so the user can understand what's up } else if (CdcVarVertex* vvertexp = dynamic_cast(vertexp)) { if (mark) vvertexp->asyncPath(true); // If primary I/O, it's ok here back if (vvertexp->varScp()->varp()->isPrimaryIn()) { // Show the source "input" statement if it exists for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { CdcEitherVertex* eFromVertexp = (CdcEitherVertex*)edgep->fromp(); eFromVertexp->asyncPath(true); } return NULL; } // Also ok if from flop, but partially trace the flop so more obvious to users if (vvertexp->fromFlop()) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { CdcEitherVertex* eFromVertexp = (CdcEitherVertex*)edgep->fromp(); eFromVertexp->asyncPath(true); } return NULL; } } for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { CdcEitherVertex* eFromVertexp = (CdcEitherVertex*)edgep->fromp(); CdcEitherVertex* submarkp = traceAsyncRecurse(eFromVertexp, mark); if (submarkp && !mark_outp) mark_outp = submarkp; } if (mark) vertexp->asyncPath(true); return mark_outp; } void dumpAsync(CdcVarVertex* vertexp, CdcEitherVertex* markp) { AstNode* nodep = vertexp->varScp(); *m_ofp<<"\n"; *m_ofp<<"\n"; CdcEitherVertex* targetp = vertexp; // One example destination flop (of possibly many) for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { CdcEitherVertex* eToVertexp = (CdcEitherVertex*)edgep->top(); if (!eToVertexp) targetp = eToVertexp; if (CdcLogicVertex* vvertexp = dynamic_cast(eToVertexp)) { if (vvertexp->isFlop() // IE the target flop that is upsetting us && edgep->weight() >= CDC_WEIGHT_ASYNC) { // And this signal feeds an async reset line targetp = eToVertexp; //UINFO(9," targetasync "<name()<<" "<<" from "<name()<name()<<" "<nodep()->fileline()<nodep(),V3ErrorCode::CDCRSTLOGIC,"Logic in path that feeds async reset, via signal: "+nodep->prettyName()); dumpAsyncRecurse(targetp, "", " ",0); } bool dumpAsyncRecurse(CdcEitherVertex* vertexp, const string& prefix, const string& sep, int level) { // level=0 is special, indicates to dump destination flop // Return true if printed anything // If mark, also mark the output even if nothing hazardous below if (vertexp->user()>=m_userGeneration) return false; // Processed - prevent loop vertexp->user(m_userGeneration); if (!vertexp->asyncPath() && level!=0) return false; // Not part of path // Other logic in the path string cont = prefix+sep; string nextsep = " "; for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { CdcEitherVertex* eFromVertexp = (CdcEitherVertex*)edgep->fromp(); if (dumpAsyncRecurse(eFromVertexp, cont, nextsep, level+1)) { nextsep = " | "; } } // Dump single variable/logic block // See also OrderGraph::loopsVertexCb(V3GraphVertex* vertexp) AstNode* nodep = vertexp->nodep(); string front = pad(filelineWidth(),nodep->fileline()->ascii()+":")+" "+prefix+" +- "; if (nodep->castVarScope()) { *m_ofp<prettyName()<srcDomainp(), true); if (debug()) { CdcDumpVisitor visitor (nodep, m_ofp, front+"DBG: "); } } nextsep = " | "; if (level) *m_ofp<(vertexp)) { // Now that we've printed a path with this hazard, don't bother to print any more // Otherwise, we'd get a path for almost every destination flop vvertexp->clearHazard(); } return true; } //---------------------------------------- // EDGE REPORTS void edgeReport() { // Make report of all signal names and what clock edges they have // // Due to flattening, many interesting direct-connect signals are // lost, so we can't make a report showing I/Os for a low level // module. Disabling flattening though makes us consider each // signal in it's own unique clock domain. UINFO(3,__FUNCTION__<<": "<verticesNextp()) { if (CdcVarVertex* vvertexp = dynamic_cast(itp)) { UINFO(9, " Trace One edge: "< ofp (V3File::new_ofstream(filename)); if (ofp->fail()) v3fatalSrc("Can't write "< report; // Sort output by name for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (CdcVarVertex* vvertexp = dynamic_cast(itp)) { AstVar* varp = vvertexp->varScp()->varp(); if (1) { // varp->isPrimaryIO() const char* whatp = "wire"; if (varp->isPrimaryIO()) whatp = (varp->isInout()?"inout":varp->isInput()?"input":"output"); ostringstream os; os.setf(ios::left); // Module name - doesn't work due to flattening having lost the original // so we assume the modulename matches the filebasename string fname = vvertexp->varScp()->fileline()->filebasename() + ":"; os<<" "<varScp()->prettyName(); os<<" SRC="; if (vvertexp->srcDomainp()) V3EmitV::verilogForTree(vvertexp->srcDomainp(), os); os<<" DST="; if (vvertexp->dstDomainp()) V3EmitV::verilogForTree(vvertexp->dstDomainp(), os); os<::iterator it = report.begin(); it!=report.end(); ++it) { *ofp << *it; } } void edgeDomainRecurse(CdcEitherVertex* vertexp, bool traceDests, int level) { // Scan back to inputs/outputs, flops, and compute clock domain information UINFO(8,spaces(level)<<" Tracein "<user()>=m_userGeneration) return; // Mid-Processed - prevent loop vertexp->user(m_userGeneration); // Variables from flops already are domained if (traceDests ? vertexp->dstDomainSet() : vertexp->srcDomainSet()) return; // Fully computed typedef set SenSet; SenSet senouts; // List of all sensitivities for new signal if (CdcLogicVertex* vvertexp = dynamic_cast(vertexp)) { if (vvertexp) {} // Unused } else if (CdcVarVertex* vvertexp = dynamic_cast(vertexp)) { // If primary I/O, give it domain of the input AstVar* varp = vvertexp->varScp()->varp(); if (varp->isPrimaryIO() && varp->isInput() && !traceDests) { senouts.insert(new AstSenTree(varp->fileline(), new AstSenItem(varp->fileline(), AstSenItem::Combo()))); } } // Now combine domains of sources/dests if (traceDests) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { CdcEitherVertex* eToVertexp = (CdcEitherVertex*)edgep->top(); edgeDomainRecurse(eToVertexp, traceDests, level+1); if (eToVertexp->dstDomainp()) senouts.insert(eToVertexp->dstDomainp()); } } else { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { CdcEitherVertex* eFromVertexp = (CdcEitherVertex*)edgep->fromp(); edgeDomainRecurse(eFromVertexp, traceDests, level+1); if (eFromVertexp->srcDomainp()) senouts.insert(eFromVertexp->srcDomainp()); } } // Convert list of senses into one sense node AstSenTree* senoutp = NULL; bool senedited = false; for (SenSet::iterator it=senouts.begin(); it!=senouts.end(); ++it) { if (!senoutp) senoutp = *it; else { if (!senedited) { senedited = true; senoutp = senoutp->cloneTree(true); } senoutp->addSensesp((*it)->sensesp()->cloneTree(true)); } } // If multiple domains need to do complicated optimizations if (senedited) { senoutp = V3Const::constifyExpensiveEdit(senoutp)->castSenTree(); } if (traceDests) { vertexp->dstDomainSet(true); // Note it's set - domainp may be null, so can't use that vertexp->dstDomainp(senoutp); if (debug()>=9) { UINFO(9,spaces(level)+" Tracedst "<srcDomainSet(true); // Note it's set - domainp may be null, so can't use that vertexp->srcDomainp(senoutp); if (debug()>=9) { UINFO(9,spaces(level)+" Tracesrc "<iterateChildren(*this); m_modp = NULL; } virtual void visit(AstScope* nodep, AstNUser*) { UINFO(4," SCOPE "<iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstActive* nodep, AstNUser*) { // Create required blocks and add to module UINFO(4," BLOCK "<sensesp(); if (!m_domainp || m_domainp->hasCombo() || m_domainp->hasClocked()) { // IE not hasSettle/hasInitial iterateNewStmt(nodep); } m_domainp = NULL; AstNode::user2ClearTree(); } virtual void visit(AstNodeVarRef* nodep, AstNUser*) { if (m_scopep) { if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block\n"); AstVarScope* varscp = nodep->varScopep(); if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n"); CdcVarVertex* varvertexp = makeVarVertex(varscp); UINFO(5," VARREF to "<lvalue()) { new V3GraphEdge(&m_graph, m_logicVertexp, varvertexp, 1); if (m_inDly) { varvertexp->fromFlop(true); varvertexp->srcDomainp(m_domainp); varvertexp->srcDomainSet(true); } } else { if (varvertexp->cntAsyncRst()) { //UINFO(9," edgeasync "<name()<<" to "<name()<<" to "<iterateChildren(*this); m_inDly = false; } virtual void visit(AstSenItem* nodep, AstNUser*) { // Note we look at only AstSenItems, not AstSenGate's // The gating term of a AstSenGate is normal logic m_inSenItem = true; nodep->iterateChildren(*this); m_inSenItem = false; } virtual void visit(AstAlways* nodep, AstNUser*) { iterateNewStmt(nodep); } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { // CDC doesn't care about public variables } virtual void visit(AstCFunc* nodep, AstNUser*) { iterateNewStmt(nodep); } virtual void visit(AstSenGate* nodep, AstNUser*) { // First handle the clock part will be handled in a minute by visit AstSenItem // The logic gating term is delt with as logic iterateNewStmt(nodep); } virtual void visit(AstAssignAlias* nodep, AstNUser*) { iterateNewStmt(nodep); } virtual void visit(AstAssignW* nodep, AstNUser*) { iterateNewStmt(nodep); } // Math that shouldn't cause us to clear hazard virtual void visit(AstConst* nodep, AstNUser*) { } virtual void visit(AstReplicate* nodep, AstNUser*) { nodep->iterateChildren(*this); } virtual void visit(AstConcat* nodep, AstNUser*) { nodep->iterateChildren(*this); } virtual void visit(AstNot* nodep, AstNUser*) { nodep->iterateChildren(*this); } virtual void visit(AstSel* nodep, AstNUser*) { if (!nodep->lsbp()->castConst()) setNodeHazard(nodep); nodep->iterateChildren(*this); } virtual void visit(AstNodeSel* nodep, AstNUser*) { if (!nodep->bitp()->castConst()) setNodeHazard(nodep); nodep->iterateChildren(*this); } // Ignores virtual void visit(AstInitial* nodep, AstNUser*) { } virtual void visit(AstTraceInc* nodep, AstNUser*) { } virtual void visit(AstCoverToggle* nodep, AstNUser*) { } virtual void visit(AstNodeDType* nodep, AstNUser*) { } //-------------------- // Default virtual void visit(AstNodeMath* nodep, AstNUser*) { setNodeHazard(nodep); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS CdcVisitor(AstNode* nodep) { m_logicVertexp = NULL; m_scopep = NULL; m_modp = NULL; m_domainp = NULL; m_inDly = false; m_inSenItem = 0; m_userGeneration = 0; m_filelineWidth = 0; // Make report of all signal names and what clock edges they have string filename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__cdc.txt"; m_ofp = V3File::new_ofstream(filename); if (m_ofp->fail()) v3fatalSrc("Can't write "<accept(*this); analyze(); if (debug()>=1) edgeReport(); // Not useful to users at the moment if (0) { *m_ofp<<"\nDBG-test-dumper\n"; V3EmitV::verilogPrefixedTree(nodep, *m_ofp, "DBG ",40,NULL,true); *m_ofp< #include #include #include #include "V3Global.h" #include "V3Depth.h" #include "V3Ast.h" //###################################################################### class DepthVisitor : public AstNVisitor { private: // NODE STATE // STATE AstNodeModule* m_modp; // Current module AstCFunc* m_funcp; // Current block AstNode* m_stmtp; // Current statement int m_depth; // How deep in an expression int m_maxdepth; // Maximum depth in an expression // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void createDeepTemp(AstNode* nodep) { UINFO(6," Deep "<=9) nodep->dumpTree(cout,"deep:"); string newvarname = ((string)"__Vdeeptemp"+cvtToStr(m_modp->varNumGetInc())); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname, // Width, not widthMin, as we may be in middle of BITSEL expression which // though it's one bit wide, needs the mask in the upper bits. // (Someday we'll have a valid bitmask instead of widths....) // See t_func_crc for an example test that requires this VFlagLogicPacked(), nodep->width()); if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function"); m_funcp->addInitsp(varp); // Replace node tree with reference to var AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false); nodep->replaceWith(newp); // Put assignment before the referencing statement AstAssign* assp = new AstAssign (nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true), nodep); AstNRelinker linker2; m_stmtp->unlinkFrBack(&linker2); assp->addNext(m_stmtp); linker2.relink(assp); } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { UINFO(4," MOD "<iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCFunc* nodep, AstNUser*) { m_funcp = nodep; m_depth = 0; m_maxdepth = 0; nodep->iterateChildren(*this); m_funcp = NULL; } void visitStmt(AstNodeStmt* nodep) { m_depth = 0; m_maxdepth = 0; m_stmtp = nodep; nodep->iterateChildren(*this); m_stmtp = NULL; } virtual void visit(AstNodeStmt* nodep, AstNUser*) { visitStmt(nodep); } // Operators virtual void visit(AstNodeTermop* nodep, AstNUser*) { } virtual void visit(AstNodeMath* nodep, AstNUser*) { // We have some operator defines that use 2 parens, so += 2. m_depth += 2; if (m_depth>m_maxdepth) m_maxdepth=m_depth; nodep->iterateChildren(*this); m_depth -= 2; if (m_stmtp && (v3Global.opt.compLimitParens() >= 1) // Else compiler doesn't need it && (m_maxdepth-m_depth) > v3Global.opt.compLimitParens() && !nodep->backp()->castNodeStmt() // Not much point if we're about to use it ) { m_maxdepth = m_depth; createDeepTemp(nodep); } } //-------------------- // Marking of non-static functions (because they might need "this") // (Here just to avoid another iteration) void needNonStaticFunc(AstNode* nodep) { if (!m_funcp) nodep->v3fatalSrc("Non-static accessor not under a function"); if (m_funcp->isStatic()) { UINFO(5,"Mark non-public due to "<isStatic(false); } } virtual void visit(AstUCFunc* nodep, AstNUser*) { needNonStaticFunc(nodep); nodep->iterateChildren(*this); } virtual void visit(AstUCStmt* nodep, AstNUser*) { needNonStaticFunc(nodep); visitStmt(nodep); } //-------------------- // Default: Just iterate virtual void visit(AstVar* nodep, AstNUser*) {} // Don't hit varrefs under vars virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS DepthVisitor(AstNetlist* nodep) { m_modp=NULL; m_funcp=NULL; m_stmtp=NULL; m_depth=0; m_maxdepth=0; // nodep->accept(*this); } virtual ~DepthVisitor() {} }; //###################################################################### // Depth class functions void V3Depth::depthAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.874/src/V3AstNodes.h0000664000177100017500000072643312525247644016446 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Ast node structure // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3ASTNODES_H_ #define _V3ASTNODES_H_ 1 #ifndef _V3AST_H_ #error "Use V3Ast.h as the include" #endif //###################################################################### // Standard defines for all AstNode final classes #define ASTNODE_NODE_FUNCS(name,ucname) \ virtual ~Ast ##name() {} \ virtual AstType type() const { return AstType::at ##ucname; } \ virtual AstNode* clone() { return new Ast ##name (*this); } \ virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); } \ Ast ##name * cloneTree(bool cloneNext) { return AstNode::cloneTree(cloneNext)->cast ##name(); } //###################################################################### //=== Ast* : Specific types // Netlist interconnect class AstConst : public AstNodeMath { // A constant private: V3Number m_num; // Constant value public: AstConst(FileLine* fl, const V3Number& num) :AstNodeMath(fl) ,m_num(num) { if (m_num.isDouble()) { dtypeSetDouble(); } else if (m_num.isString()) { dtypeSetString(); } else { dtypeSetLogicSized(m_num.width(), m_num.sized()?0:m_num.widthMin(), m_num.isSigned() ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); } } AstConst(FileLine* fl, uint32_t num) :AstNodeMath(fl) ,m_num(V3Number(fl,32,num)) { dtypeSetLogicSized(m_num.width(), m_num.sized()?0:m_num.widthMin(), AstNumeric::UNSIGNED); } class Unsized32 {}; // for creator type-overload selection AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value :AstNodeMath(fl) ,m_num(V3Number(fl,32,num)) { m_num.width(32,false); dtypeSetLogicSized(32,m_num.widthMin(), AstNumeric::UNSIGNED); } class Signed32 {}; // for creator type-overload selection AstConst(FileLine* fl, Signed32, int32_t num) // Signed 32-bit integer of specified value :AstNodeMath(fl) ,m_num(V3Number(fl,32,num)) { m_num.width(32,32); dtypeSetLogicSized(32,m_num.widthMin(), AstNumeric::SIGNED); } class RealDouble {}; // for creator type-overload selection AstConst(FileLine* fl, RealDouble, double num) :AstNodeMath(fl) ,m_num(V3Number(fl,64)) { m_num.setDouble(num); dtypeSetDouble(); } class String {}; // for creator type-overload selection AstConst(FileLine* fl, String, const string& num) :AstNodeMath(fl) ,m_num(V3Number(V3Number::String(), fl, num)) { dtypeSetString(); } class LogicFalse {}; AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, know the dtype should be a logic of size 1 :AstNodeMath(fl) ,m_num(V3Number(fl,1,0)) { dtypeSetLogicBool(); } class LogicTrue {}; AstConst(FileLine* fl, LogicTrue) // Shorthand const 1, know the dtype should be a logic of size 1 :AstNodeMath(fl) ,m_num(V3Number(fl,1,1)) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Const, CONST) virtual string name() const { return num().ascii(); } // * = Value virtual const V3Number& num() const { return m_num; } // * = Value uint32_t toUInt() const { return num().toUInt(); } vlsint32_t toSInt() const { return num().toSInt(); } vluint64_t toUQuad() const { return num().toUQuad(); } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } virtual V3Hash sameHash() const { return V3Hash(num().toHash()); } virtual bool same(AstNode* samep) const { return num().isCaseEq(samep->castConst()->num()); } virtual int instrCount() const { return widthInstrs(); } bool isEqAllOnes() const { return num().isEqAllOnes(width()); } bool isEqAllOnesV() const { return num().isEqAllOnes(widthMinV()); } }; class AstRange : public AstNode { // Range specification, for use under variables and cells private: bool m_littleEndian:1; // Bit vector is little endian public: AstRange(FileLine* fl, AstNode* msbp, AstNode* lsbp) :AstNode(fl) { m_littleEndian = false; setOp2p(msbp); setOp3p(lsbp); } AstRange(FileLine* fl, int msb, int lsb) :AstNode(fl) { m_littleEndian = false; setOp2p(new AstConst(fl,msb)); setOp3p(new AstConst(fl,lsb)); } AstRange(FileLine* fl, VNumRange range) :AstNode(fl) { m_littleEndian = range.littleEndian(); setOp2p(new AstConst(fl,range.hi())); setOp3p(new AstConst(fl,range.lo())); } ASTNODE_NODE_FUNCS(Range, RANGE) AstNode* msbp() const { return op2p()->castNode(); } // op2 = Msb expression AstNode* lsbp() const { return op3p()->castNode(); } // op3 = Lsb expression AstNode* leftp() const { return littleEndian()?lsbp():msbp(); } // How to show a declaration AstNode* rightp() const { return littleEndian()?msbp():lsbp(); } int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->toSInt():0); } int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->toSInt():0); } int elementsConst() const { return (msbConst()>lsbConst()) ? msbConst()-lsbConst()+1 : lsbConst()-msbConst()+1; } bool littleEndian() const { return m_littleEndian; } void littleEndian(bool flag) { m_littleEndian=flag; } virtual void dump(ostream& str); virtual string emitC() { V3ERROR_NA; return ""; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstGatePin : public AstNodeMath { // Possibly expand a gate primitive input pin value to match the range of the gate primitive public: AstGatePin(FileLine* fl, AstNode* lhsp, AstRange* rangep) : AstNodeMath(fl) { setOp1p(lhsp); setOp2p(rangep); } ASTNODE_NODE_FUNCS(GatePin, GATEPIN) virtual string emitVerilog() { return "%l"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } AstNode* exprp() const { return op1p(); } // op1 = Pin expression AstRange* rangep() const { return op2p()->castRange(); } // op2 = Range of pin }; //###################################################################### //==== Data Types class AstTypedef : public AstNode { private: string m_name; bool m_attrPublic; public: AstTypedef(FileLine* fl, const string& name, AstNode* attrsp, VFlagChildDType, AstNodeDType* dtp) : AstNode(fl), m_name(name) { childDTypep(dtp); // Only for parser addAttrsp(attrsp); dtypep(NULL); // V3Width will resolve m_attrPublic = false; } ASTNODE_NODE_FUNCS(Typedef, TYPEDEF) virtual void dump(ostream& str); AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } void addAttrsp(AstNode* nodep) { addNOp4p(nodep); } AstNode* attrsp() const { return op4p()->castNode(); } // op4 = Attributes during early parse // METHODS virtual string name() const { return m_name; } virtual bool maybePointedTo() const { return true; } virtual bool hasDType() const { return true; } void name(const string& flag) { m_name = flag; } bool attrPublic() const { return m_attrPublic; } void attrPublic(bool flag) { m_attrPublic = flag; } }; class AstTypedefFwd : public AstNode { // Forward declaration of a type; stripped after netlist parsing is complete private: string m_name; public: AstTypedefFwd(FileLine* fl, const string& name) : AstNode(fl), m_name(name) {} ASTNODE_NODE_FUNCS(TypedefFwd, TYPEDEFFWD) // METHODS virtual string name() const { return m_name; } }; class AstDefImplicitDType : public AstNodeDType { // For parsing enum/struct/unions that are declared with a variable rather than typedef // This allows "var enum {...} a,b" to share the enum definition for both variables // After link, these become typedefs private: string m_name; void* m_containerp; // In what scope is the name unique, so we can know what are duplicate definitions (arbitrary value) int m_uniqueNum; public: AstDefImplicitDType(FileLine* fl, const string& name, void* containerp, VFlagChildDType, AstNodeDType* dtp) : AstNodeDType(fl), m_name(name), m_containerp(containerp) { childDTypep(dtp); // Only for parser dtypep(NULL); // V3Width will resolve m_uniqueNum = uniqueNumInc(); } ASTNODE_NODE_FUNCS(DefImplicitDType, DEFIMPLICITDTYPE) virtual bool same(AstNode* samep) const { return m_uniqueNum==samep->castDefImplicitDType()->m_uniqueNum; } virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); } AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } void* containerp() const { return m_containerp; } // METHODS AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); } virtual string name() const { return m_name; } void name(const string& flag) { m_name = flag; } }; class AstPackArrayDType : public AstNodeArrayDType { // Array data type, ie "some_dtype var_name [2:0]" // Children: DTYPE (moved to refDTypep() in V3Width) // Children: RANGE (array bounds) public: AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep) : AstNodeArrayDType(fl) { childDTypep(dtp); // Only for parser refDTypep(NULL); setOp2p(rangep); dtypep(NULL); // V3Width will resolve int width = subDTypep()->width() * rangep->elementsConst(); widthForce(width,width); } AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep) : AstNodeArrayDType(fl) { refDTypep(dtp); setOp2p(rangep); dtypep(this); int width = subDTypep()->width() * rangep->elementsConst(); widthForce(width,width); } ASTNODE_NODE_FUNCS(PackArrayDType, PACKARRAYDTYPE) }; class AstUnpackArrayDType : public AstNodeArrayDType { // Array data type, ie "some_dtype var_name [2:0]" // Children: DTYPE (moved to refDTypep() in V3Width) // Children: RANGE (array bounds) public: AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep) : AstNodeArrayDType(fl) { childDTypep(dtp); // Only for parser refDTypep(NULL); setOp2p(rangep); dtypep(NULL); // V3Width will resolve // For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type widthFromSub(subDTypep()); } AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep) : AstNodeArrayDType(fl) { refDTypep(dtp); setOp2p(rangep); dtypep(this); // For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type widthFromSub(subDTypep()); } ASTNODE_NODE_FUNCS(UnpackArrayDType, UNPACKARRAYDTYPE) }; class AstBasicDType : public AstNodeDType { // Builtin atomic/vectored data type // Children: RANGE (converted to constant in V3Width) private: struct Members { AstBasicDTypeKwd m_keyword; // (also in VBasicTypeKey) What keyword created basic type VNumRange m_nrange; // (also in VBasicTypeKey) Numeric msb/lsb (if non-opaque keyword) bool operator== (const Members& rhs) const { return rhs.m_keyword == m_keyword && rhs.m_nrange == m_nrange; } } m; // See also in AstNodeDtype: m_width, m_widthMin, m_numeric(issigned) public: AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, VSignedState signst=signedst_NOSIGN) : AstNodeDType(fl) { init(kwd, AstNumeric(signst), 0, -1, NULL); } AstBasicDType(FileLine* fl, VFlagLogicPacked, int wantwidth) : AstNodeDType(fl) { init(AstBasicDTypeKwd::LOGIC, AstNumeric::NOSIGN, wantwidth, -1, NULL); } AstBasicDType(FileLine* fl, VFlagBitPacked, int wantwidth) : AstNodeDType(fl) { init(AstBasicDTypeKwd::BIT, AstNumeric::NOSIGN, wantwidth, -1, NULL); } AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstNumeric numer, int wantwidth, int widthmin) : AstNodeDType(fl) { init(kwd, numer, wantwidth, widthmin, NULL); } AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstNumeric numer, VNumRange range, int widthmin) : AstNodeDType(fl) { init(kwd, numer, range.elements(), widthmin, NULL); m.m_nrange = range; // as init() presumes lsb==0, but range.lsb() might not be } // See also addRange in verilog.y private: void init(AstBasicDTypeKwd kwd, AstNumeric numer, int wantwidth, int wantwidthmin, AstRange* rangep) { // wantwidth=0 means figure it out, but if a widthmin is >=0 // we allow width 0 so that {{0{x}},y} works properly // wantwidthmin=-1: default, use wantwidth if it is non zero m.m_keyword = kwd; // Implicitness: // "parameter X" is implicit and sized from initial value, "parameter reg x" not if (keyword()==AstBasicDTypeKwd::LOGIC_IMPLICIT) { if (rangep || wantwidth) m.m_keyword = AstBasicDTypeKwd::LOGIC; } if (numer == AstNumeric::NOSIGN) { if (keyword().isSigned()) numer = AstNumeric::SIGNED; else if (keyword().isUnsigned()) numer = AstNumeric::UNSIGNED; } numeric(numer); if (!rangep && (wantwidth || wantwidthmin>=0)) { // Constant width if (wantwidth>1) m.m_nrange.init(wantwidth-1, 0, false); int wmin = wantwidthmin>=0 ? wantwidthmin : wantwidth; widthForce(wantwidth, wmin); } else if (!rangep) { // Set based on keyword properties // V3Width will pull from this width if (keyword().width() > 1 && !isOpaque()) { m.m_nrange.init(keyword().width()-1, 0, false); } widthForce(keyword().width(), keyword().width()); } else { widthForce(rangep->elementsConst(), rangep->elementsConst()); // Maybe unknown if parameters underneath it } setNOp1p(rangep); dtypep(this); } public: ASTNODE_NODE_FUNCS(BasicDType, BASICDTYPE) virtual void dump(ostream& str); virtual V3Hash sameHash() const { return V3Hash(V3Hash(m.m_keyword), V3Hash(m.m_nrange.hi())); } virtual bool same(AstNode* samep) const { // width/widthMin/numeric compared elsewhere return samep->castBasicDType()->m == m; } virtual string name() const { return m.m_keyword.ascii(); } virtual const char* broken() const { BROKEN_RTN(dtypep()!=this); return NULL; } AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable void rangep(AstRange* nodep) { setNOp1p(nodep); } void setSignedState(VSignedState signst) { // Note NOSIGN does NOT change the state; this is required by the parser if (signst==signedst_UNSIGNED) numeric(VSignedState(signst)); else if (signst==signedst_SIGNED) numeric(VSignedState(signst)); } // METHODS virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... AstBasicDTypeKwd keyword() const { return m.m_keyword; } // Avoid using - use isSomething accessors instead bool isBitLogic() const { return keyword().isBitLogic(); } bool isDouble() const { return keyword().isDouble(); } bool isOpaque() const { return keyword().isOpaque(); } bool isString() const { return keyword().isString(); } bool isSloppy() const { return keyword().isSloppy(); } bool isZeroInit() const { return keyword().isZeroInit(); } bool isRanged() const { return rangep() || m.m_nrange.ranged(); } const VNumRange& nrange() const { return m.m_nrange; } // Generally the msb/lsb/etc funcs should be used instead int msb() const { return (rangep() ? rangep()->msbConst() : m.m_nrange.hi()); } int lsb() const { return (rangep() ? rangep()->lsbConst() : m.m_nrange.lo()); } int left() const { return littleEndian()?lsb():msb(); } // How to show a declaration int right() const { return littleEndian()?msb():lsb(); } bool littleEndian() const { return (rangep() ? rangep()->littleEndian() : m.m_nrange.littleEndian()); } bool implicit() const { return keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT; } VNumRange declRange() const { return isRanged() ? VNumRange(msb(), lsb(), littleEndian()) : VNumRange(); } void cvtRangeConst() { // Convert to smaller represenation if (rangep() && rangep()->msbp()->castConst() && rangep()->lsbp()->castConst()) { m.m_nrange.init(rangep()->msbConst(), rangep()->lsbConst(), rangep()->littleEndian()); rangep()->unlinkFrBackWithNext()->deleteTree(); rangep(NULL); } } }; class AstConstDType : public AstNodeDType { // const data type, ie "const some_dtype var_name [2:0]" // ConstDType are removed in V3LinkLValue and become AstVar::isConst. // When more generic types are supported AstConstDType will be propagated further. private: AstNodeDType* m_refDTypep; // Inherit from this base data type public: AstConstDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp) : AstNodeDType(fl) { childDTypep(dtp); // Only for parser refDTypep(NULL); // V3Width will resolve dtypep(NULL); // V3Width will resolve widthFromSub(subDTypep()); } ASTNODE_NODE_FUNCS(ConstDType, CONSTDTYPE) virtual const char* broken() const { BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists()) || (!m_refDTypep && childDTypep()))); return NULL; } virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) { m_refDTypep = m_refDTypep->clonep()->castNodeDType(); }} virtual bool same(AstNode* samep) const { return (m_refDTypep==samep->castConstDType()->m_refDTypep); } virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); } // node's type() included elsewhere AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } // METHODS virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } }; class AstIfaceRefDType : public AstNodeDType { // Reference to an interface, either for a port, or inside parent cell private: string m_cellName; // "" = no cell, such as when connects to 'input' iface string m_ifaceName; // Interface name string m_modportName; // "" = no modport AstIface* m_ifacep; // Pointer to interface; note cellp() should override AstCell* m_cellp; // When exact parent cell known; not a guess AstModport* m_modportp; // NULL = unlinked or no modport public: AstIfaceRefDType(FileLine* fl, const string& cellName, const string& ifaceName) : AstNodeDType(fl), m_cellName(cellName), m_ifaceName(ifaceName), m_modportName(""), m_ifacep(NULL), m_cellp(NULL), m_modportp(NULL) { } AstIfaceRefDType(FileLine* fl, const string& cellName, const string& ifaceName, const string& modport) : AstNodeDType(fl), m_cellName(cellName), m_ifaceName(ifaceName), m_modportName(modport), m_ifacep(NULL), m_cellp(NULL), m_modportp(NULL) { } ASTNODE_NODE_FUNCS(IfaceRefDType, IFACEREFDTYPE) // METHODS virtual const char* broken() const; virtual void dump(ostream& str=cout); virtual void dumpSmall(ostream& str); virtual void cloneRelink(); virtual AstBasicDType* basicp() const { return NULL; } virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return 1; } virtual int widthTotalBytes() const { return 1; } string cellName() const { return m_cellName; } void cellName(const string& name) { m_cellName=name; } string ifaceName() const { return m_ifaceName; } void ifaceName(const string& name) { m_ifaceName=name; } string modportName() const { return m_modportName; } void modportName(const string& name) { m_modportName=name; } AstIface* ifaceViaCellp() const; // Use cellp or ifacep AstIface* ifacep() const { return m_ifacep; } void ifacep(AstIface* nodep) { m_ifacep=nodep; } AstCell* cellp() const { return m_cellp; } void cellp(AstCell* nodep) { m_cellp=nodep; } AstModport* modportp() const { return m_modportp; } void modportp(AstModport* modportp) { m_modportp=modportp; } bool isModport() { return !m_modportName.empty(); } }; class AstRefDType : public AstNodeDType { private: AstNodeDType* m_refDTypep; // data type pointed to, BELOW the AstTypedef string m_name; // Name of an AstTypedef AstPackage* m_packagep; // Package hierarchy public: AstRefDType(FileLine* fl, const string& name) : AstNodeDType(fl), m_refDTypep(NULL), m_name(name), m_packagep(NULL) {} AstRefDType(FileLine* fl, AstNodeDType* defp) : AstNodeDType(fl), m_refDTypep(defp), m_packagep(NULL) { dtypeFrom(defp->dtypep()); widthFromSub(subDTypep()); } ASTNODE_NODE_FUNCS(RefDType, REFDTYPE) // METHODS virtual const char* broken() const { BROKEN_RTN(m_refDTypep && !m_refDTypep->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) { m_refDTypep = m_refDTypep->clonep()->castNodeDType(); }} virtual bool same(AstNode* samep) const { return (m_refDTypep==samep->castRefDType()->m_refDTypep && m_name==samep->castRefDType()->m_name && m_packagep==samep->castRefDType()->m_packagep); } virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(m_packagep)); } virtual void dump(ostream& str=cout); virtual string name() const { return m_name; } virtual AstBasicDType* basicp() const { return subDTypep() ? subDTypep()->basicp() : NULL; } virtual AstNodeDType* skipRefp() const { // Skip past both the Ref and the Typedef if (defp()) return defp()->skipRefp(); else { v3fatalSrc("Typedef not linked"); return NULL; } } virtual AstNodeDType* skipRefToConstp() const { if (defp()) return defp()->skipRefToConstp(); else { v3fatalSrc("Typedef not linked"); return NULL; } } virtual AstNodeDType* skipRefToEnump() const { if (defp()) return defp()->skipRefToEnump(); else { v3fatalSrc("Typedef not linked"); return NULL; } } virtual int widthAlignBytes() const { return dtypeSkipRefp()->widthAlignBytes(); } virtual int widthTotalBytes() const { return dtypeSkipRefp()->widthTotalBytes(); } void name(const string& flag) { m_name = flag; } AstNodeDType* dtypeSkipRefp() const { return defp()->skipRefp(); } // op1 = Range of variable AstNodeDType* defp() const { return m_refDTypep; } // Code backward compatibility name for refDTypep AstNodeDType* refDTypep() const { return m_refDTypep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep=nodep; } virtual AstNodeDType* virtRefDTypep() const { return refDTypep(); } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } AstNodeDType* subDTypep() const { return m_refDTypep; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; class AstStructDType : public AstNodeClassDType { public: AstStructDType(FileLine* fl, AstNumeric numericUnpack) : AstNodeClassDType(fl,numericUnpack) {} ASTNODE_NODE_FUNCS(StructDType, STRUCTDTYPE) virtual string verilogKwd() const { return "struct"; }; }; class AstUnionDType : public AstNodeClassDType { public: //UNSUP: bool isTagged; AstUnionDType(FileLine* fl, AstNumeric numericUnpack) : AstNodeClassDType(fl,numericUnpack) {} ASTNODE_NODE_FUNCS(UnionDType, UNIONDTYPE) virtual string verilogKwd() const { return "union"; }; }; class AstMemberDType : public AstNodeDType { // A member of a struct/union // PARENT: AstClassDType private: AstNodeDType* m_refDTypep; // Elements of this type (after widthing) string m_name; // Name of variable 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: AstMemberDType(FileLine* fl, const string& name, VFlagChildDType, AstNodeDType* dtp) : AstNodeDType(fl) , m_name(name), m_lsb(-1) { childDTypep(dtp); // Only for parser dtypep(NULL); // V3Width will resolve refDTypep(NULL); } AstMemberDType(FileLine* fl, const string& name, AstNodeDType* dtp) : AstNodeDType(fl) , m_name(name), m_lsb(-1) { UASSERT(dtp,"AstMember created with no dtype"); refDTypep(dtp); dtypep(this); widthFromSub(subDTypep()); } ASTNODE_NODE_FUNCS(MemberDType, MEMBERDTYPE) virtual string name() const { return m_name; } // * = Var name virtual bool hasDType() const { return true; } virtual bool maybePointedTo() const { return true; } AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } // virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType) AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType) virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); } virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) 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; } int lsb() const { return m_lsb; } void lsb(int lsb) { m_lsb=lsb; } }; class AstEnumItem : public AstNode { private: string m_name; public: // Parents: ENUM AstEnumItem(FileLine* fl, const string& name, AstNode* rangep, AstNode* initp) : AstNode(fl), m_name(name) { addNOp1p(rangep); addNOp2p(initp); } ASTNODE_NODE_FUNCS(EnumItem, ENUMITEM) virtual string name() const { return m_name; } virtual bool maybePointedTo() const { return true; } virtual bool hasDType() const { return true; } void name(const string& flag) { m_name = flag; } AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range for name appending void rangep(AstNode* nodep) { addOp1p(nodep); } AstNode* valuep() const { return op2p(); } // op2 = Value void valuep(AstNode* nodep) { addOp2p(nodep); } }; class AstEnumItemRef : public AstNodeMath { private: AstEnumItem* m_itemp; // [AfterLink] Pointer to item AstPackage* m_packagep; // Package hierarchy public: AstEnumItemRef(FileLine* fl, AstEnumItem* itemp, AstPackage* packagep) : AstNodeMath(fl), m_itemp(itemp), m_packagep(packagep) { dtypeFrom(m_itemp); } ASTNODE_NODE_FUNCS(EnumItemRef, ENUMITEMREF) virtual void dump(ostream& str); virtual string name() const { return itemp()->name(); } virtual const char* broken() const { BROKEN_RTN(!itemp()); return NULL; } virtual int instrCount() const { return 0; } virtual void cloneRelink() { if (m_itemp->clonep()) m_itemp = m_itemp->clonep()->castEnumItem(); } virtual bool same(AstNode* samep) const { return itemp()==samep->castEnumItemRef()->itemp(); } AstEnumItem* itemp() const { return m_itemp; } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; class AstEnumDType : public AstNodeDType { // Parents: TYPEDEF/MODULE // Children: ENUMVALUEs private: AstNodeDType* m_refDTypep; // Elements are of this type after V3Width int m_uniqueNum; public: AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* itemsp) : AstNodeDType(fl) { childDTypep(dtp); // Only for parser refDTypep(NULL); addNOp2p(itemsp); dtypep(NULL); // V3Width will resolve widthFromSub(subDTypep()); m_uniqueNum = uniqueNumInc(); } ASTNODE_NODE_FUNCS(EnumDType, ENUMDTYPE) virtual const char* broken() const { BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists()) || (!m_refDTypep && childDTypep()))); return NULL; } virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) { m_refDTypep = m_refDTypep->clonep()->castNodeDType(); }} virtual bool same(AstNode* samep) const { return m_uniqueNum==samep->castEnumDType()->m_uniqueNum; } virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); } AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Data type void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } // op1 = Range of variable void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } AstEnumItem* itemsp() const { return op2p()->castEnumItem(); } // op2 = AstEnumItem's void addValuesp(AstNode* nodep) { addOp2p(nodep); } // METHODS virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); } virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } }; //###################################################################### class AstArraySel : public AstNodeSel { // Parents: math|stmt // Children: varref|arraysel, math private: unsigned m_start; unsigned m_length; void init(AstNode* fromp) { if (fromp && fromp->dtypep()->skipRefp()->castNodeArrayDType()) { // Strip off array to find what array references dtypeFrom(fromp->dtypep()->skipRefp()->castNodeArrayDType()->subDTypep()); } } public: AstArraySel(FileLine* fl, AstNode* fromp, AstNode* bitp) :AstNodeSel(fl, fromp, bitp), m_start(0), m_length(1) { init(fromp); } AstArraySel(FileLine* fl, AstNode* fromp, int bit) :AstNodeSel(fl, fromp, new AstConst(fl,bit)), m_start(0), m_length(1) { init(fromp); } ASTNODE_NODE_FUNCS(ArraySel, ARRAYSEL) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; /* How can from be a const? */ } virtual string emitVerilog() { return "%k(%l%f[%r])"; } virtual string emitC() { return "%li%k[%ri]"; } virtual bool cleanOut() { return true; } virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } virtual int instrCount() const { return widthInstrs(); } unsigned length() const { return m_length; } void length(unsigned length) { m_length = length; } void start(unsigned start) { m_start = start; } unsigned start() const { return m_start; } // Special operators static AstNode* baseFromp(AstNode* nodep); ///< What is the base variable (or const) this dereferences? virtual void dump(ostream& str); }; class AstWordSel : public AstNodeSel { // Select a single word from a multi-word wide value public: AstWordSel(FileLine* fl, AstNode* fromp, AstNode* bitp) :AstNodeSel(fl, fromp, bitp) { dtypeSetUInt32(); // Always used on IData arrays so returns word entities } ASTNODE_NODE_FUNCS(WordSel, WORDSEL) virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) { V3ERROR_NA; } virtual string emitVerilog() { return "%k(%l%f[%r])"; } virtual string emitC() { return "%li[%ri]"; } // Not %k, as usually it's a small constant rhsp virtual bool cleanOut() { return true; } virtual bool cleanLhs() { return true; } virtual bool cleanRhs() { return true; } virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstSelExtract : public AstNodePreSel { // Range extraction, gets replaced with AstSel public: AstSelExtract(FileLine* fl, AstNode* fromp, AstNode* msbp, AstNode* lsbp) : AstNodePreSel(fl, fromp, msbp, lsbp) {} ASTNODE_NODE_FUNCS(SelExtract, SELEXTRACT) AstNode* msbp() const { return rhsp(); } AstNode* lsbp() const { return thsp(); } }; class AstSelBit : public AstNodePreSel { // Single bit range extraction, perhaps with non-constant selection or array selection // Gets replaced during link with AstArraySel or AstSel public: AstSelBit(FileLine* fl, AstNode* fromp, AstNode* bitp) :AstNodePreSel(fl, fromp, bitp, NULL) { if (v3Global.assertDTypesResolved()) { v3fatalSrc("not coded to create after dtypes resolved"); } } ASTNODE_NODE_FUNCS(SelBit, SELBIT) AstNode* bitp() const { return rhsp(); } }; class AstSelPlus : public AstNodePreSel { // +: range extraction, perhaps with non-constant selection // Gets replaced during link with AstSel public: AstSelPlus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp) :AstNodePreSel(fl, fromp, bitp, widthp) {} ASTNODE_NODE_FUNCS(SelPlus, SELPLUS) AstNode* bitp() const { return rhsp(); } AstNode* widthp() const { return thsp(); } }; class AstSelMinus : public AstNodePreSel { // -: range extraction, perhaps with non-constant selection // Gets replaced during link with AstSel public: AstSelMinus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp) :AstNodePreSel(fl, fromp, bitp, widthp) {} ASTNODE_NODE_FUNCS(SelMinus, SELMINUS) AstNode* bitp() const { return rhsp(); } AstNode* widthp() const { return thsp(); } }; class AstSel : public AstNodeTriop { // Multiple bit range extraction // Parents: math|stmt // Children: varref|arraysel, math, constant math // Tempting to have an lvalue() style method here as LHS selects are quite // different, but that doesn't play well with V3Inst and bidirects which don't know direction private: VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid int m_declElWidth; // If a packed array, the number of bits per element public: AstSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, AstNode* widthp) :AstNodeTriop(fl, fromp, lsbp, widthp) { m_declElWidth = 1; if (widthp->castConst()) { dtypeSetLogicSized(widthp->castConst()->toUInt(), widthp->castConst()->toUInt(), AstNumeric::UNSIGNED); } } AstSel(FileLine* fl, AstNode* fromp, int lsb, int bitwidth) :AstNodeTriop(fl, fromp, new AstConst(fl,lsb), new AstConst(fl,bitwidth)) { m_declElWidth = 1; dtypeSetLogicSized(bitwidth,bitwidth,AstNumeric::UNSIGNED); } ASTNODE_NODE_FUNCS(Sel, SEL) virtual void dump(ostream& str); virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit, const V3Number& width) { out.opSel(from, bit.toUInt()+width.toUInt()-1, bit.toUInt()); } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { return this->widthp()->isOne() ? "VL_BITSEL_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri)" : "VL_SEL_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; } virtual bool cleanOut() { return false; } virtual bool cleanLhs() { return true;} virtual bool cleanRhs() {return true;} virtual bool cleanThs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool sizeMattersThs() {return false;} virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode*) const { return true; } virtual int instrCount() const { return widthInstrs()*(lsbp()->castConst()?3:10); } AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing) AstNode* lsbp() const { return op2p()->castNode(); } // op2 = Msb selection expression AstNode* widthp() const { return op3p()->castNode(); } // op3 = Width int widthConst() const { return widthp()->castConst()->toSInt(); } int lsbConst() const { return lsbp()->castConst()->toSInt(); } int msbConst() const { return lsbConst()+widthConst()-1; } VNumRange& declRange() { return m_declRange; } void declRange(const VNumRange& flag) { m_declRange = flag; } int declElWidth() const { return m_declElWidth; } void declElWidth(int flag) { m_declElWidth = flag; } }; class AstMemberSel : public AstNodeMath { // Parents: math|stmt // Children: varref|arraysel, math private: // Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it string m_name; public: AstMemberSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name) : AstNodeMath(fl), m_name(name) { setOp1p(fromp); dtypep(NULL); // V3Width will resolve } AstMemberSel(FileLine* fl, AstNode* fromp, AstMemberDType* dtp) : AstNodeMath(fl) { setOp1p(fromp); dtypep(dtp); m_name = dtp->name(); } ASTNODE_NODE_FUNCS(MemberSel, MEMBERSEL) virtual string name() const { return m_name; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; /* How can from be a const? */ } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return false; } virtual bool same(AstNode* samep) const { return true; } // dtype comparison does it all for us virtual int instrCount() const { return widthInstrs(); } AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing) void fromp(AstNode* nodep) { setOp1p(nodep); } }; class AstMethodSel : public AstNode { // A reference to a member task (or function) // We do not support generic member calls yet, so this is only enough to make built-in methods work private: string m_name; // Name of variable public: AstMethodSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name, AstNode* pinsp) : AstNode(fl), m_name(name) { setOp1p(fromp); dtypep(NULL); // V3Width will resolve addNOp2p(pinsp); } AstMethodSel(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp) :AstNode(fl), m_name(name) { setOp1p(fromp); addNOp2p(pinsp); } ASTNODE_NODE_FUNCS(MethodSel, METHODSEL) virtual string name() const { return m_name; } // * = Var name virtual void name(const string& name) { m_name = name; } AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing) void fromp(AstNode* nodep) { setOp1p(nodep); } AstNode* pinsp() const { return op2p()->castNode(); } // op2 = Pin interconnection list void addPinsp(AstNode* nodep) { addOp2p(nodep); } }; class AstVar : public AstNode { // A variable (in/out/wire/reg/param) inside a module private: string m_name; // Name of variable string m_origName; // Original name before dot addition AstVarType m_varType; // Type of variable bool m_input:1; // Input or inout bool m_output:1; // Output or inout bool m_tristate:1; // Inout or triwire or trireg bool m_declOutput:1; // Inout or output before tristate resolution bool m_primaryIO:1; // In/out to top level (or directly assigned from same) bool m_sc:1; // SystemC variable bool m_scClocked:1; // SystemC sc_clk<> needed bool m_scSensitive:1;// SystemC sensitive() needed bool m_sigPublic:1; // User C code accesses this signal or is top signal bool m_sigModPublic:1;// User C code accesses this signal and module bool m_sigUserRdPublic:1; // User C code accesses this signal, read only bool m_sigUserRWPublic:1; // User C code accesses this signal, read-write bool m_usedClock:1; // Signal used as a clock bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup) bool m_usedLoopIdx:1; // Variable subject of for unrolling bool m_funcLocal:1; // Local variable for a function bool m_funcReturn:1; // Return variable for a function bool m_attrClockEn:1;// User clock enable attribute bool m_attrScBv:1; // User force bit vector attribute bool m_attrIsolateAssign:1;// User isolate_assignments attribute bool m_attrSFormat:1;// User sformat attribute bool m_fileDescr:1; // File descriptor bool m_isConst:1; // Table contains constant data bool m_isStatic:1; // Static variable bool m_isPulldown:1; // Tri0 bool m_isPullup:1; // Tri1 bool m_isIfaceParent:1; // dtype is reference to interface present in this module bool m_noSubst:1; // Do not substitute out references bool m_trace:1; // Trace this variable AstVarAttrClocker m_attrClocker; void init() { m_input=false; m_output=false; m_tristate=false; m_declOutput=false; m_primaryIO=false; m_sc=false; m_scClocked=false; m_scSensitive=false; m_usedClock=false; m_usedParam=false; m_usedLoopIdx=false; m_sigPublic=false; m_sigModPublic=false; m_sigUserRdPublic=false; m_sigUserRWPublic=false; m_funcLocal=false; m_funcReturn=false; m_attrClockEn=false; m_attrScBv=false; m_attrIsolateAssign=false; m_attrSFormat=false; m_fileDescr=false; m_isConst=false; m_isStatic=false; m_isPulldown=false; m_isPullup=false; m_isIfaceParent=false; m_attrClocker=AstVarAttrClocker::CLOCKER_UNKNOWN; m_noSubst=false; m_trace=false; } public: AstVar(FileLine* fl, AstVarType type, const string& name, VFlagChildDType, AstNodeDType* dtp) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); childDTypep(dtp); // Only for parser dtypep(NULL); // V3Width will resolve } AstVar(FileLine* fl, AstVarType type, const string& name, AstNodeDType* dtp) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); UASSERT(dtp,"AstVar created with no dtype"); dtypep(dtp); } AstVar(FileLine* fl, AstVarType type, const string& name, VFlagLogicPacked, int wantwidth) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED); } AstVar(FileLine* fl, AstVarType type, const string& name, VFlagBitPacked, int wantwidth) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); dtypeSetLogicSized(wantwidth,wantwidth,AstNumeric::UNSIGNED); } AstVar(FileLine* fl, AstVarType type, const string& name, AstVar* examplep) :AstNode(fl) , m_name(name), m_origName(name) { init(); combineType(type); if (examplep->childDTypep()) { childDTypep(examplep->childDTypep()->cloneTree(true)); } dtypeFrom(examplep); } ASTNODE_NODE_FUNCS(Var, VAR) virtual void dump(ostream& str); virtual string name() const { return m_name; } // * = Var name virtual bool hasDType() const { return true; } virtual bool maybePointedTo() const { return true; } string origName() const { return m_origName; } // * = Original name void origName(const string& name) { m_origName = name; } AstVarType varType() const { return m_varType; } // * = Type of variable void varType(AstVarType type) { m_varType = type; } void varType2Out() { m_tristate=0; m_input=0; m_output=1; } void varType2In() { m_tristate=0; m_input=1; m_output=0; } string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv string cPubArgType(bool named, bool forReturn) const; // Return C /*public*/ type for argument: bool, uint32_t, uint64_t, etc. string dpiArgType(bool named, bool forReturn) const; // Return DPI-C type for argument string vlArgType(bool named, bool forReturn, bool forFunc) const; // Return Verilator internal type for argument: CData, SData, IData, WData string vlEnumType() const; // Return VerilatorVarType: VLVT_UINT32, etc string vlEnumDir() const; // Return VerilatorVarDir: VLVD_INOUT, etc void combineType(AstVarType type); AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType) AstNode* valuep() const { return op3p()->castNode(); } // op3 = Initial value that never changes (static const) void valuep(AstNode* nodep) { setOp3p(nodep); } // It's valuep, not constp, as may be more complicated than an AstConst void addAttrsp(AstNode* nodep) { addNOp4p(nodep); } AstNode* attrsp() const { return op4p()->castNode(); } // op4 = Attributes during early parse void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } void attrClockEn(bool flag) { m_attrClockEn = flag; } void attrClocker(AstVarAttrClocker flag) { m_attrClocker = flag; } void attrFileDescr(bool flag) { m_fileDescr = flag; } void attrScClocked(bool flag) { m_scClocked = flag; } void attrScBv(bool flag) { m_attrScBv = flag; } void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; } void attrSFormat(bool flag) { m_attrSFormat = flag; } void usedClock(bool flag) { m_usedClock = flag; } void usedParam(bool flag) { m_usedParam = flag; } void usedLoopIdx(bool flag) { m_usedLoopIdx = flag; } void sigPublic(bool flag) { m_sigPublic = flag; } void sigModPublic(bool flag) { m_sigModPublic = flag; } void sigUserRdPublic(bool flag) { m_sigUserRdPublic = flag; if (flag) sigPublic(true); } void sigUserRWPublic(bool flag) { m_sigUserRWPublic = flag; if (flag) sigUserRdPublic(true); } void sc(bool flag) { m_sc = flag; } void scSensitive(bool flag) { m_scSensitive = flag; } void primaryIO(bool flag) { m_primaryIO = flag; } void isConst(bool flag) { m_isConst = flag; } void isStatic(bool flag) { m_isStatic = flag; } void isIfaceParent(bool flag) { m_isIfaceParent = flag; } void funcLocal(bool flag) { m_funcLocal = flag; } void funcReturn(bool flag) { m_funcReturn = flag; } void noSubst(bool flag) { m_noSubst=flag; } bool noSubst() const { return m_noSubst; } void trace(bool flag) { m_trace=flag; } // METHODS virtual void name(const string& name) { m_name = name; } virtual string directionName() const { return (isInout() ? "inout" : isInput() ? "input" : isOutput() ? "output" : varType().ascii()); } bool isInput() const { return m_input; } bool isOutput() const { return m_output; } bool isInOnly() const { return m_input && !m_output; } bool isOutOnly() const { return m_output && !m_input; } bool isInout() const { return m_input && m_output; } bool isTristate() const { return m_tristate; } bool isDeclOutput() const { return m_declOutput; } bool isPrimaryIO() const { return m_primaryIO; } bool isPrimaryIn() const { return isPrimaryIO() && isInput(); } bool isIO() const { return (m_input||m_output); } bool isIfaceRef() const { return (varType()==AstVarType::IFACEREF); } bool isIfaceParent() const { return m_isIfaceParent; } bool isSignal() const { return varType().isSignal(); } bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP || varType()==AstVarType::STMTTEMP || varType()==AstVarType::XTEMP); } bool isToggleCoverable() const { return ((isIO() || isSignal()) && (isIO() || isBitLogic()) // Wrapper would otherwise duplicate wrapped module's coverage && !isSc() && !isPrimaryIO() && !isConst()); } bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); } bool isMovableToBlock() const { return (varType()==AstVarType::BLOCKTEMP || isFuncLocal()); } bool isXTemp() const { return (varType()==AstVarType::XTEMP); } bool isParam() const { return (varType()==AstVarType::LPARAM || varType()==AstVarType::GPARAM); } bool isGParam() const { return (varType()==AstVarType::GPARAM); } bool isGenVar() const { return (varType()==AstVarType::GENVAR); } bool isBitLogic() const { AstBasicDType* bdtypep = basicp(); return bdtypep && bdtypep->isBitLogic(); } bool isUsedClock() const { return m_usedClock; } bool isUsedParam() const { return m_usedParam; } bool isUsedLoopIdx() const { return m_usedLoopIdx; } bool isSc() const { return m_sc; } bool isScQuad() const; bool isScBv() const; bool isScUint() const; bool isScBigUint() const; bool isScSensitive() const { return m_scSensitive; } bool isSigPublic() const; bool isSigModPublic() const { return m_sigModPublic; } bool isSigUserRdPublic() const { return m_sigUserRdPublic; } bool isSigUserRWPublic() const { return m_sigUserRWPublic; } bool isTrace() const { return m_trace; } bool isConst() const { return m_isConst; } bool isStatic() const { return m_isStatic; } bool isFuncLocal() const { return m_funcLocal; } bool isFuncReturn() const { return m_funcReturn; } bool isPullup() const { return m_isPullup; } bool isPulldown() const { return m_isPulldown; } bool attrClockEn() const { return m_attrClockEn; } bool attrScBv() const { return m_attrScBv; } bool attrFileDescr() const { return m_fileDescr; } bool attrScClocked() const { return m_scClocked; } bool attrSFormat() const { return m_attrSFormat; } bool attrIsolateAssign() const { return m_attrIsolateAssign; } AstVarAttrClocker attrClocker() const { return m_attrClocker; } virtual string verilogKwd() const; void propagateAttrFrom(AstVar* fromp) { // This is getting connected to fromp; keep attributes // Note the method below too if (fromp->attrClockEn()) attrClockEn(true); if (fromp->attrFileDescr()) attrFileDescr(true); if (fromp->attrIsolateAssign()) attrIsolateAssign(true); } bool gateMultiInputOptimizable() const { // Ok to gate optimize; must return false if propagateAttrFrom would do anything return (!attrClockEn() && !isUsedClock()); } void combineType(AstVar* typevarp) { // This is same as typevarp (for combining input & reg decls) propagateAttrFrom(typevarp); combineType(typevarp->varType()); if (typevarp->isSigPublic()) sigPublic(true); if (typevarp->isSigModPublic()) sigModPublic(true); if (typevarp->isSigUserRdPublic()) sigUserRdPublic(true); if (typevarp->isSigUserRWPublic()) sigUserRWPublic(true); if (typevarp->attrScClocked()) attrScClocked(true); } void inlineAttrReset(const string& name) { m_input=m_output=false; m_name = name; if (varType()==AstVarType::INOUT) m_varType = AstVarType::TRIWIRE; if (varType()==AstVarType::INPUT || varType()==AstVarType::OUTPUT) m_varType = AstVarType::WIRE; } static AstVar* scVarRecurse(AstNode* nodep); }; class AstDefParam : public AstNode { // A defparam assignment // Parents: MODULE // Children: math private: string m_name; // Name of variable getting set string m_path; // Dotted cellname to set parameter of public: AstDefParam(FileLine* fl, const string& path, const string& name, AstNode* rhsp) : AstNode(fl) { setOp1p(rhsp); m_name = name; m_path = path; } virtual string name() const { return m_name; } // * = Scope name ASTNODE_NODE_FUNCS(DefParam, DEFPARAM) virtual bool cleanRhs() { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode*) const { return true; } AstNode* rhsp() const { return op1p()->castNode(); } // op1 = Assign from string path() const { return m_path; } }; class AstImplicit : public AstNode { // Create implicit wires and do nothing else, for gates that are ignored // Parents: MODULE public: AstImplicit(FileLine* fl, AstNode* exprsp) : AstNode(fl) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(Implicit, IMPLICIT) AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Assign from }; class AstScope : public AstNode { // A particular usage of a cell // Parents: MODULE // Children: NODEBLOCK private: // An AstScope->name() is special: . indicates an uninlined scope, __DOT__ an inlined scope string m_name; // Name AstScope* m_aboveScopep; // Scope above this one in the hierarchy (NULL if top) AstCell* m_aboveCellp; // Cell above this in the hierarchy (NULL if top) AstNodeModule* m_modp; // Module scope corresponds to public: AstScope(FileLine* fl, AstNodeModule* modp, const string& name, AstScope* aboveScopep, AstCell* aboveCellp) :AstNode(fl) ,m_name(name) ,m_aboveScopep(aboveScopep) ,m_aboveCellp(aboveCellp), m_modp(modp) {} ASTNODE_NODE_FUNCS(Scope, SCOPE) virtual void cloneRelink(); virtual const char* broken() const; virtual bool maybePointedTo() const { return true; } virtual string name() const { return m_name; } // * = Scope name virtual void name(const string& name) { m_name = name; } string nameDotless() const; string nameVlSym() const { return (((string)"vlSymsp->") + nameDotless()); } AstNodeModule* modp() const { return m_modp; } void addVarp(AstNode* nodep) { addOp1p(nodep); } AstNode* varsp() const { return op1p()->castNode(); } // op1 = AstVarScope's void addActivep(AstNode* nodep) { addOp2p(nodep); } AstNode* blocksp() const { return op2p()->castNode(); } // op2 = Block names void addFinalClkp(AstNode* nodep) { addOp3p(nodep); } AstNode* finalClksp() const { return op3p()->castNode(); } // op3 = Final assigns for clock correction AstScope* aboveScopep() const { return m_aboveScopep; } AstCell* aboveCellp() const { return m_aboveCellp; } bool isTop() const { return aboveScopep()==NULL; } // At top of hierarchy }; class AstTopScope : public AstNode { // In the top level netlist, a complete scope tree // There may be two of these, when we support "rare" and "usual" splitting // Parents: topMODULE // Children: SCOPEs public: AstTopScope(FileLine* fl, AstScope* ascopep) :AstNode(fl) {addNOp2p(ascopep);} ASTNODE_NODE_FUNCS(TopScope, TOPSCOPE) AstNode* stmtsp() const { return op1p()->castNode(); } void addStmtsp(AstNode* nodep) { addOp1p(nodep); } AstScope* scopep() const { return op2p()->castScope(); } // op1 = AstVarScope's }; class AstVarScope : public AstNode { // A particular scoped usage of a variable // That is, as a module is used under multiple cells, we get a different varscope for each var in the module // Parents: MODULE // Children: none private: AstScope* m_scopep; // Scope variable is underneath AstVar* m_varp; // [AfterLink] Pointer to variable itself bool m_circular:1; // Used in circular ordering dependency, need change detect bool m_trace:1; // Tracing is turned on for this scope public: AstVarScope(FileLine* fl, AstScope* scopep, AstVar* varp) :AstNode(fl) , m_scopep(scopep), m_varp(varp) { m_circular = false; m_trace = true; dtypeFrom(varp); } ASTNODE_NODE_FUNCS(VarScope, VARSCOPE) virtual void cloneRelink() { if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep()->castVar(); UASSERT(m_scopep->clonep(), "No clone cross link: "<clonep()->castScope(); }} virtual const char* broken() const { BROKEN_RTN(m_varp && !m_varp->brokeExists()); BROKEN_RTN(m_scopep && !m_scopep->brokeExists()); return NULL; } virtual bool maybePointedTo() const { return true; } virtual string name() const {return scopep()->name()+"->"+varp()->name();} // * = Var name virtual void dump(ostream& str); virtual bool hasDType() const { return true; } AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable AstScope* scopep() const { return m_scopep; } // Pointer to scope it's under AstNode* valuep() const { return op1p(); } // op1 = Calculation of value of variable, NULL=complicated void valuep(AstNode* valuep) { addOp1p(valuep); } bool isCircular() const { return m_circular; } void circular(bool flag) { m_circular = flag; } bool isTrace() const { return m_trace; } void trace(bool flag) { m_trace = flag; } }; class AstVarRef : public AstNodeVarRef { // A reference to a variable (lvalue or rvalue) public: AstVarRef(FileLine* fl, const string& name, bool lvalue) :AstNodeVarRef(fl, name, NULL, lvalue) {} AstVarRef(FileLine* fl, AstVar* varp, bool lvalue) // This form only allowed post-link :AstNodeVarRef(fl, varp->name(), varp, lvalue) {} // because output/wire compression may lead to deletion of AstVar's AstVarRef(FileLine* fl, AstVarScope* varscp, bool lvalue) // This form only allowed post-link :AstNodeVarRef(fl, varscp->varp()->name(), varscp->varp(), lvalue) { // because output/wire compression may lead to deletion of AstVar's varScopep(varscp); } ASTNODE_NODE_FUNCS(VarRef, VARREF) virtual void dump(ostream& str); virtual V3Hash sameHash() const { return V3Hash(V3Hash(varp()->name()),V3Hash(hiername())); } virtual bool same(AstNode* samep) const { return same(samep->castVarRef()); } inline bool same(AstVarRef* samep) const { if (varScopep()) return (varScopep()==samep->varScopep() && lvalue()==samep->lvalue()); else return (hiername()==samep->hiername() && varp()->name()==samep->varp()->name() && lvalue()==samep->lvalue()); } inline bool sameNoLvalue(AstVarRef* samep) const { if (varScopep()) return (varScopep()==samep->varScopep()); else return (hiername()==samep->hiername() && varp()->name()==samep->varp()->name()); } virtual int instrCount() const { return widthInstrs()*(lvalue()?1:instrCountLd()); } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } }; class AstVarXRef : public AstNodeVarRef { // A VarRef to something in another module before AstScope. // Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope private: string m_dotted; // Scope name to connected to string m_inlinedDots; // Dotted hierarchy flattened out public: AstVarXRef(FileLine* fl, const string& name, const string& dotted, bool lvalue) :AstNodeVarRef(fl, name, NULL, lvalue) , m_dotted(dotted) { } AstVarXRef(FileLine* fl, AstVar* varp, const string& dotted, bool lvalue) :AstNodeVarRef(fl, varp->name(), varp, lvalue) , m_dotted(dotted) { dtypeFrom(varp); } ASTNODE_NODE_FUNCS(VarXRef, VARXREF) virtual void dump(ostream& str); string dotted() const { return m_dotted; } string prettyDotted() const { return prettyName(dotted()); } string inlinedDots() const { return m_inlinedDots; } void inlinedDots(const string& flag) { m_inlinedDots = flag; } virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(V3Hash(varp()),V3Hash(dotted())); } virtual bool same(AstNode* samep) const { return (hiername()==samep->castVarXRef()->hiername() && varp()==samep->castVarXRef()->varp() && name()==samep->castVarXRef()->name() && dotted()==samep->castVarXRef()->dotted()); } }; class AstPin : public AstNode { // A pin on a cell private: int m_pinNum; // Pin number string m_name; // Pin name, or "" for number based interconnect AstVar* m_modVarp; // Input/output this pin connects to on submodule. bool m_param; // Pin connects to parameter bool m_svImplicit; // Pin is SystemVerilog .name'ed public: AstPin(FileLine* fl, int pinNum, const string& name, AstNode* exprp) :AstNode(fl) ,m_name(name), m_param(false), m_svImplicit(false) { m_pinNum = pinNum; m_modVarp = NULL; setNOp1p(exprp); } AstPin(FileLine* fl, int pinNum, AstVarRef* varname, AstNode* exprp) :AstNode(fl), m_param(false), m_svImplicit(false) { m_name = varname->name(); m_pinNum = pinNum; m_modVarp = NULL; setNOp1p(exprp); } ASTNODE_NODE_FUNCS(Pin, PIN) virtual void dump(ostream& str); virtual const char* broken() const { BROKEN_RTN(m_modVarp && !m_modVarp->brokeExists()); return NULL; } virtual string name() const { return m_name; } // * = Pin name, ""=go by number virtual void name(const string& name) { m_name = name; } virtual string prettyOperatorName() const { return modVarp() ? (modVarp()->directionName()+" port connection '"+modVarp()->prettyName()+"'") : "port connection"; } 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, NULL if unconnected AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable void modVarp(AstVar* varp) { m_modVarp=varp; } bool param() const { return m_param; } void param(bool flag) { m_param=flag; } bool svImplicit() const { return m_svImplicit; } void svImplicit(bool flag) { m_svImplicit=flag; } }; class AstArg : public AstNode { // An argument to a function/task private: string m_name; // Pin name, or "" for number based interconnect public: AstArg(FileLine* fl, const string& name, AstNode* exprp) : AstNode(fl) ,m_name(name) { setNOp1p(exprp); } ASTNODE_NODE_FUNCS(Arg, ARG) virtual string name() const { return m_name; } // * = Pin name, ""=go by number virtual void name(const string& name) { m_name = name; } virtual V3Hash sameHash() const { return V3Hash(); } void exprp(AstNode* nodep) { addOp1p(nodep); } AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin, NULL if unconnected bool emptyConnectNoNext() const { return !exprp() && name()=="" && !nextp(); } }; class AstModule : public AstNodeModule { // A module declaration public: AstModule(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(Module, MODULE) virtual string verilogKwd() const { return "module"; } }; class AstNotFoundModule : public AstNodeModule { // A missing module declaration public: AstNotFoundModule(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(NotFoundModule, NOTFOUNDMODULE) virtual string verilogKwd() const { return "/*not-found-*/ module"; } }; class AstPackage : public AstNodeModule { // A package declaration public: AstPackage(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(Package, PACKAGE) virtual string verilogKwd() const { return "package"; } static string dollarUnitName() { return AstNode::encodeName("$unit"); } bool isDollarUnit() const { return name() == dollarUnitName(); } }; class AstPrimitive : public AstNodeModule { // A primitive declaration public: AstPrimitive(FileLine* fl, const string& name) : AstNodeModule (fl,name) {} ASTNODE_NODE_FUNCS(Primitive, PRIMITIVE) virtual string verilogKwd() const { return "primitive"; } }; class AstPackageImport : public AstNode { private: // A package import declaration string m_name; AstPackage* m_packagep; // Package hierarchy public: AstPackageImport(FileLine* fl, AstPackage* packagep, const string& name) : AstNode (fl), m_name(name), m_packagep(packagep) {} ASTNODE_NODE_FUNCS(PackageImport, PACKAGEIMPORT) virtual const char* broken() const { BROKEN_RTN(!m_packagep || !m_packagep->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep()->castPackage(); } virtual void dump(ostream& str); virtual string name() const { return m_name; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; class AstIface : public AstNodeModule { // A module declaration public: AstIface(FileLine* fl, const string& name) : AstNodeModule (fl,name) { } ASTNODE_NODE_FUNCS(Iface, IFACE) }; class AstModportFTaskRef : public AstNode { // An import/export referenced under a modport // The storage for the function itself is inside the interface/instantiator, thus this is a reference // PARENT: AstModport private: string m_name; // Name of the variable referenced bool m_export; // Type of the function (import/export) AstNodeFTask* m_ftaskp; // Link to the function public: AstModportFTaskRef(FileLine* fl, const string& name, bool isExport) : AstNode(fl), m_name(name), m_export(isExport), m_ftaskp(NULL) { } ASTNODE_NODE_FUNCS(ModportFTaskRef, MODPORTFTASKREF) virtual const char* broken() const { BROKEN_RTN(m_ftaskp && !m_ftaskp->brokeExists()); return NULL; } virtual void dump(ostream& str); virtual string name() const { return m_name; } virtual void cloneRelink() { if (m_ftaskp && m_ftaskp->clonep()) m_ftaskp = m_ftaskp->clonep()->castNodeFTask(); } bool isImport() const { return !m_export; } bool isExport() const { return m_export; } AstNodeFTask* ftaskp() const { return m_ftaskp; } // [After Link] Pointer to variable void ftaskp(AstNodeFTask* ftaskp) { m_ftaskp=ftaskp; } }; class AstModportVarRef : public AstNode { // A input/output/etc variable referenced under a modport // The storage for the variable itself is inside the interface, thus this is a reference // PARENT: AstModport private: string m_name; // Name of the variable referenced AstVarType m_type; // Type of the variable (in/out) AstVar* m_varp; // Link to the actual Var public: AstModportVarRef(FileLine* fl, const string& name, AstVarType::en type) : AstNode(fl), m_name(name), m_type(type), m_varp(NULL) { } ASTNODE_NODE_FUNCS(ModportVarRef, MODPORTVARREF) virtual const char* broken() const { BROKEN_RTN(m_varp && !m_varp->brokeExists()); return NULL; } virtual void dump(ostream& str); virtual void cloneRelink() { if (m_varp && m_varp->clonep()) m_varp = m_varp->clonep()->castVar(); } virtual string name() const { return m_name; } AstVarType varType() const { return m_type; } // * = Type of variable bool isInput() const { return (varType()==AstVarType::INPUT || varType()==AstVarType::INOUT); } bool isOutput() const { return (varType()==AstVarType::OUTPUT || varType()==AstVarType::INOUT); } AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable void varp(AstVar* varp) { m_varp=varp; } }; class AstModport : public AstNode { // A modport in an interface private: string m_name; // Name of the modport public: AstModport(FileLine* fl, const string& name, AstNode* varsp) : AstNode(fl), m_name(name) { addNOp1p(varsp); } virtual string name() const { return m_name; } virtual bool maybePointedTo() const { return true; } ASTNODE_NODE_FUNCS(Modport, MODPORT) AstNode* varsp() const { return op1p(); } // op1 = List of Vars }; class AstCell : public AstNode { // A instantiation cell or interface call (don't know which until link) private: string m_name; // Cell name string m_origName; // Original name before dot addition string m_modName; // Module the cell instances AstNodeModule* m_modp; // [AfterLink] Pointer to module instanced bool m_hasIfaceVar:1; // True if a Var has been created for this cell bool m_trace:1; // Trace this cell 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_modp(NULL), m_hasIfaceVar(false), m_trace(true) { addNOp1p(pinsp); addNOp2p(paramsp); setNOp3p(rangep); } ASTNODE_NODE_FUNCS(Cell, CELL) // No cloneRelink, we presume cloneee's want the same module linkages virtual void dump(ostream& str); virtual const char* broken() const { BROKEN_RTN(m_modp && !m_modp->brokeExists()); return NULL; } virtual bool maybePointedTo() const { return true; } // ACCESSORS virtual string name() const { return m_name; } // * = Cell name virtual void name(const string& name) { m_name = name; } string origName() const { return m_origName; } // * = Original name void origName(const string& name) { m_origName = name; } string modName() const { return m_modName; } // * = Instance name void modName(const string& name) { m_modName = name; } 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) AstNodeModule* modp() const { return m_modp; } // [AfterLink] = Pointer to module instantiated void addPinsp(AstPin* nodep) { addOp1p(nodep); } void addParamsp(AstPin* nodep) { addOp2p(nodep); } void modp(AstNodeModule* nodep) { m_modp = nodep; } bool hasIfaceVar() const { return m_hasIfaceVar; } void hasIfaceVar(bool flag) { m_hasIfaceVar = flag; } void trace(bool flag) { m_trace=flag; } bool isTrace() const { return m_trace; } }; class AstCellInline : public AstNode { // A instantiation cell that was removed by inlining // For communication between V3Inline and V3LinkDot only // Children: When 2 levels inlined, other CellInline under this private: string m_name; // Cell name, possibly {a}__DOT__{b}... string m_origModName; // Original name of the module, ignoring name() changes, for dot lookup public: AstCellInline(FileLine* fl, const string& name, const string& origModName) : AstNode(fl) , m_name(name), m_origModName(origModName) {} ASTNODE_NODE_FUNCS(CellInline, CELLINLINE) virtual void dump(ostream& str); // ACCESSORS virtual string name() const { return m_name; } // * = Cell name string origModName() const { return m_origModName; } // * = modp()->origName() before inlining virtual void name(const string& name) { m_name = name; } }; class AstBind : public AstNode { // Parents: MODULE // Children: CELL private: string m_name; // Binding to name public: AstBind(FileLine* fl, const string& name, AstNode* cellsp) : AstNode(fl) , m_name(name) { if (!cellsp->castCell()) cellsp->v3fatalSrc("Only cells allowed to be bound"); addNOp1p(cellsp); } ASTNODE_NODE_FUNCS(Bind, BIND) // ACCESSORS virtual string name() const { return m_name; } // * = Bind Target name virtual void name(const string& name) { m_name = name; } AstNode* cellsp() const { return op1p(); } // op1= cells }; class AstPort : public AstNode { // A port (in/out/inout) on a module private: int m_pinNum; // Pin number string m_name; // Name of pin public: AstPort(FileLine* fl, int pinnum, const string& name) :AstNode(fl) ,m_pinNum(pinnum) ,m_name(name) {} ASTNODE_NODE_FUNCS(Port, PORT) virtual string name() const { return m_name; } // * = Port name int pinNum() const { return m_pinNum; } // * = Pin number, for order based instantiation AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to port }; //###################################################################### class AstGenerate : public AstNode { // A Generate/end block // Parents: MODULE // Children: modItems public: AstGenerate(FileLine* fileline, AstNode* stmtsp) : AstNode(fileline) { addNOp1p(stmtsp); } ASTNODE_NODE_FUNCS(Generate, GENERATE) // op1 = Statements AstNode* stmtsp() const { return op1p()->castNode(); } // op1 = List of statements void addStmtp(AstNode* nodep) { addOp1p(nodep); } }; class AstParseRef : public AstNode { // A reference to a variable, function or task // We don't know which at parse time due to bison constraints // The link stages will replace this with AstVarRef, or AstTaskRef, etc. // Parents: math|stmt // Children: TEXT|DOT|SEL*|TASK|FUNC (or expression under sel) private: AstParseRefExp m_expect; // Type we think it should resolve to string m_name; public: AstParseRef(FileLine* fl, AstParseRefExp expect, const string& name, AstNode* lhsp, AstNodeFTaskRef* ftaskrefp) :AstNode(fl), m_expect(expect), m_name(name) { setNOp1p(lhsp); setNOp2p(ftaskrefp); } ASTNODE_NODE_FUNCS(ParseRef, PARSEREF) virtual void dump(ostream& str); virtual string name() const { return m_name; } // * = Var name virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_expect),V3Hash(m_name)); } virtual bool same(AstNode* samep) const { return (expect() == samep->castParseRef()->expect() && m_name==samep->castParseRef()->m_name); } virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; } virtual void name(const string& name) { m_name = name; } AstParseRefExp expect() const { return m_expect; } void expect(AstParseRefExp exp) { m_expect=exp; } // op1 = Components AstNode* lhsp() const { return op1p(); } // op1 = List of statements AstNode* ftaskrefp() const { return op2p(); } // op2 = Function/task reference void ftaskrefp(AstNodeFTaskRef* nodep) { setNOp2p(nodep); } // op2 = Function/task reference }; class AstPackageRef : public AstNode { private: AstPackage* m_packagep; // Package hierarchy public: AstPackageRef(FileLine* fl, AstPackage* packagep) : AstNode(fl), m_packagep(packagep) {} ASTNODE_NODE_FUNCS(PackageRef, PACKAGEREF) // METHODS virtual const char* broken() const { BROKEN_RTN(!m_packagep || !m_packagep->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_packagep && m_packagep->clonep()) { m_packagep = m_packagep->clonep()->castPackage(); }} virtual bool same(AstNode* samep) const { return (m_packagep==samep->castPackageRef()->m_packagep); } virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_packagep)); } virtual void dump(ostream& str=cout); AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; class AstDot : public AstNode { // A dot separating paths in an AstXRef, AstFuncRef or AstTaskRef // These are eliminated in the link stage public: AstDot(FileLine* fl, AstNode* lhsp, AstNode* rhsp) :AstNode(fl) { setOp1p(lhsp); setOp2p(rhsp); } ASTNODE_NODE_FUNCS(Dot, DOT) static AstNode* newIfPkg(FileLine*fl, AstPackage* packagep, AstNode* rhsp) { // For parser, make only if non-null package if (!packagep) return rhsp; return new AstDot(fl, new AstPackageRef(fl, packagep), rhsp); } virtual void dump(ostream& str); virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; } AstNode* lhsp() const { return op1p(); } AstNode* rhsp() const { return op2p(); } }; //###################################################################### class AstTask : public AstNodeFTask { // A task inside a module public: AstTask(FileLine* fl, const string& name, AstNode* stmtp) :AstNodeFTask(fl, name, stmtp) {} ASTNODE_NODE_FUNCS(Task, TASK) }; class AstFunc : public AstNodeFTask { // A function inside a module public: AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp) :AstNodeFTask(fl, name, stmtp) { addNOp1p(fvarsp); } ASTNODE_NODE_FUNCS(Func, FUNC) virtual bool hasDType() const { return true; } }; class AstTaskRef : public AstNodeFTaskRef { // A reference to a task public: AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp) :AstNodeFTaskRef(fl, namep, pinsp) {} AstTaskRef(FileLine* fl, const string& name, AstNode* pinsp) :AstNodeFTaskRef(fl, name, pinsp) {} ASTNODE_NODE_FUNCS(TaskRef, TASKREF) }; class AstFuncRef : public AstNodeFTaskRef { // A reference to a function public: AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp) :AstNodeFTaskRef(fl, namep, pinsp) {} AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp) :AstNodeFTaskRef(fl, name, pinsp) {} ASTNODE_NODE_FUNCS(FuncRef, FUNCREF) virtual bool hasDType() const { return true; } }; class AstDpiExport : public AstNode { // We could put an AstNodeFTaskRef instead of the verilog function name, // however we're not *calling* it, so that seems somehow wrong. // (Probably AstNodeFTaskRef should be renamed AstNodeFTaskCall and have-a AstNodeFTaskRef) private: string m_name; // Name of function string m_cname; // Name of function on c side public: AstDpiExport(FileLine* fl, const string& vname, const string& cname) :AstNode(fl), m_name(vname), m_cname(cname) { } ASTNODE_NODE_FUNCS(DpiExport, DPIEXPORT) virtual string name() const { return m_name; } virtual void name(const string& name) { m_name = name; } string cname() const { return m_cname; } void cname(const string& cname) { m_cname = cname; } }; //###################################################################### class AstSenItem : public AstNodeSenItem { // Parents: SENTREE // Children: (optional) VARREF SENGATE private: AstEdgeType m_edgeType; // Edge type public: class Combo {}; // for creator type-overload selection class Initial {}; // for creator type-overload selection class Settle {}; // for creator type-overload selection class Never {}; // for creator type-overload selection AstSenItem(FileLine* fl, AstEdgeType edgeType, AstNode* varrefp) : AstNodeSenItem(fl), m_edgeType(edgeType) { setOp1p(varrefp); } AstSenItem(FileLine* fl, Combo) : AstNodeSenItem(fl) { m_edgeType = AstEdgeType::ET_COMBO; } AstSenItem(FileLine* fl, Initial) : AstNodeSenItem(fl) { m_edgeType = AstEdgeType::ET_INITIAL; } AstSenItem(FileLine* fl, Settle) : AstNodeSenItem(fl) { m_edgeType = AstEdgeType::ET_SETTLE; } AstSenItem(FileLine* fl, Never) : AstNodeSenItem(fl) { m_edgeType = AstEdgeType::ET_NEVER; } ASTNODE_NODE_FUNCS(SenItem, SENITEM) virtual void dump(ostream& str); virtual V3Hash sameHash() const { return V3Hash(V3Hash(edgeType())); } virtual bool same(AstNode* samep) const { return edgeType()==samep->castSenItem()->edgeType(); } AstEdgeType edgeType() const { return m_edgeType; } // * = Posedge/negedge void edgeType(AstEdgeType type) { m_edgeType=type; editCountInc(); }// * = Posedge/negedge AstNode* sensp() const { return op1p(); } // op1 = Signal sensitized AstNodeVarRef* varrefp() const { return op1p()->castNodeVarRef(); } // op1 = Signal sensitized // virtual bool isClocked() const { return edgeType().clockedStmt(); } virtual bool isCombo() const { return edgeType()==AstEdgeType::ET_COMBO; } virtual bool isInitial() const { return edgeType()==AstEdgeType::ET_INITIAL; } virtual bool isSettle() const { return edgeType()==AstEdgeType::ET_SETTLE; } virtual bool isNever() const { return edgeType()==AstEdgeType::ET_NEVER; } bool hasVar() const { return !(isCombo()||isInitial()||isSettle()||isNever()); } }; class AstSenGate : public AstNodeSenItem { // Parents: SENTREE // Children: SENITEM expr // AND as applied to a sensitivity list and a gating expression // Performing this gating is optional; it may be removed by later optimizations public: AstSenGate(FileLine* fl, AstSenItem* sensesp, AstNode* rhsp) : AstNodeSenItem(fl) { dtypeSetLogicBool(); addOp1p(sensesp); setOp2p(rhsp); } ASTNODE_NODE_FUNCS(SenGate, SENGATE) virtual string emitVerilog() { return "(%l) %f&& (%r)"; } AstSenItem* sensesp() const { return op1p()->castSenItem(); } AstNode* rhsp() const { return op2p()->castNode(); } void sensesp(AstSenItem* nodep) { addOp1p(nodep); } void rhsp(AstNode* nodep) { setOp2p(nodep); } // virtual bool isClocked() const { return true; } virtual bool isCombo() const { return false; } virtual bool isInitial() const { return false; } virtual bool isSettle() const { return false; } virtual bool isNever() const { return false; } }; class AstSenTree : public AstNode { // A list of senitems // Parents: MODULE | SBLOCK // Children: SENITEM list private: bool m_multi; // Created from combo logic by ORing multiple clock domains public: AstSenTree(FileLine* fl, AstNodeSenItem* sensesp) : AstNode(fl), m_multi(false) { addNOp1p(sensesp); } ASTNODE_NODE_FUNCS(SenTree, SENTREE) virtual void dump(ostream& str); virtual bool maybePointedTo() const { return true; } bool isMulti() const { return m_multi; } AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list void addSensesp(AstNodeSenItem* nodep) { addOp1p(nodep); } void multi(bool flag) { m_multi = true; } // METHODS bool hasClocked(); // Includes a clocked statement bool hasSettle(); // Includes a SETTLE SenItem bool hasInitial(); // Includes a INITIAL SenItem bool hasCombo(); // Includes a COMBO SenItem }; class AstAlways : public AstNode { VAlwaysKwd m_keyword; public: AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp) : AstNode(fl), m_keyword(keyword) { addNOp1p(sensesp); addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(Always, ALWAYS) // virtual void dump(ostream& str); AstSenTree* sensesp() const { return op1p()->castSenTree(); } // op1 = Sensitivity list AstNode* bodysp() const { return op2p()->castNode(); } // op2 = Statements to evaluate void addStmtp(AstNode* nodep) { addOp2p(nodep); } VAlwaysKwd keyword() const { return m_keyword; } // Special accessors bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } }; class AstAlwaysPublic : public AstNodeStmt { // "Fake" sensitivity created by /*verilator public_flat_rw @(edgelist)*/ // Body statements are just AstVarRefs to the public signals public: AstAlwaysPublic(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp) : AstNodeStmt(fl) { addNOp1p(sensesp); addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(AlwaysPublic, ALWAYSPUBLIC) virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } // AstSenTree* sensesp() const { return op1p()->castSenTree(); } // op1 = Sensitivity list AstNode* bodysp() const { return op2p()->castNode(); } // op2 = Statements to evaluate void addStmtp(AstNode* nodep) { addOp2p(nodep); } // Special accessors bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } }; class AstAlwaysPost : public AstNode { // Like always but post assignments for memory assignment IFs public: AstAlwaysPost(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp) : AstNode(fl) { addNOp1p(sensesp); addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(AlwaysPost, ALWAYSPOST) // AstNode* bodysp() const { return op2p()->castNode(); } // op2 = Statements to evaluate void addBodysp(AstNode* newp) { addOp2p(newp); } }; class AstAssign : public AstNodeAssign { public: AstAssign(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Assign, ASSIGN) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssign(this->fileline(), lhsp, rhsp); } }; class AstAssignAlias : public AstNodeAssign { // Like AstAssignW, but a true bidirect interconnection alias // If both sides are wires, there's no LHS vs RHS, public: AstAssignAlias(FileLine* fileline, AstVarRef* lhsp, AstVarRef* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(AssignAlias, ASSIGNALIAS) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { V3ERROR_NA; return NULL; } }; class AstAssignDly : public AstNodeAssign { public: AstAssignDly(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(AssignDly, ASSIGNDLY) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignDly(this->fileline(), lhsp, rhsp); } virtual bool isGateOptimizable() const { return false; } virtual string verilogKwd() const { return "<="; } }; class AstAssignW : public AstNodeAssign { // Like assign, but wire/assign's in verilog, the only setting of the specified variable public: AstAssignW(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) { } ASTNODE_NODE_FUNCS(AssignW, ASSIGNW) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignW(this->fileline(), lhsp, rhsp); } AstAlways* convertToAlways() { AstNode* lhs1p = lhsp()->unlinkFrBack(); AstNode* rhs1p = rhsp()->unlinkFrBack(); AstAlways* newp = new AstAlways (fileline(), VAlwaysKwd::ALWAYS, NULL, new AstAssign (fileline(), lhs1p, rhs1p)); replaceWith(newp); // User expected to then deleteTree(); return newp; } }; class AstAssignVarScope : public AstNodeAssign { // Assign two VarScopes to each other public: AstAssignVarScope(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) { dtypeFrom(rhsp); } ASTNODE_NODE_FUNCS(AssignVarScope, ASSIGNVARSCOPE) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignVarScope(this->fileline(), lhsp, rhsp); } }; class AstPull : public AstNode { private: bool m_direction; public: AstPull(FileLine* fileline, AstNode* lhsp, bool direction) : AstNode(fileline) { setOp1p(lhsp); m_direction = direction; } ASTNODE_NODE_FUNCS(Pull, PULL) virtual bool same(AstNode* samep) const { return direction()==samep->castPull()->direction(); } void lhsp(AstNode* np) { setOp1p(np); } AstNode* lhsp() const { return op1p()->castNode(); } // op1 = Assign to uint32_t direction() const { return (uint32_t) m_direction; } }; class AstAssignPre : public AstNodeAssign { // Like Assign, but predelayed assignment requiring special order handling public: AstAssignPre(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(AssignPre, ASSIGNPRE) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPre(this->fileline(), lhsp, rhsp); } }; class AstAssignPost : public AstNodeAssign { // Like Assign, but predelayed assignment requiring special order handling public: AstAssignPost(FileLine* fileline, AstNode* lhsp, AstNode* rhsp) : AstNodeAssign(fileline, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(AssignPost, ASSIGNPOST) virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPost(this->fileline(), lhsp, rhsp); } }; class AstComment : public AstNodeStmt { // Some comment to put into the output stream // Parents: {statement list} // Children: none private: string m_name; // Name of variable public: AstComment(FileLine* fl, const string& name) : AstNodeStmt(fl) , m_name(name) {} ASTNODE_NODE_FUNCS(Comment, COMMENT) virtual string name() const { return m_name; } // * = Var name virtual V3Hash sameHash() const { return V3Hash(); } // Ignore name in comments virtual bool same(AstNode* samep) const { return true; } // Ignore name in comments }; class AstCond : public AstNodeCond { // Conditional ?: statement // Parents: MATH // Children: MATH public: AstCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) : AstNodeCond(fl, condp, expr1p, expr2p) {} ASTNODE_NODE_FUNCS(Cond, COND) }; class AstCondBound : public AstNodeCond { // Conditional ?: statement, specially made for saftey checking of array bounds // Parents: MATH // Children: MATH public: AstCondBound(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p) : AstNodeCond(fl, condp, expr1p, expr2p) {} ASTNODE_NODE_FUNCS(CondBound, CONDBOUND) }; class AstCoverDecl : public AstNodeStmt { // Coverage analysis point declaration // Parents: {statement list} // Children: none private: AstCoverDecl* m_dataDeclp; // [After V3CoverageJoin] Pointer to duplicate declaration to get data from instead string m_page; string m_text; string m_hier; int m_column; int m_binNum; // Set by V3EmitCSyms to tell final V3Emit what to increment public: AstCoverDecl(FileLine* fl, int column, const string& page, const string& comment) : AstNodeStmt(fl) { m_text = comment; m_page = page; m_column = column; m_binNum = 0; m_dataDeclp = NULL; } ASTNODE_NODE_FUNCS(CoverDecl, COVERDECL) virtual const char* broken() const { BROKEN_RTN(m_dataDeclp && !m_dataDeclp->brokeExists()); if (m_dataDeclp && m_dataDeclp->m_dataDeclp) v3fatalSrc("dataDeclp should point to real data, not be a list"); // Avoid O(n^2) accessing return NULL; } virtual void cloneRelink() { if (m_dataDeclp && m_dataDeclp->clonep()) m_dataDeclp = m_dataDeclp->clonep()->castCoverDecl(); } virtual void dump(ostream& str); virtual int instrCount() const { return 1+2*instrCountLd(); } virtual bool maybePointedTo() const { return true; } int column() const { return m_column; } void binNum(int flag) { m_binNum = flag; } int binNum() const { return m_binNum; } const string& comment() const { return m_text; } // text to insert in code const string& page() const { return m_page; } const string& hier() const { return m_hier; } void hier(const string& flag) { m_hier=flag; } void comment(const string& flag) { m_text=flag; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return (fileline() == samep->castCoverDecl()->fileline() && hier()==samep->castCoverDecl()->hier() && comment()==samep->castCoverDecl()->comment() && column()==samep->castCoverDecl()->column()); } virtual bool isPredictOptimizable() const { return false; } void dataDeclp(AstCoverDecl* nodep) { m_dataDeclp=nodep; } // dataDecl NULL means "use this one", but often you want "this" to indicate to get data from here AstCoverDecl* dataDeclNullp() const { return m_dataDeclp; } AstCoverDecl* dataDeclThisp() { return dataDeclNullp()?dataDeclNullp():this; } }; class AstCoverInc : public AstNodeStmt { // Coverage analysis point; increment coverage count // Parents: {statement list} // Children: none private: AstCoverDecl* m_declp; // [After V3Coverage] Pointer to declaration public: AstCoverInc(FileLine* fl, AstCoverDecl* declp) : AstNodeStmt(fl) { m_declp = declp; } ASTNODE_NODE_FUNCS(CoverInc, COVERINC) virtual const char* broken() const { BROKEN_RTN(!declp()->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_declp->clonep()) m_declp = m_declp->clonep()->castCoverDecl(); } virtual void dump(ostream& str); virtual int instrCount() const { return 1+2*instrCountLd(); } virtual V3Hash sameHash() const { return V3Hash(declp()); } virtual bool same(AstNode* samep) const { return declp()==samep->castCoverInc()->declp(); } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isOutputter() const { return true; } // but isPure() true AstCoverDecl* declp() const { return m_declp; } // Where defined }; class AstCoverToggle : public AstNodeStmt { // Toggle analysis of given signal // Parents: MODULE // Children: AstCoverInc, orig var, change det var public: AstCoverToggle(FileLine* fl, AstCoverInc* incp, AstNode* origp, AstNode* changep) : AstNodeStmt(fl) { setOp1p(incp); setOp2p(origp); setOp3p(changep); } ASTNODE_NODE_FUNCS(CoverToggle, COVERTOGGLE) virtual int instrCount() const { return 3+instrCountBranch()+instrCountLd(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode*) const { return true; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return true; } virtual bool isOutputter() const { return false; } // Though the AstCoverInc under this is an outputter // but isPure() true AstCoverInc* incp() const { return op1p()->castCoverInc(); } void incp(AstCoverInc* nodep) { setOp1p(nodep); } AstNode* origp() const { return op2p(); } AstNode* changep() const { return op3p(); } }; class AstGenCase : public AstNodeCase { // Generate Case statement // Parents: {statement list} // exprp Children: MATHs // casesp Children: CASEITEMs public: AstGenCase(FileLine* fileline, AstNode* exprp, AstNode* casesp) : AstNodeCase(fileline, exprp, casesp) { } ASTNODE_NODE_FUNCS(GenCase, GENCASE) }; class AstCase : public AstNodeCase { // Case statement // Parents: {statement list} // exprp Children: MATHs // casesp Children: CASEITEMs private: VCaseType m_casex; // 0=case, 1=casex, 2=casez bool m_fullPragma; // Synthesis full_case bool m_parallelPragma; // Synthesis parallel_case bool m_uniquePragma; // unique case bool m_unique0Pragma; // unique0 case bool m_priorityPragma; // priority case public: AstCase(FileLine* fileline, VCaseType casex, AstNode* exprp, AstNode* casesp) : AstNodeCase(fileline, exprp, casesp) { m_casex=casex; m_fullPragma=false; m_parallelPragma=false; m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false; } ASTNODE_NODE_FUNCS(Case, CASE) virtual string verilogKwd() const { return casez()?"casez":casex()?"casex":"case"; } virtual bool same(AstNode* samep) const { return m_casex==samep->castCase()->m_casex; } bool casex() const { return m_casex==VCaseType::CT_CASEX; } bool casez() const { return m_casex==VCaseType::CT_CASEZ; } bool caseInside() const { return m_casex==VCaseType::CT_CASEINSIDE; } bool caseSimple() const { return m_casex==VCaseType::CT_CASE; } void caseInsideSet() { m_casex=VCaseType::CT_CASEINSIDE; } bool fullPragma() const { return m_fullPragma; } void fullPragma(bool flag) { m_fullPragma=flag; } bool parallelPragma() const { return m_parallelPragma; } void parallelPragma(bool flag) { m_parallelPragma=flag; } bool uniquePragma() const { return m_uniquePragma; } void uniquePragma(bool flag) { m_uniquePragma=flag; } bool unique0Pragma() const { return m_unique0Pragma; } void unique0Pragma(bool flag) { m_unique0Pragma=flag; } bool priorityPragma() const { return m_priorityPragma; } void priorityPragma(bool flag) { m_priorityPragma=flag; } }; class AstCaseItem : public AstNode { // Single item of a case statement // Parents: CASE // condsp Children: MATH (Null condition used for default block) // bodysp Children: Statements private: bool m_ignoreOverlap; // Default created by assertions; ignore overlaps public: AstCaseItem(FileLine* fileline, AstNode* condsp, AstNode* bodysp) : AstNode(fileline) { addNOp1p(condsp); addNOp2p(bodysp); m_ignoreOverlap = false; } ASTNODE_NODE_FUNCS(CaseItem, CASEITEM) virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } AstNode* condsp() const { return op1p()->castNode(); } // op1= list of possible matching expressions AstNode* bodysp() const { return op2p()->castNode(); } // op2= what to do void condsp(AstNode* nodep) { setOp1p(nodep); } void addBodysp(AstNode* newp) { addOp2p(newp); } bool isDefault() const { return condsp()==NULL; } bool ignoreOverlap() const { return m_ignoreOverlap; } void ignoreOverlap(bool flag) { m_ignoreOverlap = flag; } }; class AstSFormatF : public AstNode { // Convert format to string, generally under an AstDisplay or AstSFormat // Also used as "real" function for /*verilator sformat*/ functions string m_text; bool m_hidden; // Under display, etc public: AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp) : AstNode(fl), m_text(text), m_hidden(hidden) { addNOp1p(exprsp); addNOp2p(NULL); } ASTNODE_NODE_FUNCS(SFormatF, SFORMATF) virtual string name() const { return m_text; } virtual int instrCount() const { return instrCountPli(); } virtual V3Hash sameHash() const { return V3Hash(text()); } virtual bool same(AstNode* samep) const { return text()==samep->castSFormatF()->text(); } virtual string verilogKwd() const { return "$sformatf"; } void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text=text; } AstScopeName* scopeNamep() const { return op2p()->castScopeName(); } void scopeNamep(AstNode* nodep) { setNOp2p(nodep); } bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive return (name().find("%m") != string::npos || name().find("%M") != string::npos); } bool hidden() const { return m_hidden; } }; class AstDisplay : public AstNodeStmt { // Parents: stmtlist // Children: file which must be a varref // Children: SFORMATF to generate print string private: AstDisplayType m_displayType; public: AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp) : AstNodeStmt (fileline) { setOp1p(new AstSFormatF(fileline,text,true,exprsp)); setNOp3p(filep); m_displayType = dispType; } ASTNODE_NODE_FUNCS(Display, DISPLAY) virtual void dump(ostream& str); virtual const char* broken() const { BROKEN_RTN(!fmtp()); return NULL; } virtual string verilogKwd() const { return (filep() ? (string)"$f"+(string)displayType().ascii() : (string)"$"+(string)displayType().ascii()); } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } // SPECIAL: $display has 'visual' ordering virtual bool isOutputter() const { return true; } // SPECIAL: $display makes output virtual bool isUnlikely() const { return true; } virtual V3Hash sameHash() const { return V3Hash(displayType()); } virtual bool same(AstNode* samep) const { return displayType()==samep->castDisplay()->displayType(); } virtual int instrCount() const { return instrCountPli(); } AstDisplayType displayType() const { return m_displayType; } void displayType(AstDisplayType type) { m_displayType = type; } bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter AstSFormatF* fmtp() const { return op1p()->castSFormatF(); } AstNode* filep() const { return op3p(); } void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); } }; class AstSFormat : public AstNodeStmt { // Parents: statement container // Children: string to load // Children: SFORMATF to generate print string public: AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp) : AstNodeStmt (fileline) { setOp1p(new AstSFormatF(fileline,text,true,exprsp)); setOp3p(lhsp); } ASTNODE_NODE_FUNCS(SFormat, SFORMAT) virtual const char* broken() const { BROKEN_RTN(!fmtp()); return NULL; } virtual string verilogKwd() const { return "$sformat"; } virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return true; } virtual bool isPure() const { return true; } virtual bool isOutputter() const { return false; } virtual bool cleanOut() { return false; } virtual int instrCount() const { return instrCountPli(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter AstSFormatF* fmtp() const { return op1p()->castSFormatF(); } AstNode* lhsp() const { return op3p(); } void lhsp(AstNode* nodep) { setOp3p(nodep); } }; class AstSysIgnore : public AstNodeStmt { // Parents: stmtlist // Children: varrefs or exprs public: AstSysIgnore(FileLine* fileline, AstNode* exprsp) : AstNodeStmt (fileline) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(SysIgnore, SYSIGNORE) virtual string verilogKwd() const { return "$ignored"; } virtual bool isGateOptimizable() const { return false; } // Though deleted before opt virtual bool isPredictOptimizable() const { return false; } // Though deleted before opt virtual bool isPure() const { return false; } // Though deleted before opt virtual bool isOutputter() const { return true; } // Though deleted before opt virtual int instrCount() const { return instrCountPli(); } AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output }; class AstFClose : public AstNodeStmt { // Parents: stmtlist // Children: file which must be a varref public: AstFClose(FileLine* fileline, AstNode* filep) : AstNodeStmt (fileline) { setNOp2p(filep); } ASTNODE_NODE_FUNCS(FClose, FCLOSE) virtual string verilogKwd() const { return "$fclose"; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } virtual bool isOutputter() const { return true; } virtual bool isUnlikely() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } }; class AstFOpen : public AstNodeStmt { // Although a system function in IEEE, here a statement which sets the file pointer (MCD) public: AstFOpen(FileLine* fileline, AstNode* filep, AstNode* filenamep, AstNode* modep) : AstNodeStmt (fileline) { setOp1p(filep); setOp2p(filenamep); setOp3p(modep); } ASTNODE_NODE_FUNCS(FOpen, FOPEN) virtual string verilogKwd() const { return "$fopen"; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } virtual bool isOutputter() const { return true; } virtual bool isUnlikely() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } AstNode* filep() const { return op1p(); } AstNode* filenamep() const { return op2p(); } AstNode* modep() const { return op3p(); } }; class AstFFlush : public AstNodeStmt { // Parents: stmtlist // Children: file which must be a varref public: AstFFlush(FileLine* fileline, AstNode* filep) : AstNodeStmt (fileline) { setNOp2p(filep); } ASTNODE_NODE_FUNCS(FFlush, FFLUSH) virtual string verilogKwd() const { return "$fflush"; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } virtual bool isOutputter() const { return true; } virtual bool isUnlikely() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } }; class AstFScanF : public AstNodeMath { // Parents: expr // Children: file which must be a varref // Children: varrefs to load private: string m_text; public: AstFScanF(FileLine* fileline, const string& text, AstNode* filep, AstNode* exprsp) : AstNodeMath (fileline), m_text(text) { addNOp1p(exprsp); setNOp2p(filep); } ASTNODE_NODE_FUNCS(FScanF, FSCANF) virtual string name() const { return m_text; } virtual string verilogKwd() const { return "$fscanf"; } virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } // SPECIAL: has 'visual' ordering virtual bool isOutputter() const { return true; } // SPECIAL: makes output virtual bool cleanOut() { return false; } virtual V3Hash sameHash() const { return V3Hash(text()); } virtual bool same(AstNode* samep) const { return text()==samep->castFScanF()->text(); } AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text=text; } AstNode* filep() const { return op2p(); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); } }; class AstSScanF : public AstNodeMath { // Parents: expr // Children: file which must be a varref // Children: varrefs to load private: string m_text; public: AstSScanF(FileLine* fileline, const string& text, AstNode* fromp, AstNode* exprsp) : AstNodeMath (fileline), m_text(text) { addNOp1p(exprsp); setOp2p(fromp); } ASTNODE_NODE_FUNCS(SScanF, SSCANF) virtual string name() const { return m_text; } virtual string verilogKwd() const { return "$sscanf"; } virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } // SPECIAL: has 'visual' ordering virtual bool isOutputter() const { return true; } // SPECIAL: makes output virtual bool cleanOut() { return false; } virtual V3Hash sameHash() const { return V3Hash(text()); } virtual bool same(AstNode* samep) const { return text()==samep->castSScanF()->text(); } AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text=text; } AstNode* fromp() const { return op2p(); } void fromp(AstNode* nodep) { setOp2p(nodep); } }; class AstReadMem : public AstNodeStmt { private: bool m_isHex; // readmemh, not readmemb public: AstReadMem(FileLine* fileline, bool hex, AstNode* filenamep, AstNode* memp, AstNode* lsbp, AstNode* msbp) : AstNodeStmt (fileline), m_isHex(hex) { setOp1p(filenamep); setOp2p(memp); setNOp3p(lsbp); setNOp4p(msbp); } ASTNODE_NODE_FUNCS(ReadMem, READMEM) virtual string verilogKwd() const { return (isHex()?"$readmemh":"$readmemb"); } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } virtual bool isOutputter() const { return true; } virtual bool isUnlikely() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return isHex()==samep->castReadMem()->isHex(); } bool isHex() const { return m_isHex; } AstNode* filenamep() const { return op1p()->castNode(); } AstNode* memp() const { return op2p()->castNode(); } AstNode* lsbp() const { return op3p()->castNode(); } AstNode* msbp() const { return op4p()->castNode(); } }; class AstSystemT : public AstNodeStmt { // $system used as task public: AstSystemT(FileLine* fileline, AstNode* lhsp) : AstNodeStmt (fileline) { setOp1p(lhsp); } ASTNODE_NODE_FUNCS(SystemT, SYSTEMT) virtual string verilogKwd() const { return "$system"; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } virtual bool isOutputter() const { return true; } virtual bool isUnlikely() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } AstNode* lhsp() const { return op1p(); } }; class AstSystemF : public AstNodeMath { // $system used as function public: AstSystemF(FileLine* fileline, AstNode* lhsp) : AstNodeMath (fileline) { setOp1p(lhsp); } ASTNODE_NODE_FUNCS(SystemF, SYSTEMF) virtual string verilogKwd() const { return "$system"; } virtual string emitVerilog() { return verilogKwd(); } virtual string emitC() { return "VL_SYSTEM_%nq(%lw, %P)"; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } virtual bool isOutputter() const { return true; } virtual bool isUnlikely() const { return true; } virtual bool cleanOut() { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } AstNode* lhsp() const { return op1p(); } }; class AstValuePlusArgs : public AstNodeMath { // Parents: expr // Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs private: string m_text; public: AstValuePlusArgs(FileLine* fileline, const string& text, AstNode* exprsp) : AstNodeMath (fileline), m_text(text) { setOp1p(exprsp); } ASTNODE_NODE_FUNCS(ValuePlusArgs, VALUEPLUSARGS) virtual string name() const { return m_text; } virtual string verilogKwd() const { return "$value$plusargs"; } virtual string emitVerilog() { return verilogKwd(); } virtual string emitC() { return "VL_VALUEPLUSARGS_%nq(%lw, %P, NULL)"; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool cleanOut() { return true; } virtual V3Hash sameHash() const { return V3Hash(text()); } virtual bool same(AstNode* samep) const { return text()==samep->castValuePlusArgs()->text(); } AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output void exprsp(AstNode* nodep) { setOp1p(nodep); } // op1 = Expressions to output string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text=text; } }; class AstTestPlusArgs : public AstNodeMath { // Parents: expr // Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs private: string m_text; public: AstTestPlusArgs(FileLine* fileline, const string& text) : AstNodeMath (fileline), m_text(text) { } ASTNODE_NODE_FUNCS(TestPlusArgs, TESTPLUSARGS) virtual string name() const { return m_text; } virtual string verilogKwd() const { return "$test$plusargs"; } virtual string emitVerilog() { return verilogKwd(); } virtual string emitC() { return "VL_VALUEPLUSARGS_%nq(%lw, %P, NULL)"; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool cleanOut() { return true; } virtual V3Hash sameHash() const { return V3Hash(text()); } virtual bool same(AstNode* samep) const { return text()==samep->castTestPlusArgs()->text(); } string text() const { return m_text; } // * = Text to display void text(const string& text) { m_text=text; } }; class AstGenFor : public AstNodeFor { public: AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp, AstNode* incsp, AstNode* bodysp) : AstNodeFor(fileline, initsp, condp, incsp, bodysp) { } ASTNODE_NODE_FUNCS(GenFor, GENFOR) }; class AstRepeat : public AstNodeStmt { public: AstRepeat(FileLine* fileline, AstNode* countp, AstNode* bodysp) : AstNodeStmt(fileline) { setOp2p(countp); addNOp3p(bodysp); } ASTNODE_NODE_FUNCS(Repeat, REPEAT) AstNode* countp() const { return op2p()->castNode(); } // op2= condition to continue AstNode* bodysp() const { return op3p()->castNode(); } // op3= body of loop virtual bool isGateOptimizable() const { return false; } // Not releavant - converted to FOR virtual int instrCount() const { return instrCountBranch(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstWhile : public AstNodeStmt { public: AstWhile(FileLine* fileline, AstNode* condp, AstNode* bodysp, AstNode* incsp=NULL) : AstNodeStmt(fileline) { setOp2p(condp); addNOp3p(bodysp); addNOp4p(incsp); } ASTNODE_NODE_FUNCS(While, WHILE) AstNode* precondsp() const { return op1p()->castNode(); } // op1= prepare statements for condition (exec every loop) AstNode* condp() const { return op2p()->castNode(); } // op2= condition to continue AstNode* bodysp() const { return op3p()->castNode(); } // op3= body of loop AstNode* incsp() const { return op4p()->castNode(); } // op4= increment (if from a FOR loop) void addPrecondsp(AstNode* newp) { addOp1p(newp); } void addBodysp(AstNode* newp) { addOp3p(newp); } void addIncsp(AstNode* newp) { addOp4p(newp); } virtual bool isGateOptimizable() const { return false; } virtual int instrCount() const { return instrCountBranch(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here }; class AstBreak : public AstNodeStmt { public: AstBreak(FileLine* fileline) : AstNodeStmt (fileline) {} ASTNODE_NODE_FUNCS(Break, BREAK) virtual string verilogKwd() const { return "break"; }; virtual V3Hash sameHash() const { return V3Hash(); } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; class AstContinue : public AstNodeStmt { public: AstContinue(FileLine* fileline) : AstNodeStmt (fileline) {} ASTNODE_NODE_FUNCS(Continue, CONTINUE) virtual string verilogKwd() const { return "continue"; }; virtual V3Hash sameHash() const { return V3Hash(); } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; class AstDisable : public AstNodeStmt { private: string m_name; // Name of block public: AstDisable(FileLine* fileline, const string& name) : AstNodeStmt(fileline), m_name(name) {} ASTNODE_NODE_FUNCS(Disable, DISABLE) virtual string name() const { return m_name; } // * = Block name void name(const string& flag) { m_name=flag; } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; class AstReturn : public AstNodeStmt { public: AstReturn(FileLine* fileline, AstNode* lhsp=NULL) : AstNodeStmt (fileline) { setNOp1p(lhsp); } ASTNODE_NODE_FUNCS(Return, RETURN) virtual string verilogKwd() const { return "return"; }; virtual V3Hash sameHash() const { return V3Hash(); } AstNode* lhsp() const { return op1p(); } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks }; class AstGenIf : public AstNodeIf { public: AstGenIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp) : AstNodeIf(fileline, condp, ifsp, elsesp) { } ASTNODE_NODE_FUNCS(GenIf, GENIF) }; class AstIf : public AstNodeIf { private: bool m_uniquePragma; // unique case bool m_unique0Pragma; // unique0 case bool m_priorityPragma; // priority case public: AstIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp) : AstNodeIf(fileline, condp, ifsp, elsesp) { m_uniquePragma=false; m_unique0Pragma=false; m_priorityPragma=false; } ASTNODE_NODE_FUNCS(If, IF) bool uniquePragma() const { return m_uniquePragma; } void uniquePragma(bool flag) { m_uniquePragma=flag; } bool unique0Pragma() const { return m_unique0Pragma; } void unique0Pragma(bool flag) { m_unique0Pragma=flag; } bool priorityPragma() const { return m_priorityPragma; } void priorityPragma(bool flag) { m_priorityPragma=flag; } }; class AstJumpLabel : public AstNodeStmt { // Jump point declaration // Separate from AstJumpGo; as a declaration can't be deleted // Parents: {statement list} // Children: {statement list, with JumpGo below} private: int m_labelNum; // Set by V3EmitCSyms to tell final V3Emit what to increment public: AstJumpLabel(FileLine* fl, AstNode* stmtsp) : AstNodeStmt(fl) ,m_labelNum(0) { addNOp1p(stmtsp); } virtual int instrCount() const { return 0; } ASTNODE_NODE_FUNCS(JumpLabel, JUMPLABEL) virtual bool maybePointedTo() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } // op1 = Statements AstNode* stmtsp() const { return op1p()->castNode(); } // op1 = List of statements void addStmtsp(AstNode* nodep) { addNOp1p(nodep); } int labelNum() const { return m_labelNum; } void labelNum(int flag) { m_labelNum=flag; } }; class AstJumpGo : public AstNodeStmt { // Jump point; branch up to the JumpLabel // Parents: {statement list} private: AstJumpLabel* m_labelp; // [After V3Jump] Pointer to declaration public: AstJumpGo(FileLine* fl, AstJumpLabel* labelp) : AstNodeStmt(fl) { m_labelp = labelp; } ASTNODE_NODE_FUNCS(JumpGo, JUMPGO) virtual const char* broken() const { BROKEN_RTN(!labelp()->brokeExistsAbove()); return NULL; } virtual void cloneRelink() { if (m_labelp->clonep()) m_labelp = m_labelp->clonep()->castJumpLabel(); } virtual void dump(ostream& str); virtual int instrCount() const { return instrCountBranch(); } virtual V3Hash sameHash() const { return V3Hash(labelp()); } virtual bool same(AstNode* samep) const { // Also same if identical tree structure all the way down, but hard to detect return labelp()==samep->castJumpGo()->labelp(); } virtual bool isGateOptimizable() const { return false; } virtual bool isBrancher() const { return true; } // SPECIAL: We don't process code after breaks AstJumpLabel* labelp() const { return m_labelp; } }; class AstUntilStable : public AstNodeStmt { // Quasi-while loop until given signals are stable // Parents: CFUNC (generally) // Children: VARREF, statements public: AstUntilStable(FileLine* fileline, AstVarRef* stablesp, AstNode* bodysp) : AstNodeStmt(fileline) { addNOp2p(stablesp); addNOp3p(bodysp); } ASTNODE_NODE_FUNCS(UntilStable, UNTILSTABLE) AstVarRef* stablesp() const { return op2p()->castVarRef(); } // op2= list of variables that must become stable AstNode* bodysp() const { return op3p()->castNode(); } // op3= body of loop void addStablesp(AstVarRef* newp) { addOp2p(newp); } void addBodysp(AstNode* newp) { addOp3p(newp); } virtual bool isGateOptimizable() const { return false; } // Not relevant virtual bool isPredictOptimizable() const { return false; } // Not relevant virtual int instrCount() const { return instrCountBranch(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstChangeXor : public AstNodeBiComAsv { // A comparison to determine change detection, common & must be fast. // Returns 32-bit or 64-bit value where 0 indicates no change. // Parents: OR or LOGOR // Children: VARREF public: AstChangeXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeSetUInt32(); // Always used on, and returns word entities } ASTNODE_NODE_FUNCS(ChangeXor, CHANGEXOR) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opChangeXor(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f^ %r)"; } virtual string emitC() { return "VL_CHANGEXOR_%li(%lw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "^"; } virtual bool cleanOut() {return false;} // Lclean && Rclean virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs(); } }; class AstChangeDet : public AstNodeStmt { // A comparison to determine change detection, common & must be fast. private: bool m_clockReq; // Type of detection public: // Null lhs+rhs used to indicate change needed with no spec vars AstChangeDet(FileLine* fl, AstNode* lhsp, AstNode* rhsp, bool clockReq) : AstNodeStmt(fl) { setNOp1p(lhsp); setNOp2p(rhsp); m_clockReq=clockReq; } ASTNODE_NODE_FUNCS(ChangeDet, CHANGEDET) AstNode* lhsp() const { return op1p(); } AstNode* rhsp() const { return op2p(); } bool isClockReq() const { return m_clockReq; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstBegin : public AstNode { // A Begin/end named block, only exists shortly after parsing until linking // Parents: statement // Children: statements private: string m_name; // Name of block bool m_unnamed; // Originally unnamed bool m_generate; // Underneath a generate public: // Node that simply puts name into the output stream AstBegin(FileLine* fileline, const string& name, AstNode* stmtsp, bool generate=false) : AstNode(fileline) , m_name(name) { addNOp1p(stmtsp); m_unnamed = (name==""); m_generate = generate; } ASTNODE_NODE_FUNCS(Begin, BEGIN) virtual void dump(ostream& str); virtual string name() const { return m_name; } // * = Block name virtual void name(const string& name) { m_name = name; } // op1 = Statements AstNode* stmtsp() const { return op1p()->castNode(); } // op1 = List of statements void addStmtsp(AstNode* nodep) { addNOp1p(nodep); } AstNode* genforp() const { return op2p(); } // op2 = GENFOR, if applicable, // might NOT be a GenFor, as loop unrolling replaces with Begin void addGenforp(AstGenFor* nodep) { addOp2p(nodep); } bool unnamed() const { return m_unnamed; } void generate(bool flag) { m_generate = flag; } bool generate() const { return m_generate; } }; class AstInitial : public AstNode { public: AstInitial(FileLine* fl, AstNode* bodysp) : AstNode(fl) { addNOp1p(bodysp); } ASTNODE_NODE_FUNCS(Initial, INITIAL) AstNode* bodysp() const { return op1p()->castNode(); } // op1 = Expressions to evaluate // Special accessors bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } }; class AstFinal : public AstNode { public: AstFinal(FileLine* fl, AstNode* bodysp) : AstNode(fl) { addNOp1p(bodysp); } ASTNODE_NODE_FUNCS(Final, FINAL) AstNode* bodysp() const { return op1p()->castNode(); } // op1 = Expressions to evaluate }; class AstInside : public AstNodeMath { public: AstInside(FileLine* fl, AstNode* exprp, AstNode* itemsp) : AstNodeMath(fl) { addOp1p(exprp); addOp2p(itemsp); dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Inside, INSIDE) AstNode* exprp() const { return op1p()->castNode(); } // op1 = LHS expression to compare with AstNode* itemsp() const { return op2p()->castNode(); } // op2 = RHS, possibly a list of expr or AstInsideRange virtual string emitVerilog() { return "%l inside { %r }"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return false; } // NA }; class AstInsideRange : public AstNodeMath { public: AstInsideRange(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeMath(fl) { addOp1p(lhsp); addOp2p(rhsp); } ASTNODE_NODE_FUNCS(InsideRange, INSIDERANGE) AstNode* lhsp() const { return op1p()->castNode(); } // op1 = LHS AstNode* rhsp() const { return op2p()->castNode(); } // op2 = RHS virtual string emitVerilog() { return "[%l:%r]"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return false; } // NA }; class AstInitArray : public AstNode { // Set a var to a large list of values // The values must be in sorted order, and not exceed the size of the var's array. // The first value on the initsp() list is for the lo() index of the array. // Parents: ASTVAR::init() // Children: CONSTs... public: AstInitArray(FileLine* fl, AstNodeArrayDType* newDTypep, AstNode* initsp) : AstNode(fl) { dtypep(newDTypep); addNOp1p(initsp); } ASTNODE_NODE_FUNCS(InitArray, INITARRAY) AstNode* initsp() const { return op1p()->castNode(); } // op1 = Initial value expressions void addInitsp(AstNode* newp) { addOp1p(newp); } virtual bool hasDType() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstPragma : public AstNode { private: AstPragmaType m_pragType; // Type of pragma public: // Pragmas don't result in any output code, they're just flags that affect // other processing in verilator. AstPragma(FileLine* fl, AstPragmaType pragType) : AstNode(fl) { m_pragType = pragType; } ASTNODE_NODE_FUNCS(Pragma, PRAGMA) AstPragmaType pragType() const { return m_pragType; } // *=type of the pragma virtual V3Hash sameHash() const { return V3Hash(pragType()); } virtual bool isPredictOptimizable() const { return false; } virtual bool same(AstNode* samep) const { return pragType()==samep->castPragma()->pragType(); } }; class AstStop : public AstNodeStmt { public: AstStop(FileLine* fl) : AstNodeStmt(fl) {} ASTNODE_NODE_FUNCS(Stop, STOP) virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } // SPECIAL: $display has 'visual' ordering virtual bool isOutputter() const { return true; } // SPECIAL: $display makes output virtual bool isUnlikely() const { return true; } virtual int instrCount() const { return 0; } // Rarely executes virtual V3Hash sameHash() const { return V3Hash(fileline()->lineno()); } virtual bool same(AstNode* samep) const { return fileline() == samep->fileline(); } }; class AstFinish : public AstNodeStmt { public: AstFinish(FileLine* fl) : AstNodeStmt(fl) {} ASTNODE_NODE_FUNCS(Finish, FINISH) virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } // SPECIAL: $display has 'visual' ordering virtual bool isOutputter() const { return true; } // SPECIAL: $display makes output virtual bool isUnlikely() const { return true; } virtual int instrCount() const { return 0; } // Rarely executes virtual V3Hash sameHash() const { return V3Hash(fileline()->lineno()); } virtual bool same(AstNode* samep) const { return fileline() == samep->fileline(); } }; class AstTraceDecl : public AstNodeStmt { // Trace point declaration // Separate from AstTraceInc; as a declaration can't be deleted // Parents: {statement list} // Children: none private: string m_showname; // Name of variable uint32_t m_code; // Trace identifier code; converted to ASCII by trace routines VNumRange m_bitRange; // Property of var the trace details VNumRange m_arrayRange; // Property of var the trace details uint32_t m_codeInc; // Code increment public: AstTraceDecl(FileLine* fl, const string& showname, AstNode* valuep, const VNumRange& bitRange, const VNumRange& arrayRange) : AstNodeStmt(fl) , m_showname(showname), m_bitRange(bitRange), m_arrayRange(arrayRange) { dtypeFrom(valuep); m_code = 0; m_codeInc = ((arrayRange.ranged() ? arrayRange.elements() : 1) * valuep->dtypep()->widthWords()); } virtual int instrCount() const { return 100; } // Large... ASTNODE_NODE_FUNCS(TraceDecl, TRACEDECL) virtual string name() const { return m_showname; } virtual bool maybePointedTo() const { return true; } virtual bool hasDType() const { return true; } virtual bool same(AstNode* samep) const { return false; } string showname() const { return m_showname; } // * = Var name // Details on what we're tracing uint32_t code() const { return m_code; } void code(uint32_t code) { m_code=code; } uint32_t codeInc() const { return m_codeInc; } const VNumRange& bitRange() const { return m_bitRange; } const VNumRange& arrayRange() const { return m_arrayRange; } }; class AstTraceInc : public AstNodeStmt { // Trace point; incremental change detect and dump // Parents: {statement list} // Children: incremental value private: AstTraceDecl* m_declp; // [After V3Trace] Pointer to declaration public: AstTraceInc(FileLine* fl, AstTraceDecl* declp, AstNode* valuep) : AstNodeStmt(fl) { dtypeFrom(declp); m_declp = declp; addNOp2p(valuep); } ASTNODE_NODE_FUNCS(TraceInc, TRACEINC) virtual const char* broken() const { BROKEN_RTN(!declp()->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_declp->clonep()) m_declp = m_declp->clonep()->castTraceDecl(); } virtual void dump(ostream& str); virtual int instrCount() const { return 10+2*instrCountLd(); } virtual bool hasDType() const { return true; } virtual V3Hash sameHash() const { return V3Hash(declp()); } virtual bool same(AstNode* samep) const { return declp()==samep->castTraceInc()->declp(); } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isOutputter() const { return true; } // but isPure() true // op1 = Statements before the value AstNode* precondsp() const { return op1p()->castNode(); } // op1= prepare statements for condition (exec every loop) void addPrecondsp(AstNode* newp) { addOp1p(newp); } // op2 = Value to trace AstTraceDecl* declp() const { return m_declp; } // Where defined AstNode* valuep() const { return op2p()->castNode(); } }; class AstActive : public AstNode { // Block of code with sensitivity activation // Parents: MODULE | CFUNC // Children: SENTREE, statements private: string m_name; AstSenTree* m_sensesp; public: AstActive(FileLine* fileline, const string& name, AstSenTree* sensesp) : AstNode(fileline) { m_name = name; // Copy it UASSERT(sensesp, "Sensesp required arg"); m_sensesp = sensesp; } ASTNODE_NODE_FUNCS(Active, ACTIVE) virtual void dump(ostream& str=cout); virtual string name() const { return m_name; } virtual const char* broken() const { BROKEN_RTN(m_sensesp && !m_sensesp->brokeExists()); return NULL; } virtual void cloneRelink() { if (m_sensesp->clonep()) { m_sensesp = m_sensesp->clonep()->castSenTree(); UASSERT(m_sensesp, "Bad clone cross link: "<castSenTree(); } // op2 = Combo logic AstNode* stmtsp() const { return op2p()->castNode(); } void addStmtsp(AstNode* nodep) { addOp2p(nodep); } // METHODS bool hasInitial() const { return m_sensesp->hasInitial(); } bool hasSettle() const { return m_sensesp->hasSettle(); } bool hasClocked() const { return m_sensesp->hasClocked(); } }; class AstAttrOf : public AstNode { private: // Return a value of a attribute, for example a LSB or array LSB of a signal AstAttrType m_attrType; // What sort of extraction public: AstAttrOf(FileLine* fl, AstAttrType attrtype, AstNode* fromp=NULL, AstNode* dimp=NULL) : AstNode(fl) { setNOp1p(fromp); setNOp2p(dimp); m_attrType = attrtype; } ASTNODE_NODE_FUNCS(AttrOf, ATTROF) AstNode* fromp() const { return op1p(); } AstNode* dimp() const { return op2p(); } AstAttrType attrType() const { return m_attrType; } virtual void dump(ostream& str=cout); }; class AstScopeName : public AstNodeMath { // For display %m and DPI context imports // Parents: DISPLAY // Children: TEXT private: bool m_dpiExport; // Is for dpiExport public: AstScopeName(FileLine* fl) : AstNodeMath(fl), m_dpiExport(false) { dtypeSetUInt64(); } ASTNODE_NODE_FUNCS(ScopeName, SCOPENAME) virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return m_dpiExport==samep->castScopeName()->m_dpiExport; } virtual string emitVerilog() { return ""; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } AstText* scopeAttrp() const { return op1p()->castText(); } void scopeAttrp(AstNode* nodep) { addOp1p(nodep); } AstText* scopeEntrp() const { return op2p()->castText(); } void scopeEntrp(AstNode* nodep) { addOp2p(nodep); } string scopeSymName() const; // Name for __Vscope variable including children string scopeDpiName() const; // Name for DPI import scope string scopePrettyName() const; // Name for __Vscope printing bool dpiExport() const { return m_dpiExport; } void dpiExport(bool flag) { m_dpiExport=flag; } }; class AstUdpTable : public AstNode { public: AstUdpTable(FileLine* fl, AstNode* bodysp) : AstNode(fl) { addNOp1p(bodysp); } ASTNODE_NODE_FUNCS(UdpTable, UDPTABLE) AstUdpTableLine* bodysp() const { return op1p()->castUdpTableLine(); } // op1 = List of UdpTableLines }; class AstUdpTableLine : public AstNode { string m_text; public: AstUdpTableLine(FileLine* fl, const string& text) : AstNode(fl), m_text(text) {} ASTNODE_NODE_FUNCS(UdpTableLine, UDPTABLELINE) virtual string name() const { return m_text; } string text() const { return m_text; } }; //====================================================================== // non-ary ops class AstRand : public AstNodeTermop { // Return a random number, based upon width() private: bool m_reset; // Random reset, versus always random public: AstRand(FileLine* fl, AstNodeDType* dtp, bool reset) : AstNodeTermop(fl) { dtypep(dtp); m_reset=reset; } AstRand(FileLine* fl) : AstNodeTermop(fl), m_reset(false) { } ASTNODE_NODE_FUNCS(Rand, RAND) virtual string emitVerilog() { return "%f$random"; } virtual string emitC() { return (m_reset ? "VL_RAND_RESET_%nq(%nw, %P)" :"VL_RANDOM_%nq(%nw, %P)"); } virtual bool cleanOut() { return true; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual int instrCount() const { return instrCountPli(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstTime : public AstNodeTermop { public: AstTime(FileLine* fl) : AstNodeTermop(fl) { dtypeSetUInt64(); } ASTNODE_NODE_FUNCS(Time, TIME) virtual string emitVerilog() { return "%f$time"; } virtual string emitC() { return "VL_TIME_%nq()"; } virtual bool cleanOut() { return true; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual int instrCount() const { return instrCountTime(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstTimeD : public AstNodeTermop { public: AstTimeD(FileLine* fl) : AstNodeTermop(fl) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(TimeD, TIMED) virtual string emitVerilog() { return "%f$realtime"; } virtual string emitC() { return "VL_TIME_D()"; } virtual bool cleanOut() { return true; } virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual int instrCount() const { return instrCountTime(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstUCFunc : public AstNodeMath { // User's $c function // Perhaps this should be an AstNodeListop; but there's only one list math right now public: AstUCFunc(FileLine* fl, AstNode* exprsp) : AstNodeMath(fl) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(UCFunc, UCFUNC) virtual bool cleanOut() { return false; } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } AstNode* bodysp() const { return op1p()->castNode(); } // op1= expressions to print virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } virtual bool isGateOptimizable() const { return false; } virtual bool isSubstOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual int instrCount() const { return instrCountPli(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; //====================================================================== // Unary ops class AstNegate : public AstNodeUniop { public: AstNegate(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Negate, NEGATE) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNegate(lhs); } virtual string emitVerilog() { return "%f(- %l)"; } virtual string emitC() { return "VL_NEGATE_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return true;} }; class AstNegateD : public AstNodeUniop { public: AstNegateD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(NegateD, NEGATED) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNegateD(lhs); } virtual string emitVerilog() { return "%f(- %l)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "-"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstRedAnd : public AstNodeUniop { public: AstRedAnd(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(RedAnd, REDAND) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedAnd(lhs); } virtual string emitVerilog() { return "%f(& %l)"; } virtual string emitC() { return "VL_REDAND_%nq%lq(%nw,%lw, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} }; class AstRedOr : public AstNodeUniop { public: AstRedOr(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(RedOr, REDOR) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedOr(lhs); } virtual string emitVerilog() { return "%f(| %l)"; } virtual string emitC() { return "VL_REDOR_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} }; class AstRedXor : public AstNodeUniop { public: AstRedXor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(RedXor, REDXOR) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXor(lhs); } virtual string emitVerilog() { return "%f(^ %l)"; } virtual string emitC() { return "VL_REDXOR_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {int w = lhsp()->width(); return (w!=1 && w!=2 && w!=4 && w!=8 && w!=16); } virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return 1+V3Number::log2b(width()); } }; class AstRedXnor : public AstNodeUniop { // AstRedXnors are replaced with AstRedXors in V3Const. public: AstRedXnor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(RedXnor, REDXNOR) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXnor(lhs); } virtual string emitVerilog() { return "%f(~^ %l)"; } virtual string emitC() { v3fatalSrc("REDXNOR should have became REDXOR"); return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return 1+V3Number::log2b(width()); } }; class AstLogNot : public AstNodeUniop { public: AstLogNot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogNot, LOGNOT) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opLogNot(lhs); } virtual string emitVerilog() { return "%f(! %l)"; } virtual string emitC() { return "VL_LOGNOT_%nq%lq(%nw,%lw, %P, %li)"; } virtual string emitSimpleOperator() { return "!"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} }; class AstNot : public AstNodeUniop { public: AstNot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Not, NOT) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNot(lhs); } virtual string emitVerilog() { return "%f(~ %l)"; } virtual string emitC() { return "VL_NOT_%lq(%lW, %P, %li)"; } virtual string emitSimpleOperator() { return "~"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return true;} }; class AstExtend : public AstNodeUniop { // Expand a value into a wider entity by 0 extension. Width is implied from nodep->width() public: AstExtend(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} AstExtend(FileLine* fl, AstNode* lhsp, int width) : AstNodeUniop(fl, lhsp) { dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); } ASTNODE_NODE_FUNCS(Extend, EXTEND) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); } virtual string emitVerilog() { return "%l"; } virtual string emitC() { return "VL_EXTEND_%nq%lq(%nw,%lw, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts virtual int instrCount() const { return 0; } }; class AstExtendS : public AstNodeUniop { // Expand a value into a wider entity by sign extension. Width is implied from nodep->width() public: AstExtendS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} AstExtendS(FileLine* fl, AstNode* lhsp, int width) : AstNodeUniop(fl, lhsp) { // Important that widthMin be correct, as opExtend requires it after V3Expand dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); } ASTNODE_NODE_FUNCS(ExtendS, EXTENDS) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opExtendS(lhs, lhsp()->widthMinV()); } virtual string emitVerilog() { return "%l"; } virtual string emitC() { return "VL_EXTENDS_%nq%lq(%nw,%lw, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts virtual int instrCount() const { return 0; } virtual bool signedFlavor() const { return true; } }; class AstSigned : public AstNodeUniop { // $signed(lhs) public: AstSigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { if (v3Global.assertDTypesResolved()) { v3fatalSrc("not coded to create after dtypes resolved"); } } ASTNODE_NODE_FUNCS(Signed, SIGNED) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); } virtual string emitVerilog() { return "%f$signed(%l)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return true;} // Eliminated before matters virtual int instrCount() const { return 0; } }; class AstUnsigned : public AstNodeUniop { // $unsigned(lhs) public: AstUnsigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { if (v3Global.assertDTypesResolved()) { v3fatalSrc("not coded to create after dtypes resolved"); } } ASTNODE_NODE_FUNCS(Unsigned, UNSIGNED) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); } virtual string emitVerilog() { return "%f$unsigned(%l)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return true;} // Eliminated before matters virtual int instrCount() const { return 0; } }; class AstRToIS : public AstNodeUniop { // $rtoi(lhs) public: AstRToIS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetSigned32(); } ASTNODE_NODE_FUNCS(RToIS, RTOIS) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRToIS(lhs); } virtual string emitVerilog() { return "%f$rtoi(%l)"; } virtual string emitC() { return "VL_RTOI_I_D(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstRToIRoundS : public AstNodeUniop { public: AstRToIRoundS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetSigned32(); } ASTNODE_NODE_FUNCS(RToIRoundS, RTOIROUNDS) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRToIRoundS(lhs); } virtual string emitVerilog() { return "%f$rtoi_rounded(%l)"; } virtual string emitC() { return "VL_RTOIROUND_I_D(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstIToRD : public AstNodeUniop { public: AstIToRD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(IToRD, ITORD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIToRD(lhs); } virtual string emitVerilog() { return "%f$itor(%l)"; } virtual string emitC() { return "VL_ITOR_D_I(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstRealToBits : public AstNodeUniop { public: AstRealToBits(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetUInt64(); } ASTNODE_NODE_FUNCS(RealToBits, REALTOBITS) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRealToBits(lhs); } virtual string emitVerilog() { return "%f$realtobits(%l)"; } virtual string emitC() { return "VL_CVT_Q_D(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstBitsToRealD : public AstNodeUniop { public: AstBitsToRealD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(BitsToRealD, BITSTOREALD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opBitsToRealD(lhs); } virtual string emitVerilog() { return "%f$bitstoreal(%l)"; } virtual string emitC() { return "VL_CVT_D_Q(%li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool sizeMattersLhs() {return false;} // Eliminated before matters virtual int instrCount() const { return instrCountDouble(); } }; class AstCLog2 : public AstNodeUniop { public: AstCLog2(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(CLog2, CLOG2) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCLog2(lhs); } virtual string emitVerilog() { return "%f$clog2(%l)"; } virtual string emitC() { return "VL_CLOG2_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*16; } }; class AstCountOnes : public AstNodeUniop { // Number of bits set in vector public: AstCountOnes(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(CountOnes, COUNTONES) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCountOnes(lhs); } virtual string emitVerilog() { return "%f$countones(%l)"; } virtual string emitC() { return "VL_COUNTONES_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*16; } }; class AstIsUnknown : public AstNodeUniop { // True if any unknown bits public: AstIsUnknown(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(IsUnknown, ISUNKNOWN) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIsUnknown(lhs); } virtual string emitVerilog() { return "%f$isunknown(%l)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} }; class AstOneHot : public AstNodeUniop { // True if only single bit set in vector public: AstOneHot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(OneHot, ONEHOT) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot(lhs); } virtual string emitVerilog() { return "%f$onehot(%l)"; } virtual string emitC() { return "VL_ONEHOT_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*4; } }; class AstOneHot0 : public AstNodeUniop { // True if only single bit, or no bits set in vector public: AstOneHot0(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(OneHot0, ONEHOT0) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot0(lhs); } virtual string emitVerilog() { return "%f$onehot0(%l)"; } virtual string emitC() { return "VL_ONEHOT0_%lq(%lW, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*3; } }; class AstCast : public AstNode { // Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc public: AstCast(FileLine* fl, AstNode* lhsp, AstNodeDType* dtp) : AstNode(fl) { setOp1p(lhsp); setOp2p(dtp); dtypeFrom(dtp); } ASTNODE_NODE_FUNCS(Cast, CAST) virtual bool hasDType() const { return true; } virtual string emitVerilog() { return "((%d)'(%l))"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} AstNode* lhsp() const { return op1p(); } AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op2p()->castNodeDType(); } }; class AstCastParse : public AstNode { // Cast to appropriate type, where we haven't determined yet what the data type is public: AstCastParse(FileLine* fl, AstNode* lhsp, AstNode* dtp) : AstNode(fl) { setOp1p(lhsp); setOp2p(dtp); } ASTNODE_NODE_FUNCS(CastParse, CASTPARSE) virtual string emitVerilog() { return "((%d)'(%l))"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} AstNode* lhsp() const { return op1p(); } AstNode* dtp() const { return op2p(); } }; class AstCastSize : public AstNode { // Cast to specific size; signed/twostate inherited from lower element per IEEE public: AstCastSize(FileLine* fl, AstNode* lhsp, AstConst* rhsp) : AstNode(fl) { setOp1p(lhsp); setOp2p(rhsp); } ASTNODE_NODE_FUNCS(CastSize, CASTSIZE) virtual string emitVerilog() { return "((%r)'(%l))"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} AstNode* lhsp() const { return op1p(); } AstNode* rhsp() const { return op2p(); } }; class AstCCast : public AstNodeUniop { // Cast to C-based data type private: int m_size; public: AstCCast(FileLine* fl, AstNode* lhsp, int setwidth, int minwidth=-1) : AstNodeUniop(fl, lhsp) { m_size=setwidth; if (setwidth) { if (minwidth==-1) minwidth=setwidth; dtypeSetLogicSized(setwidth,minwidth,AstNumeric::UNSIGNED); } } AstCCast(FileLine* fl, AstNode* lhsp, AstNode* typeFromp) : AstNodeUniop(fl, lhsp) { dtypeFrom(typeFromp); m_size=width(); } ASTNODE_NODE_FUNCS(CCast, CCAST) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); } virtual string emitVerilog() { return "%f$_CAST(%l)"; } virtual string emitC() { return "VL_CAST_%nq%lq(%nw,%lw, %P, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} // Special cased in V3Cast virtual V3Hash sameHash() const { return V3Hash(size()); } virtual bool same(AstNode* samep) const { return size()==samep->castCCast()->size(); } virtual void dump(ostream& str=cout); // int size() const { return m_size; } }; class AstCvtPackString : public AstNodeUniop { // Convert to Verilator Packed String (aka verilog "string") public: AstCvtPackString(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetString(); } // Really, width should be dtypep -> STRING ASTNODE_NODE_FUNCS(CvtPackString, CVTPACKSTRING) virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; } virtual string emitVerilog() { return "%f$_CAST(%l)"; } virtual string emitC() { return "VL_CVT_PACK_STR_N%lq(%lW, %li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; class AstFEof : public AstNodeUniop { public: AstFEof(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(FEof, FEOF) virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; } virtual string emitVerilog() { return "%f$feof(%l)"; } virtual string emitC() { return "(%li ? feof(VL_CVT_I_FP(%li)) : true)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*16; } virtual bool isPure() const { return false; } // SPECIAL: $display has 'visual' ordering AstNode* filep() const { return lhsp(); } }; class AstFGetC : public AstNodeUniop { public: AstFGetC(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} ASTNODE_NODE_FUNCS(FGetC, FGETC) virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; } virtual string emitVerilog() { return "%f$fgetc(%l)"; } // Non-existent filehandle returns EOF virtual string emitC() { return "(%li ? fgetc(VL_CVT_I_FP(%li)) : -1)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return widthInstrs()*64; } virtual bool isPure() const { return false; } // SPECIAL: $display has 'visual' ordering AstNode* filep() const { return lhsp(); } }; class AstCeilD : public AstNodeUniop { public: AstCeilD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(CeilD, CEILD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(ceil(lhs.toDouble())); } virtual string emitVerilog() { return "%f$ceil(%l)"; } virtual string emitC() { return "ceil(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstExpD : public AstNodeUniop { public: AstExpD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(ExpD, EXPD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(exp(lhs.toDouble())); } virtual string emitVerilog() { return "%f$exp(%l)"; } virtual string emitC() { return "exp(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstFloorD : public AstNodeUniop { public: AstFloorD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(FloorD, FLOORD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(floor(lhs.toDouble())); } virtual string emitVerilog() { return "%f$floor(%l)"; } virtual string emitC() { return "floor(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstLogD : public AstNodeUniop { public: AstLogD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(LogD, LOGD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(log(lhs.toDouble())); } virtual string emitVerilog() { return "%f$ln(%l)"; } virtual string emitC() { return "log(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstLog10D : public AstNodeUniop { public: AstLog10D(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(Log10D, LOG10D) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(log10(lhs.toDouble())); } virtual string emitVerilog() { return "%f$log10(%l)"; } virtual string emitC() { return "log10(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; class AstSqrtD : public AstNodeUniop { public: AstSqrtD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(SqrtD, SQRTD) virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.setDouble(sqrt(lhs.toDouble())); } virtual string emitVerilog() { return "%f$sqrt(%l)"; } virtual string emitC() { return "sqrt(%li)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual int instrCount() const { return instrCountDoubleTrig(); } virtual bool doubleFlavor() const { return true; } }; //====================================================================== // Binary ops class AstLogOr : public AstNodeBiop { public: AstLogOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogOr, LOGOR) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogOr(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f|| %r)"; } virtual string emitC() { return "VL_LOGOR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "||"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } }; class AstLogAnd : public AstNodeBiop { public: AstLogAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogAnd, LOGAND) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogAnd(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f&& %r)"; } virtual string emitC() { return "VL_LOGAND_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "&&"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } }; class AstLogIf : public AstNodeBiop { public: AstLogIf(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogIf, LOGIF) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogIf(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f-> %r)"; } virtual string emitC() { return "VL_LOGIF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "->"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } }; class AstLogIff : public AstNodeBiCom { public: AstLogIff(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LogIff, LOGIFF) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogIff(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<-> %r)"; } virtual string emitC() { return "VL_LOGIFF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "<->"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } }; class AstOr : public AstNodeBiComAsv { public: AstOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Or, OR) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opOr(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f| %r)"; } virtual string emitC() { return "VL_OR_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "|"; } virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean && Rclean virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstAnd : public AstNodeBiComAsv { public: AstAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(And, AND) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAnd(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f& %r)"; } virtual string emitC() { return "VL_AND_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "&"; } virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean || Rclean virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstXor : public AstNodeBiComAsv { public: AstXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Xor, XOR) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXor(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f^ %r)"; } virtual string emitC() { return "VL_XOR_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "^"; } virtual bool cleanOut() {return false;} // Lclean && Rclean virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstXnor : public AstNodeBiComAsv { public: AstXnor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Xnor, XNOR) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXnor(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f^ ~ %r)"; } virtual string emitC() { return "VL_XNOR_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "^ ~"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} }; class AstEq : public AstNodeBiCom { public: AstEq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Eq, EQ) static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstEq/AstEqD virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f== %r)"; } virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstEqD : public AstNodeBiCom { public: AstEqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(EqD, EQD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEqD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f== %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstEqN : public AstNodeBiCom { public: AstEqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(EqN, EQN) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEqN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f== %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstNeq : public AstNodeBiCom { public: AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Neq, NEQ) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!= %r)"; } virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstNeqD : public AstNodeBiCom { public: AstNeqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(NeqD, NEQD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeqD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstNeqN : public AstNodeBiCom { public: AstNeqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(NeqN, NEQN) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeqN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstLt : public AstNodeBiop { public: AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Lt, LT) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLt(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f< %r)"; } virtual string emitC() { return "VL_LT_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "<"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstLtD : public AstNodeBiop { public: AstLtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LtD, LTD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f< %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "<"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstLtS : public AstNodeBiop { public: AstLtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LtS, LTS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f< %r)"; } virtual string emitC() { return "VL_LTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstLtN : public AstNodeBiop { public: AstLtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LtN, LTN) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f< %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "<"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstGt : public AstNodeBiop { public: AstGt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Gt, GT) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGt(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f> %r)"; } virtual string emitC() { return "VL_GT_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ">"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstGtD : public AstNodeBiop { public: AstGtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GtD, GTD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f> %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return ">"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstGtS : public AstNodeBiop { public: AstGtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GtS, GTS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f> %r)"; } virtual string emitC() { return "VL_GTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstGtN : public AstNodeBiop { public: AstGtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GtN, GTN) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f> %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return ">"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstGte : public AstNodeBiop { public: AstGte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Gte, GTE) static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstGte/AstGteS/AstGteD virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGte(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>= %r)"; } virtual string emitC() { return "VL_GTE_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ">="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstGteD : public AstNodeBiop { public: AstGteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GteD, GTED) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return ">="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstGteS : public AstNodeBiop { public: AstGteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GteS, GTES) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>= %r)"; } virtual string emitC() { return "VL_GTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstGteN : public AstNodeBiop { public: AstGteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(GteN, GTEN) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return ">="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstLte : public AstNodeBiop { public: AstLte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(Lte, LTE) static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstLte/AstLteS/AstLteD virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLte(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<= %r)"; } virtual string emitC() { return "VL_LTE_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "<="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstLteD : public AstNodeBiop { public: AstLteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LteD, LTED) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "<="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstLteS : public AstNodeBiop { public: AstLteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LteS, LTES) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<= %r)"; } virtual string emitC() { return "VL_LTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstLteN : public AstNodeBiop { public: AstLteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(LteN, LTEN) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteN(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<= %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "<="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstShiftL : public AstNodeBiop { public: AstShiftL(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0) : AstNodeBiop(fl, lhsp, rhsp) { if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(ShiftL, SHIFTL) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftL(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f<< %r)"; } virtual string emitC() { return "VL_SHIFTL_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "<<"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} }; class AstShiftR : public AstNodeBiop { public: AstShiftR(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0) : AstNodeBiop(fl, lhsp, rhsp) { if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(ShiftR, SHIFTR) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftR(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f>> %r)"; } virtual string emitC() { return "VL_SHIFTR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ">>"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} // LHS size might be > output size, so don't want to force size }; class AstShiftRS : public AstNodeBiop { // Shift right with sign extension, >>> operator // Output data type's width determines which bit is used for sign extension public: AstShiftRS(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0) : AstNodeBiop(fl, lhsp, rhsp) { // Important that widthMin be correct, as opExtend requires it after V3Expand if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::SIGNED); } } ASTNODE_NODE_FUNCS(ShiftRS, SHIFTRS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftRS(lhs,rhs,lhsp()->widthMinV()); } virtual string emitVerilog() { return "%k(%l %f>>> %r)"; } virtual string emitC() { return "VL_SHIFTRS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool signedFlavor() const { return true; } }; class AstAdd : public AstNodeBiComAsv { public: AstAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Add, ADD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAdd(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f+ %r)"; } virtual string emitC() { return "VL_ADD_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "+"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} }; class AstAddD : public AstNodeBiComAsv { public: AstAddD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(AddD, ADDD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAddD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f+ %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "+"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstSub : public AstNodeBiop { public: AstSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Sub, SUB) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSub(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f- %r)"; } virtual string emitC() { return "VL_SUB_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "-"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} }; class AstSubD : public AstNodeBiop { public: AstSubD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(SubD, SUBD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSubD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f- %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "-"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstMul : public AstNodeBiComAsv { public: AstMul(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Mul, MUL) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMul(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f* %r)"; } virtual string emitC() { return "VL_MUL_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "*"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountMul(); } }; class AstMulD : public AstNodeBiComAsv { public: AstMulD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(MulD, MULD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f* %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "*"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return instrCountDouble(); } virtual bool doubleFlavor() const { return true; } }; class AstMulS : public AstNodeBiComAsv { public: AstMulS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(MulS, MULS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f* %r)"; } virtual string emitC() { return "VL_MULS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountMul(); } virtual bool signedFlavor() const { return true; } }; class AstDiv : public AstNodeBiop { public: AstDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Div, DIV) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDiv(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f/ %r)"; } virtual string emitC() { return "VL_DIV_%nq%lq%rq(%lw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountDiv(); } }; class AstDivD : public AstNodeBiop { public: AstDivD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(DivD, DIVD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f/ %r)"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual string emitSimpleOperator() { return "/"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDoubleDiv(); } virtual bool doubleFlavor() const { return true; } }; class AstDivS : public AstNodeBiop { public: AstDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(DivS, DIVS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f/ %r)"; } virtual string emitC() { return "VL_DIVS_%nq%lq%rq(%lw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountDiv(); } virtual bool signedFlavor() const { return true; } }; class AstModDiv : public AstNodeBiop { public: AstModDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(ModDiv, MODDIV) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDiv(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f%% %r)"; } virtual string emitC() { return "VL_MODDIV_%nq%lq%rq(%lw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountDiv(); } }; class AstModDivS : public AstNodeBiop { public: AstModDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(ModDivS, MODDIVS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDivS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f%% %r)"; } virtual string emitC() { return "VL_MODDIVS_%nq%lq%rq(%lw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual int instrCount() const { return widthInstrs()*instrCountDiv(); } virtual bool signedFlavor() const { return true; } }; class AstPow : public AstNodeBiop { public: AstPow(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(Pow, POW) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPow(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "VL_POW_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*instrCountMul()*10; } }; class AstPowD : public AstNodeBiop { public: AstPowD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetDouble(); } ASTNODE_NODE_FUNCS(PowD, POWD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowD(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "pow(%li,%ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountDoubleDiv()*5; } virtual bool doubleFlavor() const { return true; } }; class AstPowSU : public AstNodeBiop { public: AstPowSU(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(PowSU, POWSU) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowSU(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,0)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*instrCountMul()*10; } virtual bool signedFlavor() const { return true; } }; class AstPowSS : public AstNodeBiop { public: AstPowSS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(PowSS, POWSS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowSS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,1)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*instrCountMul()*10; } virtual bool signedFlavor() const { return true; } }; class AstPowUS : public AstNodeBiop { public: AstPowUS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(PowUS, POWUS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowUS(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f** %r)"; } virtual string emitC() { return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 0,1)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*instrCountMul()*10; } virtual bool signedFlavor() const { return true; } }; class AstEqCase : public AstNodeBiCom { public: AstEqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(EqCase, EQCASE) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseEq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f=== %r)"; } virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstNeqCase : public AstNodeBiCom { public: AstNeqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(NeqCase, NEQCASE) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseNeq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!== %r)"; } virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstEqWild : public AstNodeBiop { // Note wildcard operator rhs differs from lhs public: AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(EqWild, EQWILD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f==? %r)"; } virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "=="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstNeqWild : public AstNodeBiop { public: AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetLogicBool(); } ASTNODE_NODE_FUNCS(NeqWild, NEQWILD) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildNeq(lhs,rhs); } virtual string emitVerilog() { return "%k(%l %f!=? %r)"; } virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; } virtual string emitSimpleOperator() { return "!="; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstConcat : public AstNodeBiop { // If you're looking for {#{}}, see AstReplicate public: AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { if (lhsp->dtypep() && rhsp->dtypep()) { dtypeSetLogicSized(lhsp->dtypep()->width()+rhsp->dtypep()->width(), lhsp->dtypep()->width()+rhsp->dtypep()->width(), AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(Concat, CONCAT) virtual string emitVerilog() { return "%f{%l, %k%r}"; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcat(lhs,rhs); } virtual string emitC() { return "VL_CONCAT_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } }; class AstConcatN : public AstNodeBiop { // String concatenate public: AstConcatN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeSetString(); } ASTNODE_NODE_FUNCS(ConcatN, CONCATN) virtual string emitVerilog() { return "%f{%l, %k%r}"; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcatN(lhs,rhs); } virtual string emitC() { return "VL_CONCATN_NNN(%li, %ri)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return instrCountString(); } virtual bool stringFlavor() const { return true; } }; class AstReplicate : public AstNodeBiop { // Also used as a "Uniop" flavor of Concat, e.g. "{a}" // Verilog {rhs{lhs}} - Note rhsp() is the replicate value, not the lhsp() private: void init() { if (lhsp()) { if (AstConst* constp=rhsp()->castConst()) { dtypeSetLogicSized(lhsp()->width()*constp->toUInt(), lhsp()->width()*constp->toUInt(), AstNumeric::UNSIGNED); } } } public: AstReplicate(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { init(); } AstReplicate(FileLine* fl, AstNode* lhsp, uint32_t repCount) : AstNodeBiop(fl, lhsp, new AstConst(fl, repCount)) { init(); } ASTNODE_NODE_FUNCS(Replicate, REPLICATE) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opRepl(lhs,rhs); } virtual string emitVerilog() { return "%f{%r{%k%l}}"; } virtual string emitC() { return "VL_REPLICATE_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } }; class AstReplicateN : public AstNodeBiop { // String replicate private: void init() { dtypeSetString(); } public: AstReplicateN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { init(); } AstReplicateN(FileLine* fl, AstNode* lhsp, uint32_t repCount) : AstNodeBiop(fl, lhsp, new AstConst(fl, repCount)) { init(); } ASTNODE_NODE_FUNCS(ReplicateN, REPLICATEN) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opReplN(lhs,rhs); } virtual string emitVerilog() { return "%f{%r{%k%l}}"; } virtual string emitC() { return "VL_REPLICATEN_NN%rq(0,0,%rw, %li, %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } virtual bool stringFlavor() const { return true; } }; class AstStreamL : public AstNodeStream { // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp() public: AstStreamL(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStream(fl, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(StreamL, STREAML) virtual string emitVerilog() { return "%f{ << %r %k{%l} }"; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opStreamL(lhs,rhs); } virtual string emitC() { return "VL_STREAML_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; } virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } }; class AstStreamR : public AstNodeStream { // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp() public: AstStreamR(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStream(fl, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(StreamR, STREAMR) virtual string emitVerilog() { return "%f{ >> %r %k{%l} }"; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAssign(lhs); } virtual string emitC() { return isWide() ? "VL_ASSIGN_W(%nw, %P, %li)" : "%li"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*2; } }; class AstBufIf1 : public AstNodeBiop { // lhs is enable, rhs is data to drive // Note unlike the Verilog bufif1() UDP, this allows any width; each lhsp bit enables respective rhsp bit public: AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { dtypeFrom(lhsp); } ASTNODE_NODE_FUNCS(BufIf1, BUFIF1) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opBufIf1(lhs,rhs); } virtual string emitVerilog() { return "bufif(%r,%l)"; } virtual string emitC() { V3ERROR_NA; return "";} // Lclean || Rclean virtual string emitSimpleOperator() { V3ERROR_NA; return "";} // Lclean || Rclean virtual bool cleanOut() {V3ERROR_NA; return "";} // Lclean || Rclean virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} }; class AstFGetS : public AstNodeBiop { public: AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {} ASTNODE_NODE_FUNCS(FGetS, FGETS) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; } virtual string emitVerilog() { return "%f$fgets(%l,%r)"; } virtual string emitC() { return "VL_FGETS_%nqX%rq(%lw, %P, &(%li), %ri)"; } virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual int instrCount() const { return widthInstrs()*64; } AstNode* strgp() const { return lhsp(); } AstNode* filep() const { return rhsp(); } }; class AstPattern : public AstNodeMath { // Verilog '{a,b,c,d...} // Parents: AstNodeAssign, AstPattern, ... // Children: expression, AstPattern, AstPatReplicate public: AstPattern(FileLine* fl, AstNode* itemsp) : AstNodeMath(fl) { addNOp2p(itemsp); } ASTNODE_NODE_FUNCS(Pattern, PATTERN) virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; } virtual string emitC() { V3ERROR_NA; return "";} virtual string emitSimpleOperator() { V3ERROR_NA; return "";} virtual bool cleanOut() {V3ERROR_NA; return "";} virtual int instrCount() const { return widthInstrs(); } AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc }; class AstPatMember : public AstNodeMath { // Verilog '{a} or '{a{b}} // Parents: AstPattern // Children: expression, AstPattern, replication count private: bool m_default; public: AstPatMember(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* repp) : AstNodeMath(fl) { addOp1p(lhsp), setNOp2p(keyp), setNOp3p(repp); m_default = false; } ASTNODE_NODE_FUNCS(PatMember, PATMEMBER) virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; } virtual string emitVerilog() { return lhssp()?"%f{%r{%k%l}}":"%l"; } virtual string emitC() { V3ERROR_NA; return "";} virtual string emitSimpleOperator() { V3ERROR_NA; return "";} virtual bool cleanOut() {V3ERROR_NA; return "";} virtual int instrCount() const { return widthInstrs()*2; } AstNode* lhssp() const { return op1p(); } // op1 = expression to assign or another AstPattern (list if replicated) AstNode* keyp() const { return op2p(); } // op2 = assignment key (Const, id Text) AstNode* repp() const { return op3p(); } // op3 = replication count, or NULL for count 1 bool isDefault() const { return m_default; } void isDefault(bool flag) { m_default = flag; } }; //====================================================================== // SysVerilog assertions class AstVAssert : public AstNodeStmt { // Verilog Assertion // Parents: {statement list} // Children: expression, if pass statements, if fail statements public: AstVAssert(FileLine* fl, AstNode* propp, AstNode* passsp, AstNode* failsp) : AstNodeStmt(fl) { addOp1p(propp); addNOp2p(passsp); addNOp3p(failsp); } ASTNODE_NODE_FUNCS(VAssert, VASSERT) virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } AstNode* propp() const { return op1p(); } // op1 = property AstNode* passsp() const { return op2p(); } // op2 = if passes AstNode* failsp() const { return op3p(); } // op3 = if fails }; //====================================================================== // Assertions class AstClocking : public AstNode { // Set default clock region // Parents: MODULE // Children: Assertions public: AstClocking(FileLine* fl, AstNodeSenItem* sensesp, AstNode* bodysp) : AstNode(fl) { addOp1p(sensesp); addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(Clocking, CLOCKING) AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list AstNode* bodysp() const { return op2p(); } // op2 = Body }; //====================================================================== // PSL class AstPslClocked : public AstNode { // A clocked property // Parents: ASSERT|COVER (property) // Children: SENITEM, Properties public: AstPslClocked(FileLine* fl, AstNodeSenItem* sensesp, AstNode* disablep, AstNode* propp) : AstNode(fl) { addNOp1p(sensesp); addNOp2p(disablep); addOp3p(propp); } ASTNODE_NODE_FUNCS(PslClocked, PSLCLOCKED) virtual bool hasDType() const { return true; } // Used under PslCover, which expects a bool child AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list AstNode* disablep() const { return op2p(); } // op2 = disable AstNode* propp() const { return op3p(); } // op3 = property }; class AstPslCover : public AstNodeStmt { // Psl Cover // Parents: {statement list} // Children: expression, report string private: string m_name; // Name to report public: AstPslCover(FileLine* fl, AstNode* propp, AstNode* stmtsp, const string& name="") : AstNodeStmt(fl) , m_name(name) { addOp1p(propp); addNOp4p(stmtsp); } ASTNODE_NODE_FUNCS(PslCover, PSLCOVER) virtual string name() const { return m_name; } // * = Var name virtual V3Hash sameHash() const { return V3Hash(name()); } virtual bool same(AstNode* samep) const { return samep->name() == name(); } virtual void name(const string& name) { m_name = name; } AstNode* propp() const { return op1p(); } // op1 = property AstSenTree* sentreep() const { return op2p()->castSenTree(); } // op2 = clock domain void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain AstNode* coverincp() const { return op3p(); } // op3 = coverage node void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node AstNode* stmtsp() const { return op4p(); } // op4 = statements }; //====================================================================== // Text based nodes class AstText : public AstNodeText { private: bool m_tracking; // When emit, it's ok to parse the string to do indentation public: AstText(FileLine* fl, const string& textp, bool tracking=false) : AstNodeText(fl, textp), m_tracking(tracking) {} ASTNODE_NODE_FUNCS(Text, TEXT) void tracking(bool flag) { m_tracking = flag; } bool tracking() const { return m_tracking; } }; class AstScCtor : public AstNodeText { public: AstScCtor(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScCtor, SCCTOR) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScDtor : public AstNodeText { public: AstScDtor(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScDtor, SCDTOR) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScHdr : public AstNodeText { public: AstScHdr(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScHdr, SCHDR) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScImp : public AstNodeText { public: AstScImp(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScImp, SCIMP) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScImpHdr : public AstNodeText { public: AstScImpHdr(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScImpHdr, SCIMPHDR) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstScInt : public AstNodeText { public: AstScInt(FileLine* fl, const string& textp) : AstNodeText(fl, textp) {} ASTNODE_NODE_FUNCS(ScInt, SCINT) virtual bool isPure() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isOutputter() const { return true; } }; class AstUCStmt : public AstNodeStmt { // User $c statement public: AstUCStmt(FileLine* fl, AstNode* exprsp) : AstNodeStmt(fl) { addNOp1p(exprsp); } ASTNODE_NODE_FUNCS(UCStmt, UCSTMT) AstNode* bodysp() const { return op1p()->castNode(); } // op1= expressions to print virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } virtual bool isOutputter() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } }; //====================================================================== // Emit C nodes class AstCFile : public AstNode { // C++ output file // Parents: NETLIST // Children: nothing yet private: string m_name; ///< Filename bool m_slow:1; ///< Compile w/o optimization bool m_source:1; ///< Source file (vs header file) bool m_support:1; ///< Support file (non systemc) public: AstCFile(FileLine* fl, const string& name) : AstNode(fl) { m_name = name; m_slow = false; m_source = false; m_support = false; } ASTNODE_NODE_FUNCS(CFile, CFILE) virtual string name() const { return m_name; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } virtual void dump(ostream& str=cout); bool slow() const { return m_slow; } void slow(bool flag) { m_slow = flag; } bool source() const { return m_source; } void source(bool flag) { m_source = flag; } bool support() const { return m_support; } void support(bool flag) { m_support = flag; } }; class AstCFunc : public AstNode { // C++ function // Parents: MODULE/SCOPE // Children: VAR/statements private: AstCFuncType m_funcType; AstScope* m_scopep; string m_name; string m_cname; // C name, for dpiExports string m_rtnType; // void, bool, or other return type string m_argTypes; bool m_dontCombine:1; // V3Combine shouldn't compare this func tree, it's special bool m_skipDecl:1; // Don't declare it bool m_declPrivate:1; // Declare it private bool m_formCallTree:1; // Make a global function to call entire tree of functions bool m_slow:1; // Slow routine, called once or just at init time bool m_funcPublic:1; // From user public task/function bool m_isInline:1; // Inline function bool m_isStatic:1; // Function is declared static (no this) bool m_symProlog:1; // Setup symbol table for later instructions bool m_entryPoint:1; // User may call into this top level function bool m_pure:1; // Pure function bool m_dpiExport:1; // From dpi export bool m_dpiExportWrapper:1; // From dpi export; static function with dispatch table bool m_dpiImport:1; // From dpi import public: AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType="") : AstNode(fl) { m_funcType = AstCFuncType::FT_NORMAL; m_scopep = scopep; m_name = name; m_rtnType = rtnType; m_dontCombine = false; m_skipDecl = false; m_declPrivate = false; m_formCallTree = false; m_slow = false; m_funcPublic = false; m_isInline = false; m_isStatic = true; // Note defaults to static, later we see where thisp is needed m_symProlog = false; m_entryPoint = false; m_pure = false; m_dpiExport = false; m_dpiExportWrapper = false; m_dpiImport = false; } ASTNODE_NODE_FUNCS(CFunc, CFUNC) virtual string name() const { return m_name; } virtual const char* broken() const { BROKEN_RTN((m_scopep && !m_scopep->brokeExists())); return NULL; } virtual bool maybePointedTo() const { return true; } virtual void dump(ostream& str=cout); virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return ((funcType()==samep->castCFunc()->funcType()) && (rtnTypeVoid()==samep->castCFunc()->rtnTypeVoid()) && (argTypes()==samep->castCFunc()->argTypes()) && (!(dpiImport() || dpiExport()) || name()==samep->castCFunc()->name())); } // virtual void name(const string& name) { m_name = name; } virtual int instrCount() const { return dpiImport() ? instrCountDpi() : 0; } void cname(const string& name) { m_cname = name; } string cname() const { return m_cname; } AstScope* scopep() const { return m_scopep; } void scopep(AstScope* nodep) { m_scopep = nodep; } string rtnTypeVoid() const { return ((m_rtnType=="") ? "void" : m_rtnType); } bool dontCombine() const { return m_dontCombine || funcType()!=AstCFuncType::FT_NORMAL; } void dontCombine(bool flag) { m_dontCombine = flag; } bool dontInline() const { return dontCombine() || slow() || skipDecl() || funcPublic(); } bool skipDecl() const { return m_skipDecl; } void skipDecl(bool flag) { m_skipDecl = flag; } bool declPrivate() const { return m_declPrivate; } void declPrivate(bool flag) { m_declPrivate = flag; } bool formCallTree() const { return m_formCallTree; } void formCallTree(bool flag) { m_formCallTree = flag; } bool slow() const { return m_slow; } void slow(bool flag) { m_slow = flag; } bool funcPublic() const { return m_funcPublic; } void funcPublic(bool flag) { m_funcPublic = flag; } void argTypes(const string& str) { m_argTypes = str; } string argTypes() const { return m_argTypes; } void funcType(AstCFuncType flag) { m_funcType = flag; } AstCFuncType funcType() const { return m_funcType; } bool isInline() const { return m_isInline; } void isInline(bool flag) { m_isInline = flag; } bool isStatic() const { return m_isStatic; } void isStatic(bool flag) { m_isStatic = flag; } bool symProlog() const { return m_symProlog; } void symProlog(bool flag) { m_symProlog = flag; } bool entryPoint() const { return m_entryPoint; } void entryPoint(bool flag) { m_entryPoint = flag; } bool pure() const { return m_pure; } void pure(bool flag) { m_pure = flag; } bool dpiExport() const { return m_dpiExport; } void dpiExport(bool flag) { m_dpiExport = flag; } bool dpiExportWrapper() const { return m_dpiExportWrapper; } void dpiExportWrapper(bool flag) { m_dpiExportWrapper = flag; } bool dpiImport() const { return m_dpiImport; } void dpiImport(bool flag) { m_dpiImport = flag; } // // If adding node accessors, see below emptyBody AstNode* argsp() const { return op1p()->castNode(); } void addArgsp(AstNode* nodep) { addOp1p(nodep); } AstNode* initsp() const { return op2p()->castNode(); } void addInitsp(AstNode* nodep) { addOp2p(nodep); } AstNode* stmtsp() const { return op3p()->castNode(); } void addStmtsp(AstNode* nodep) { addOp3p(nodep); } AstNode* finalsp() const { return op4p()->castNode(); } void addFinalsp(AstNode* nodep) { addOp4p(nodep); } // Special methods bool emptyBody() const { return argsp()==NULL && initsp()==NULL && stmtsp()==NULL && finalsp()==NULL; } }; class AstCCall : public AstNodeStmt { // C++ function call // Parents: Anything above a statement // Children: Args to the function private: AstCFunc* m_funcp; string m_hiername; string m_argTypes; public: AstCCall(FileLine* fl, AstCFunc* funcp, AstNode* argsp=NULL) : AstNodeStmt(fl) { m_funcp = funcp; addNOp1p(argsp); } AstCCall(AstCCall* oldp, AstCFunc* funcp) // Replacement form for V3Combine // Note this removes old attachments from the oldp : AstNodeStmt(oldp->fileline()) { m_funcp = funcp; m_hiername = oldp->hiername(); m_argTypes = oldp->argTypes(); if (oldp->argsp()) addNOp1p(oldp->argsp()->unlinkFrBackWithNext()); } ASTNODE_NODE_FUNCS(CCall, CCALL) virtual void dump(ostream& str=cout); virtual void cloneRelink() { if (m_funcp && m_funcp->clonep()) { m_funcp = m_funcp->clonep()->castCFunc(); }} virtual const char* broken() const { BROKEN_RTN(m_funcp && !m_funcp->brokeExists()); return NULL; } virtual int instrCount() const { return instrCountCall(); } virtual V3Hash sameHash() const { return V3Hash(funcp()); } virtual bool same(AstNode* samep) const { return (funcp()==samep->castCCall()->funcp() && argTypes()==samep->castCCall()->argTypes()); } AstNode* exprsp() const { return op1p()->castNode(); } // op1= expressions to print virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return funcp()->pure(); } virtual bool isOutputter() const { return !(funcp()->pure()); } AstCFunc* funcp() const { return m_funcp; } string hiername() const { return m_hiername; } void hiername(const string& hn) { m_hiername = hn; } void argTypes(const string& str) { m_argTypes = str; } string argTypes() const { return m_argTypes; } // AstNode* argsp() const { return op1p()->castNode(); } void addArgsp(AstNode* nodep) { addOp1p(nodep); } }; class AstCReturn : public AstNodeStmt { // C++ return from a function // Parents: CFUNC/statement // Children: Math public: AstCReturn(FileLine* fl, AstNode* lhsp) : AstNodeStmt(fl) { setOp1p(lhsp); } ASTNODE_NODE_FUNCS(CReturn, CRETURN) virtual int instrCount() const { return widthInstrs(); } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode*) const { return true; } // AstNode* lhsp() const { return op1p(); } }; class AstCMath : public AstNodeMath { private: bool m_cleanOut; public: // Emit C textual math function (like AstUCFunc) AstCMath(FileLine* fl, AstNode* exprsp) : AstNodeMath(fl), m_cleanOut(true) { addOp1p(exprsp); dtypeFrom(exprsp); } AstCMath(FileLine* fl, const string& textStmt, int setwidth, bool cleanOut=true) : AstNodeMath(fl), m_cleanOut(cleanOut) { addNOp1p(new AstText(fl, textStmt, true)); if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); } } ASTNODE_NODE_FUNCS(CMath, CMATH) virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual bool cleanOut() { return m_cleanOut; } virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } void addBodysp(AstNode* nodep) { addNOp1p(nodep); } AstNode* bodysp() const { return op1p()->castNode(); } // op1= expressions to print }; class AstCStmt : public AstNodeStmt { // Emit C statement public: AstCStmt(FileLine* fl, AstNode* exprsp) : AstNodeStmt(fl) { addNOp1p(exprsp); } AstCStmt(FileLine* fl, const string& textStmt) : AstNodeStmt(fl) { addNOp1p(new AstText(fl, textStmt, true)); } ASTNODE_NODE_FUNCS(CStmt, CSTMT) virtual bool isGateOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } void addBodysp(AstNode* nodep) { addNOp1p(nodep); } AstNode* bodysp() const { return op1p()->castNode(); } // op1= expressions to print }; //###################################################################### // Right below top class AstTypeTable : public AstNode { // Container for hash of standard data types // Children: NODEDTYPEs typedef map,AstBasicDType*> LogicMap; AstBasicDType* m_basicps[AstBasicDTypeKwd::_ENUM_MAX]; // enum { IDX0_LOGIC, IDX0_BIT, _IDX0_MAX }; LogicMap m_logicMap[_IDX0_MAX][AstNumeric::_ENUM_MAX]; // uses above IDX enums // typedef map DetailedMap; DetailedMap m_detailedMap; public: AstTypeTable(FileLine* fl) : AstNode(fl) { for (int i=0; icastNodeDType();} // op1 = List of dtypes void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); } AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd); AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, int widthMin, AstNumeric numeric); AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, VNumRange range, int widthMin, AstNumeric numeric); AstBasicDType* findInsertSameDType(AstBasicDType* nodep); void clearCache(); void repairCache(); virtual void dump(ostream& str=cout); }; //###################################################################### // Top class AstNetlist : public AstNode { // All modules are under this single top node. // Parents: none // Children: MODULEs & CFILEs private: AstTypeTable* m_typeTablep; // Reference to top type table, for faster lookup AstPackage* m_dollarUnitPkgp; public: AstNetlist() : AstNode(new FileLine("AstRoot",0)) { m_typeTablep = NULL; m_dollarUnitPkgp = NULL; } ASTNODE_NODE_FUNCS(Netlist, NETLIST) virtual const char* broken() const { BROKEN_RTN(m_dollarUnitPkgp && !m_dollarUnitPkgp->brokeExists()); return NULL; } AstNodeModule* modulesp() const { return op1p()->castNodeModule();} // op1 = List of modules AstNodeModule* topModulep() const { return op1p()->castNodeModule(); } // * = Top module in hierarchy (first one added, for now) void addModulep(AstNodeModule* modulep) { addOp1p(modulep); } AstCFile* filesp() const { return op2p()->castCFile();} // op2 = List of files void addFilesp(AstCFile* filep) { addOp2p(filep); } AstNode* miscsp() const { return op3p();} // op3 = List of dtypes etc void addMiscsp(AstNode* nodep) { addOp3p(nodep); } AstTypeTable* typeTablep() { return m_typeTablep; } void addTypeTablep(AstTypeTable* nodep) { m_typeTablep = nodep; addMiscsp(nodep); } AstPackage* dollarUnitPkgp() const { return m_dollarUnitPkgp; } AstPackage* dollarUnitPkgAddp() { if (!m_dollarUnitPkgp) { m_dollarUnitPkgp = new AstPackage(fileline(), AstPackage::dollarUnitName()); m_dollarUnitPkgp->inLibrary(true); // packages are always libraries; don't want to make them a "top" m_dollarUnitPkgp->modTrace(false); // may reconsider later m_dollarUnitPkgp->internal(true); addModulep(m_dollarUnitPkgp); } return m_dollarUnitPkgp; } }; //###################################################################### #endif // Guard verilator-3.874/src/VlcTop.cpp0000664000177100017500000002063012525171734016235 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: top implementation // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "V3Error.h" #include "V3Os.h" #include "VlcOptions.h" #include "VlcTop.h" #include #include #include //###################################################################### void VlcTop::readCoverage(const string& filename, bool nonfatal) { UINFO(2,"readCoverage "<= VlcBuckets::sufficient()) { points().pointNumber(pointnum).testsCoveringInc(); testp->buckets().addData(pointnum, hits); } } } } } void VlcTop::writeCoverage(const string& filename) { UINFO(2,"writeCoverage "<second); os <<"C '"<computrons() != rhsp->computrons()) { return lhsp->computrons() < rhsp->computrons(); } return lhsp->bucketsCovered() > rhsp->bucketsCovered(); } }; void VlcTop::rank() { UINFO(2,"rank...\n"); vluint64_t nextrank=1; // Sort by computrons, so fast tests get selected first vector bytime; for (VlcTests::ByName::iterator it=m_tests.begin(); it!=m_tests.end(); ++it) { VlcTest* testp = *it; if (testp->bucketsCovered()) { // else no points, so can't help us bytime.push_back(*it); } } sort(bytime.begin(), bytime.end(), CmpComputrons()); // Sort the vector VlcBuckets remaining; for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) { VlcPoint* pointp = &points().pointNumber(it->second); // If any tests hit this point, then we'll need to cover it. if (pointp->testsCovering()) { remaining.addData(pointp->pointNum(), 1); } } // Additional Greedy algorithm // O(n^2) Ouch. Probably the thing to do is randomize the order of data // then hierarchically solve a small subset of tests, and take resulting // solution and move up to larger subset of tests. (Aka quick sort.) while (1) { if (debug()) { UINFO(9,"Left on iter"<::iterator it=bytime.begin(); it!=bytime.end(); ++it) { VlcTest* testp = *it; if (!testp->rank()) { vluint64_t remain = testp->buckets().dataPopCount(remaining); if (remain > bestRemain) { bestTestp = testp; bestRemain = remain; } } } if (VlcTest* testp = bestTestp) { testp->rank(nextrank++); testp->rankPoints(bestRemain); remaining.orData(bestTestp->buckets()); } else { break; // No test covering more stuff found } } } //###################################################################### void VlcTop::annotateCalc() { // Calculate per-line information into filedata structure for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) { const VlcPoint& point = m_points.pointNumber(it->second); string filename = point.filename(); int lineno = point.lineno(); if (filename!="" && lineno!=0) { int column = point.column(); VlcSource& source = sources().findNewSource(filename); string threshStr = point.thresh(); unsigned thresh = (threshStr!="") ? atoi(threshStr.c_str()) : opt.annotateMin(); bool ok = (point.count() >= thresh); UINFO(9, "AnnoCalc count "<second; //UINFO(1,"Source "<second; for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) { VlcSourceCount& col = cit->second; //UINFO(0,"Source "<second; if (!source.needed()) continue; string filename = source.name(); string outfilename = dirname+"/"+V3Os::filenameNonDir(filename); UINFO(1,"annotateOutputFile "< "<second; for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) { VlcSourceCount& col = cit->second; //UINFO(0,"Source "< #include #include #include #include #include #include #include "V3Global.h" #include "V3String.h" #include "V3EmitXml.h" #include "V3EmitCBase.h" //###################################################################### // Emit statements and math operators class EmitXmlFileVisitor : public EmitCBaseVisitor { // MEMBERS V3OutFile* m_ofp; // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // Outfile methods V3OutFile* ofp() const { return m_ofp; } virtual void puts(const string& str) { ofp()->puts(str); } virtual void putbs(const string& str) { ofp()->putbs(str); } virtual void putfs(AstNode*, const string& str) { putbs(str); } virtual void putqs(AstNode*, const string& str) { putbs(str); } virtual void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); } virtual void putsQuoted(const string& str) { // Quote \ and " for use inside C programs // Don't use to quote a filename for #include - #include doesn't \ escape. // Duplicate in V3File - here so we can print to string putsNoTracking("\""); putsNoTracking(V3Number::quoteNameControls(str)); putsNoTracking("\""); } // XML methods void outputTag(AstNode* nodep, string tag) { if (tag=="") tag = VString::downcase(nodep->typeName()); puts("<"+tag+" "+nodep->fileline()->xml()); if (nodep->name()!="") { puts(" name="); putsQuoted(nodep->prettyName()); } } void outputChildrenEnd(AstNode* nodep, string tag) { if (tag=="") tag = VString::downcase(nodep->typeName()); if (nodep->op1p() || nodep->op2p() || nodep->op3p() || nodep->op4p()) { puts(">\n"); nodep->iterateChildren(*this); puts("\n"); } else { puts("/>\n"); } } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { puts("\n"); nodep->iterateChildren(*this); puts("\n"); } virtual void visit(AstNodeModule* nodep, AstNUser*) { outputTag(nodep, ""); if (nodep->level()==1 || nodep->level()==2) // ==2 because we don't add wrapper when in XML mode puts(" topModule=\"1\""); // IEEE vpiTopModule outputChildrenEnd(nodep, ""); } virtual void visit(AstCell* nodep, AstNUser*) { outputTag(nodep, "instance"); // IEEE: vpiInstance puts(" defName="); putsQuoted(nodep->modName()); // IEEE vpiDefName outputChildrenEnd(nodep, "instance"); } virtual void visit(AstPin* nodep, AstNUser*) { // What we call a pin in verilator is a port in the IEEE spec. outputTag(nodep, "port"); // IEEE: vpiPort if (nodep->modVarp()->isInOnly()) puts(" direction=\"in\""); else if (nodep->modVarp()->isOutOnly()) puts(" direction=\"out\""); else puts(" direction=\"inout\""); puts(" portIndex=\""+cvtToStr(nodep->pinNum())+"\""); // IEEE: vpiPortIndex // Children includes vpiHighConn and vpiLowConn; we don't support port bits (yet?) outputChildrenEnd(nodep, "port"); } virtual void visit(AstAssignW* nodep, AstNUser*) { outputTag(nodep, "contAssign"); // IEEE: vpiContAssign outputChildrenEnd(nodep, "contAssign"); } // Data types virtual void visit(AstBasicDType* nodep, AstNUser*) { outputTag(nodep, "basicDType "); if (nodep->isRanged()) { puts(" left=\""+cvtToStr(nodep->left())+"\""); puts(" right=\""+cvtToStr(nodep->right())+"\""); } puts("/>\n"); } // Default virtual void visit(AstNode* nodep, AstNUser*) { outputTag(nodep, ""); outputChildrenEnd(nodep, ""); } public: EmitXmlFileVisitor(AstNode* nodep, V3OutFile* ofp) { m_ofp = ofp; nodep->accept(*this); } virtual ~EmitXmlFileVisitor() {} }; //###################################################################### // Emit to a stream (perhaps stringstream) class EmitXmlPrefixedFormatter : public V3OutFormatter { ostream& m_os; string m_prefix; // What to print at beginning of each line int m_flWidth; // Padding of fileline int m_column; // Rough location; need just zero or non-zero FileLine* m_prefixFl; // METHODS virtual void putcOutput(char chr) { if (chr == '\n') { m_column = 0; m_os<ascii()+":"; m_os<ascii().length()+1)); m_os<<" "; m_os<fileline(); // NETLIST's fileline instead of NULL to avoid NULL checks } virtual ~EmitXmlPrefixedFormatter() {} }; //###################################################################### // EmitXml class functions void V3EmitXml::emitxml() { UINFO(2,__FUNCTION__<<": "<\n"); of.puts("\n"); { stringstream sstr; FileLine::fileNameNumMapDumpXml(sstr); of.puts(sstr.str()); } EmitXmlFileVisitor visitor (v3Global.rootp(), &of); of.puts("\n"); } verilator-3.874/src/V3Descope.cpp0000664000177100017500000002304112525171733016617 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Rename scope references to module-local references // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // DESCOPE TRANSFORMATIONS: // All modules: // Each VARREF/FUNCCALL // Change varref name() to be relative to current module // Remove varScopep() // This allows for better V3Combine'ing. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Descope.h" #include "V3Ast.h" #include "V3EmitCBase.h" //###################################################################### class DescopeVisitor : public AstNVisitor { private: // NODE STATE // Cleared entire netlist // AstCFunc::user() // bool. Indicates processing completed AstUser1InUse m_inuser1; // TYPES typedef multimap FuncMmap; // STATE AstNodeModule* m_modp; // Current module AstScope* m_scopep; // Current scope bool m_needThis; // Add thisp to function FuncMmap m_modFuncs; // Name of public functions added // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } string descopedName(AstScope* scopep, bool& hierThisr, AstVar* varp=NULL) { UASSERT(scopep, "Var/Func not scoped\n"); hierThisr = true; if (varp && varp->isFuncLocal()) { return ""; // Relative to function, not in this } else if (scopep == m_scopep && m_modp->isTop()) { //return ""; // Reference to scope we're in, no need to HIER-> it return "vlTOPp->"; } else if (scopep == m_scopep && !m_modp->isTop() && 0) { // We no longer thisp-> as still get ambiguation problems m_needThis = true; return "thisp->"; // this-> but with restricted aliasing } else if (scopep->aboveScopep() && scopep->aboveScopep()==m_scopep && 0 // DISABLED: GCC considers the pointers ambiguous, so goes ld/store crazy ) { // Reference to scope of cell directly under this module, can just "cell->" string name = scopep->name(); string::size_type pos; if ((pos = name.rfind(".")) != string::npos) { name.erase(0,pos+1); } hierThisr = false; return name+"->"; } else { // Reference to something else, use global variable UINFO(8," Descope "<name()<name()<aboveScopep()) { // Top return "vlTOPp->"; // == "vlSymsp->TOPp->", but GCC would suspect aliases } else { return scopep->nameVlSym()+"."; } } } void makePublicFuncWrappers() { // We recorded all public functions in m_modFuncs. // If for any given name only one function exists, we can use that function directly. // If multiple functions exist, we need to select the appropriate scope. for (FuncMmap::iterator it = m_modFuncs.begin(); it!=m_modFuncs.end(); ++it) { string name = it->first; AstCFunc* topFuncp = it->second; FuncMmap::iterator nextIt1 = it; ++nextIt1; bool moreOfSame1 = (nextIt1!=m_modFuncs.end() && nextIt1->first == name); if (moreOfSame1) { // Multiple functions under this name, need a wrapper function UINFO(6," Wrapping "<cloneTree(false); if (newfuncp->initsp()) newfuncp->initsp()->unlinkFrBackWithNext()->deleteTree(); if (newfuncp->stmtsp()) newfuncp->stmtsp()->unlinkFrBackWithNext()->deleteTree(); if (newfuncp->finalsp()) newfuncp->finalsp()->unlinkFrBackWithNext()->deleteTree(); newfuncp->name(name); newfuncp->isStatic(false); newfuncp->addInitsp( new AstCStmt(newfuncp->fileline(), EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n")); newfuncp->addInitsp(new AstCStmt(newfuncp->fileline(), EmitCBaseVisitor::symTopAssign()+"\n")); topFuncp->addNextHere(newfuncp); // In the body, call each function if it matches the given scope for (FuncMmap::iterator eachIt = it; eachIt!=m_modFuncs.end() && eachIt->first==name; ++eachIt) { it = eachIt; AstCFunc* funcp = eachIt->second; FuncMmap::iterator nextIt2 = eachIt; ++nextIt2; bool moreOfSame = (nextIt2!=m_modFuncs.end() && nextIt2->first == name); if (!funcp->scopep()) funcp->v3fatalSrc("Not scoped"); UINFO(6," Wrapping "<argTypes()<<" und "<argTypes()<declPrivate(true); AstNode* argsp = NULL; for (AstNode* stmtp = newfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && !portp->isFuncReturn()) { argsp = argsp->addNextNull(new AstVarRef(portp->fileline(), portp, portp->isOutput())); } } } AstNode* returnp = new AstCReturn (funcp->fileline(), new AstCCall (funcp->fileline(), funcp, argsp)); if (moreOfSame) { AstIf* ifp = new AstIf (funcp->fileline(), new AstEq(funcp->fileline(), new AstCMath(funcp->fileline(), "this", 64), new AstCMath(funcp->fileline(), string("&(") +funcp->scopep()->nameVlSym() +")", 64)), returnp, NULL); newfuncp->addStmtsp(ifp); } else { newfuncp->addStmtsp(returnp); } } // Not really any way the user could do this, and we'd need to come up with some return value //newfuncp->addStmtsp(new AstDisplay (newfuncp->fileline(), AstDisplayType::DT_DISPLAY, // string("%%Error: ")+name+"() called with bad scope", NULL)); //newfuncp->addStmtsp(new AstStop (newfuncp->fileline())); if (debug()>=9) newfuncp->dumpTree(cout," newfunc: "); } else { // Only a single function under this name, we can simply rename it UINFO(6," Wrapping "<name(name); } } } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; m_modFuncs.clear(); nodep->iterateChildren(*this); makePublicFuncWrappers(); m_modp = NULL; } virtual void visit(AstScope* nodep, AstNUser*) { m_scopep = nodep; nodep->iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstVarScope* nodep, AstNUser*) { // Delete the varscope when we're finished nodep->unlinkFrBack(); pushDeletep(nodep); } virtual void visit(AstNodeVarRef* nodep, AstNUser*) { nodep->iterateChildren(*this); // Convert the hierch name if (!m_scopep) nodep->v3fatalSrc("Node not under scope"); bool hierThis; nodep->hiername(descopedName(nodep->varScopep()->scopep(), hierThis/*ref*/, nodep->varScopep()->varp())); nodep->hierThis(hierThis); nodep->varScopep(NULL); } virtual void visit(AstCCall* nodep, AstNUser*) { //UINFO(9," "<iterateChildren(*this); // Convert the hierch name if (!m_scopep) nodep->v3fatalSrc("Node not under scope"); if (!nodep->funcp()->scopep()) nodep->v3fatalSrc("CFunc not under scope"); bool hierThis; nodep->hiername(descopedName(nodep->funcp()->scopep(), hierThis/*ref*/)); // Can't do this, as we may have more calls later // nodep->funcp()->scopep(NULL); } virtual void visit(AstCFunc* nodep, AstNUser*) { if (!nodep->user1()) { m_needThis = false; nodep->iterateChildren(*this); nodep->user1(true); if (m_needThis) { nodep->v3fatalSrc("old code"); // Really we should have more node types for backend optimization of this stuff string text = v3Global.opt.modPrefix() + "_" + m_modp->name() +"* thisp = &("+m_scopep->nameVlSym()+");\n"; nodep->addInitsp(new AstCStmt(nodep->fileline(), text)); } // If it's under a scope, move it up to the top if (m_scopep) { nodep->unlinkFrBack(); m_modp->addStmtp(nodep); if (nodep->funcPublic()) { // There may be multiple public functions by the same name; // record for later correction or making of shells m_modFuncs.insert(make_pair(nodep->name(), nodep)); nodep->name(m_scopep->nameDotless() +"__" + nodep->name()); } } } } virtual void visit(AstVar*, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS DescopeVisitor(AstNetlist* nodep) { m_modp = NULL; m_scopep = NULL; m_needThis = false; nodep->accept(*this); } virtual ~DescopeVisitor() {} }; //###################################################################### // Descope class functions void V3Descope::descopeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Broken.cpp0000664000177100017500000002213212525247644016462 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Find broken links in tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Broken's Transformations: // // Entire netlist // Mark all nodes // Check all links point to marked nodes // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Broken.h" #include "V3Ast.h" // This visitor does not edit nodes, and is called at error-exit, so should use constant iterators #include "V3AstConstOnly.h" //###################################################################### class BrokenTable : public AstNVisitor { // Table of brokenExists node pointers private: // MEMBERS // For each node, we keep if it exists or not. typedef map NodeMap; static NodeMap s_nodes; // Set of all nodes that exist // BITMASK enum { FLAG_ALLOCATED = 0x01 }; // new() and not delete()ed enum { FLAG_IN_TREE = 0x02 }; // Is in netlist tree enum { FLAG_LINKABLE = 0x04 }; // Is in netlist tree, can be linked to enum { FLAG_LEAKED = 0x08 }; // Known to have been leaked enum { FLAG_UNDER_NOW = 0x10 }; // Is in tree as parent of current node public: // METHODS static void deleted(const AstNode* nodep) { // Called by operator delete on any node - only if VL_LEAK_CHECKS if (debug()>=9) cout<<"-nodeDel: "<<(void*)(nodep)<second & FLAG_ALLOCATED)) { ((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted\n"); } if (iter!=s_nodes.end()) s_nodes.erase(iter); } static void addNewed(const AstNode* nodep) { // Called by operator new on any node - only if VL_LEAK_CHECKS if (debug()>=9) cout<<"-nodeNew: "<<(void*)(nodep)<second & FLAG_ALLOCATED)) { ((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated\n"); } if (iter == s_nodes.end()) { int flags = FLAG_ALLOCATED; // This int needed to appease GCC 4.1.2 s_nodes.insert(make_pair(nodep,flags)); } } static void setUnder(const AstNode* nodep, bool flag) { // Called by BrokenCheckVisitor when each node entered/exited if (!okIfLinkedTo(nodep)) return; NodeMap::iterator iter = s_nodes.find(nodep); if (iter!=s_nodes.end()) { iter->second &= ~FLAG_UNDER_NOW; if (flag) iter->second |= FLAG_UNDER_NOW; } } static void addInTree(AstNode* nodep, bool linkable) { #ifndef VL_LEAK_CHECKS if (!linkable) return; // save some time, else the map will get huge! #endif NodeMap::iterator iter = s_nodes.find(nodep); if (iter == s_nodes.end()) { #ifdef VL_LEAK_CHECKS nodep->v3fatalSrc("AstNode is in tree, but not allocated\n"); #endif } else { if (!(iter->second & FLAG_ALLOCATED)) { #ifdef VL_LEAK_CHECKS nodep->v3fatalSrc("AstNode is in tree, but not allocated\n"); #endif } if (iter->second & FLAG_IN_TREE) { nodep->v3fatalSrc("AstNode is already in tree at another location\n"); } } int or_flags = FLAG_IN_TREE | (linkable?FLAG_LINKABLE:0); if (iter == s_nodes.end()) { s_nodes.insert(make_pair(nodep,or_flags)); } else { iter->second |= or_flags; } } static bool okIfLinkedTo(const AstNode* nodep) { // Someone has a pointer to this node. Is it kosher? NodeMap::iterator iter = s_nodes.find(nodep); if (iter == s_nodes.end()) return false; #ifdef VL_LEAK_CHECKS if (!(iter->second & FLAG_ALLOCATED)) return false; #endif if (!(iter->second & FLAG_IN_TREE)) return false; if (!(iter->second & FLAG_LINKABLE)) return false; return true; } static bool okIfBelow(const AstNode* nodep) { // Must be linked to and below current node if (!okIfLinkedTo(nodep)) return false; NodeMap::iterator iter = s_nodes.find(nodep); if (iter == s_nodes.end()) return false; if (!(iter->second & FLAG_UNDER_NOW)) return false; return true; } static void prepForTree() { #ifndef VL_LEAK_CHECKS s_nodes.clear(); #endif for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) { it->second &= ~FLAG_IN_TREE; it->second &= ~FLAG_LINKABLE; } } static void doneWithTree() { for (int backs=0; backs<2; backs++) { // Those with backp() are probably under one leaking without for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) { if ((it->second & FLAG_ALLOCATED) && !(it->second & FLAG_IN_TREE) && !(it->second & FLAG_LEAKED) && (it->first->backp() ? backs==1 : backs==0)) { // Use only AstNode::dump instead of the virtual one, as there // may be varp() and other cross links that are bad. if (v3Global.opt.debugCheck()) { cerr<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": "); ((AstNode*)(it->first))->AstNode::dump(cerr); cerr<second |= FLAG_LEAKED; } } } } public: // CONSTUCTORS BrokenTable() {} virtual ~BrokenTable() {} }; BrokenTable::NodeMap BrokenTable::s_nodes; bool AstNode::brokeExists() const { // Called by node->broken() routines to do table lookup return BrokenTable::okIfLinkedTo(this); } bool AstNode::brokeExistsAbove() const { // Called by node->broken() routines to do table lookup return BrokenTable::okIfBelow(this); } //###################################################################### class BrokenMarkVisitor : public AstNVisitor { // Mark every node in the tree private: // NODE STATE // Nothing! // This may be called deep inside other routines // // so userp and friends may not be used // VISITORS virtual void visit(AstNode* nodep, AstNUser*) { BrokenTable::addInTree(nodep, nodep->maybePointedTo()); nodep->iterateChildrenConst(*this); } public: // CONSTUCTORS BrokenMarkVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~BrokenMarkVisitor() {} }; //###################################################################### // Broken state, as a visitor of each AstNode class BrokenCheckVisitor : public AstNVisitor { private: void checkWidthMin(AstNode* nodep) { if (nodep->width() != nodep->widthMin() && v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH) { nodep->v3fatalSrc("Width != WidthMin"); } } virtual void visit(AstNode* nodep, AstNUser*) { BrokenTable::setUnder(nodep,true); if (const char* whyp=nodep->broken()) { nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<dtypep()) { if (!nodep->dtypep()->brokeExists()) { nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep()); } else if (!nodep->dtypep()->castNodeDType()) { nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); } } if (v3Global.assertDTypesResolved()) { if (nodep->hasDType()) { if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype on node with hasDType(): "<prettyTypeName()); } else { if (nodep->dtypep()) nodep->v3fatalSrc("DType on node without hasDType(): "<prettyTypeName()); } if (nodep->getChildDTypep()) nodep->v3fatalSrc("childDTypep() non-null on node after should have removed"); if (AstNodeDType* dnodep = nodep->castNodeDType()) checkWidthMin(dnodep); } checkWidthMin(nodep); nodep->iterateChildrenConst(*this); BrokenTable::setUnder(nodep,false); } public: // CONSTUCTORS BrokenCheckVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~BrokenCheckVisitor() {} }; //###################################################################### // Broken class functions void V3Broken::brokenAll(AstNetlist* nodep) { //UINFO(9,__FUNCTION__<<": "< #include #include #include #include #include #include "V3Global.h" #include "V3SplitAs.h" #include "V3Stats.h" #include "V3Ast.h" //###################################################################### class SplitAsBaseVisitor : public AstNVisitor { public: // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### // Find all split variables in a block class SplitAsFindVisitor : public SplitAsBaseVisitor { private: // STATE AstVarScope* m_splitVscp; // Variable we want to split // METHODS virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->lvalue() && !m_splitVscp && nodep->varp()->attrIsolateAssign()) { m_splitVscp = nodep->varScopep(); } } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS SplitAsFindVisitor(AstAlways* nodep) { m_splitVscp = NULL; nodep->accept(*this); } virtual ~SplitAsFindVisitor() {} // METHODS AstVarScope* splitVscp() const { return m_splitVscp; } }; //###################################################################### // Remove nodes not containing proper references class SplitAsCleanVisitor : public SplitAsBaseVisitor { private: // STATE AstVarScope* m_splitVscp; // Variable we want to split bool m_modeMatch; // Remove matching Vscp, else non-matching bool m_keepStmt; // Current Statement must be preserved bool m_matches; // Statement below has matching lvalue reference // METHODS virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->lvalue()) { if (nodep->varScopep()==m_splitVscp) { UINFO(6," CL VAR "<iterateChildren(*this); if (m_keepStmt || (m_modeMatch ? m_matches : !m_matches)) { UINFO(6," Keep STMT "<unlinkFrBack(); pushDeletep(nodep); } } // If something below matches, the upper statement remains too. m_keepStmt = oldKeep || m_keepStmt; UINFO(9," upKeep="<iterateChildren(*this); } public: // CONSTUCTORS SplitAsCleanVisitor(AstAlways* nodep, AstVarScope* vscp, bool modeMatch) { m_splitVscp = vscp; m_modeMatch = modeMatch; nodep->accept(*this); } virtual ~SplitAsCleanVisitor() {} }; //###################################################################### // SplitAs class functions class SplitAsVisitor : public SplitAsBaseVisitor { private: // NODE STATE // AstAlways::user() -> bool. True if already processed AstUser1InUse m_inuser1; // STATE V3Double0 m_statSplits; // Statistic tracking AstVarScope* m_splitVscp; // Variable we want to split // METHODS void splitAlways(AstAlways* nodep) { UINFO(3,"Split "<=9) nodep->dumpTree(cout,"-in : "); // Duplicate it and link in AstAlways* newp = nodep->cloneTree(false); newp->user1(true); // So we don't clone it again nodep->addNextHere(newp); { // Delete stuff we don't want in old SplitAsCleanVisitor visitor (nodep, m_splitVscp, false); if (debug()>=9) nodep->dumpTree(cout,"-out0: "); } { // Delete stuff we don't want in new SplitAsCleanVisitor visitor (newp, m_splitVscp, true); if (debug()>=9) newp->dumpTree(cout,"-out1: "); } } virtual void visit(AstAlways* nodep, AstNUser*) { // Are there any lvalue references below this? // There could be more than one. So, we process the first one found first. AstVarScope* lastSplitVscp = NULL; while (!nodep->user1()) { // Find any splittable variables SplitAsFindVisitor visitor (nodep); m_splitVscp = visitor.splitVscp(); if (m_splitVscp && m_splitVscp == lastSplitVscp) { // We did this last time! Something's stuck! nodep->v3fatalSrc("Infinite loop in isolate_assignments removal for: "<prettyName()) m_splitVscp = NULL; } lastSplitVscp = m_splitVscp; // Now isolate the always if (m_splitVscp) { splitAlways(nodep); ++m_statSplits; } else { nodep->user1(true); } } } // Speedup; no always under math virtual void visit(AstNodeMath* nodep, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS SplitAsVisitor(AstNetlist* nodep) { m_splitVscp = NULL; AstNode::user1ClearTree(); // user1p() used on entire tree nodep->accept(*this); } virtual ~SplitAsVisitor() { V3Stats::addStat("Optimizations, isolate_assignments blocks", m_statSplits); } }; //###################################################################### // SplitAs class functions void V3SplitAs::splitAsAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Cast.h0000664000177100017500000000226212525171733015576 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add C++ casts across expression size changes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CAST_H_ #define _V3CAST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Cast { public: static void castAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Dead.h0000664000177100017500000000254112525171733015541 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Dead branch elimination // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3DEAD_H_ #define _V3DEAD_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Dead { public: // Modules, no vars/dtypes static void deadifyModules(AstNetlist* nodep); // Modules, Data types static void deadifyDTypes(AstNetlist* nodep); // Everything that's possible static void deadifyAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/vlcovgen0000775000177100017500000000776412525171734016110 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### #require 5.006_001; use Getopt::Long; use IO::File; use Pod::Usage; use strict; use vars qw ($Debug); our @Items; #====================================================================== # main $Debug = 0; my $Opt_Srcdir = "."; Getopt::Long::config ("pass_through", "no_auto_abbrev"); if (! GetOptions ( "help" => \&usage, "debug" => sub { $Debug = 1; }, "srcdir=s" => \$Opt_Srcdir, "<>" => sub { die "%Error: Unknown parameter: $_[0],"; }, )) { usage(); } read_keys("$Opt_Srcdir/../include/verilated_cov_key.h"); lint(); write_keys("$Opt_Srcdir/../include/verilated_cov_key.h"); #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } ####################################################################### sub read_keys { my $filename = shift; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename,"; while (defined (my $line = $fh->getline())) { $line =~ s/\/\/.*$//; next if $line =~ /^\s*$/; if ($line =~ /^\s*VLCOVGEN_ITEM/) { $line =~ /^\s*VLCOVGEN_ITEM *\( *"([^"]+)" *\)/ or die "%Error: $filename:$.: Misformed VLCOVGEN_ITEM line,"; my @data; my $code = "\@data = ($1);"; eval $code; die "%Error: $filename:$.: Parsing '$code': $@," if $@; push @Items, {@data}; } } } ####################################################################### sub lint { my %shorts; my $ok = 1; foreach my $itemref (@Items) { if ($shorts{$itemref->{short}}) { warn "%Error: Duplicate short code: $itemref->{short},"; $ok = 0; } $shorts{$itemref->{short}} = 1; } return $ok; } sub write_keys { my $filename = shift; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; my @in; my @out; my $deleting; while (defined(my $line = $fh->getline)) { push @in, $line; if ($line =~ /VLCOVGEN_CIK_AUTO_EDIT_BEGIN/) { $deleting = 1; push @out, $line; foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) { push @out, sprintf("#define VL_CIK_%s \"%s\"\n", uc $keyref->{name}, $keyref->{short}); } } elsif ($line =~ /VLCOVGEN_SHORT_AUTO_EDIT_BEGIN/) { $deleting = 1; push @out, $line; foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) { push @out, sprintf("\tif (key == \"%s\") return VL_CIK_%s;\n", $keyref->{name}, uc $keyref->{name}); } } elsif ($line =~ /VLCOVGEN_.*AUTO_EDIT_END/) { $deleting = 0; push @out, $line; } elsif ($deleting) { } else { push @out, $line; } } $fh->close; my $ok = join("", @out) eq join("", @in); if (!$ok) { my $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename\n"; $fh->print(join "", @out); $fh->close; } } ####################################################################### __END__ =pod =head1 NAME vlcovgen - Generate verilated_cov headers to reduce C++ code duplication =head1 SYNOPSIS (called from make rules) vlcovgen =head1 DESCRIPTION Generates several files for Verilator compilations. =head1 ARGUMENTS =over 4 =item --help Displays this message and program version and exits. =back =head1 DISTRIBUTION Copyright 2002-2015 by Wilson Snyder. Verilator 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO =cut ###################################################################### ### Local Variables: ### compile-command: "./vlcovgen --srcdir ." ### End: verilator-3.874/src/V3PreShell.h0000664000177100017500000000317512525171733016426 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Preprocessing wrapper program // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3PRESHELL_H_ #define _V3PRESHELL_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3FileLine.h" class V3ParseImp; class V3InFilter; //============================================================================ class V3PreShell { // Static class for calling preprocessor public: static void boot(char** env); static bool preproc(FileLine* fileline, const string& module, V3InFilter* filterp, V3ParseImp* parsep, const string& errmsg); static void preprocInclude(FileLine* fileline, const string& module); static string dependFiles() { return ""; } // Perl only static void defineCmdLine(const string& name, const string& value); static void undef(const string& name); }; #endif // Guard verilator-3.874/src/V3LinkJump.cpp0000664000177100017500000002304212525171733016767 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Replace return/continue with jumps // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3LinkJump's Transformations: // // Each module: // Look for BEGINs // BEGIN(VAR...) -> VAR ... {renamed} // FOR -> WHILEs // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3LinkJump.h" #include "V3Ast.h" //###################################################################### class LinkJumpVisitor : public AstNVisitor { private: // TYPES typedef vector BeginStack; // STATE AstNodeModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Current function/task AstWhile* m_loopp; // Current loop bool m_loopInc; // In loop increment int m_repeatNum; // Repeat counter BeginStack m_beginStack; // All begin blocks above current node // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } AstJumpLabel* findAddLabel(AstNode* nodep, bool endOfIter) { // Put label under given node, and if WHILE optionally at end of iteration UINFO(4,"Create label for "<castJumpLabel()) return nodep->castJumpLabel(); // Done AstNode* underp = NULL; bool under_and_next = true; if (nodep->castBegin()) underp = nodep->castBegin()->stmtsp(); else if (nodep->castNodeFTask()) underp = nodep->castNodeFTask()->stmtsp(); else if (nodep->castWhile()) { if (endOfIter) { // Note we jump to end of bodysp; a FOR loop has its increment under incsp() which we don't skip underp = nodep->castWhile()->bodysp(); } else { underp = nodep; under_and_next=false; // IE we skip the entire while } } else { nodep->v3fatalSrc("Unknown jump point for break/disable/continue"); return NULL; } // Skip over variables as we'll just move them in a momement // Also this would otherwise prevent us from using a label twice // see t_func_return test. while (underp && underp->castVar()) underp = underp->nextp(); if (underp) UINFO(5," Underpoint is "<v3fatalSrc("Break/disable/continue not under expected statement"); return NULL; } else if (underp->castJumpLabel()) { return underp->castJumpLabel(); } else { // Move underp stuff to be under a new label AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), NULL); AstNRelinker repHandle; if (under_and_next) underp->unlinkFrBackWithNext(&repHandle); else underp->unlinkFrBack(&repHandle); repHandle.relink(labelp); labelp->addStmtsp(underp); // Keep any AstVars under the function not under the new JumpLabel for (AstNode* nextp, *varp=underp; varp; varp = nextp) { nextp = varp->nextp(); if (varp->castVar()) { labelp->addPrev(varp->unlinkFrBack()); } } return labelp; } } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { if (nodep->dead()) return; m_modp = nodep; m_repeatNum = 0; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstNodeFTask* nodep, AstNUser*) { m_ftaskp = nodep; nodep->iterateChildren(*this); m_ftaskp = NULL; } virtual void visit(AstBegin* nodep, AstNUser*) { UINFO(8," "<iterateChildren(*this); m_beginStack.pop_back(); } virtual void visit(AstRepeat* nodep, AstNUser*) { // So later optimizations don't need to deal with them, // REPEAT(count,body) -> loop=count,WHILE(loop>0) { body, loop-- } // Note var can be signed or unsigned based on original number. AstNode* countp = nodep->countp()->unlinkFrBackWithNext(); string name = string("__Vrepeat")+cvtToStr(m_repeatNum++); // Spec says value is integral, if negative is ignored AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name, nodep->findSigned32DType()); varp->usedLoopIdx(true); m_modp->addStmtp(varp); AstNode* initsp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true), countp); AstNode* decp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true), new AstSub(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false), new AstConst(nodep->fileline(), 1))); V3Number zero (nodep->fileline(), 32, 0); zero.isSigned(true); AstNode* zerosp = new AstConst(nodep->fileline(), zero); AstNode* condp = new AstGtS(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false), zerosp); AstNode* bodysp = nodep->bodysp(); if (bodysp) bodysp->unlinkFrBackWithNext(); AstNode* newp = new AstWhile(nodep->fileline(), condp, bodysp, decp); initsp = initsp->addNext(newp); newp = initsp; nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } virtual void visit(AstWhile* nodep, AstNUser*) { // Don't need to track AstRepeat/AstFor as they have already been converted AstWhile* lastLoopp = m_loopp; bool lastInc = m_loopInc; m_loopp = nodep; m_loopInc = false; nodep->precondsp()->iterateAndNext(*this); nodep->condp()->iterateAndNext(*this); nodep->bodysp()->iterateAndNext(*this); m_loopInc = true; nodep->incsp()->iterateAndNext(*this); m_loopInc = lastInc; m_loopp = lastLoopp; } virtual void visit(AstReturn* nodep, AstNUser*) { nodep->iterateChildren(*this); AstFunc* funcp = m_ftaskp->castFunc(); if (!m_ftaskp) { nodep->v3error("Return isn't underneath a task or function"); } else if (funcp && !nodep->lhsp()) { nodep->v3error("Return underneath a function should have return value"); } else if (!funcp && nodep->lhsp()) { nodep->v3error("Return underneath a task shouldn't have return value"); } else { if (funcp && nodep->lhsp()) { // Set output variable to return value nodep->addPrev(new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), funcp->fvarp()->castVar(), true), nodep->lhsp()->unlinkFrBackWithNext())); } // Jump to the end of the function call AstJumpLabel* labelp = findAddLabel(m_ftaskp, false); nodep->addPrev(new AstJumpGo(nodep->fileline(), labelp)); } nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } virtual void visit(AstBreak* nodep, AstNUser*) { nodep->iterateChildren(*this); if (!m_loopp) { nodep->v3error("break isn't underneath a loop"); } else { // Jump to the end of the loop AstJumpLabel* labelp = findAddLabel(m_loopp, false); nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp)); } nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } virtual void visit(AstContinue* nodep, AstNUser*) { nodep->iterateChildren(*this); if (!m_loopp) { nodep->v3error("continue isn't underneath a loop"); } else { // Jump to the end of this iteration // If a "for" loop then need to still do the post-loop increment AstJumpLabel* labelp = findAddLabel(m_loopp, true); nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp)); } nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } virtual void visit(AstDisable* nodep, AstNUser*) { UINFO(8," DISABLE "<iterateChildren(*this); AstBegin* beginp = NULL; for (BeginStack::reverse_iterator it = m_beginStack.rbegin(); it != m_beginStack.rend(); ++it) { UINFO(9," UNDERBLK "<<*it<name() == nodep->name()) { beginp = *it; break; } } //if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout," labeli: "); } if (!beginp) { nodep->v3error("disable isn't underneath a begin with name: "<prettyName()); } else { // Jump to the end of the named begin AstJumpLabel* labelp = findAddLabel(beginp, false); nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp)); } nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; //if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout," labelo: "); } } virtual void visit(AstVarRef* nodep, AstNUser*) { if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true); } virtual void visit(AstConst* nodep, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkJumpVisitor(AstNetlist* nodep) { m_modp = NULL; m_ftaskp = NULL; m_loopp = NULL; m_loopInc = false; m_repeatNum = 0; nodep->accept(*this); } virtual ~LinkJumpVisitor() {} }; //###################################################################### // Task class functions void V3LinkJump::linkJump(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Branch.h0000664000177100017500000000225712525171733016105 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Branch prediction // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3BRANCH_H_ #define _V3BRANCH_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Branch { public: // CREATORS static void branchAll(AstNetlist* rootp); }; #endif // Guard verilator-3.874/src/V3EmitCBase.h0000664000177100017500000000751212525172036016500 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit C++ for tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EMITCBASE_H_ #define _V3EMITCBASE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3File.h" #include "V3Ast.h" //###################################################################### // Base Visitor class -- holds output file pointer class EmitCBaseVisitor : public AstNVisitor { public: // STATE V3OutCFile* m_ofp; // METHODS V3OutCFile* ofp() const { return m_ofp; } void puts(const string& str) { ofp()->puts(str); } void putbs(const string& str) { ofp()->putbs(str); } void putsQuoted(const string& str) { ofp()->putsQuoted(str); } bool optSystemC() { return v3Global.opt.systemC(); } bool optSystemPerl() { return v3Global.opt.systemPerl(); } static string symClassName() { return v3Global.opt.prefix()+"__Syms"; } static string symClassVar() { return symClassName()+"* __restrict vlSymsp"; } static string symTopAssign() { return v3Global.opt.prefix()+"* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;"; } static string modClassName(AstNodeModule* modp) { // Return name of current module being processed if (modp->isTop()) { return v3Global.opt.prefix(); } else { return v3Global.opt.modPrefix() + "_" + modp->name(); } } static string topClassName() { // Return name of top wrapper module return v3Global.opt.prefix(); } AstCFile* newCFile(const string& filename, bool slow, bool source) { AstCFile* cfilep = new AstCFile(v3Global.rootp()->fileline(), filename); cfilep->slow(slow); cfilep->source(source); v3Global.rootp()->addFilesp(cfilep); return cfilep; } string cFuncArgs(AstCFunc* nodep) { // Return argument list for given C function string args = nodep->argTypes(); // Might be a user function with argument list. for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && !portp->isFuncReturn()) { if (args != "") args+= ", "; if (nodep->dpiImport() || nodep->dpiExportWrapper()) args += portp->dpiArgType(true,false); else if (nodep->funcPublic()) args += portp->cPubArgType(true,false); else args += portp->vlArgType(true,false,true); } } } return args; } // CONSTRUCTORS EmitCBaseVisitor() { m_ofp = NULL; } virtual ~EmitCBaseVisitor() {} }; //###################################################################### // Count operations under the given node, as a visitor of each AstNode class EmitCBaseCounterVisitor : public AstNVisitor { private: // STATE int m_count; // Number of statements // VISITORS virtual void visit(AstNode* nodep, AstNUser*) { m_count++; nodep->iterateChildren(*this); } public: // CONSTUCTORS EmitCBaseCounterVisitor(AstNode* nodep) { m_count = 0; nodep->accept(*this); } virtual ~EmitCBaseCounterVisitor() {} int count() const { return m_count; } }; #endif // guard verilator-3.874/src/V3Simulate.h0000664000177100017500000006174112525172076016477 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Simulate code to determine output values/variables // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // // void example_usage() { // SimulateVisitor simvis (false, false); // simvis.clear(); // // Set all inputs to the constant // for (deque::iterator it = m_inVarps.begin(); it!=m_inVarps.end(); ++it) { // simvis.newNumber(invscp, #); // } // // Simulate // simvis.main(nodep); // // Read outputs // for (deque::iterator it = m_outVarps.begin(); it!=m_outVarps.end(); ++it) { // V3Number* outnump = simvis.fetchOutNumberNull(outvscp); // //************************************************************************* #ifndef _V3SIMULATE_H_ #define _V3SIMULATE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" #include "V3Width.h" #include "V3Task.h" #include //============================================================================ //###################################################################### // Simulate class functions class SimulateVisitor : public AstNVisitor { // Simulate a node tree, returning value of variables // Two major operating modes: // Test the tree to see if it is conformant // Given a set of input values, find the output values // Both are done in this same visitor to reduce risk; if a visitor // is missing, we will simply not apply the optimization, rather then bomb. private: // NODE STATE // Cleared on each always/assignw AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; // Checking: // AstVar(Scope)::user1() -> VarUsage. Set true to indicate tracking as lvalue/rvalue // Simulating: // AstVar(Scope)::user3() -> V3Number*. Input value of variable or node (and output for non-delayed assignments) // AstVar(Scope)::user2() -> V3Number*. Output value of variable (delayed assignments) enum VarUsage { VU_NONE=0, VU_LV=1, VU_RV=2, VU_LVDLY=4 }; // STATE // Major mode bool m_checkOnly; ///< Checking only (no simulation) mode bool m_scoped; ///< Running with AstVarScopes instead of AstVars bool m_params; ///< Doing parameter propagation // Checking: string m_whyNotOptimizable; ///< String explaining why not optimizable or NULL to optimize AstNode* m_whyNotNodep; ///< First node not optimizable bool m_anyAssignDly; ///< True if found a delayed assignment bool m_anyAssignComb; ///< True if found a non-delayed assignment bool m_inDlyAssign; ///< Under delayed assignment int m_instrCount; ///< Number of nodes int m_dataCount; ///< Bytes of data AstJumpGo* m_jumpp; ///< Jump label we're branching from // Simulating: deque m_numFreeps; ///< List of all numbers free and not in use deque m_numAllps; ///< List of all numbers free and in use // Note level 8&9 include debugging each simulation value static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // Checking METHODS public: /// Call other-this function on all new *non-constant* var references virtual void varRefCb(AstVarRef* nodep) {} void clearOptimizable(AstNode* nodep/*null ok*/, const string& why) { // Something bad found. optimizable() will return false, // and fetchNumber should not be called or it may assert. if (!m_whyNotNodep) { m_whyNotNodep = nodep; if (debug()>=5) { UINFO(0,"Clear optimizable: "<width()<width(nodep->width()); nump->fileline(nodep->fileline()); nump->setLong(value); // We do support more than 32 bit numbers, just valuep=0 in that case } else { //UINFO(7,"Num New "<width()<fileline(), nodep->width(), value); m_numAllps.push_back(nump); } nump->isDouble(nodep->isDouble()); return nump; } public: V3Number* newNumber(AstNode* nodep, uint32_t value=0) { // Set a constant value for this node if (!nodep->user3p()) { V3Number* nump = allocNumber(nodep, value); setNumber(nodep, nump); return nump; } else { return (fetchNumber(nodep)); } } V3Number* newOutNumber(AstNode* nodep, uint32_t value=0) { // Set a constant value for this node if (!nodep->user2p()) { V3Number* nump = allocNumber(nodep, value); setOutNumber(nodep, nump); return nump; } else { return (fetchOutNumber(nodep)); } } V3Number* fetchNumberNull(AstNode* nodep) { return ((V3Number*)nodep->user3p()); } V3Number* fetchOutNumberNull(AstNode* nodep) { return ((V3Number*)nodep->user2p()); } V3Number* fetchNumber(AstNode* nodep) { V3Number* nump = fetchNumberNull(nodep); if (!nump) nodep->v3fatalSrc("No value found for node."); //UINFO(9," fetch num "<<*nump<<" on "<v3fatalSrc("No value found for node."); return nump; } private: inline void setNumber(AstNode* nodep, const V3Number* nump) { UINFO(9," set num "<<*nump<<" on "<user3p((AstNUser*)nump); } inline void setOutNumber(AstNode* nodep, const V3Number* nump) { UINFO(9," set num "<<*nump<<" on "<user2p((AstNUser*)nump); } void checkNodeInfo(AstNode* nodep) { if (m_checkOnly) { m_instrCount += nodep->instrCount(); m_dataCount += nodep->width(); } if (!nodep->isPredictOptimizable()) { //UINFO(9," !predictopt "<prettyTypeName()<varScopep(); else vscp = nodep->varp(); if (!vscp) nodep->v3fatalSrc("Not linked"); return vscp; } int unrollCount() { return m_params ? v3Global.opt.unrollCount()*16 : v3Global.opt.unrollCount(); } bool jumpingOver(AstNode* nodep) { // True to jump over this node - all visitors must call this up front return (m_jumpp && m_jumpp->labelp()!=nodep); } void assignOutNumber(AstNodeAssign* nodep, AstNode* vscp, const V3Number* nump) { // Don't do setNumber, as value isn't yet visible to following statements if (nodep->castAssignDly()) { // Don't do setNumber, as value isn't yet visible to following statements newOutNumber(vscp)->opAssign(*nump); } else { newNumber(vscp)->opAssign(*nump); newOutNumber(vscp)->opAssign(*nump); } } // VISITORS virtual void visit(AstAlways* nodep, AstNUser*) { if (jumpingOver(nodep)) return; checkNodeInfo(nodep); nodep->iterateChildren(*this); } virtual void visit(AstSenTree* nodep, AstNUser*) { // Sensitivities aren't inputs per se; we'll keep our tree under the same sens. } virtual void visit(AstVarRef* nodep, AstNUser*) { if (jumpingOver(nodep)) return; if (!optimizable()) return; // Accelerate AstNode* vscp = varOrScope(nodep); // We can't have non-delayed assignments with same value on LHS and RHS // as we don't figure out variable ordering. // Delayed is OK though, as we'll decode the next state separately. if (!nodep->varp()->dtypeSkipRefp()->castBasicDType()) clearOptimizable(nodep,"Array references/not basic"); if (nodep->lvalue()) { if (m_inDlyAssign) { if (!(vscp->user1() & VU_LVDLY)) { vscp->user1( vscp->user1() | VU_LVDLY); if (m_checkOnly) varRefCb (nodep); } } else { // nondly asn if (!(vscp->user1() & VU_LV)) { if (!m_params && (vscp->user1() & VU_RV)) clearOptimizable(nodep,"Var read & write"); vscp->user1( vscp->user1() | VU_LV); if (m_checkOnly) varRefCb (nodep); } } } else { if (!(vscp->user1() & VU_RV)) { if (!m_params && (vscp->user1() & VU_LV)) clearOptimizable(nodep,"Var write & read"); vscp->user1( vscp->user1() | VU_RV); bool isConst = nodep->varp()->isParam(); AstConst* constp = (isConst ? nodep->varp()->valuep()->castConst() : NULL); if (isConst && constp) { // Propagate PARAM constants for constant function analysis if (!m_checkOnly && optimizable()) { newNumber(vscp)->opAssign(constp->num()); } } else { if (m_checkOnly) varRefCb (nodep); } } } if (!m_checkOnly && optimizable()) { // simulating if (nodep->lvalue()) { nodep->v3fatalSrc("LHS varref should be handled in AstAssign visitor."); } else { // Return simulation value - copy by reference instead of value for speed V3Number* nump = fetchNumberNull(vscp); if (!nump) { if (m_params) { clearOptimizable(nodep,"Language violation: reference to non-function-local variable"); } else { nodep->v3fatalSrc("Variable value should have been set before any visitor called."); } nump = allocNumber(nodep, 0); // Any value; just so recover from error } setNumber(nodep, nump); } } } virtual void visit(AstVarXRef* nodep, AstNUser*) { if (jumpingOver(nodep)) return; if (m_scoped) { badNodeType(nodep); return; } else { clearOptimizable(nodep,"Language violation: Dotted hierarchical references not allowed in constant functions"); } } virtual void visit(AstNodeFTask* nodep, AstNUser*) { if (jumpingOver(nodep)) return; if (!m_params) { badNodeType(nodep); return; } if (nodep->dpiImport()) { clearOptimizable(nodep,"DPI import functions aren't simulatable"); } checkNodeInfo(nodep); nodep->iterateChildren(*this); } virtual void visit(AstNodeIf* nodep, AstNUser*) { if (jumpingOver(nodep)) return; UINFO(5," IF "<iterateChildren(*this); } else { nodep->condp()->iterateAndNext(*this); if (optimizable()) { if (fetchNumber(nodep->condp())->isNeqZero()) { nodep->ifsp()->iterateAndNext(*this); } else { nodep->elsesp()->iterateAndNext(*this); } } } } virtual void visit(AstConst* nodep, AstNUser*) { checkNodeInfo(nodep); if (!m_checkOnly && optimizable()) { setNumber(nodep, &(nodep->num())); } } virtual void visit(AstNodeUniop* nodep, AstNUser*) { if (!optimizable()) return; // Accelerate checkNodeInfo(nodep); nodep->iterateChildren(*this); if (!m_checkOnly && optimizable()) { nodep->numberOperate(*newNumber(nodep), *fetchNumber(nodep->lhsp())); } } virtual void visit(AstNodeBiop* nodep, AstNUser*) { if (!optimizable()) return; // Accelerate checkNodeInfo(nodep); nodep->iterateChildren(*this); if (!m_checkOnly && optimizable()) { nodep->numberOperate(*newNumber(nodep), *fetchNumber(nodep->lhsp()), *fetchNumber(nodep->rhsp())); } } virtual void visit(AstNodeTriop* nodep, AstNUser*) { if (!optimizable()) return; // Accelerate checkNodeInfo(nodep); nodep->iterateChildren(*this); if (!m_checkOnly && optimizable()) { nodep->numberOperate(*newNumber(nodep), *fetchNumber(nodep->lhsp()), *fetchNumber(nodep->rhsp()), *fetchNumber(nodep->thsp())); } } virtual void visit(AstLogAnd* nodep, AstNUser*) { // Need to short circuit if (!optimizable()) return; // Accelerate checkNodeInfo(nodep); if (m_checkOnly) { nodep->iterateChildren(*this); } else { nodep->lhsp()->accept(*this); if (fetchNumber(nodep->lhsp())->isNeqZero()) { nodep->rhsp()->accept(*this); newNumber(nodep)->opAssign(*fetchNumber(nodep->rhsp())); } else { newNumber(nodep)->opAssign(*fetchNumber(nodep->lhsp())); // a zero } } } virtual void visit(AstLogOr* nodep, AstNUser*) { // Need to short circuit if (!optimizable()) return; // Accelerate checkNodeInfo(nodep); if (m_checkOnly) { nodep->iterateChildren(*this); } else { nodep->lhsp()->accept(*this); if (fetchNumber(nodep->lhsp())->isNeqZero()) { newNumber(nodep)->opAssign(*fetchNumber(nodep->lhsp())); // a one } else { nodep->rhsp()->accept(*this); newNumber(nodep)->opAssign(*fetchNumber(nodep->rhsp())); } } } virtual void visit(AstLogIf* nodep, AstNUser*) { // Need to short circuit, same as (!A || B) if (!optimizable()) return; // Accelerate checkNodeInfo(nodep); if (m_checkOnly) { nodep->iterateChildren(*this); } else { nodep->lhsp()->accept(*this); if (fetchNumber(nodep->lhsp())->isEqZero()) { newNumber(nodep)->opAssign(V3Number(nodep->fileline(), 1, 1)); // a one } else { nodep->rhsp()->accept(*this); newNumber(nodep)->opAssign(*fetchNumber(nodep->rhsp())); } } } virtual void visit(AstNodeCond* nodep, AstNUser*) { // We could use above visit(AstNodeTriop), but need to do short circuiting. // It's also slower even O(n^2) to evaluate both sides when we really only need to evaluate one side. if (!optimizable()) return; // Accelerate checkNodeInfo(nodep); if (m_checkOnly) { nodep->iterateChildren(*this); } else { nodep->condp()->accept(*this); if (fetchNumber(nodep->condp())->isNeqZero()) { nodep->expr1p()->accept(*this); newNumber(nodep)->opAssign(*fetchNumber(nodep->expr1p())); } else { nodep->expr2p()->accept(*this); newNumber(nodep)->opAssign(*fetchNumber(nodep->expr2p())); } } } virtual void visit(AstNodeAssign* nodep, AstNUser*) { if (jumpingOver(nodep)) return; if (!optimizable()) return; // Accelerate if (nodep->castAssignDly()) { if (m_anyAssignComb) clearOptimizable(nodep, "Mix of dly/non-dly assigns"); m_anyAssignDly = true; m_inDlyAssign = true; } else { if (m_anyAssignDly) clearOptimizable(nodep, "Mix of dly/non-dly assigns"); m_anyAssignComb = true; } if (AstSel* selp = nodep->lhsp()->castSel()) { if (!m_params) { clearOptimizable(nodep, "LHS has select"); return; } checkNodeInfo(selp); AstVarRef* varrefp = selp->fromp()->castVarRef(); if (!varrefp) { clearOptimizable(nodep, "Select LHS isn't simple variable"); return; } if (m_checkOnly) { nodep->iterateChildren(*this); } else { selp->lsbp()->iterateAndNext(*this); nodep->rhsp()->iterateAndNext(*this); if (optimizable()) { AstNode* vscp = varOrScope(varrefp); if (optimizable()) { V3Number outnum (nodep->fileline(), varrefp->varp()->widthMin()); if (V3Number* outnump = fetchOutNumberNull(vscp)) { outnum = *outnump; } else if (V3Number* outnump = fetchNumberNull(vscp)) { outnum = *outnump; } else { // Assignment to unassigned variable, all bits are X or 0 if (varrefp->varp()->basicp() && varrefp->varp()->basicp()->isZeroInit()) { outnum.setAllBits0(); } else { outnum.setAllBitsX(); } } outnum.opSelInto(*fetchNumber(nodep->rhsp()), *fetchNumber(selp->lsbp()), selp->widthConst()); assignOutNumber(nodep, vscp, &outnum); } } } } else if (!nodep->lhsp()->castVarRef()) { clearOptimizable(nodep, "LHS isn't simple variable"); } else if (m_checkOnly) { nodep->iterateChildren(*this); } else if (optimizable()) { nodep->rhsp()->iterateAndNext(*this); if (optimizable()) { AstNode* vscp = varOrScope(nodep->lhsp()->castVarRef()); assignOutNumber(nodep, vscp, fetchNumber(nodep->rhsp())); } } m_inDlyAssign = false; } virtual void visit(AstBegin* nodep, AstNUser*) { checkNodeInfo(nodep); nodep->iterateChildren(*this); } virtual void visit(AstNodeCase* nodep, AstNUser*) { if (jumpingOver(nodep)) return; UINFO(5," CASE "<iterateChildren(*this); } else if (optimizable()) { nodep->exprp()->iterateAndNext(*this); bool hit = false; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { if (!itemp->isDefault()) { for (AstNode* ep = itemp->condsp(); ep; ep=ep->nextp()) { if (hit) break; ep->iterateAndNext(*this); if (optimizable()) { V3Number match (nodep->fileline(), 1); match.opEq(*fetchNumber(nodep->exprp()), *fetchNumber(ep)); if (match.isNeqZero()) { itemp->bodysp()->iterateAndNext(*this); hit = true; } } } } } // Else default match for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { if (hit) break; if (!hit && itemp->isDefault()) { itemp->bodysp()->iterateAndNext(*this); hit = true; } } } } virtual void visit(AstCaseItem* nodep, AstNUser*) { // Real handling is in AstNodeCase if (jumpingOver(nodep)) return; checkNodeInfo(nodep); nodep->iterateChildren(*this); } virtual void visit(AstComment*, AstNUser*) {} virtual void visit(AstJumpGo* nodep, AstNUser*) { if (jumpingOver(nodep)) return; checkNodeInfo(nodep); if (!m_checkOnly) { UINFO(5," JUMP GO "<iterateChildren(*this); if (m_jumpp && m_jumpp->labelp() == nodep) { UINFO(5," JUMP DONE "<iterateChildren(*this); } else if (optimizable()) { int loops = 0; nodep->initsp()->iterateAndNext(*this); while (1) { UINFO(5," FOR-ITER "<condp()->iterateAndNext(*this); if (!optimizable()) break; if (!fetchNumber(nodep->condp())->isNeqZero()) { break; } nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); if (loops++ > unrollCount()*16) { clearOptimizable(nodep, "Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above "+cvtToStr(unrollCount())); break; } } } } virtual void visit(AstWhile* nodep, AstNUser*) { // Doing lots of Whiles is slow, so only for parameters if (jumpingOver(nodep)) return; UINFO(5," WHILE "<iterateChildren(*this); } else if (optimizable()) { int loops = 0; while (1) { UINFO(5," WHILE-ITER "<precondsp()->iterateAndNext(*this); if (jumpingOver(nodep)) break; nodep->condp()->iterateAndNext(*this); if (jumpingOver(nodep)) break; if (!optimizable()) break; if (!fetchNumber(nodep->condp())->isNeqZero()) { break; } nodep->bodysp()->iterateAndNext(*this); if (jumpingOver(nodep)) break; nodep->incsp()->iterateAndNext(*this); if (jumpingOver(nodep)) break; // Prep for next loop if (loops++ > unrollCount()*16) { clearOptimizable(nodep, "Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above "+cvtToStr(unrollCount())); break; } } } } virtual void visit(AstFuncRef* nodep, AstNUser*) { if (jumpingOver(nodep)) return; UINFO(5," FUNCREF "<taskp()->castNodeFTask(); if (!funcp) nodep->v3fatalSrc("Not linked"); // cppcheck-suppress redundantAssignment if (m_params) { V3Width::widthParamsEdit(funcp); } funcp=NULL; // Make sure we've sized the function funcp = nodep->taskp()->castNodeFTask(); if (!funcp) nodep->v3fatalSrc("Not linked"); // Apply function call values to function V3TaskConnects tconnects = V3Task::taskConnects(nodep, nodep->taskp()->stmtsp()); // Must do this in two steps, eval all params, then apply them // Otherwise chained functions may have the wrong results for (V3TaskConnects::iterator it=tconnects.begin(); it!=tconnects.end(); ++it) { AstVar* portp = it->first; AstNode* pinp = it->second->exprp(); if (pinp) { // Else too few arguments in function call - ignore it if (portp->isOutput()) { clearOptimizable(portp,"Language violation: Outputs not allowed in constant functions"); return; } // Evaluate pin value pinp->accept(*this); } } for (V3TaskConnects::iterator it=tconnects.begin(); it!=tconnects.end(); ++it) { AstVar* portp = it->first; AstNode* pinp = it->second->exprp(); if (pinp) { // Else too few arguments in function call - ignore it // Apply value to the function if (!m_checkOnly && optimizable()) { newNumber(portp)->opAssign(*fetchNumber(pinp)); } } } // Evaluate the function funcp->accept(*this); if (!m_checkOnly && optimizable()) { // Grab return value from output variable (if it's a function) if (!funcp->fvarp()) nodep->v3fatalSrc("Function reference points at non-function"); newNumber(nodep)->opAssign(*fetchNumber(funcp->fvarp())); } } virtual void visit(AstVar* nodep, AstNUser*) { if (jumpingOver(nodep)) return; if (!m_params) { badNodeType(nodep); return; } } // default // These types are definately not reducable // AstCoverInc, AstDisplay, AstArraySel, AstStop, AstFinish, // AstRand, AstTime, AstUCFunc, AstCCall, AstCStmt, AstUCStmt virtual void visit(AstNode* nodep, AstNUser*) { if (jumpingOver(nodep)) return; badNodeType(nodep); } private: // MEMBERS - called by constructor void setMode(bool scoped, bool checkOnly, bool params) { m_checkOnly = checkOnly; m_scoped = scoped; m_params = params; } void mainGuts(AstNode* nodep) { nodep->accept(*this); if (m_jumpp) { m_jumpp->v3fatalSrc("JumpGo branched to label that wasn't found"); m_jumpp = NULL; } } public: // CONSTRUCTORS SimulateVisitor() { setMode(false,false,false); clear(); // We reuse this structure in the main loop, so put initializers inside clear() } void clear() { m_whyNotOptimizable = ""; m_whyNotNodep = NULL; m_anyAssignComb = false; m_anyAssignDly = false; m_inDlyAssign = false; m_instrCount = 0; m_dataCount = 0; m_jumpp = NULL; AstNode::user1ClearTree(); // user1p() used on entire tree AstNode::user2ClearTree(); // user2p() used on entire tree AstNode::user3ClearTree(); // user3p() used on entire tree // Move all allocated numbers to the free pool m_numFreeps = m_numAllps; } void mainTableCheck (AstNode* nodep) { setMode(true/*scoped*/,true/*checking*/, false/*params*/); mainGuts(nodep); } void mainTableEmulate (AstNode* nodep) { setMode(true/*scoped*/,false/*checking*/, false/*params*/); mainGuts(nodep); } void mainParamEmulate (AstNode* nodep) { setMode(false/*scoped*/,false/*checking*/, true/*params*/); mainGuts(nodep); } virtual ~SimulateVisitor() { for (deque::iterator it = m_numAllps.begin(); it != m_numAllps.end(); ++it) { delete (*it); } m_numFreeps.clear(); m_numAllps.clear(); } }; #endif // Guard verilator-3.874/src/V3Undriven.cpp0000664000177100017500000003267612525171733017045 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Check for unused/undriven signals // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Undriven's Transformations: // // Each module: // Make vector for all variables // SEL(VARREF(...))) mark only some bits as used/driven // else VARREF(...) mark all bits as used/driven // Report unused/undriven nets // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3String.h" #include "V3Undriven.h" #include "V3Ast.h" //###################################################################### // Class for every variable we may process class UndrivenVarEntry { // MEMBERS AstVar* m_varp; // Variable this tracks bool m_usedWhole; // True if whole vector used bool m_drivenWhole; // True if whole vector driven vector m_flags; // Used/Driven on each subbit enum { FLAG_USED = 0, FLAG_DRIVEN = 1, FLAGS_PER_BIT = 2 }; static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } public: // CONSTRUCTORS UndrivenVarEntry (AstVar* varp) { // Construction for when a var is used UINFO(9, "create "<width()*FLAGS_PER_BIT); for (int i=0; iwidth()*FLAGS_PER_BIT; i++) { m_flags[i] = false; } } ~UndrivenVarEntry() {} private: // METHODS inline bool bitNumOk(int bit) const { return bit>=0 && (bit*FLAGS_PER_BIT < (int)m_flags.size()); } inline bool usedFlag(int bit) const { return m_usedWhole || m_flags[bit*FLAGS_PER_BIT + FLAG_USED]; } inline bool drivenFlag(int bit) const { return m_drivenWhole || m_flags[bit*FLAGS_PER_BIT + FLAG_DRIVEN]; } enum BitNamesWhich { BN_UNUSED, BN_UNDRIVEN, BN_BOTH }; string bitNames(BitNamesWhich which) { string bits=""; bool prev = false; int msb = 0; // bit==-1 loops below; we do one extra iteration so end with prev=false for (int bit=(m_flags.size()/FLAGS_PER_BIT)-1; bit >= -1; --bit) { if (bit>=0 && ((which == BN_UNUSED && !usedFlag(bit) && drivenFlag(bit)) || (which == BN_UNDRIVEN && usedFlag(bit) && !drivenFlag(bit)) || (which == BN_BOTH && !usedFlag(bit) && !drivenFlag(bit)))) { if (!prev) { prev=true; msb = bit; } } else if (prev) { AstBasicDType* bdtypep = m_varp->basicp(); int lsb = bit+1; if (bits != "") bits += ","; if (lsb==msb) { bits += cvtToStr(lsb+bdtypep->lsb()); } else { if (bdtypep->littleEndian()) { bits += cvtToStr(lsb+bdtypep->lsb())+":"+cvtToStr(msb+bdtypep->lsb()); } else { bits += cvtToStr(msb+bdtypep->lsb())+":"+cvtToStr(lsb+bdtypep->lsb()); } } prev = false; } } return "["+bits+"]"; } public: void usedWhole() { UINFO(9, "set u[*] "<name()<name()<name()<name()<prettyName(); return VString::wildmatch(prettyName.c_str(), regexp.c_str()); } void reportViolations() { // Combine bits into overall state AstVar* nodep = m_varp; if (!nodep->isParam() && !nodep->isGenVar()) { bool allU=true; bool allD=true; bool anyU=m_usedWhole; bool anyD=m_drivenWhole; bool anyUnotD=false; bool anyDnotU=false; bool anynotDU=false; for (unsigned bit=0; bitv3warn(UNUSED, "Signal is not driven, nor used: "<prettyName()); nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once } } else if (allD && !anyU) { if (!unusedMatch(nodep)) { nodep->v3warn(UNUSED, "Signal is not used: "<prettyName()); nodep->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once } } else if (!anyD && allU) { nodep->v3warn(UNDRIVEN, "Signal is not driven: "<prettyName()); nodep->fileline()->modifyWarnOff(V3ErrorCode::UNDRIVEN, true); // Warn only once } else { // Bits have different dispositions bool setU=false; bool setD=false; if (anynotDU && !unusedMatch(nodep)) { nodep->v3warn(UNUSED, "Bits of signal are not driven, nor used: "<prettyName() <v3warn(UNUSED, "Bits of signal are not used: "<prettyName() <v3warn(UNDRIVEN, "Bits of signal are not driven: "<prettyName() <fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true); // Warn only once if (setD) nodep->fileline()->modifyWarnOff(V3ErrorCode::UNDRIVEN, true); // Warn only once } } } }; //###################################################################### // Undriven state, as a visitor of each AstNode class UndrivenVisitor : public AstNVisitor { private: // NODE STATE // AstVar::user1p -> UndrivenVar* for usage var, 0=not set yet AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // STATE vector m_entryps[3]; // Nodes to delete when we are finished bool m_markBoth; // Mark as driven+used AstNodeFTask* m_taskp; // Current task AstAlways* m_alwaysp; // Current always // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } UndrivenVarEntry* getEntryp(AstVar* nodep, int which_user) { if (!(which_user==1 ? nodep->user1p() : nodep->user2p())) { UndrivenVarEntry* entryp = new UndrivenVarEntry (nodep); //UINFO(9," Associate u="<name()<user1p(entryp); else if (which_user==2) nodep->user2p(entryp); else nodep->v3fatalSrc("Bad case"); return entryp; } else { UndrivenVarEntry* entryp = (UndrivenVarEntry*)(which_user==1 ? nodep->user1p() : nodep->user2p()); return entryp; } } void warnAlwCombOrder(AstVarRef* nodep) { AstVar* varp = nodep->varp(); if (!varp->isParam() && !varp->isGenVar() && !varp->isUsedLoopIdx() && !varp->fileline()->warnIsOff(V3ErrorCode::ALWCOMBORDER)) { // Warn only once per variable nodep->v3warn(ALWCOMBORDER, "Always_comb variable driven after use: "<prettyName()); varp->fileline()->modifyWarnOff(V3ErrorCode::ALWCOMBORDER, true); // Complain just once for any usage } } // VISITORS virtual void visit(AstVar* nodep, AstNUser*) { for (int usr=1; usr<(m_alwaysp?3:2); ++usr) { UndrivenVarEntry* entryp = getEntryp (nodep, usr); if (nodep->isInput() || nodep->isSigPublic() || nodep->isSigUserRWPublic() || (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) { entryp->drivenWhole(); } if (nodep->isOutput() || nodep->isSigPublic() || nodep->isSigUserRWPublic() || nodep->isSigUserRdPublic() || (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) { entryp->usedWhole(); } } // Discover variables used in bit definitions, etc nodep->iterateChildren(*this); } virtual void visit(AstArraySel* nodep, AstNUser*) { // Arrays are rarely constant assigned, so for now we punt and do all entries nodep->iterateChildren(*this); } virtual void visit(AstSel* nodep, AstNUser*) { AstVarRef* varrefp = nodep->fromp()->castVarRef(); AstConst* constp = nodep->lsbp()->castConst(); if (varrefp && constp && !constp->num().isFourState()) { for (int usr=1; usr<(m_alwaysp?3:2); ++usr) { UndrivenVarEntry* entryp = getEntryp (varrefp->varp(), usr); int lsb = constp->toUInt(); if (m_markBoth || varrefp->lvalue()) { // Don't warn if already driven earlier as "a=0; if(a) a=1;" is fine. if (usr==2 && m_alwaysp && entryp->isUsedNotDrivenBit(lsb, nodep->width())) { UINFO(9," Select. Entryp="<<(void*)entryp<drivenBit(lsb, nodep->width()); } if (m_markBoth || !varrefp->lvalue()) entryp->usedBit(lsb, nodep->width()); } } else { // else other varrefs handled as unknown mess in AstVarRef nodep->iterateChildren(*this); } } virtual void visit(AstVarRef* nodep, AstNUser*) { // Any variable for (int usr=1; usr<(m_alwaysp?3:2); ++usr) { UndrivenVarEntry* entryp = getEntryp (nodep->varp(), usr); bool fdrv = nodep->lvalue() && nodep->varp()->attrFileDescr(); // FD's are also being read from if (m_markBoth || nodep->lvalue()) { if (usr==2 && m_alwaysp && entryp->isUsedNotDrivenAny()) { UINFO(9," Full bus. Entryp="<<(void*)entryp<drivenWhole(); } if (m_markBoth || !nodep->lvalue() || fdrv) entryp->usedWhole(); } } // Don't know what black boxed calls do, assume in+out virtual void visit(AstSysIgnore* nodep, AstNUser*) { bool prevMark = m_markBoth; m_markBoth = true; nodep->iterateChildren(*this); m_markBoth = prevMark; } virtual void visit(AstAlways* nodep, AstNUser*) { AstAlways* prevAlwp = m_alwaysp; { AstNode::user2ClearTree(); if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) UINFO(9," "<keyword() == VAlwaysKwd::ALWAYS_COMB) m_alwaysp = nodep; else m_alwaysp = NULL; nodep->iterateChildren(*this); if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) UINFO(9," Done "<iterateChildren(*this); m_taskp = prevTaskp; } // Until we support tables, primitives will have undriven and unused I/Os virtual void visit(AstPrimitive* nodep, AstNUser*) {} // Coverage artifacts etc shouldn't count as a sink virtual void visit(AstCoverDecl* nodep, AstNUser*) {} virtual void visit(AstCoverInc* nodep, AstNUser*) {} virtual void visit(AstCoverToggle* nodep, AstNUser*) {} virtual void visit(AstTraceDecl* nodep, AstNUser*) {} virtual void visit(AstTraceInc* nodep, AstNUser*) {} // iterate virtual void visit(AstConst* nodep, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS UndrivenVisitor(AstNetlist* nodep) { m_markBoth = false; m_taskp = NULL; m_alwaysp = NULL; nodep->accept(*this); } virtual ~UndrivenVisitor() { for (vector::iterator it = m_entryps[1].begin(); it != m_entryps[1].end(); ++it) { (*it)->reportViolations(); } for (int usr=1; usr<3; ++usr) { for (vector::iterator it = m_entryps[usr].begin(); it != m_entryps[usr].end(); ++it) { delete (*it); } } } }; //###################################################################### // Undriven class functions void V3Undriven::undrivenAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "< #include #include #include #include #include #include "V3Ast.h" #include "V3File.h" #include "V3Global.h" //====================================================================== // Special methods // We need these here, because the classes they point to aren't defined when we declare the class const char* AstIfaceRefDType::broken() const { BROKEN_RTN(m_ifacep && !m_ifacep->brokeExists()); BROKEN_RTN(m_cellp && !m_cellp->brokeExists()); BROKEN_RTN(m_modportp && !m_modportp->brokeExists()); return NULL; } AstIface* AstIfaceRefDType::ifaceViaCellp() const { return ((m_cellp && m_cellp->modp()) ? m_cellp->modp()->castIface() : m_ifacep); } const char* AstNodeVarRef::broken() const { BROKEN_RTN(m_varScopep && !m_varScopep->brokeExists()); BROKEN_RTN(m_varp && !m_varp->brokeExists()); return NULL; } void AstNodeVarRef::cloneRelink() { if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep()->castVar(); } } int AstNodeSel::bitConst() const { AstConst* constp=bitp()->castConst(); return (constp?constp->toSInt():0); } void AstNodeClassDType::repairMemberCache() { clearCache(); for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) { if (m_members.find(itemp->name())!=m_members.end()) { itemp->v3error("Duplicate declaration of member name: "<prettyName()); } else m_members.insert(make_pair(itemp->name(), itemp)); } } const char* AstNodeClassDType::broken() const { set exists; for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) { exists.insert(itemp); } for (MemberNameMap::const_iterator it=m_members.begin(); it!=m_members.end(); ++it) { if (VL_UNLIKELY(exists.find(it->second) == exists.end())) { this->v3error("Internal: Structure member broken: "<first); return "member broken"; } } return NULL; } int AstBasicDType::widthAlignBytes() const { if (width()<=8) return 1; else if (width()<=16) return 2; else if (isQuad()) return 8; else return 4; } int AstBasicDType::widthTotalBytes() const { if (width()<=8) return 1; else if (width()<=16) return 2; else if (isQuad()) return 8; else return widthWords()*(VL_WORDSIZE/8); } int AstNodeClassDType::widthTotalBytes() const { if (width()<=8) return 1; else if (width()<=16) return 2; else if (isQuad()) return 8; else return widthWords()*(VL_WORDSIZE/8); } int AstNodeClassDType::widthAlignBytes() const { // Could do max across members but that would be slow, // instead intuit based on total structure size if (width()<=8) return 1; else if (width()<=16) return 2; else if (width()<=32) return 4; else return 8; } AstNodeBiop* AstEq::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) { if (lhsp->isDouble() && rhsp->isDouble()) { return new AstEqD(fl, lhsp, rhsp); } else { return new AstEq(fl, lhsp, rhsp); } } AstNodeBiop* AstGte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) { if (lhsp->isDouble() && rhsp->isDouble()) { return new AstGteD(fl, lhsp, rhsp); } else if (lhsp->isSigned() && rhsp->isSigned()) { return new AstGteS(fl, lhsp, rhsp); } else { return new AstGte(fl, lhsp, rhsp); } } AstNodeBiop* AstLte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) { if (lhsp->isDouble() && rhsp->isDouble()) { return new AstLteD(fl, lhsp, rhsp); } else if (lhsp->isSigned() && rhsp->isSigned()) { return new AstLteS(fl, lhsp, rhsp); } else { return new AstLte(fl, lhsp, rhsp); } } bool AstVar::isSigPublic() const { return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar())); } bool AstVar::isScQuad() const { return (isSc() && isQuad() && !isScBv() && !isScBigUint()); } bool AstVar::isScBv() const { return ((isSc() && width() >= v3Global.opt.pinsBv()) || m_attrScBv); } bool AstVar::isScUint() const { return ((isSc() && v3Global.opt.pinsScUint() && width() >= 2 && width() <= 64) && !isScBv()); } bool AstVar::isScBigUint() const { return ((isSc() && v3Global.opt.pinsScBigUint() && width() >= 65 && width() <= 512) && !isScBv()); } void AstVar::combineType(AstVarType type) { // These flags get combined with the existing settings of the flags. // We don't test varType for certain types, instead set flags since // when we combine wires cross-hierarchy we need a union of all characteristics. if (type == AstVarType::SUPPLY0) type = AstVarType::WIRE; if (type == AstVarType::SUPPLY1) type = AstVarType::WIRE; m_varType=type; // For debugging prints only // These flags get combined with the existing settings of the flags. if (type==AstVarType::INPUT || type==AstVarType::INOUT) m_input = true; if (type==AstVarType::OUTPUT || type==AstVarType::INOUT) { m_output = true; m_declOutput = true; } if (type==AstVarType::INOUT || type==AstVarType::TRIWIRE || type==AstVarType::TRI0 || type==AstVarType::TRI1) m_tristate = true; if (type==AstVarType::TRI0) m_isPulldown = true; if (type==AstVarType::TRI1) m_isPullup = true; } string AstVar::verilogKwd() const { if (isInout()) { return "inout"; } else if (isInput()) { return "input"; } else if (isOutput()) { return "output"; } else if (isTristate()) { return "tri"; } else if (varType()==AstVarType::WIRE) { return "wire"; } else { return dtypep()->name(); } } string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const { if (forReturn) named=false; if (forReturn) v3fatalSrc("verilator internal data is never passed as return, but as first argument"); string arg; if (isWide() && isInOnly()) arg += "const "; AstBasicDType* bdtypep = basicp(); bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING; if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) { arg += "const char*"; } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) { arg += "const VerilatedScope*"; } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::DOUBLE) { arg += "double"; } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::FLOAT) { arg += "float"; } else if (strtype) { if (isInOnly()) arg += "const "; arg += "string"; } else if (widthMin() <= 8) { arg += "CData"; } else if (widthMin() <= 16) { arg += "SData"; } else if (widthMin() <= VL_WORDSIZE) { arg += "IData"; } else if (isQuad()) { arg += "QData"; } else if (isWide()) { arg += "WData"; // []'s added later } if (isWide() && !strtype) { arg += " (& "+name(); arg += ")["+cvtToStr(widthWords())+"]"; } else { if (forFunc && (isOutput() || (strtype && isInput()))) arg += "&"; if (named) arg += " "+name(); } return arg; } string AstVar::vlEnumType() const { string arg; AstBasicDType* bdtypep = basicp(); bool strtype = bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::STRING; if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::CHARPTR) { return "VLVT_PTR"; } else if (bdtypep && bdtypep->keyword()==AstBasicDTypeKwd::SCOPEPTR) { return "VLVT_PTR"; } else if (strtype) { arg += "VLVT_STRING"; } else if (widthMin() <= 8) { arg += "VLVT_UINT8"; } else if (widthMin() <= 16) { arg += "VLVT_UINT16"; } else if (widthMin() <= VL_WORDSIZE) { arg += "VLVT_UINT32"; } else if (isQuad()) { arg += "VLVT_UINT64"; } else if (isWide()) { arg += "VLVT_WDATA"; } // else return "VLVT_UNKNOWN" return arg; } string AstVar::vlEnumDir() const { if (isInout()) { return "VLVD_INOUT"; } else if (isInOnly()) { return "VLVD_IN"; } else if (isOutOnly()) { return "VLVD_OUT"; } else { return "VLVD_NODIR"; } } string AstVar::cPubArgType(bool named, bool forReturn) const { if (forReturn) named=false; string arg; if (isWide() && isInOnly()) arg += "const "; if (widthMin() == 1) { arg += "bool"; } else if (widthMin() <= VL_WORDSIZE) { arg += "uint32_t"; } else if (isWide()) { arg += "uint32_t"; // []'s added later } else { arg += "vluint64_t"; } if (isWide()) { if (forReturn) v3error("Unsupported: Public functions with >64 bit outputs; make an output of a public task instead"); arg += " (& "+name(); arg += ")["+cvtToStr(widthWords())+"]"; } else { if (isOutput() && !forReturn) arg += "&"; if (named) arg += " "+name(); } return arg; } string AstVar::dpiArgType(bool named, bool forReturn) const { if (forReturn) named=false; string arg; if (!basicp()) arg = "UNKNOWN"; if (basicp()->isBitLogic()) { if (widthMin() == 1) { arg = "unsigned char"; if (!forReturn && isOutput()) arg += "*"; } else { if (forReturn) { arg = "svBitVecVal"; } else if (isInOnly()) { arg = "const svBitVecVal*"; } else { arg = "svBitVecVal*"; } } } else { arg = basicp()->keyword().dpiType(); if (basicp()->keyword().isDpiUnsignable() && !basicp()->isSigned()) { arg = "unsigned "+arg; } if (!forReturn && isOutput()) arg += "*"; } if (named) arg += " "+name(); return arg; } string AstVar::scType() const { if (isScBigUint()) { return (string("sc_biguint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >> } else if (isScUint()) { return (string("sc_uint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >> } else if (isScBv()) { return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >> } else if (widthMin() == 1) { return "bool"; } else if (widthMin() <= VL_WORDSIZE) { if (widthMin() <= 8 && v3Global.opt.pinsUint8()) { return "uint8_t"; } else if (widthMin() <= 16 && v3Global.opt.pinsUint8()) { return "uint16_t"; } else { return "uint32_t"; } } else { return "vluint64_t"; } } AstVar* AstVar::scVarRecurse(AstNode* nodep) { // See if this is a SC assignment; if so return that type // Historically sc variables are identified by a variable // attribute. TODO it would better be a data type attribute. if (AstVar* anodep = nodep->castVar()) { if (anodep->isSc()) return anodep; else return NULL; } else if (nodep->castVarRef()) { if (nodep->castVarRef()->varp()->isSc()) return nodep->castVarRef()->varp(); else return NULL; } else if (nodep->castArraySel()) { if (nodep->op1p()) if (AstVar* p = scVarRecurse(nodep->op1p())) return p; if (nodep->op2p()) if (AstVar* p = scVarRecurse(nodep->op2p())) return p; if (nodep->op3p()) if (AstVar* p = scVarRecurse(nodep->op3p())) return p; if (nodep->op4p()) if (AstVar* p = scVarRecurse(nodep->op4p())) return p; } return NULL; } AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) { // dimension passed from AstArraySel::dimension // Dimension 0 means the VAR itself, 1 is the closest SEL to the AstVar, // which is the lowest in the dtype list. // ref order: a[1][2][3][4] // Created as: reg [4] a [1][2][3]; // *or* reg a [1][2][3][4]; // // The bit select is optional; used only if "leftover" []'s // SEL: SEL4(SEL3(SEL2(SEL1(VARREF0 a)))) // DECL: VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (DT RANGE3)))) // *or* VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (ARRAYSEL3 (DT)))) // SEL1 needs to select from entire variable which is a pointer to ARRAYSEL0 // TODO this function should be removed in favor of recursing the dtype(), // as that allows for more complicated data types. int dim = 0; for (AstNodeDType* dtypep=this; dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { if ((dim++)==dimension) { return dtypep; } dtypep = adtypep->subDTypep(); continue; } else if (AstBasicDType* adtypep = dtypep->castBasicDType()) { // AstBasicDType - nothing below, return null if (adtypep->isRanged()) { if ((dim++) == dimension) { return adtypep; } } return NULL; } else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) { if (adtypep->packed()) { if ((dim++) == dimension) { return adtypep; } } return NULL; } // Node no ->next in loop; use continue where necessary break; } return NULL; } uint32_t AstNodeDType::arrayUnpackedElements() { uint32_t entries=1; for (AstNodeDType* dtypep=this; dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) { entries *= adtypep->elementsConst(); dtypep = adtypep->subDTypep(); } else { // AstBasicDType - nothing below, 1 break; } } return entries; } pair AstNodeDType::dimensions(bool includeBasic) { // How many array dimensions (packed,unpacked) does this Var have? uint32_t packed = 0; uint32_t unpacked = 0; for (AstNodeDType* dtypep=this; dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { if (adtypep->castPackArrayDType()) packed++; else unpacked++; dtypep = adtypep->subDTypep(); continue; } else if (AstBasicDType* adtypep = dtypep->castBasicDType()) { if (includeBasic && adtypep->isRanged()) packed++; } break; } return make_pair(packed, unpacked); } int AstNodeDType::widthPow2() const { // I.e. width 30 returns 32, width 32 returns 32. uint32_t width = this->width(); for (int p2=30; p2>=0; p2--) { if (width > (1UL<castArraySel()) { nodep=nodep->castArraySel()->fromp(); continue; } else if (nodep->castSel()) { nodep=nodep->castSel()->fromp(); continue; } // AstNodeSelPre stashes the associated variable under an ATTROF of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified else if (nodep->castAttrOf()) { nodep=nodep->castAttrOf()->fromp(); continue; } else if (nodep->castNodePreSel()) { if (nodep->castNodePreSel()->attrp()) { nodep=nodep->castNodePreSel()->attrp(); } else { nodep=nodep->castNodePreSel()->lhsp(); } continue; } else break; } return nodep; } const char* AstScope::broken() const { BROKEN_RTN(m_aboveScopep && !m_aboveScopep->brokeExists()); BROKEN_RTN(m_aboveCellp && !m_aboveCellp->brokeExists()); BROKEN_RTN(!m_modp); BROKEN_RTN(m_modp && !m_modp->brokeExists()); return NULL; } void AstScope::cloneRelink() { if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep()->castScope(); if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep()->castCell(); if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep()->castNodeModule(); } string AstScope::nameDotless() const { string out = shortName(); string::size_type pos; while ((pos=out.find(".")) != string::npos) { out.replace(pos, 1, "__"); } return out; } string AstScopeName::scopePrettyName() const { string out; for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) { out += textp->text(); } // TOP will be replaced by top->name() if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,""); if (out.substr(0,7) == "__DOT__") out.replace(0,7,""); if (out.substr(0,1) == ".") out.replace(0,1,""); return AstNode::prettyName(out); } string AstScopeName::scopeSymName() const { string out; for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) { out += textp->text(); } if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,""); if (out.substr(0,7) == "__DOT__") out.replace(0,7,""); if (out.substr(0,1) == ".") out.replace(0,1,""); string::size_type pos; while ((pos=out.find(".")) != string::npos) { out.replace(pos, 1, "__"); } while ((pos=out.find("__DOT__")) != string::npos) { out.replace(pos, 7, "__"); } return out; } string AstScopeName::scopeDpiName() const { string out; for (AstText* textp=scopeEntrp(); textp; textp=textp->nextp()->castText()) { out += textp->text(); } if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,""); if (out.substr(0,7) == "__DOT__") out.replace(0,7,""); if (out.substr(0,1) == ".") out.replace(0,1,""); string::size_type pos; while ((pos=out.find(".")) != string::npos) { out.replace(pos, 1, "__"); } while ((pos=out.find("__DOT__")) != string::npos) { out.replace(pos, 7, "__"); } return out; } bool AstSenTree::hasClocked() { if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it"); for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) { if (senp->isClocked()) return true; } return false; } bool AstSenTree::hasSettle() { if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it"); for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) { if (senp->isSettle()) return true; } return false; } bool AstSenTree::hasInitial() { if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it"); for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) { if (senp->isInitial()) return true; } return false; } bool AstSenTree::hasCombo() { if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it"); for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) { if (senp->isCombo()) return true; } return false; } void AstTypeTable::clearCache() { // When we mass-change widthMin in V3WidthCommit, we need to correct the table. // Just clear out the maps; the search functions will be used to rebuild the map for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) { m_basicps[i] = NULL; } for (int isbit=0; isbit<_IDX0_MAX; ++isbit) { for (int numer=0; numernextp()) { if (AstBasicDType* bdtypep = nodep->castBasicDType()) { bdtypep->generic(false); } } } void AstTypeTable::repairCache() { // After we mass-change widthMin in V3WidthCommit, we need to correct the table. clearCache(); for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) { if (AstBasicDType* bdtypep = nodep->castBasicDType()) { (void)findInsertSameDType(bdtypep); } } } AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd) { if (m_basicps[kwd]) return m_basicps[kwd]; // AstBasicDType* new1p = new AstBasicDType(fl, kwd); // Because the detailed map doesn't update this map, // check the detailed map for this same node // Also adds this new node to the detailed map AstBasicDType* newp = findInsertSameDType(new1p); if (newp != new1p) new1p->deleteTree(); else addTypesp(newp); // m_basicps[kwd] = newp; return newp; } AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, int widthMin, AstNumeric numeric) { int idx = IDX0_LOGIC; if (kwd == AstBasicDTypeKwd::LOGIC) idx = IDX0_LOGIC; else if (kwd == AstBasicDTypeKwd::BIT) idx = IDX0_BIT; else fl->v3fatalSrc("Bad kwd for findLogicBitDType"); pair widths = make_pair(width,widthMin); LogicMap& mapr = m_logicMap[idx][(int)numeric]; LogicMap::const_iterator it = mapr.find(widths); if (it != mapr.end()) return it->second; // AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin); // Because the detailed map doesn't update this map, // check the detailed map for this same node, and if found update this map // Also adds this new node to the detailed map AstBasicDType* newp = findInsertSameDType(new1p); if (newp != new1p) new1p->deleteTree(); else addTypesp(newp); // mapr.insert(make_pair(widths,newp)); return newp; } AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, VNumRange range, int widthMin, AstNumeric numeric) { AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin); AstBasicDType* newp = findInsertSameDType(new1p); if (newp != new1p) new1p->deleteTree(); else addTypesp(newp); return newp; } AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) { VBasicTypeKey key (nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(), nodep->nrange()); DetailedMap& mapr = m_detailedMap; DetailedMap::const_iterator it = mapr.find(key); if (it != mapr.end()) return it->second; mapr.insert(make_pair(key,nodep)); nodep->generic(true); // No addTypesp; the upper function that called new() is responsible for adding return nodep; } //====================================================================== // Special walking tree inserters void AstNode::addBeforeStmt(AstNode* newp, AstNode*) { if (!backp()) newp->v3fatalSrc("Can't find current statement to addBeforeStmt"); // Look up; virtual call will find where to put it this->backp()->addBeforeStmt(newp, this); } void AstNode::addNextStmt(AstNode* newp, AstNode*) { if (!backp()) newp->v3fatalSrc("Can't find current statement to addBeforeStmt"); // Look up; virtual call will find where to put it this->backp()->addNextStmt(newp, this); } void AstNodeStmt::addBeforeStmt(AstNode* newp, AstNode*) { // Insert newp before current node this->addHereThisAsNext(newp); } void AstNodeStmt::addNextStmt(AstNode* newp, AstNode*) { // Insert newp after current node this->addNextHere(newp); } void AstWhile::addBeforeStmt(AstNode* newp, AstNode* belowp) { // Special, as statements need to be put in different places // Belowp is how we came to recurse up to this point // Preconditions insert first just before themselves (the normal rule for other statement types) if (belowp == precondsp()) { // Must have been first statement in precondsp list, so newp is new first statement belowp->addHereThisAsNext(newp); } else if (belowp == condp()) { // Goes before condition, IE in preconditions addPrecondsp(newp); } else if (belowp == bodysp()) { // Was first statement in body, so new front belowp->addHereThisAsNext(newp); } else { belowp->v3fatalSrc("Doesn't look like this was really under the while"); } } void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) { // Special, as statements need to be put in different places // Belowp is how we came to recurse up to this point // Preconditions insert first just before themselves (the normal rule for other statement types) if (belowp == precondsp()) { // Next in precond list belowp->addNextHere(newp); } else if (belowp == condp()) { // Becomes first statement in body, body may have been empty if (bodysp()) { bodysp()->addHereThisAsNext(newp); } else { addBodysp(newp); } } else if (belowp == bodysp()) { // Next statement in body belowp->addNextHere(newp); } else { belowp->v3fatalSrc("Doesn't look like this was really under the while"); } } //====================================================================== // Per-type Debugging void AstNode::dump(ostream& str) { str<m_backp <<" =editCountLast())?"#>":">") <<" {"<filenameLetters()<lineno()<<"}"; if (user1p()) str<<" u1="<<(void*)user1p(); if (user2p()) str<<" u2="<<(void*)user2p(); if (user3p()) str<<" u3="<<(void*)user3p(); if (user4p()) str<<" u4="<<(void*)user4p(); if (user5p()) str<<" u5="<<(void*)user5p(); if (hasDType()) { if (dtypep()==this) str<<" @dt="<<"this@"; else str<<" @dt="<<(void*)dtypep()<<"@"; // Final @ so less likely to by accident think it's nodep if (AstNodeDType* dtp = dtypep()) { dtp->dumpSmall(str); } } else { // V3Broken will throw an error if (dtypep()) str<<" %Error-dtype-exp=null,got="<<(void*)dtypep(); } if (name()!="") { if (castConst()) str<<" "<AstNode::dump(str); if (keyword() != VAlwaysKwd::ALWAYS) str<<" ["<AstNode::dump(str); str<<" [start:"<AstNode::dump(str); str<<" ["<AstNodeDType::dump(str); str<<" kwd="<AstNode::dump(str); str<<" sz"<AstNode::dump(str); if (modp()) { str<<" -> "; modp()->dump(str); } else { str<<" ->UNLINKED:"<AstNode::dump(str); str<<" -> "<AstNode::dump(str); //str<<" "<AstNode::dump(str); str<<" -> "; if (itemp()) { itemp()->dump(str); } else { str<<"UNLINKED"; } } void AstIfaceRefDType::dump(ostream& str) { this->AstNode::dump(str); if (cellName()!="") { str<<" cell="< "; cellp()->dump(str); } else if (ifacep()) { str<<" -> "; ifacep()->dump(str); } else { str<<" -> UNLINKED"; } } void AstIfaceRefDType::dumpSmall(ostream& str) { this->AstNodeDType::dumpSmall(str); str<<"iface"; } void AstJumpGo::dump(ostream& str) { this->AstNode::dump(str); str<<" -> "; if (labelp()) { labelp()->dump(str); } else { str<<"%Error:UNLINKED"; } } void AstModportFTaskRef::dump(ostream& str) { this->AstNode::dump(str); if (isExport()) str<<" EXPORT"; if (isImport()) str<<" IMPORT"; if (ftaskp()) { str<<" -> "; ftaskp()->dump(str); } else { str<<" -> UNLINKED"; } } void AstModportVarRef::dump(ostream& str) { this->AstNode::dump(str); str<<" "< "; varp()->dump(str); } else { str<<" -> UNLINKED"; } } void AstPin::dump(ostream& str) { this->AstNode::dump(str); if (modVarp()) { str<<" -> "; modVarp()->dump(str); } else { str<<" ->UNLINKED"; } if (svImplicit()) str<<" [.SV]"; } void AstTypedef::dump(ostream& str) { this->AstNode::dump(str); if (attrPublic()) str<<" [PUBLIC]"; } void AstRange::dump(ostream& str) { this->AstNode::dump(str); if (littleEndian()) str<<" [LITTLE]"; } void AstRefDType::dump(ostream& str) { this->AstNodeDType::dump(str); if (defp()) { str<<" -> "; defp()->dump(str); } else { str<<" -> UNLINKED"; } } void AstNodeClassDType::dump(ostream& str) { this->AstNode::dump(str); if (packed()) str<<" [PACKED]"; } void AstNodeDType::dump(ostream& str) { this->AstNode::dump(str); if (generic()) str<<" [GENERIC]"; if (AstNodeDType* dtp = virtRefDTypep()) { str<<" refdt="<<(void*)(dtp); dtp->dumpSmall(str); } } void AstNodeDType::dumpSmall(ostream& str) { str<<"(" <<(generic()?"G/":"") <<((isSigned()&&!isDouble())?"s":"") <<(isNosign()?"n":"") <<(isDouble()?"d":"") <<(isString()?"str":""); if (!isDouble() && !isString()) { str<<"w"<<(widthSized()?"":"u")<AstNodeDType::dumpSmall(str); if (castPackArrayDType()) str<<"p"; else str<<"u"; str<AstNodeDType::dump(str); str<<" "<AstNode::dump(str); str<<" L"<AstNode::dump(str); str<<" -> "<AstNode::dump(str); if (declRange().ranged()) { str<<" decl"<AstNode::dump(str); for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) { if (AstBasicDType* subnodep=m_basicps[i]) { str< "; subnodep->dump(str); } } for (int isbit=0; isbit<2; ++isbit) { for (int issigned=0; issignedsecond; str<first.first<<"/"<first.second; str<<"\t\t"< "; dtypep->dump(str); } } } { DetailedMap& mapr = m_detailedMap; for (DetailedMap::const_iterator it = mapr.begin(); it != mapr.end(); ++it) { AstBasicDType* dtypep = it->second; str< "; dtypep->dump(str); } } // Note get newline from caller too. } void AstVarScope::dump(ostream& str) { this->AstNode::dump(str); if (isCircular()) str<<" [CIRC]"; if (varp()) { str<<" -> "; varp()->dump(str); } else { str<<" ->UNLINKED"; } } void AstVarXRef::dump(ostream& str) { this->AstNode::dump(str); if (packagep()) { str<<" pkg="<<(void*)packagep(); } if (lvalue()) str<<" [LV] => "; else str<<" [RV] <- "; str<dump(str); } else if (varp()) { varp()->dump(str); } else { str<<"UNLINKED"; } } void AstVarRef::dump(ostream& str) { this->AstNode::dump(str); if (packagep()) { str<<" pkg="<<(void*)packagep(); } if (lvalue()) str<<" [LV] => "; else str<<" [RV] <- "; if (varScopep()) { varScopep()->dump(str); } else if (varp()) { varp()->dump(str); } else { str<<"UNLINKED"; } } void AstVar::dump(ostream& str) { this->AstNode::dump(str); if (isSc()) str<<" [SC]"; if (isPrimaryIO()) str<<(isInout()?" [PIO]":(isInput()?" [PI]":" [PO]")); else { if (isInout()) str<<" [IO]"; else if (isInput()) str<<" [I]"; else if (isOutput()) str<<" [O]"; } if (isConst()) str<<" [CONST]"; if (isPullup()) str<<" [PULLUP]"; if (isPulldown()) str<<" [PULLDOWN]"; if (isUsedClock()) str<<" [CLK]"; if (isSigPublic()) str<<" [P]"; if (isUsedLoopIdx()) str<<" [LOOP]"; if (attrClockEn()) str<<" [aCLKEN]"; if (attrIsolateAssign()) str<<" [aISO]"; if (attrFileDescr()) str<<" [aFD]"; if (isFuncReturn()) str<<" [FUNCRTN]"; else if (isFuncLocal()) str<<" [FUNC]"; str<<" "<AstNode::dump(str); if (isMulti()) str<<" [MULTI]"; } void AstSenItem::dump(ostream& str) { this->AstNode::dump(str); str<<" ["<AstNode::dump(str); str<<" ["<AstNode::dump(str); if (packagep()) { str<<" pkg="<<(void*)packagep(); } str<<" -> "; if (packagep()) { packagep()->dump(str); } else { str<<"UNLINKED"; } } void AstDot::dump(ostream& str) { this->AstNode::dump(str); } void AstActive::dump(ostream& str) { this->AstNode::dump(str); str<<" => "; if (sensesp()) { sensesp()->dump(str); } else { str<<"UNLINKED"; } } void AstNodeFTaskRef::dump(ostream& str) { this->AstNode::dump(str); if (packagep()) { str<<" pkg="<<(void*)packagep(); } str<<" -> "; if (dotted()!="") { str<dump(str); } else { str<<"UNLINKED"; } } void AstNodeFTask::dump(ostream& str) { this->AstNode::dump(str); if (taskPublic()) str<<" [PUBLIC]"; if (prototype()) str<<" [PROTOTYPE]"; if (dpiImport()) str<<" [DPII]"; if (dpiExport()) str<<" [DPIX]"; if ((dpiImport() || dpiExport()) && cname()!=name()) str<<" [c="<AstNode::dump(str); if (unnamed()) str<<" [UNNAMED]"; if (generate()) str<<" [GEN]"; if (genforp()) str<<" [GENFOR]"; } void AstCoverDecl::dump(ostream& str) { this->AstNode::dump(str); if (this->dataDeclNullp()) { str<<" -> "; this->dataDeclNullp()->dump(str); } else { if (binNum()) { str<<" bin"<AstNode::dump(str); str<<" -> "; if (declp()) { declp()->dump(str); } else { str<<"%Error:UNLINKED"; } } void AstTraceInc::dump(ostream& str) { this->AstNode::dump(str); str<<" -> "; if (declp()) { declp()->dump(str); } else { str<<"%Error:UNLINKED"; } } void AstNodeText::dump(ostream& str) { this->AstNode::dump(str); string out = text(); string::size_type pos; if ((pos = out.find("\n")) != string::npos) { out.erase(pos,out.length()-pos); out += "..."; } str<<" \""<AstNode::dump(str); if (source()) str<<" [SRC]"; if (slow()) str<<" [SLOW]"; } void AstCCall::dump(ostream& str) { this->AstNode::dump(str); if (funcp()) { str<<" "<name()<<" => "; funcp()->dump(str); } } void AstCFunc::dump(ostream& str) { this->AstNode::dump(str); if (slow()) str<<" [SLOW]"; if (pure()) str<<" [PURE]"; if (dpiImport()) str<<" [DPII]"; if (dpiExport()) str<<" [DPIX]"; if (dpiExportWrapper()) str<<" [DPIXWR]"; } verilator-3.874/src/V3Cdc.h0000664000177100017500000000225512525171733015377 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity block domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CDC_H_ #define _V3CDC_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Cdc { public: static void cdcAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3TraceDecl.h0000664000177100017500000000224712525171733016535 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves Tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3TRACEDECL_H_ #define _V3TRACEDECL_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3TraceDecl { public: static void traceDeclAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Unroll.h0000664000177100017500000000234612525171734016163 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Pre C-Emit stage changes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3UNROLL_H_ #define _V3UNROLL_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Unroll { public: static void unrollAll(AstNetlist* nodep); static void unrollGen(AstNodeFor* nodep, string beginName); }; #endif // Guard verilator-3.874/src/V3Split.cpp0000664000177100017500000005317612525171733016344 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into separate statements to reduce temps // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Split's Transformations: // // Note this can be called multiple times. // ALWAYS // ASSIGN ({var} <= {cons}) // Record as generating var_DLY (independent of use of var), consumers // ASSIGN ({var} = {cons} // Record generator and consumer // Any var that is only consumed can be ignored. // Then we split into a separate ALWAYS block for each top level statement. // // Furthermore, optionally // NODEASSIGN/NODEIF/WHILE // S1: ASSIGN {v1} <= 0. // Duplicate of below // S2: ASSIGN {v1} <= {v0} // S3: IF (..., // X1: ASSIGN {v2} <= {v1} // X2: ASSIGN {v3} <= {v2} // We'd like to swap S2 and S3, and X1 and X2. // // Create a graph in split assignment order. // v3 -breakable-> v3Dly --> X2 --> v2 -brk-> v2Dly -> X1 -> v1 // Likewise on each "upper" statement vertex // v3Dly & v2Dly -> S3 -> v1 & v2 // v1 -brk-> v1Dly -> S2 -> v0 // v1Dly -> S1 -> {empty} // Multiple assignments to the same variable must remain in order // // Also vars must not be "public" and we also scoreboard nodep->isPure() // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Split.h" #include "V3Stats.h" #include "V3Ast.h" #include "V3Graph.h" //###################################################################### // Support classes class SplitPliVertex : public V3GraphVertex { public: SplitPliVertex(V3Graph* graphp) : V3GraphVertex(graphp) {} virtual ~SplitPliVertex() {} virtual string name() const { return "*PLI*"; } virtual string dotColor() const { return "green"; } }; class SplitNodeVertex : public V3GraphVertex { AstNode* m_nodep; protected: SplitNodeVertex(V3Graph* graphp, AstNode* nodep) : V3GraphVertex(graphp), m_nodep(nodep) {} virtual ~SplitNodeVertex() {} // Accessors // Do not make accessor for nodep(), It may change due to // reordering a lower block, but we don't repair it virtual string name() const { if (m_nodep->name() == "") { return cvtToStr((void*)m_nodep); } else { return m_nodep->name(); } } }; class SplitLogicVertex : public SplitNodeVertex { uint32_t m_splitColor; // Copied from color() when determined public: SplitLogicVertex(V3Graph* graphp, AstNode* nodep) : SplitNodeVertex(graphp,nodep), m_splitColor(0) {} void splitColor(uint32_t flag) { m_splitColor=flag; } uint32_t splitColor() const { return m_splitColor; } virtual ~SplitLogicVertex() {} virtual string dotColor() const { return "yellow"; } }; class SplitVarStdVertex : public SplitNodeVertex { public: SplitVarStdVertex(V3Graph* graphp, AstNode* nodep) : SplitNodeVertex(graphp,nodep) {} virtual ~SplitVarStdVertex() {} virtual string dotColor() const { return "skyblue"; } }; class SplitVarPostVertex : public SplitNodeVertex { public: SplitVarPostVertex(V3Graph* graphp, AstNode* nodep) : SplitNodeVertex(graphp,nodep) {} virtual ~SplitVarPostVertex() {} virtual string name() const { return (string)"POST "+SplitNodeVertex::name(); } virtual string dotColor() const { return "CadetBlue"; } }; //###################################################################### // Edge types class SplitEdge : public V3GraphEdge { uint32_t m_ignoreInStep; // Step number that if set to, causes this edge to be ignored static uint32_t s_stepNum; // Global step number protected: enum { WEIGHT_NORMAL=10 }; SplitEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=CUTABLE) : V3GraphEdge(graphp, fromp, top, weight, cutable) ,m_ignoreInStep(0) {} virtual ~SplitEdge() {} public: // Iterator for graph functions static void incrementStep() { ++s_stepNum; } bool ignoreThisStep() const { return m_ignoreInStep == s_stepNum; } void setIgnoreThisStep() { m_ignoreInStep = s_stepNum; } virtual bool followScoreboard() const = 0; static bool followScoreboard(const V3GraphEdge* edgep) { const SplitEdge* oedgep = dynamic_cast(edgep); if (!oedgep) v3fatalSrc("Following edge of non-SplitEdge type"); if (oedgep->ignoreThisStep()) return false; return oedgep->followScoreboard(); } static bool followCyclic(const V3GraphEdge* edgep) { const SplitEdge* oedgep = dynamic_cast(edgep); if (!oedgep) v3fatalSrc("Following edge of non-SplitEdge type"); if (oedgep->ignoreThisStep()) return false; return true; } }; uint32_t SplitEdge::s_stepNum = 0; class SplitPostEdge : public SplitEdge { public: SplitPostEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL) {} virtual ~SplitPostEdge() {} virtual bool followScoreboard() const { return false; } virtual string dotColor() const { return "khaki"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; class SplitLVEdge : public SplitEdge { public: SplitLVEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL) {} virtual ~SplitLVEdge() {} virtual bool followScoreboard() const { return true; } virtual string dotColor() const { return "yellowGreen"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; class SplitRVEdge : public SplitEdge { public: SplitRVEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL) {} virtual ~SplitRVEdge() {} virtual bool followScoreboard() const { return true; } virtual string dotColor() const { return "green"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; struct SplitScorebdEdge : public SplitEdge { public: SplitScorebdEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL) {} virtual ~SplitScorebdEdge() {} virtual bool followScoreboard() const { return true; } virtual string dotColor() const { return "blue"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; struct SplitStrictEdge : public SplitEdge { // A strict order, based on the original statement order in the graph // The only non-cutable edge type public: SplitStrictEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : SplitEdge(graphp, fromp, top, WEIGHT_NORMAL, NOT_CUTABLE) {} virtual ~SplitStrictEdge() {} virtual bool followScoreboard() const { return true; } virtual string dotColor() const { return "blue"; } virtual string dotStyle() const { return ignoreThisStep()?"dotted":V3GraphEdge::dotStyle(); } }; //###################################################################### // Split class functions class SplitVisitor : public AstNVisitor { private: // NODE STATE // AstVarScope::user1p -> Var SplitNodeVertex* for usage var, 0=not set yet // AstVarScope::user2p -> Var SplitNodeVertex* for delayed assignment var, 0=not set yet // Ast*::user3p -> Statement SplitLogicVertex* (temporary only) // Ast*::user4 -> Current ordering number (reorderBlock usage) AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; AstUser4InUse m_inuser4; // TYPES typedef vector VStack; // STATE bool m_reorder; // Reorder statements vs. just splitting string m_noReorderWhy; // Reason we can't reorder VStack m_stmtStackps; // Current statements being tracked SplitPliVertex* m_pliVertexp; // Element specifying PLI ordering V3Graph m_graph; // Scoreboard of var usages/dependencies bool m_inDly; // Inside ASSIGNDLY V3Double0 m_statSplits; // Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void scoreboardClear() { //VV***** We reset user1p() and user2p on each block!!! m_inDly = false; m_graph.clear(); m_stmtStackps.clear(); m_pliVertexp = NULL; m_noReorderWhy = ""; AstNode::user1ClearTree(); AstNode::user2ClearTree(); AstNode::user3ClearTree(); AstNode::user4ClearTree(); } void scoreboardPli() { // Order all PLI statements with other PLI statements // This insures $display's and such remain in proper order // We don't prevent splitting out other non-pli statements, however. if (!m_pliVertexp) { m_pliVertexp = new SplitPliVertex(&m_graph); // m_graph.clear() will delete it } for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { // Both ways... new SplitScorebdEdge(&m_graph, *it, m_pliVertexp); new SplitScorebdEdge(&m_graph, m_pliVertexp, *it); } } void scoreboardPushStmt(AstNode* nodep) { //UINFO(9," push "<user3p()) nodep->v3fatalSrc("user3p should not be used; cleared in processBlock\n"); nodep->user3p(vertexp); } void scoreboardPopStmt() { //UINFO(9," pop"<nextp()) { scoreboardPushStmt(nextp); nextp->accept(*this); scoreboardPopStmt(); } } void cleanupBlockGraph(AstNode* nodep) { // Transform the graph into what we need UINFO(5, "ReorderBlock "<=9) { m_graph.dumpDotFilePrefixed("splitg_nodup", false); //m_graph.dump(); cout<nextp()) { SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p(); vvertexp->user(true); } // If a var vertex has only inputs, it's a input-only node, // and can be ignored for coloring **this block only** SplitEdge::incrementStep(); uint32_t numVertexes = 1; // As colors start at 1, not 0 for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { numVertexes++; if (!vertexp->outBeginp() && dynamic_cast(vertexp)) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { SplitEdge* oedgep = dynamic_cast(edgep); oedgep->setIgnoreThisStep(); } } // Mark all logic vertexes not involved with this step as unimportant if (SplitLogicVertex* vvertexp = dynamic_cast(vertexp)) { if (!vvertexp->user()) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { SplitEdge* oedgep = dynamic_cast(edgep); oedgep->setIgnoreThisStep(); } for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { SplitEdge* oedgep = dynamic_cast(edgep); oedgep->setIgnoreThisStep(); } } } } // Weak coloring to determine what needs to remain in order // This follows all step-relevant edges excluding PostEdges, which are done later m_graph.weaklyConnected(&SplitEdge::followScoreboard); // Add hard orderings between all nodes of same color, in the order they appeared vector lastOfColor; lastOfColor.resize(numVertexes); for (uint32_t i=0; inextp()) { SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p(); vvertexp->splitColor(vvertexp->color()); uint32_t color = vvertexp->splitColor(); if (color >= numVertexes) nextp->v3fatalSrc("More colors than vertexes!\n"); if (!color) nextp->v3fatalSrc("No node color assigned\n"); if (lastOfColor[color]) { new SplitStrictEdge(&m_graph, lastOfColor[color], vvertexp); } lastOfColor[color] = vvertexp; } // And a real ordering to get the statements into something reasonable // We don't care if there's cutable violations here... // Non-cutable violations should be impossible; as those edges are program-order if (debug()>=9) m_graph.dumpDotFilePrefixed((string)"splitg_preo", false); m_graph.acyclic(&SplitEdge::followCyclic); m_graph.rank(&SplitEdge::followCyclic); // Or order(), but that's more expensive if (debug()>=9) m_graph.dumpDotFilePrefixed((string)"splitg_opt", false); } void reorderBlock(AstNode* nodep) { // Reorder statements in the completed graph AstAlways* splitAlwaysp = nodep->backp()->castAlways(); // Map the rank numbers into nodes they associate with typedef multimap RankNodeMap; typedef map ColorRankMap; ColorRankMap colorRankMap; uint32_t firstColor = 0; bool multiColors = false; int currOrder = 0; // Existing sequence number of assignment for (AstNode* nextp=nodep; nextp; nextp=nextp->nextp()) { SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p(); if (!splitAlwaysp) vvertexp->splitColor(1); // All blocks remain as-is RankNodeMap& rankMap = colorRankMap[vvertexp->splitColor()]; rankMap.insert(make_pair(vvertexp->rank(), nextp)); if (firstColor && firstColor != vvertexp->splitColor()) multiColors = true; firstColor = vvertexp->splitColor(); nextp->user4(++currOrder); // Record current ordering } // If there was only one color, we don't need multiple always blocks if (!multiColors) splitAlwaysp = NULL; // Is the current ordering OK? bool leaveAlone=true; if (splitAlwaysp) leaveAlone=false; int newOrder = 0; // New sequence number of assignment for (ColorRankMap::iterator colorIt = colorRankMap.begin(); colorIt != colorRankMap.end(); ++colorIt) { RankNodeMap& rankMap = colorIt->second; for (RankNodeMap::iterator it = rankMap.begin(); it != rankMap.end(); ++it) { AstNode* nextp = it->second; if (++newOrder != nextp->user4()) leaveAlone=false; } } if (leaveAlone) { UINFO(6," No changes\n"); } else { AstNRelinker replaceHandle; // Where to add the list AstNode* addAfterp = splitAlwaysp; for (ColorRankMap::iterator colorIt = colorRankMap.begin(); colorIt != colorRankMap.end(); ++colorIt) { uint32_t color = colorIt->first; RankNodeMap& rankMap = colorIt->second; AstNode* newListp = NULL; for (RankNodeMap::iterator it = rankMap.begin(); it != rankMap.end(); ++it) { AstNode* nextp = it->second; UINFO(6, " Color="<unlinkFrBack(&replaceHandle); else nextp->unlinkFrBack(); newListp = newListp->addNext(nextp); } if (splitAlwaysp) { ++m_statSplits; AstAlways* alwaysp = new AstAlways(newListp->fileline(), VAlwaysKwd::ALWAYS, NULL, NULL); addAfterp->addNextHere(alwaysp); addAfterp=alwaysp; alwaysp->addStmtp(newListp); } else { // Just reordering replaceHandle.relink(newListp); } } if (splitAlwaysp) { pushDeletep(splitAlwaysp->unlinkFrBack()); } } // leaveAlone } void processBlock(AstNode* nodep) { if (!nodep) return; // Empty lists are ignorable // Pass the first node in a list of block items, we'll process them // Check there's >= 2 sub statements, else nothing to analyze // Save recursion state AstNode* firstp = nodep; // We may reorder, and nodep is no longer first. void* oldBlockUser3 = nodep->user3p(); // May be overloaded in below loop, save it nodep->user3p(NULL); if (!nodep->firstAbovep()) nodep->v3fatalSrc("Node passed is in next list; should have processed all list at once"); // Process it if (!nodep->nextp()) { // Just one, so can't reorder. Just look for more blocks/statements. nodep->accept(*this); } else { UINFO(9," processBlock "<backp()->nextp()==firstp) firstp = firstp->backp(); // Walk back to first in list for (AstNode* nextp=firstp; nextp; nextp=nextp->nextp()) { SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p(); vvertexp->unlinkDelete(&m_graph); } } } // Again, nodep may no longer be first. firstp->user3p(oldBlockUser3); } // VISITORS virtual void visit(AstAlways* nodep, AstNUser*) { UINFO(4," ALW "<=9) nodep->dumpTree(cout," alwIn:: "); scoreboardClear(); processBlock(nodep->bodysp()); if (debug()>=9) nodep->dumpTree(cout," alwOut: "); } virtual void visit(AstNodeIf* nodep, AstNUser*) { if (!m_reorder) { nodep->iterateChildren(*this); } else { UINFO(4," IF "<condp()->iterateAndNext(*this); processBlock(nodep->ifsp()); processBlock(nodep->elsesp()); } } // We don't do AstNodeFor/AstWhile loops, due to the standard question // of what is before vs. after virtual void visit(AstAssignDly* nodep, AstNUser*) { m_inDly = true; UINFO(4," ASSIGNDLY "<iterateChildren(*this); m_inDly = false; } virtual void visit(AstVarRef* nodep, AstNUser*) { if (!m_stmtStackps.empty()) { AstVarScope* vscp = nodep->varScopep(); if (!vscp) nodep->v3fatalSrc("Not linked"); if (!nodep->varp()->isConst()) { // Constant lookups can be ignored if (nodep->varp()->isSigPublic()) { // Public signals shouldn't be changed, pli code might be messing with them scoreboardPli(); } // Create vertexes for variable if (!vscp->user1p()) { SplitVarStdVertex* vstdp = new SplitVarStdVertex(&m_graph, vscp); vscp->user1p(vstdp); } SplitVarStdVertex* vstdp = (SplitVarStdVertex*) vscp->user1p(); // SPEEDUP: We add duplicate edges, that should be fixed if (m_inDly && nodep->lvalue()) { UINFO(4," VARREFDLY: "<user2p()) { SplitVarPostVertex* vpostp = new SplitVarPostVertex(&m_graph, vscp); vscp->user2p(vpostp); new SplitPostEdge(&m_graph, vstdp, vpostp); } SplitVarPostVertex* vpostp = (SplitVarPostVertex*)vscp->user2p(); // Add edges for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { new SplitLVEdge(&m_graph, vpostp, *it); } } else { // Nondelayed assignment if (nodep->lvalue()) { // Non-delay; need to maintain existing ordering with all consumers of the signal UINFO(4," VARREFLV: "<iterateChildren(*this); } //-------------------- // Default virtual void visit(AstNode* nodep, AstNUser*) { // **** SPECIAL default type that sets PLI_ORDERING if (!m_stmtStackps.empty() && !nodep->isPure()) { UINFO(9," NotSplittable "<iterateChildren(*this); } public: // CONSTUCTORS SplitVisitor(AstNetlist* nodep, bool reorder) : m_reorder(reorder) { scoreboardClear(); nodep->accept(*this); } virtual ~SplitVisitor() { V3Stats::addStat("Optimizations, Split always", m_statSplits); } }; //###################################################################### // Split class functions void V3Split::splitReorderAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Split::splitAlwaysAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.874/src/VlcOptions.h0000664000177100017500000000514412525171734016576 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Command line options // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCOPTIONS_H_ #define _VLCOPTIONS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "config_rev.h" //###################################################################### // V3Options - Command line options typedef vector VlStringList; typedef set VlStringSet; class VlcOptions { // MEMBERS (general options) string m_annotateOut; // main switch: --annotate I bool m_annotateAll; // main switch: --annotate-all int m_annotateMin; // main switch: --annotate-min I VlStringSet m_readFiles; // main switch: --read bool m_rank; // main switch: --rank bool m_unlink; // main switch: --unlink string m_writeFile; // main switch: --write private: // METHODS void showVersion(bool verbose); bool onoff(const char* sw, const char* arg, bool& flag); public: // CREATORS VlcOptions() { m_annotateAll = false; m_annotateMin = 10; m_rank = false; m_unlink = false; } ~VlcOptions() {} void setDebugMode(int level); // METHODS void parseOptsList(int argc, char** argv); void addReadFile(const string& filename); // ACCESSORS (options) const VlStringSet& readFiles() const { return m_readFiles; } string annotateOut() const { return m_annotateOut; } bool annotateAll() const { return m_annotateAll; } int annotateMin() const { return m_annotateMin; } bool rank() const { return m_rank; } bool unlink() const { return m_unlink; } string writeFile() const { return m_writeFile; } // METHODS (from main) static string version(); }; //###################################################################### #endif // guard verilator-3.874/src/V3FileLine.cpp0000664000177100017500000002200212525171733016720 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Error handling // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include #include #include "V3Error.h" #include "V3FileLine.h" #ifndef _V3ERROR_NO_GLOBAL_ # include "V3Ast.h" # include "V3Global.h" # include "V3Stats.h" # include "V3Config.h" #endif //###################################################################### // FileLineSingleton class functions const string FileLineSingleton::filenameLetters(int no) { const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number char out[size]; char* op = out+size-1; *--op = '\0'; // We build backwards int num = no; do { *--op = 'a'+num%26; num /= 26; } while (num); return op; } //! Convert filenames to a filenameno //! This lets us assign a nice small identifier for debug messages, but more //! importantly lets us use a 4 byte int instead of 8 byte pointer in every //! FileLine. //! We associate a language with each source file, so we also set the default //! for this. int FileLineSingleton::nameToNumber(const string& filename) { FileNameNumMap::const_iterator it = m_namemap.find(filename); if (VL_LIKELY(it != m_namemap.end())) return it->second; int num = m_names.size(); m_names.push_back(filename); m_languages.push_back(V3LangCode::mostRecent()); m_namemap.insert(make_pair(filename,num)); return num; } //! Support XML output //! Experimental. Updated to also put out the language. void FileLineSingleton::fileNameNumMapDumpXml(ostream& os) { os<<"\n"; for (FileNameNumMap::const_iterator it = m_namemap.begin(); it != m_namemap.end(); ++it) { os<<"second) <<"\" filename=\""<first <<"\" language=\""<second).ascii()<<"\"/>\n"; } os<<"\n"; } //###################################################################### // FileLine class functions FileLine::FileLine(FileLine::EmptySecret) { // Sort of a singleton m_lineno=0; m_filenameno=singleton().nameToNumber("AstRoot"); m_warnOn=0; for (int codei=V3ErrorCode::EC_MIN; codeilineno(atoi(ln)); } while (*textp && (isspace(*textp) || *textp=='"')) textp++; // Grab filename const char *fn = textp; while (*textp && !(isspace(*textp) || *textp=='"')) textp++; if (textp != fn) { string strfn = fn; strfn = strfn.substr(0, textp-fn); this->filename(strfn); } // Grab level while (*textp && (isspace(*textp) || *textp=='"')) textp++; if (isdigit(*textp)) enterExitRef = atoi(textp); else enterExitRef = 0; //printf ("PPLINE %d '%s'\n", s_lineno, s_filename.c_str()); } FileLine* FileLine::copyOrSameFileLine() { // When a fileline is "used" to produce a node, calls this function. // Return this, or a copy of this // There are often more than one token per line, thus we use the // same pointer as long as we're on the same line, file & warn state. #ifndef _V3ERROR_NO_GLOBAL_ V3Config::applyIgnores(this); // Toggle warnings based on global config file #endif static FileLine* lastNewp = NULL; if (lastNewp && *lastNewp == *this) { // Compares lineno, filename, etc return lastNewp; } FileLine* newp = new FileLine(this); lastNewp = newp; return newp; } const string FileLine::filebasename() const { string name = filename(); string::size_type pos; if ((pos = name.rfind("/")) != string::npos) { name.erase(0,pos+1); } return name; } const string FileLine::filebasenameNoExt() const { string name = filebasename(); string::size_type pos; if ((pos = name.find(".")) != string::npos) { name = name.substr(0,pos); } return name; } const string FileLine::profileFuncname() const { // Return string that is OK as a function name - for profiling string name = filebasenameNoExt(); string::size_type pos; while ((pos = name.find_first_not_of("abcdefghijlkmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789_")) != string::npos) { name.replace(pos, 1, "_"); } name += "__l"+cvtToStr(lineno()); return name; } string FileLine::ascii() const { return filename()+":"+cvtToStr(lineno()); } ostream& operator<<(ostream& os, FileLine* fileline) { os <ascii()<<": "<warnIsOff(code)) { this->warnOff(code, true); } } } void FileLine::v3errorEnd(ostringstream& str) { if (this && m_lineno) { ostringstream nsstr; nsstr< FileLineCheckSet; FileLineCheckSet fileLineLeakChecks; void* FileLine::operator new(size_t size) { FileLine* objp = static_cast(::operator new(size)); fileLineLeakChecks.insert(objp); return objp; } void FileLine::operator delete(void* objp, size_t size) { if (!objp) return; FileLine* flp = static_cast(objp); FileLineCheckSet::iterator it = fileLineLeakChecks.find(flp); if (it != fileLineLeakChecks.end()) { fileLineLeakChecks.erase(it); } else { flp->v3fatalSrc("Deleting FileLine object that was never tracked\n"); } ::operator delete(objp); } #endif void FileLine::deleteAllRemaining() { #ifdef VL_LEAK_CHECKS // FileLines are allocated, but never nicely freed, as it's much faster // that way. Unfortunately this makes our leak checking a big mess, so // only when leak checking we'll track them all and cleanup. while (1) { FileLineCheckSet::iterator it=fileLineLeakChecks.begin(); if (it==fileLineLeakChecks.end()) break; delete *it; // Operator delete will remove the iterated object from the list. // Eventually the list will be empty and terminate the loop. } fileLineLeakChecks.clear(); singleton().clear(); #endif } verilator-3.874/src/V3EmitC.h0000664000177100017500000000235612525171733015711 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit C++ code for module tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EMITC_H_ #define _V3EMITC_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3EmitC { public: static void emitc(); static void emitcInlines(); static void emitcSyms(); static void emitcTrace(); }; #endif // Guard verilator-3.874/src/V3Inst.h0000664000177100017500000000255512525171733015626 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity inst domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3INST_H_ #define _V3INST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Inst { public: static void instAll(AstNetlist* nodep); static void dearrayAll(AstNetlist* nodep); static AstAssignW* pinReconnectSimple(AstPin* nodep, AstCell* cellp, AstNodeModule* modp, bool forTristate, bool alwaysCvt=false); }; #endif // Guard verilator-3.874/src/V3SplitAs.h0000664000177100017500000000230712525171733016263 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into separate statements to reduce temps // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3SPLITAS_H_ #define _V3SPLITAS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3SplitAs { public: static void splitAsAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3GenClk.cpp0000664000177100017500000001642612525171733016411 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Generated Clock repairs // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // GENCLK TRANSFORMATIONS: // Follow control-flow graph with assignments and var usages // ASSIGNDLY to variable later used as clock requires change detect // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3GenClk.h" #include "V3Ast.h" //###################################################################### // GenClk state, as a visitor of each AstNode class GenClkBaseVisitor : public AstNVisitor { protected: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### // GenClk Read class GenClkRenameVisitor : public GenClkBaseVisitor { private: // NODE STATE // Cleared on top scope // AstVarScope::user2() -> AstVarScope*. Signal replacing activation with // AstVarRef::user3() -> bool. Signal is replaced activation (already done) AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; // STATE AstActive* m_activep; // Inside activate statement AstNodeModule* m_topModp; // Top module AstScope* m_scopetopp; // Scope under TOPSCOPE // METHODS AstVarScope* genInpClk(AstVarScope* vscp) { if (vscp->user2p()) { return vscp->user2p()->castNode()->castVarScope(); } else { AstVar* varp = vscp->varp(); string newvarname = "__VinpClk__"+vscp->scopep()->nameDotless()+"__"+varp->name(); // Create: VARREF(inpclk) // ... // ASSIGN(VARREF(inpclk), VARREF(var)) AstVar* newvarp = new AstVar (varp->fileline(), AstVarType::MODULETEMP, newvarname, varp); m_topModp->addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp); m_scopetopp->addVarp(newvscp); AstAssign* asninitp = new AstAssign (vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, true), new AstVarRef(vscp->fileline(), vscp, false)); m_scopetopp->addFinalClkp(asninitp); // vscp->user2p(newvscp); return newvscp; } } // VISITORS virtual void visit(AstTopScope* nodep, AstNUser*) { AstNode::user2ClearTree(); // user2p() used on entire tree AstScope* scopep = nodep->scopep(); if (!scopep) nodep->v3fatalSrc("No scope found on top level"); m_scopetopp = scopep; nodep->iterateChildren(*this); } //---- virtual void visit(AstVarRef* nodep, AstNUser*) { // Consumption/generation of a variable, AstVarScope* vscp = nodep->varScopep(); if (!vscp) nodep->v3fatalSrc("Scope not assigned"); if (m_activep && !nodep->user3()) { nodep->user3(true); if (vscp->isCircular()) { UINFO(8," VarActReplace "<fileline(), newvscp, nodep->lvalue()); nodep->replaceWith(newrefp); pushDeletep(nodep); nodep=NULL; } } } virtual void visit(AstActive* nodep, AstNUser*) { m_activep = nodep; nodep->sensesp()->iterateChildren(*this); // iterateAndNext? m_activep = NULL; nodep->iterateChildren(*this); } virtual void visit(AstCFunc* nodep, AstNUser*) { nodep->iterateChildren(*this); } //----- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS GenClkRenameVisitor(AstTopScope* nodep, AstNodeModule* topModp) { m_topModp = topModp; m_scopetopp = NULL; m_activep = NULL; nodep->accept(*this); } virtual ~GenClkRenameVisitor() {} }; //###################################################################### // GenClk Read class GenClkReadVisitor : public GenClkBaseVisitor { private: // NODE STATE // Cleared on top scope // AstVarScope::user() -> bool. Set when the var has been used as clock AstUser1InUse m_inuser1; // STATE AstActive* m_activep; // Inside activate statement AstNodeAssign* m_assignp; // Inside assigndly statement AstNodeModule* m_topModp; // Top module // VISITORS virtual void visit(AstTopScope* nodep, AstNUser*) { AstNode::user1ClearTree(); // user1p() used on entire tree nodep->iterateChildren(*this); { // Make the new clock signals and replace any activate references // See rename, it does some AstNode::userClearTree()'s GenClkRenameVisitor visitor (nodep, m_topModp); } } virtual void visit(AstNodeModule* nodep, AstNUser*) { // Only track the top scopes, not lower level functions if (nodep->isTop()) { m_topModp = nodep; nodep->iterateChildren(*this); } } virtual void visit(AstCCall* nodep, AstNUser*) { nodep->iterateChildren(*this); // Enter the function and trace it nodep->funcp()->accept(*this); } //---- virtual void visit(AstVarRef* nodep, AstNUser*) { // Consumption/generation of a variable, AstVarScope* vscp = nodep->varScopep(); if (!vscp) nodep->v3fatalSrc("Scope not assigned"); if (m_activep) { UINFO(8," VarAct "<user1(true); } if (m_assignp && nodep->lvalue() && vscp->user1()) { // Variable was previously used as a clock, and is now being set // Thus a unordered generated clock... UINFO(8," VarSetAct "<circular(true); } } virtual void visit(AstNodeAssign* nodep, AstNUser*) { //UINFO(8,"ASS "<iterateChildren(*this); m_assignp = NULL; } virtual void visit(AstActive* nodep, AstNUser*) { UINFO(8,"ACTIVE "<sensesp()->iterateChildren(*this); // iterateAndNext? m_activep = NULL; nodep->iterateChildren(*this); } //----- virtual void visit(AstVar*, AstNUser*) {} // Don't want varrefs under it virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS GenClkReadVisitor(AstNetlist* nodep) { m_activep = NULL; m_assignp = NULL; m_topModp = NULL; nodep->accept(*this); } virtual ~GenClkReadVisitor() {} }; //###################################################################### // GenClk class functions void V3GenClk::genClkAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3ActiveTop.cpp0000664000177100017500000001362712525171733017144 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity active domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Active's Transformations: // // Note this can be called multiple times. // Across all ACTIVES // SenTrees are now under each ACTIVE statement, we want them global: // Find SenTree in under global TopScope, or create it there // Move SenTree the global SenTree // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3ActiveTop.h" #include "V3Ast.h" #include "V3SenTree.h" #include "V3Const.h" //###################################################################### // Active class functions class ActiveTopVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist // AstNode::user() bool. True if processed // Each call to V3Const::constify // AstNode::user4() Used by V3Const::constify, called below AstUser1InUse m_inuser1; // STATE AstTopScope* m_topscopep; // Top scope for adding sentrees under SenTreeFinder m_finder; // Find global sentree's and add them // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstTopScope* nodep, AstNUser*) { m_topscopep = nodep; m_finder.main(m_topscopep); nodep->iterateChildren(*this); m_topscopep = NULL; } virtual void visit(AstNodeModule* nodep, AstNUser*) { // Create required actives and add to module // We can start ordering at a module, or a scope UINFO(4," MOD "<iterateChildren(*this); } virtual void visit(AstActive* nodep, AstNUser*) { UINFO(4," ACTIVE "<sensesp(); if (!sensesp) nodep->v3fatalSrc("NULL"); if (sensesp->sensesp() && sensesp->sensesp()->castSenItem() && sensesp->sensesp()->castSenItem()->isNever()) { // Never executing. Kill it. if (sensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated."); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; return; } // Copy combo tree to settlement tree with duplicated statements if (sensesp->hasCombo()) { AstSenTree* newsentreep = new AstSenTree (nodep->fileline(), new AstSenItem (nodep->fileline(), AstSenItem::Settle())); AstActive* newp = new AstActive(nodep->fileline(),"settle", newsentreep); newp->sensesStorep(newsentreep); if (nodep->stmtsp()) newp->addStmtsp(nodep->stmtsp()->cloneTree(true)); nodep->addNextHere(newp); } // Move the SENTREE for each active up to the global level. // This way we'll easily see what clock domains are identical AstSenTree* wantp = m_finder.getSenTree(nodep->fileline(), sensesp); UINFO(4," lookdone\n"); if (wantp != sensesp) { // Move the active's contents to the other active UINFO(4," merge active "<sensesStorep()) { if (sensesp != nodep->sensesStorep()) nodep->v3fatalSrc("sensesStore should have been deleted earlier if different\n"); sensesp->unlinkFrBack(); // There may be other references to same sense tree, // we'll be removing all references when we get to them, // but don't dangle our pointer yet! pushDeletep(sensesp); } nodep->sensesp(wantp); } // No need to do statements under it, they're already moved. //nodep->iterateChildren(*this); } virtual void visit(AstInitial* nodep, AstNUser*) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstAssignAlias* nodep, AstNUser*) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstAssignW* nodep, AstNUser*) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstAlways* nodep, AstNUser*) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstFinal* nodep, AstNUser*) { nodep->v3fatalSrc("Node should have been deleted"); } // Empty visitors, speed things up virtual void visit(AstNodeMath* nodep, AstNUser*) {} virtual void visit(AstVarScope* nodep, AstNUser*) {} //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ActiveTopVisitor(AstNetlist* nodep) { m_topscopep = NULL; nodep->accept(*this); } virtual ~ActiveTopVisitor() {} }; //###################################################################### // Active class functions void V3ActiveTop::activeTopAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3TraceDecl.cpp0000664000177100017500000002714312525171733017072 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Waves tracing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3TraceDecl's Transformations: // Create trace CFUNCs // For each VARSCOPE // If appropriate type of signal, create a TRACE // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3TraceDecl.h" #include "V3EmitCBase.h" #include "V3Stats.h" //###################################################################### // TraceDecl state, as a visitor of each AstNode class TraceDeclVisitor : public EmitCBaseVisitor { private: // NODE STATE // STATE AstScope* m_scopetopp; // Current top scope AstCFunc* m_initFuncp; // Trace function being built AstCFunc* m_initSubFuncp; // Trace function being built (under m_init) int m_initSubStmts; // Number of statements in function AstCFunc* m_fullFuncp; // Trace function being built AstCFunc* m_chgFuncp; // Trace function being built int m_funcNum; // Function number being built AstVarScope* m_traVscp; // Signal being trace constructed AstNode* m_traValuep; // Signal being traced's value to trace in it string m_traShowname; // Signal being traced's component name V3Double0 m_statSigs; // Statistic tracking V3Double0 m_statIgnSigs; // Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } const char* vscIgnoreTrace(AstVarScope* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3Coverage::varIgnoreToggle AstVar* varp = nodep->varp(); string prettyName = varp->prettyName(); if (!varp->isTrace()) { return "Verilator trace_off"; } else if (!nodep->isTrace()) { return "Verilator cell trace_off"; } else if (!v3Global.opt.traceUnderscore()) { if (prettyName.size()>=1 && prettyName[0] == '_') return "Leading underscore"; if (prettyName.find("._") != string::npos) return "Inlined leading underscore"; } return NULL; } AstCFunc* newCFunc(AstCFuncType type, const string& name, bool slow) { AstCFunc* funcp = new AstCFunc(m_scopetopp->fileline(), name, m_scopetopp); funcp->slow(slow); funcp->argTypes(EmitCBaseVisitor::symClassVar()+", "+v3Global.opt.traceClassBase()+"* vcdp, uint32_t code"); funcp->funcType(type); funcp->symProlog(true); m_scopetopp->addActivep(funcp); UINFO(5," Newfunc "<name()+"__"+cvtToStr(++m_funcNum); AstCFunc* funcp = NULL; if (basep->funcType()==AstCFuncType::TRACE_INIT) { funcp = newCFunc(AstCFuncType::TRACE_INIT_SUB, name, basep->slow()); } else { basep->v3fatalSrc("Strange base function type"); } // cppcheck-suppress nullPointer // above fatal prevents it AstCCall* callp = new AstCCall(funcp->fileline(), funcp); callp->argTypes("vlSymsp, vcdp, code"); basep->addStmtsp(callp); return funcp; } void addCFuncStmt(AstCFunc* basep, AstNode* nodep, VNumRange arrayRange) { basep->addStmtsp(nodep); } void addTraceDecl(const VNumRange& arrayRange, int widthOverride) { // If !=0, is packed struct/array where basicp size misreflects one element VNumRange bitRange; AstBasicDType* bdtypep = m_traValuep->dtypep()->basicp(); if (widthOverride) bitRange = VNumRange(widthOverride-1,0,false); else if (bdtypep) bitRange = bdtypep->nrange(); AstTraceDecl* declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname, m_traValuep, bitRange, arrayRange); UINFO(9,"Decl "< v3Global.opt.outputSplitCTrace()) { m_initSubFuncp = newCFuncSub(m_initFuncp); m_initSubStmts = 0; } m_initSubFuncp->addStmtsp(declp); m_initSubStmts += EmitCBaseCounterVisitor(declp).count(); m_chgFuncp->addStmtsp(new AstTraceInc(m_traVscp->fileline(), declp, m_traValuep->cloneTree(true))); // The full version will get constructed in V3Trace } void addIgnore(const char* why) { ++m_statIgnSigs; m_initSubFuncp->addStmtsp( new AstComment(m_traVscp->fileline(), "Tracing: "+m_traShowname+" // Ignored: "+why)); } // VISITORS virtual void visit(AstTopScope* nodep, AstNUser*) { m_scopetopp = nodep->scopep(); // Make containers for TRACEDECLs first m_initFuncp = newCFunc(AstCFuncType::TRACE_INIT, "traceInitThis", true); m_fullFuncp = newCFunc(AstCFuncType::TRACE_FULL, "traceFullThis", true); m_chgFuncp = newCFunc(AstCFuncType::TRACE_CHANGE, "traceChgThis", false); // m_initSubFuncp = newCFuncSub(m_initFuncp); // And find variables nodep->iterateChildren(*this); } virtual void visit(AstVarScope* nodep, AstNUser*) { nodep->iterateChildren(*this); // Avoid updating this if (), instead see varp->isTrace() if (!nodep->varp()->isTemp() && !nodep->varp()->isFuncLocal()) { UINFO(5, " vsc "<varp(); AstScope* scopep = nodep->scopep(); // Compute show name // This code assumes SPTRACEVCDC_VERSION >= 1330; // it uses spaces to separate hierarchy components. m_traShowname = AstNode::vcdName(scopep->name() + " " + varp->name()); if (m_traShowname.substr(0,4) == "TOP ") m_traShowname.replace(0,4,""); if (!m_initSubFuncp) nodep->v3fatalSrc("NULL"); m_traVscp = nodep; m_traValuep = NULL; if (vscIgnoreTrace(nodep)) { addIgnore(vscIgnoreTrace(nodep)); } else { ++m_statSigs; if (nodep->valuep()) m_traValuep = nodep->valuep()->cloneTree(true); else m_traValuep = new AstVarRef(nodep->fileline(), nodep, false); { // Recurse into data type of the signal; the visitors will call addTraceDecl() varp->dtypeSkipRefp()->accept(*this); } // Cleanup if (m_traValuep) { m_traValuep->deleteTree(); m_traValuep=NULL; } } m_traVscp = NULL; m_traValuep = NULL; m_traShowname = ""; } } // VISITORS - Data types when tracing virtual void visit(AstConstDType* nodep, AstNUser*) { if (m_traVscp) { nodep->subDTypep()->skipRefp()->accept(*this); } } virtual void visit(AstRefDType* nodep, AstNUser*) { if (m_traVscp) { nodep->subDTypep()->skipRefp()->accept(*this); } } virtual void visit(AstUnpackArrayDType* nodep, AstNUser*) { // Note more specific dtypes above if (m_traVscp) { if ((int)nodep->arrayUnpackedElements() > v3Global.opt.traceMaxArray()) { addIgnore("Wide memory > --trace-max-array ents"); } else if (nodep->subDTypep()->skipRefp()->castBasicDType() // Nothing lower than this array && m_traVscp->dtypep()->skipRefp() == nodep) { // Nothing above this array // Simple 1-D array, use exising V3EmitC runtime loop rather than unrolling // This will put "(index)" at end of signal name for us addTraceDecl(nodep->declRange(), 0); } else { // Unroll now, as have no other method to get right signal names AstNodeDType* subtypep = nodep->subDTypep()->skipRefp(); for (int i=nodep->lsb(); i<=nodep->msb(); ++i) { string oldShowname = m_traShowname; AstNode* oldValuep = m_traValuep; { m_traShowname += string("(")+cvtToStr(i)+string(")"); m_traValuep = new AstArraySel(nodep->fileline(), m_traValuep->cloneTree(true), i - nodep->lsb()); subtypep->accept(*this); m_traValuep->deleteTree(); m_traValuep = NULL; } m_traShowname = oldShowname; m_traValuep = oldValuep; } } } } virtual void visit(AstPackArrayDType* nodep, AstNUser*) { if (m_traVscp) { if (!v3Global.opt.traceStructs()) { // Everything downstream is packed, so deal with as one trace unit // This may not be the nicest for user presentation, but is a much faster way to trace addTraceDecl(VNumRange(), nodep->width()); } else { AstNodeDType* subtypep = nodep->subDTypep()->skipRefp(); for (int i=nodep->lsb(); i<=nodep->msb(); ++i) { string oldShowname = m_traShowname; AstNode* oldValuep = m_traValuep; { m_traShowname += string("(")+cvtToStr(i)+string(")"); m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), (i - nodep->lsb())*subtypep->width(), subtypep->width()); subtypep->accept(*this); m_traValuep->deleteTree(); m_traValuep = NULL; } m_traShowname = oldShowname; m_traValuep = oldValuep; } } } } virtual void visit(AstNodeClassDType* nodep, AstNUser*) { if (m_traVscp) { if (nodep->packed() && !v3Global.opt.traceStructs()) { // Everything downstream is packed, so deal with as one trace unit // This may not be the nicest for user presentation, but is a much faster way to trace addTraceDecl(VNumRange(), nodep->width()); } else { if (!nodep->packed()) { addIgnore("Unsupported: Unpacked struct/union"); } else { for (AstMemberDType* itemp = nodep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) { AstNodeDType* subtypep = itemp->subDTypep()->skipRefp(); string oldShowname = m_traShowname; AstNode* oldValuep = m_traValuep; { m_traShowname += string(" ")+itemp->prettyName(); if (nodep->castStructDType()) { m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), itemp->lsb(), subtypep->width()); subtypep->accept(*this); m_traValuep->deleteTree(); m_traValuep = NULL; } else { // Else union, replicate fields subtypep->accept(*this); } } m_traShowname = oldShowname; m_traValuep = oldValuep; } } } } } virtual void visit(AstBasicDType* nodep, AstNUser*) { if (m_traVscp) { if (nodep->keyword()==AstBasicDTypeKwd::STRING) { addIgnore("Unsupported: strings"); } else { addTraceDecl(VNumRange(), 0); } } } virtual void visit(AstNodeDType* nodep, AstNUser*) { // Note more specific dtypes above if (!m_traVscp) return; addIgnore("Unsupported: data type"); } //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS TraceDeclVisitor(AstNetlist* nodep) { m_scopetopp = NULL; m_initFuncp = NULL; m_initSubFuncp = NULL; m_initSubStmts = 0; m_fullFuncp = NULL; m_chgFuncp = NULL; m_funcNum = 0; m_traVscp = NULL; m_traValuep = NULL; nodep->accept(*this); } virtual ~TraceDeclVisitor() { V3Stats::addStat("Tracing, Traced signals", m_statSigs); V3Stats::addStat("Tracing, Ignored signals", m_statIgnSigs); } }; //###################################################################### // Trace class functions void V3TraceDecl::traceDeclAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Inline.h0000664000177100017500000000224112525171733016117 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Inlining of modules // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3INLINE_H_ #define _V3INLINE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Inline { public: static void inlineAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Begin.cpp0000664000177100017500000002165312525171733016270 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Removal of named begin blocks // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Begin's Transformations: // // Each module: // Look for BEGINs // BEGIN(VAR...) -> VAR ... {renamed} // FOR -> WHILEs // // There are two scopes; named BEGINs change %m and variable scopes. // Unnamed BEGINs change only variable, not $display("%m") scope. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Begin.h" #include "V3Inst.h" #include "V3Ast.h" //###################################################################### class BeginState { private: // NODE STATE //Entire netlist: // AstNodeFTask::user1 -> bool, 1=processed AstUser1InUse m_inuser1; bool m_anyFuncInBegin; public: BeginState() { m_anyFuncInBegin = false; } ~BeginState() {} void userMarkChanged(AstNodeFTask* nodep) { nodep->user1(true); m_anyFuncInBegin = true; } bool anyFuncInBegin() const { return m_anyFuncInBegin; } }; //###################################################################### class BeginVisitor : public AstNVisitor { private: // STATE BeginState* m_statep; // Current global state AstNodeModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Current function/task string m_namedScope; // Name of begin blocks above us string m_unnamedScope; // Name of begin blocks, including unnamed blocks int m_repeatNum; // Repeat counter int m_ifDepth; // Current if depth // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; m_repeatNum = 0; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstNodeFTask* nodep, AstNUser*) { UINFO(8," "<name(m_unnamedScope+"__DOT__"+nodep->name()); UINFO(8," rename to "<name()<userMarkChanged(nodep); } // BEGIN wrapping a function rename that function, but don't affect the inside function's variables // We then restart with empty naming; so that any begin's inside the function will rename inside the function // Process children string oldScope = m_namedScope; string oldUnnamed = m_unnamedScope; { m_namedScope = ""; m_unnamedScope = ""; m_ftaskp = nodep; nodep->iterateChildren(*this); m_ftaskp = NULL; } m_namedScope = oldScope; m_unnamedScope = oldUnnamed; } virtual void visit(AstBegin* nodep, AstNUser*) { // Begin blocks were only useful in variable creation, change names and delete UINFO(8," "<name() != "") { // Else unneeded unnamed block // Create data for dotted variable resolution string dottedname = nodep->name() + "__DOT__"; // So always found string::size_type pos; while ((pos=dottedname.find("__DOT__")) != string::npos) { string ident = dottedname.substr(0,pos); dottedname = dottedname.substr(pos+strlen("__DOT__")); if (!nodep->unnamed()) { if (m_namedScope=="") m_namedScope = ident; else m_namedScope = m_namedScope + "__DOT__"+ident; } if (m_unnamedScope=="") m_unnamedScope = ident; else m_unnamedScope = m_unnamedScope + "__DOT__"+ident; // Create CellInline for dotted var resolution if (!m_ftaskp) { AstCellInline* inlinep = new AstCellInline(nodep->fileline(), m_unnamedScope, "__BEGIN__"); m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells } } } // Remap var names and replace lower Begins nodep->stmtsp()->iterateAndNext(*this); if (nodep->genforp()) nodep->v3fatalSrc("GENFORs should have been expanded earlier"); } m_namedScope = oldScope; m_unnamedScope = oldUnnamed; // Cleanup AstNode* addsp = NULL; if (AstNode* stmtsp = nodep->stmtsp()) { stmtsp->unlinkFrBackWithNext(); if (addsp) { addsp = addsp->addNextNull(stmtsp); } else { addsp = stmtsp; } } if (addsp) { nodep->replaceWith(addsp); } else { nodep->unlinkFrBack(); } pushDeletep(nodep); nodep=NULL; } virtual void visit(AstVar* nodep, AstNUser*) { if (m_unnamedScope != "") { // Rename it nodep->name(m_unnamedScope+"__DOT__"+nodep->name()); // Move to module nodep->unlinkFrBack(); if (m_ftaskp) m_ftaskp->addStmtsp(nodep); // Begins under funcs just move into the func else m_modp->addStmtp(nodep); } } virtual void visit(AstCell* nodep, AstNUser*) { UINFO(8," CELL "<name(m_namedScope+"__DOT__"+nodep->name()); UINFO(8," rename to "<name()<unlinkFrBack(); m_modp->addStmtp(nodep); } } virtual void visit(AstScopeName* nodep, AstNUser*) { // If there's a %m in the display text, we add a special node that will contain the name() // Similar code in V3Inline if (nodep->user1SetOnce()) return; // Don't double-add text's if (m_namedScope != "") { // To keep correct visual order, must add before other Text's AstNode* afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeAttrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_namedScope)); if (afterp) nodep->scopeAttrp(afterp); } nodep->iterateChildren(*this); } virtual void visit(AstCoverDecl* nodep, AstNUser*) { // Don't need to fix path in coverage statements, they're not under // any BEGINs, but V3Coverage adds them all under the module itself. nodep->iterateChildren(*this); } // VISITORS - LINT CHECK virtual void visit(AstIf* nodep, AstNUser*) { // Note not AstNodeIf; other types don't get covered // Check IFDEPTH warning - could be in other transform files if desire int prevIfDepth = m_ifDepth; if (m_ifDepth == -1 || v3Global.opt.ifDepth()<1) { // Turned off } else if (nodep->uniquePragma() || nodep->unique0Pragma() || nodep->priorityPragma()) { m_ifDepth = -1; } else if (++m_ifDepth > v3Global.opt.ifDepth()) { nodep->v3warn(IFDEPTH,"Deep 'if' statement; suggest unique/priority to avoid slow logic"); nodep->fileline()->modifyWarnOff(V3ErrorCode::IFDEPTH, true); // Warn only once m_ifDepth = -1; } nodep->iterateChildren(*this); m_ifDepth = prevIfDepth; } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS BeginVisitor(AstNetlist* nodep, BeginState* statep) { m_statep = statep; m_modp = NULL; m_ftaskp = NULL; m_repeatNum = 0; m_ifDepth = 0; nodep->accept(*this); } virtual ~BeginVisitor() {} }; //###################################################################### class BeginRelinkVisitor : public AstNVisitor { // Replace tasks with new pointer private: // NODE STATE // Input: // AstNodeFTask::user1p // Node replaced, rename it // VISITORS virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { if (nodep->taskp()->user1()) { // It was converted UINFO(9, " relinkFTask "<name(nodep->taskp()->name()); } nodep->iterateChildren(*this); } //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS BeginRelinkVisitor(AstNetlist* nodep, BeginState*) { nodep->accept(*this); } virtual ~BeginRelinkVisitor() {} }; //###################################################################### // Task class functions void V3Begin::debeginAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Scope.cpp0000664000177100017500000003437112525171733016316 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity block domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Scope's Transformations: // // For every CELL that references this module, create a // SCOPE // {all blocked statements} // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Scope.h" #include "V3Ast.h" //###################################################################### // Scope class functions class ScopeVisitor : public AstNVisitor { private: // NODE STATE // AstVar::user1p -> AstVarScope replacement for this variable // AstTask::user2p -> AstTask*. Replacement task AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // TYPES typedef map PackageScopeMap; typedef map, AstVarScope*> VarScopeMap; typedef set > VarRefScopeSet; // STATE, inside processing a single module AstNodeModule* m_modp; // Current module AstScope* m_scopep; // Current scope we are building // STATE, for passing down one level of hierarchy (may need save/restore) AstCell* m_aboveCellp; // Cell that instantiates this module AstScope* m_aboveScopep; // Scope that instantiates this scope PackageScopeMap m_packageScopes; // Scopes for each package VarScopeMap m_varScopes; // Varscopes created for each scope and var VarRefScopeSet m_varRefScopes; // Varrefs-in-scopes needing fixup when donw // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void cleanupVarRefs() { for (VarRefScopeSet::iterator it = m_varRefScopes.begin(); it!=m_varRefScopes.end(); ++it) { AstVarRef* nodep = it->first; AstScope* scopep = it->second; if (nodep->packagep()) { PackageScopeMap::iterator it2 = m_packageScopes.find(nodep->packagep()); if (it2==m_packageScopes.end()) nodep->v3fatalSrc("Can't locate package scope"); scopep = it2->second; } VarScopeMap::iterator it3 = m_varScopes.find(make_pair(nodep->varp(), scopep)); if (it3==m_varScopes.end()) nodep->v3fatalSrc("Can't locate varref scope"); AstVarScope* varscp = it3->second; nodep->varScopep(varscp); } } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { AstNodeModule* modp = nodep->topModulep(); if (!modp) { nodep->v3error("No root module specified"); return; } // Operate starting at the top of the hierarchy m_aboveCellp = NULL; m_aboveScopep = NULL; modp->accept(*this); cleanupVarRefs(); } virtual void visit(AstNodeModule* nodep, AstNUser*) { // Create required blocks and add to module string scopename; if (!m_aboveScopep) scopename = "TOP"; else scopename = m_aboveScopep->name()+"."+m_aboveCellp->name(); UINFO(4," MOD AT "<fileline(), nodep, scopename, m_aboveScopep, m_aboveCellp); if (nodep->castPackage()) m_packageScopes.insert(make_pair(nodep->castPackage(), m_scopep)); // Now for each child cell, iterate the module this cell points to for (AstNode* cellnextp = nodep->stmtsp(); cellnextp; cellnextp=cellnextp->nextp()) { if (AstCell* cellp = cellnextp->castCell()) { AstScope* oldScopep = m_scopep; AstCell* oldAbCellp = m_aboveCellp; AstScope* oldAbScopep = m_aboveScopep; { m_aboveCellp = cellp; m_aboveScopep = m_scopep; AstNodeModule* modp = cellp->modp(); if (!modp) cellp->v3fatalSrc("Unlinked mod"); modp->accept(*this); // Recursive call to visit(AstNodeModule) } // Done, restore vars m_scopep = oldScopep; m_aboveCellp = oldAbCellp; m_aboveScopep = oldAbScopep; } } // Create scope for the current usage of this module UINFO(4," back AT "<isTop()) { AstTopScope* topscp = new AstTopScope(nodep->fileline(), m_scopep); m_modp->addStmtp(topscp); } else { m_modp->addStmtp(m_scopep); } // Copy blocks into this scope // If this is the first usage of the block ever, we can simply move the reference nodep->iterateChildren(*this); // ***Note m_scopep is passed back to the caller of the routine (above) } virtual void visit(AstActive* nodep, AstNUser*) { nodep->v3fatalSrc("Actives now made after scoping"); } virtual void visit(AstInitial* nodep, AstNUser*) { // Add to list of blocks under this scope UINFO(4," Move "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); clonep->iterateChildren(*this); // We iterate under the *clone* } virtual void visit(AstFinal* nodep, AstNUser*) { // Add to list of blocks under this scope UINFO(4," Move "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); clonep->iterateChildren(*this); // We iterate under the *clone* } virtual void visit(AstAssignAlias* nodep, AstNUser*) { // Add to list of blocks under this scope UINFO(4," Move "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); clonep->iterateChildren(*this); // We iterate under the *clone* } virtual void visit(AstAssignVarScope* nodep, AstNUser*) { // Copy under the scope but don't recurse UINFO(4," Move "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); clonep->iterateChildren(*this); // We iterate under the *clone* } virtual void visit(AstAssignW* nodep, AstNUser*) { // Add to list of blocks under this scope UINFO(4," Move "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); clonep->iterateChildren(*this); // We iterate under the *clone* } virtual void visit(AstAlways* nodep, AstNUser*) { // Add to list of blocks under this scope UINFO(4," Move "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); clonep->iterateChildren(*this); // We iterate under the *clone* } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { // Add to list of blocks under this scope UINFO(4," Move "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); clonep->iterateChildren(*this); // We iterate under the *clone* } virtual void visit(AstCoverToggle* nodep, AstNUser*) { // Add to list of blocks under this scope UINFO(4," Move "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); clonep->iterateChildren(*this); // We iterate under the *clone* } virtual void visit(AstCFunc* nodep, AstNUser*) { // Add to list of blocks under this scope UINFO(4," CFUNC "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); clonep->scopep(m_scopep); // We iterate under the *clone* clonep->iterateChildren(*this); } virtual void visit(AstNodeFTask* nodep, AstNUser*) { // Add to list of blocks under this scope UINFO(4," FTASK "<cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); // We iterate under the *clone* clonep->iterateChildren(*this); } virtual void visit(AstVar* nodep, AstNUser*) { // Make new scope variable // This is called cross-module by AstVar, so we cannot trust any m_ variables if (!nodep->user1p()) { AstVarScope* varscp = new AstVarScope(nodep->fileline(), m_scopep, nodep); UINFO(6," New scope "<isTrace()) varscp->trace(false); nodep->user1p(varscp); if (v3Global.opt.isClocker(varscp->prettyName())) { nodep->attrClocker(AstVarAttrClocker::CLOCKER_YES); } if (v3Global.opt.isNoClocker(varscp->prettyName())) { nodep->attrClocker(AstVarAttrClocker::CLOCKER_NO); } if (!m_scopep) nodep->v3fatalSrc("No scope for var"); m_varScopes.insert(make_pair(make_pair(nodep, m_scopep), varscp)); m_scopep->addVarp(varscp); } } virtual void visit(AstVarRef* nodep, AstNUser*) { // VarRef needs to point to VarScope // Make sure variable has made user1p. if (!nodep->varp()) nodep->v3fatalSrc("Unlinked"); if (nodep->varp()->isIfaceRef()) { nodep->varScopep(NULL); } else { // We may have not made the variable yet, and we can't make it now as // the var's referenced package etc might not be created yet. // So push to a list and post-correct m_varRefScopes.insert(make_pair(nodep, m_scopep)); } } virtual void visit(AstScopeName* nodep, AstNUser*) { // If there's a %m in the display text, we add a special node that will contain the name() string prefix = (string)("__DOT__")+m_scopep->name(); // TOP and above will be the user's name(). // Note 'TOP.' is stripped by scopePrettyName // To keep correct visual order, must add before other Text's AstNode* afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeAttrp(new AstText(nodep->fileline(), prefix)); if (afterp) nodep->scopeAttrp(afterp); afterp = nodep->scopeEntrp(); if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeEntrp(new AstText(nodep->fileline(), prefix)); if (afterp) nodep->scopeEntrp(afterp); nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep, AstNUser*) { // Scope that was made by this module for different cell; // Want to ignore blocks under it, so just do nothing } //-------------------- // Default virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ScopeVisitor(AstNetlist* nodep) { m_aboveCellp = NULL; m_aboveScopep = NULL; m_modp = NULL; m_scopep = NULL; // nodep->accept(*this); } virtual ~ScopeVisitor() {} }; //###################################################################### // Scope cleanup -- remove unused activates class ScopeCleanupVisitor : public AstNVisitor { private: // STATE AstScope* m_scopep; // Current scope we are building // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstScope* nodep, AstNUser*) { // Want to ignore blocks under it m_scopep = nodep; nodep->iterateChildren(*this); m_scopep = NULL; } virtual void movedDeleteOrIterate(AstNode* nodep) { if (m_scopep) { // The new block; repair varrefs nodep->iterateChildren(*this); } else { // A block that was just moved under a scope, Kill it. nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } } virtual void visit(AstInitial* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstFinal* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstAssignAlias* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstAssignVarScope* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstAssignW* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstAlways* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstCoverToggle* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstNodeFTask* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstCFunc* nodep, AstNUser*) { movedDeleteOrIterate(nodep); } virtual void visit(AstVarXRef* nodep, AstNUser*) { // The crossrefs are dealt with in V3LinkDot nodep->varp(NULL); } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { // The crossrefs are dealt with in V3LinkDot UINFO(9," Old pkg-taskref "<packagep()) { // Point to the clone if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked"); AstNodeFTask* newp = nodep->taskp()->user2p()->castNode()->castNodeFTask(); if (!newp) nodep->v3fatalSrc("No clone for package function"); nodep->taskp(newp); UINFO(9," New pkg-taskref "<taskp(NULL); UINFO(9," New pkg-taskref "<iterateChildren(*this); } virtual void visit(AstModportFTaskRef* nodep, AstNUser*) { // The crossrefs are dealt with in V3LinkDot nodep->ftaskp(NULL); nodep->iterateChildren(*this); } //-------------------- // Default virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ScopeCleanupVisitor(AstNetlist* nodep) { m_scopep = NULL; nodep->accept(*this); } virtual ~ScopeCleanupVisitor() {} }; //###################################################################### // Scope class functions void V3Scope::scopeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3DepthBlock.h0000664000177100017500000000227312525171733016725 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Prevent very deep expressions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3DEPTHBLOCK_H_ #define _V3DEPTHBLOCK_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3DepthBlock { public: static void depthBlockAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3PreLex.h0000664000177100017500000001734512525172076016114 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilog::Preproc: Internal header for lex interfacing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2000-2015 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. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // This header provides the interface between the lex proper V3PreLex.l/.cpp // and the class implementation file V3Pre.cpp // It is not intended for user applications. //************************************************************************* #ifndef _VPREPROCLEX_H_ // Guard #define _VPREPROCLEX_H_ 1 #include #include #include "V3Error.h" #include "V3FileLine.h" //====================================================================== class V3PreLex; class V3PreProcImp; // Token codes // If changing, see V3PreProc.cpp's V3PreProcImp::tokenName() #define VP_EOF 0 #define VP_INCLUDE 256 #define VP_IFDEF 257 #define VP_IFNDEF 258 #define VP_ENDIF 259 #define VP_UNDEF 260 #define VP_DEFINE 261 #define VP_ELSE 262 #define VP_ELSIF 263 #define VP_LINE 264 #define VP_UNDEFINEALL 265 #define VP_SYMBOL 300 #define VP_STRING 301 #define VP_DEFVALUE 302 #define VP_COMMENT 303 #define VP_TEXT 304 #define VP_WHITE 305 #define VP_DEFREF 306 #define VP_DEFARG 307 #define VP_ERROR 308 #define VP_DEFFORM 309 #define VP_STRIFY 310 #define VP_BACKQUOTE 311 #define VP_SYMBOL_JOIN 312 #define VP_DEFREF_JOIN 313 #define VP_PSL 350 //====================================================================== // Externs created by flex // We add a prefix so that other lexers/flexers in the same program won't collide. #ifndef yy_create_buffer # define yy_create_buffer V3PreLex_create_buffer # define yy_delete_buffer V3PreLex_delete_buffer # define yy_scan_buffer V3PreLex_scan_buffer # define yy_scan_string V3PreLex_scan_string # define yy_scan_bytes V3PreLex_scan_bytes # define yy_flex_debug V3PreLex_flex_debug # define yy_init_buffer V3PreLex_init_buffer # define yy_flush_buffer V3PreLex_flush_buffer # define yy_load_buffer_state V3PreLex_load_buffer_state # define yy_switch_to_buffer V3PreLex_switch_to_buffer # define yyin V3PreLexin # define yyleng V3PreLexleng # define yylex V3PreLexlex # define yyout V3PreLexout # define yyrestart V3PreLexrestart # define yytext V3PreLextext # define yyerror V3PreLexerror # define yyerrorf V3PreLexerrorf #endif #ifndef yyourleng # define yyourleng V3PreLexourleng # define yyourtext V3PreLexourtext #endif #ifndef YY_BUFFER_STATE struct yy_buffer_state; typedef struct yy_buffer_state *YY_BUFFER_STATE; # define YY_BUF_SIZE 16384 #endif extern int yylex(); extern void yyrestart(FILE*); // Accessors, because flex keeps changing the type of yyleng extern char* yyourtext(); extern size_t yyourleng(); extern void yyourtext(const char* textp, size_t size); // Must call with static YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ); void yy_delete_buffer( YY_BUFFER_STATE b ); //====================================================================== #define KEEPCMT_SUB 2 #define KEEPCMT_EXP 3 //====================================================================== // Entry for each file processed; a stack of entries included class VPreStream { public: FileLine* m_curFilelinep; // Current processing point (see also m_tokFilelinep) V3PreLex* m_lexp; // Lexer, for resource tracking deque m_buffers; // Buffer of characters to process int m_ignNewlines; // Ignore multiline newlines bool m_eof; // "EOF" buffer bool m_file; // Buffer is start of new file int m_termState; // Termination fsm VPreStream(FileLine* fl, V3PreLex* lexp) : m_curFilelinep(fl), m_lexp(lexp), m_ignNewlines(0), m_eof(false), m_file(false), m_termState(0) { lexStreamDepthAdd(1); } ~VPreStream() { lexStreamDepthAdd(-1); } private: void lexStreamDepthAdd(int delta); }; //====================================================================== // Class entry for each per-lexer state class V3PreLex { public: // Used only by V3PreLex.cpp and V3PreProc.cpp V3PreProcImp* m_preimpp; // Preprocessor lexor belongs to stack m_streampStack; // Stack of processing files int m_streamDepth; // Depth of stream processing YY_BUFFER_STATE m_bufferState; // Flex state FileLine* m_tokFilelinep; // Starting position of current token // State to lexer static V3PreLex* s_currentLexp; ///< Current lexing point int m_keepComments; ///< Emit comments in output text int m_keepWhitespace; ///< Emit all whitespace in output text bool m_pedantic; ///< Obey standard; don't Substitute `error // State from lexer int m_formalLevel; // Parenthesis counting inside def formals int m_parenLevel; // Parenthesis counting inside def args bool m_defCmtSlash; // /*...*/ comment in define had \ ending bool m_defQuote; // Definition value inside quote string m_defValue; // Definition value being built. int m_enterExit; // For VL_LINE, the enter/exit level // CONSTRUCTORS V3PreLex(V3PreProcImp* preimpp, FileLine* filelinep) { m_preimpp = preimpp; m_streamDepth = 0; m_keepComments = 0; m_keepWhitespace = 1; m_pedantic = false; m_formalLevel = 0; m_parenLevel = 0; m_defQuote = false; m_defCmtSlash = false; m_tokFilelinep = filelinep; m_enterExit = 0; initFirstBuffer(filelinep); } ~V3PreLex() { while (!m_streampStack.empty()) { delete m_streampStack.top(); m_streampStack.pop(); } yy_delete_buffer(m_bufferState); m_bufferState=NULL; } // Called by V3PreLex.l from lexer VPreStream* curStreamp() { return m_streampStack.top(); } // Can't be empty, "EOF" is on top FileLine* curFilelinep() { return curStreamp()->m_curFilelinep; } void curFilelinep(FileLine* fl) { curStreamp()->m_curFilelinep = fl; } void appendDefValue(const char* textp, size_t len) { m_defValue.append(textp,len); } void lineDirective(const char* textp); void linenoInc() { if (curStreamp()->m_ignNewlines) curStreamp()->m_ignNewlines--; else curFilelinep()->linenoInc(); } // Called by V3PreProc.cpp to inform lexer void pushStateDefArg(int level); void pushStateDefForm(); void pushStateDefValue(); void pushStateIncFilename(); void scanNewFile(FileLine* filelinep); void scanBytes(const string& str); void scanBytesBack(const string& str); size_t inputToLex(char* buf, size_t max_size); /// Called by V3PreProc.cpp to get data from lexer YY_BUFFER_STATE currentBuffer(); int lex(); int currentStartState() const; void dumpSummary(); void dumpStack(); void unused(); // Called by VPreStream void streamDepthAdd(int delta) { m_streamDepth += delta; } int streamDepth() const { return m_streamDepth; } /// Utility static int debug(); static void debug(int level); static string cleanDbgStrg(const string& in); private: string currentUnreadChars(); string endOfStream(bool& againr); void initFirstBuffer(FileLine* filelinep); void scanSwitchStream(VPreStream* streamp); }; inline void VPreStream::lexStreamDepthAdd(int delta) { m_lexp->streamDepthAdd(delta); } #endif // Guard verilator-3.874/src/bisonpre0000775000177100017500000004041712525171734016076 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### require 5.006_001; use Getopt::Long; use IO::File; use Pod::Usage; use strict; use vars qw ($Debug $VERSION); $VERSION = '3.404'; our $Self; #====================================================================== # main our $Opt_Debug; our $Opt_Definitions; our $Opt_File_Prefix; our $Opt_Name_Prefix; our $Opt_Output; our $Opt_Token_Table; our $Opt_Verbose; our $Opt_Yacc = "bison"; our $Opt_Input; autoflush STDOUT 1; autoflush STDERR 1; Getopt::Long::config ("no_auto_abbrev"); if (! GetOptions ( # Local options "help" => \&usage, "version" => sub { print "Version $VERSION\n"; exit(0); }, "yacc=s" => \$Opt_Yacc, # Passed to Bison "t|debug" => sub { $Opt_Debug = 1; }, "b|file-prefix=s" => \$Opt_File_Prefix, "d" => \$Opt_Definitions, "k|token-table" => \$Opt_Token_Table, "o=s" => \$Opt_Output, "p|name-prefix=s" => \$Opt_Name_Prefix, "v|verbose" => \$Opt_Verbose, "<>" => \¶meter, )) { die "%Error: Bad usage, try 'bisonpre --help'\n"; } $Opt_Input or die "bisonpre: %Error: input file not specified\n"; $Opt_Output or die "bisonpre: %Error: --o option is required\n"; process(); #---------------------------------------------------------------------- sub usage { print "Version $VERSION\n"; pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT, -noperldoc=>1); exit (1); } sub parameter { my $param = shift; if (!defined $Opt_Input) { $Opt_Input = $param; } else { die "bisonpre: %Error: Unknown parameter: $param\n"; } } ####################################################################### sub process { remove_outputs(); $Self->{bison_version} = bison_version_check(); my $supports_report = ($Self->{bison_version} >= 2.3); clean_input($Opt_Input, tmp_prefix().".y"); # Run bison my $command = ($Opt_Yacc .($Opt_Debug?" -t":"") .($Opt_Definitions?" -d":"") .($Opt_Token_Table?" -k":"") .($Opt_Verbose?" -v":"") .(($Opt_Verbose && $supports_report)?" --report=itemset --report=lookahead":"") # -p required for GLR parsers; they write to -p basename, not -o .($Opt_Name_Prefix?" -p $Opt_Name_Prefix":"") ." -b ".tmp_prefix() ." -o ".tmp_prefix().".c" ." ".tmp_prefix().".y" ); print " $command\n"; system $command; my $status = $?; if ($status != 0) { remove_outputs(); my $v = bison_version_check(); die "bisonpre: %Error: $Opt_Yacc version $v run failed due to errors\n"; } clean_output(tmp_prefix().".output",output_prefix().".output", 1,0); warning_check(output_prefix().".output"); clean_output(tmp_prefix().".c", output_prefix().".c", 0,1); clean_output(tmp_prefix().".h", output_prefix().".h", 0,1); remove_tmp(); } sub tmp_prefix { return output_prefix()."_pretmp"; } sub output_prefix { my $o; if ($Opt_Output) { (my $o = $Opt_Output) =~ s!\.[^.]*$!!; return $o; } else { return $Opt_File_Prefix.".tab"; } } sub remove_tmp { unlink(tmp_prefix().".c"); # Ok if errors unlink(tmp_prefix().".h"); # Ok if errors unlink(tmp_prefix().".output"); # Ok if errors } sub remove_outputs { remove_tmp(); unlink(output_prefix().".c"); # Ok if errors unlink(output_prefix().".h"); # Ok if errors # We don't remove .output file, as it's useful for debugging errors } sub bison_version_check { my $v = `$Opt_Yacc --version`; if ($v && $v =~ /([0-9]+\.[0-9]+)/) { my $v = $1; ($v >= 1.875) or die "bisonpre: %Error: '$Opt_Yacc' is version $v; version 1.875 or newer is required\n"; return $v; } else { die "bisonpre: %Error: '$Opt_Yacc' is not installed, or not working\n"; } } sub clean_output { my $filename = shift; my $outname = shift || $filename; my $is_output = shift; my $is_c = shift; print " edit $filename $outname\n"; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; my @lines = $fh->getlines; $fh->close; (my $basename = tmp_prefix().".") =~ s!.*/!!; $basename = quotemeta($basename); (my $newbase = $Opt_Input) =~ s!.*/!!; $newbase =~ s/\.y/./; if ($is_output) { my %state_line; my $l=0; foreach my $line (@lines) { $l++; # We add a colon so it's easy to search for the definition $state_line{$1} = $l if $line =~ s/^state (\d+)\s*$/state $1:/; } my @out; foreach my $line (@lines) { if ($line =~ /^State (\d+) (conflicts)/) { chomp $line; $line .= " // line $state_line{$1}" if $state_line{$1}; $line .= "\n"; } push @out, $line; } @lines = @out; @out = (); } if ($is_c) { my %token_values; my $in_en=0; foreach my $line (@lines) { $in_en=1 if $line =~ /enum\s+yytokentype/; $in_en=0 if $line =~ /;/; $token_values{$2} = $1 if $in_en && $line =~ /\b(\S+) = (\d+)/; } my @out; foreach my $line (@lines) { if ($line =~ /BISONPRE_TOKEN_NAMES/) { push @out, $line; foreach my $tv (sort keys %token_values) { push @out, sprintf("\tcase %d: return \"%s\";\n", $tv, $token_values{$tv}); } next; } push @out, $line; } @lines = @out; @out = (); } $fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n"; foreach my $line (@lines) { # Fix filename refs $line =~ s!$basename!$newbase!g; # Fix bison 2.3 and GCC 4.2.1 $line =~ s!\(YY_\("!(YY_((char*)"!g; # Fix bison 2.3 glr-parser warning about yyerrorloc.YYTYPE::yydummy uninit $line =~ s!(YYLTYPE yyerrloc;)!$1 yyerrloc.yydummy=0;/*bisonpre*/!g; $fh->write($line); } $fh->close; } sub warning_check { my $filename = shift; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; while (defined(my $line = $fh->getline)) { if ($line =~ /(conflicts|warning:|^useless)/i) { die "%Error: $filename:$.: $line\n"; } } $fh->close; } ####################################################################### sub clean_input { my $filename = shift; my $outname = shift || $filename; # Can == filename if desired print " edit $filename $outname\n"; $Self->{filename} = $filename; my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; my @lines = $fh->getlines; $fh->close; # Find "%tokens:" # Find "rule:" and replace with just "rule:" my %types; my %rules; $Self->{rules} = \%rules; my %tokens; my $last_rule; my $section = 1; { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; # ^/ to prevent comments from matching $line =~ m!^[a-zA-Z0-9_<>]+:[^/]*[a-zA-Z]! and die "%Error: $filename:$l: Move text on rule line to next line: $line\n"; if ($line =~ /^%%/) { $section++; if ($section==2) { $last_rule = undef; } } elsif ($line =~ s/^([a-zA-Z0-9_]+)<(\S*)>:/$1:/) { !$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n"; $types{$2}{$1} = 1; $rules{$1}{name} = $1; $rules{$1}{type} = $2; !$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n"; $last_rule = $1; } elsif ($line =~ /^([a-zA-Z0-9_]+):/) { !$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n"; $rules{$1}{name} = $1; $rules{$1}{type} = ""; !$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n"; $last_rule = $1; } push @lines, $line; # Now clean the line and extract some more info (my $cline = $line) =~ s/\/\/.*$/\n/; (my $rline = $line) =~ s/\/\/.*$/\n/; if ($cline =~ /^\s*;/) { $last_rule or die "%Error: $filename:$l: Stray semicolon\n"; $last_rule = undef; } elsif ($last_rule) { $rules{$last_rule}{rules_and_productions} .= $cline; } if ($cline =~ /^%token\s*<(\S+)>\s*(\S+)/) { !$tokens{$2} or die "%Error: $filename:$l: Redeclaring '$2': $line\n"; $tokens{$2} = $1; } foreach my $tok (split /[^a-zA-Z0-9_]+/, $cline) { if ($last_rule && $tok=~/^[a-zA-Z]/) { #print "TT $last_rule $tok\n"; $rules{$last_rule}{subrules}{$tok} = 1; $rules{$tok}{parentrules}{$last_rule} = 1; } } } } #use Data::Dumper; print Dumper(\%rules); # Replace BISONPRE_VERSION(ver,,...) with expanded list { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; if ($line =~ /BISONPRE_VERSION/) { # 1 3 4 ($line =~ /BISONPRE_VERSION\((\S+)\s*,\s*((\S+)\s*,)?\s*([^\),]+)\)\s*$/) or die "%Error: $filename:$l: Bad form of BISONPRE_VERSION: $line\n"; my $ver=$1; my $ver_max=$3; my $cmd=$4; if ($Self->{bison_version} >= $1 && (!$ver_max || $Self->{bison_version} <= $ver_max)) { $line = $cmd."\n"; } else { $line = "//NOP: $line"; } } push @lines, $line; } } # Replace BISONPRE_NOT(type,...) with expanded list { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; if ($line =~ /BISONPRE_NOT/) { ($line =~ s/BISONPRE_NOT\((\S+)\)\s*({[^}]+})\s*$//) or die "%Error: $filename:$l: Bad form of BISONPRE_NOT: $line\n"; my $endtok = $1; my $action = $2; my @endtoks = split (/,/, $endtok); map { $tokens{$_} or die "%Error: $filename:$l: Can't find definition for token: $_\n" } @endtoks; # Push it all onto one line to avoid error messages changing my $bar = ""; tok: foreach my $tok (sort keys %tokens) { foreach (@endtoks) { next tok if $tok eq $_; } if ($endtok ne $tok) { $line .= "\t$bar $tok $action"; $bar = "|"; } } $line .= "\n"; } push @lines, $line; } } # Replace BISONPRE_COPY(type,{code}) { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; if ($line =~ /BISONPRE_COPY/) { $line = _bisonpre_copy($line,$l,0); } push @lines, $line; } } # Replace ~[x]~ - must be after BISONPRE_COPY expansion { my @linesin = @lines; @lines=(); my $l=0; foreach my $line (@linesin) { $l++; $line =~ s/~[a-zA-Z0-9_]+~//g; push @lines, $line; } } # Find "BISONPRE_TYPES" { my @linesin = @lines; @lines=(); my $l=0; my $needmore = 0; foreach my $line (@linesin) { $l++; if ($line =~ m!//BISONPRE_TYPES!) { push @lines, $line; foreach my $type (sort keys %types) { next if !$type; my $line = "%type<$type>\t"; foreach my $rule (sort keys %{$types{$type}}) { $line.=" ".$rule; } $line .= "\n"; push @lines, $line; $needmore++ } } elsif ($needmore) { # Bison doesn't have a #line directive, so we need somewhere to insert into $line =~ s!^\s*//.*$!!; ($line =~ m/^\s*$/) or die "%Error: $filename:$l: Need $needmore more blank lines to insure line numbers are constant\n"; $needmore--; } else { push @lines, $line; } } } $fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n"; foreach my $line (@lines) { $fh->write($line); } $fh->close; } sub _bisonpre_copy { my $text = shift; my $l = shift; my $depth = shift; while ($text =~ /BISONPRE_COPY/) { ($text =~ s/BISONPRE_COPY(_ONCE)?\((\S+)\s*,\s*{([^}]*)}\s*\)/{HERE}/) or die "%Error: $Self->{filename}:$l: Bad form of BISONPRE_NOT: $text\n"; my $once = $1; my $rule = $2; my $code = $3; $Self->{rules}{$rule} or die "%Error: $Self->{filename}:$l: Can't find definition for rule: $rule\n"; if ($depth > 0 && $once) { # _ONCE means don't inherit $text =~ s/\|[ \t]+{HERE}//; # Don't OR in nothing $text =~ s/{HERE}//; } else { # Push it all onto one line to avoid error messages changing my $insert = $Self->{rules}{$rule}{rules_and_productions}; $insert =~ s/^\S+://g; # Strip rule name # Recurse so BISONPRE under B #print "COPY $l code $code\n"; #print "COPY $l in $insert\n"; $_=$insert; eval("$code; \$_;"); $insert = $_; #print "COPY $l out $insert\n"; while ($insert =~ s/[ \t\n]+\n/\n/go) {} while ($insert =~ s/\n/ /go) {} # Optional - preserve line numbering $text =~ s/{HERE}/$insert/; } $depth++; } return $text; } ####################################################################### __END__ =pod =head1 NAME bisonpre - Bison wrapper with pre and post processing =head1 SYNOPSIS bisonpre --yacc bison --debug --verbose --defines X.h -k $< -pX -o X.c =head1 DESCRIPTION Bisonpre is a wrapper for the Bison YACC replacement. Input to Bison is preprocessed with substitution as described below under EXTENSIONS. Output from Bison is checked for additional errors, and corrected to work around various compile warnings. =head1 EXTENSIONS =over 4 =item //BISONPRE_TYPES This is expanded into %type declarations. =item ~[a-z]+~ Any text matching ~[a-z]+~ is removed. This allows optional text to be used only when the rule containing the ~~ is used in a BISONPRE_COPY. =item rule_label: This allows the label declaring a rule to also specify the type of the rule. The type will be inserted where /*BISONPRE_TYPES*/ is encountered. =item BISONPRE_COPY(rule, {code}) Copy the rules and productions from the specified rule, filter through the Perl code provided in the {} and insert here into the output file. =item BISONPRE_COPY_ONCE(rule, {code}) As with BISONPRE_COPY, but if called from underneath another BISONPRE_COPY rule, ignore it. =item BISONPRE_NOT(token[, token...]) Create a rule that matches every token except for those specified. =item BISONPRE_VERSION(ver, cmd) If the bison version is >= the specified version, include the given command. =back =head1 ARGUMENTS =over 4 =item -b file-prefix =item --file-prefix=file-prefix Passed to bison. Specify a prefix to use for all bison output file names. The names are chosen as if the input file were named file-prefix.c. =item -d Passed to bison. Write an extra output file containing macro definitions for the token type names defined in the grammar and the semantic value type YYSTYPE, as well as a few extern variable declarations. If the parser output file is named name.c then this file is named name.h. This output file is essential if you wish to put the definition of yylex in a separate source file, because yylex needs to be able to refer to token type codes and the variable yylval. =item --help Displays this message and program version and exits. =item -k =item --token-table Passed to bison. This switch causes the name.tab.c output to include a list of token names in order by their token numbers; this is defined in the array yytname. Also generated are #defines for YYNTOKENS, YYNNTS, YYNRULES, and YYNSTATES. =item -t =item --debug Passed to bison. In the parser file, define the macro YYDEBUG to 1 if it is not already defined, so that the debugging facilities are compiled. =item -v =item --verbose Passed to bison. Write an extra output file containing verbose descriptions of the parser states and what is done for each type of look-ahead token in that state. This file also describes all the conflicts, both those resolved by operator precedence and the unresolved ones. The file's name is made by removing .tab.c or .c from the parser output file name, and adding .output instead. Therefore, if the input file is foo.y, then the parser file is called foo.tab.c by default. As a consequence, the verbose output file is called foo.output. =item --version Print the version number and exit. =item --yacc Specify the name of the bison executable, defaults to "bison." =back =head1 DISTRIBUTION This is part of the L free Verilog EDA software tool suite. The latest version is available from CPAN and from L. Copyright 2008-2015 by Wilson Snyder. This package 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO C =cut ###################################################################### ### Local Variables: ### compile-command: "./bisonpre " ### End: verilator-3.874/src/V3Order.cpp0000664000177100017500000017711712525171733016326 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Block code ordering // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Order's Transformations: // // Compute near optimal scheduling of always/wire statements // Make a graph of the entire netlist // // Add master "*INPUTS*" vertex. // For inputs on top level // Add vertex for each input var. // Add edge INPUTS->var_vertex // // For seq logic // Add logic_sensitive_vertex for this list of SenItems // Add edge for each sensitive_var->logic_sensitive_vertex // For AssignPre's // Add vertex for this logic // Add edge logic_sensitive_vertex->logic_vertex // Add edge logic_consumed_var_PREVAR->logic_vertex // Add edge logic_vertex->logic_generated_var (same as if comb) // Add edge logic_vertex->generated_var_PREORDER // Cutable dependency to attempt to order dlyed // assignments to avoid saving state, thus we prefer // a <= b ... As the opposite order would // b <= c ... require the old value of b. // For Logic // Add vertex for this logic // Add edge logic_sensitive_vertex->logic_vertex // Add edge logic_generated_var_PREORDER->logic_vertex // This insures the AssignPre gets scheduled before this logic // Add edge logic_vertex->consumed_var_PREVAR // Add edge logic_vertex->consumed_var_POSTVAR // Add edge logic_vertex->logic_generated_var (same as if comb) // For AssignPost's // Add vertex for this logic // Add edge logic_sensitive_vertex->logic_vertex // Add edge logic_consumed_var->logic_vertex (same as if comb) // Add edge logic_vertex->logic_generated_var (same as if comb) // // For comb logic // For comb logic // Add vertex for this logic // Add edge logic_consumed_var->logic_vertex // Add edge logic_vertex->logic_generated_var // Mark it cutable, as circular logic may require // the generated signal to become a primary input again. // // // // Rank the graph starting at INPUTS (see V3Graph) // // Visit the graph's logic vertices in ranked order // For all logic vertices with all inputs already ordered // Make ordered block for this module // For all ^^ in same domain // Move logic to ordered activation // When we have no more choices, we move to the next module // and make a new block. Add that new activation block to the list of calls to make. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include #include #include "V3Global.h" #include "V3File.h" #include "V3Ast.h" #include "V3Graph.h" #include "V3List.h" #include "V3SenTree.h" #include "V3Stats.h" #include "V3EmitCBase.h" #include "V3Const.h" #include "V3Order.h" #include "V3OrderGraph.h" #include "V3EmitV.h" class OrderMoveDomScope; //###################################################################### // Functions for above graph classes void OrderGraph::loopsVertexCb(V3GraphVertex* vertexp) { if (debug()) cout<<"-Info-Loop: "<(vertexp)) { cerr<nodep()->fileline()<<" "<nodep()->typeName()<(vertexp)) { cerr<varScp()->fileline()<<" "<varScp()->prettyName()< m_readyDomScopeE;// List of next ready dom scope V3List m_readyVertices; // Ready vertices with same domain & scope private: bool m_onReadyList; // True if DomScope is already on list of ready dom/scopes AstSenTree* m_domainp; // Domain all vertices belong to AstScope* m_scopep; // Scope all vertices belong to OrderLoopId m_inLoop; // Loop member of typedef pair, AstScope*> DomScopeKey; typedef std::map DomScopeMap; static DomScopeMap s_dsMap; // Structure registered for each dom/scope pairing public: OrderMoveDomScope(OrderLoopId inLoop, AstSenTree* domainp, AstScope* scopep) : m_onReadyList(false), m_domainp(domainp), m_scopep(scopep), m_inLoop(inLoop) {} OrderMoveDomScope* readyDomScopeNextp() const { return m_readyDomScopeE.nextp(); } OrderLoopId inLoop() const { return m_inLoop; } AstSenTree* domainp() const { return m_domainp; } AstScope* scopep() const { return m_scopep; } void ready(OrderVisitor* ovp); // Check the domScope is on ready list, add if not void movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp); // Mark one vertex as finished, remove from ready list if done // STATIC MEMBERS (for lookup) static void clear() { for (DomScopeMap::iterator it=s_dsMap.begin(); it!=s_dsMap.end(); ++it) { delete it->second; } s_dsMap.clear(); } V3List& readyVertices() { return m_readyVertices; } static OrderMoveDomScope* findCreate (OrderLoopId inLoop, AstSenTree* domainp, AstScope* scopep) { const DomScopeKey key = make_pair(make_pair(inLoop,domainp),scopep); DomScopeMap::iterator iter = s_dsMap.find(key); if (iter != s_dsMap.end()) { return iter->second; } else { OrderMoveDomScope* domScopep = new OrderMoveDomScope(inLoop, domainp, scopep); s_dsMap.insert(make_pair(key, domScopep)); return domScopep; } } string name() const { return (string("MDS:") +" lp="+cvtToStr(inLoop()) +" d="+cvtToStr((void*)domainp()) +" s="+cvtToStr((void*)scopep())); } }; OrderMoveDomScope::DomScopeMap OrderMoveDomScope::s_dsMap; inline ostream& operator<< (ostream& lhs, const OrderMoveDomScope& rhs) { lhs<=WV_MAX) varscp->v3fatalSrc("Bad Case\n"); OrderVarVertex* vertexp = m_vertexp[type]; if (!vertexp) { UINFO(6,"New vertex "<v3fatalSrc("Bad Case\n"); } m_vertexp[type] = vertexp; } else { if (createdp) *createdp=false; } return vertexp; } public: // CONSTRUCTORS OrderUser() { for (int i=0; ivarScp()->varp()->width() > vsv2p->varScp()->varp()->width(); } }; //! Comparator for fanout of vertex struct OrderVarFanoutCmp { bool operator() (OrderVarStdVertex* vsv1p, OrderVarStdVertex* vsv2p) { return vsv1p->fanout() > vsv2p->fanout(); } }; //###################################################################### // The class is used for propagating the clocker attribute for further // avoiding marking clock signals as circular. // Transformation: // while (newClockerMarked) // check all assignments // if RHS is marked as clocker: // mark LHS as clocker as well. // newClockerMarked = true; // // In addition it also check whether clock and data signals are mixed, and // produce a CLKDATA warning if so. // class OrderClkMarkVisitor : public AstNVisitor { private: bool m_hasClk; // flag indicating whether there is clock signal on rhs bool m_inClocked; // Currently inside a sequential block bool m_newClkMarked; // Flag for deciding whether a new run is needed bool m_inAss; // Currently inside of a assignment int m_childClkWidth; // If in hasClk, width of clock signal in child int m_rightClkWidth; // Clk width on the RHS // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual void visit(AstNodeAssign* nodep, AstNUser*) { m_hasClk = false; if (AstVarRef* varrefp = nodep->rhsp()->castVarRef()) { this->visit(varrefp, NULL); m_rightClkWidth = varrefp->width(); if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { if (m_inClocked) { varrefp->v3warn(CLKDATA, "Clock used as data (on rhs of assignment) in sequential block "<rhsp()->iterateAndNext(*this); m_rightClkWidth = m_childClkWidth; m_inAss = false; } // do the marking if (m_hasClk) { if (nodep->lhsp()->width() > m_rightClkWidth) { nodep->v3warn(CLKDATA, "Clock is assigned to part of data signal "<< nodep->lhsp()<lhsp()->width() <lhsp()->castVarRef(); if (lhsp && (lhsp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_UNKNOWN)) { lhsp->varp()->attrClocker(AstVarAttrClocker::CLOCKER_YES); // mark as clocker m_newClkMarked = true; // enable a further run since new clocker is marked UINFO(5, "node is newly marked as clocker by assignment "<varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { if (m_inClocked) { nodep->v3warn(CLKDATA, "Clock used as data (on rhs of assignment) in sequential block "<prettyName()); } else { m_hasClk = true; m_childClkWidth = nodep->width(); // Pass up UINFO(5, "node is already marked as clocker "<lhsp()->iterateAndNext(*this); int lw = m_childClkWidth; nodep->rhsp()->iterateAndNext(*this); int rw = m_childClkWidth; m_childClkWidth = lw + rw; // Pass up } } virtual void visit(AstNodeSel* nodep, AstNUser* wp) { if (m_inAss) { nodep->iterateChildren(*this); // Pass up result width if (m_childClkWidth > nodep->width()) m_childClkWidth = nodep->width(); } } virtual void visit(AstSel* nodep, AstNUser*) { if (m_inAss) { nodep->iterateChildren(*this); if (m_childClkWidth > nodep->width()) m_childClkWidth = nodep->width(); } } virtual void visit(AstReplicate* nodep, AstNUser*) { if (m_inAss) { nodep->iterateChildren(*this); if (nodep->rhsp()->castConst()) { m_childClkWidth = m_childClkWidth * nodep->rhsp()->castConst()->toUInt(); } else { m_childClkWidth = nodep->width(); // can not check in this case. } } } virtual void visit(AstActive* nodep, AstNUser*) { m_inClocked = nodep->hasClocked(); nodep->iterateChildren(*this); m_inClocked = false; } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS OrderClkMarkVisitor(AstNode* nodep) { m_hasClk = false; m_inClocked = false; m_inAss = false; m_childClkWidth = 0; m_rightClkWidth = 0; do { m_newClkMarked = false; nodep->accept(*this); } while (m_newClkMarked); } virtual ~OrderClkMarkVisitor() {} }; //###################################################################### // The class used to check if the assignment has clocker inside. class OrderClkAssVisitor : public AstNVisitor { private: bool m_clkAss; // There is signals marked as clocker in the assignment // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual void visit(AstNodeAssign* nodep, AstNUser*) { if (AstVarRef* varrefp = nodep->lhsp()->castVarRef() ) if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { m_clkAss = true; UINFO(6, "node was marked as clocker "<rhsp()->iterateChildren(*this); } virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { m_clkAss = true; UINFO(6, "node was marked as clocker "<iterateChildren(*this); } public: // CONSTUCTORS OrderClkAssVisitor(AstNode* nodep) { m_clkAss = false; nodep->accept(*this); } virtual ~OrderClkAssVisitor() {} // METHODS bool isClkAss() {return m_clkAss;} }; //###################################################################### // Order class functions class OrderVisitor : public AstNVisitor { private: // NODE STATE // Forming graph: // Entire Netlist: // AstVarScope::user1p -> OrderUser* for usage var // {statement}Node::user1p-> AstModule* statement is under // USER4 Cleared on each Logic stmt // AstVarScope::user4() -> VarUsage(gen/con/both). Where already encountered signal // Ordering (user3/4/5 cleared between forming and ordering) // AstScope::user1p() -> AstNodeModule*. Module this scope is under // AstNodeModule::user3() -> Number of routines created // Each call to V3Const::constify // AstNode::user4() Used by V3Const::constify, called below AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; //AstUser4InUse m_inuser4; // Used only when building tree, so below // STATE OrderGraph m_graph; // Scoreboard of var usages/dependencies SenTreeFinder m_finder; // Find global sentree's and add them AstSenTree* m_comboDomainp; // Combo activation tree AstSenTree* m_deleteDomainp;// Delete this from tree AstSenTree* m_settleDomainp;// Initial activation tree OrderInputsVertex* m_inputsVxp; // Top level vertex all inputs point from OrderSettleVertex* m_settleVxp; // Top level vertex all settlement vertexes point from OrderLogicVertex* m_logicVxp; // Current statement being tracked, NULL=ignored AstTopScope* m_topScopep; // Current top scope being processed AstScope* m_scopetopp; // Scope under TOPSCOPE AstNodeModule* m_modp; // Current module AstScope* m_scopep; // Current scope being processed AstActive* m_activep; // Current activation block bool m_inSenTree; // Underneath AstSenItem; any varrefs are clocks bool m_inClocked; // Underneath clocked block bool m_inClkAss; // Underneath AstAssign bool m_inPre; // Underneath AstAssignPre bool m_inPost; // Underneath AstAssignPost OrderLogicVertex* m_activeSenVxp; // Sensitivity vertex deque m_orderUserps; // All created OrderUser's for later deletion. // STATE... for inside process OrderLoopId m_loopIdMax; // Maximum BeginLoop id number assigned vector m_pmlLoopEndps; // processInsLoop: End vertex for each color vector m_pomLoopMoveps;// processMoveLoop: Loops next nodes are under AstCFunc* m_pomNewFuncp; // Current function being created int m_pomNewStmts; // Statements in function being created V3Graph m_pomGraph; // Graph of logic elements to move V3List m_pomWaiting; // List of nodes needing inputs to become ready protected: friend class OrderMoveDomScope; V3List m_pomReadyDomScope; // List of ready domain/scope pairs, by loopId vector m_unoptflatVars; // Vector of variables in UNOPTFLAT loop private: // STATS V3Double0 m_statCut[OrderVEdgeType::_ENUM_END]; // Count of each edge type cut // TYPES enum VarUsage { VU_NONE=0, VU_CON=1, VU_GEN=2 }; // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void iterateNewStmt(AstNode* nodep) { if (m_scopep) { UINFO(4," STMT "<sensesp()) nodep->v3fatalSrc("NULL"); // If inside combo logic, ignore the domain, we'll assign one based on interconnect AstSenTree* startDomainp = m_activep->sensesp(); if (startDomainp->hasCombo()) startDomainp=NULL; m_logicVxp = new OrderLogicVertex(&m_graph, m_scopep, startDomainp, nodep); if (m_activeSenVxp) { // If in a clocked activation, add a link from the sensitivity to this block // Add edge logic_sensitive_vertex->logic_vertex new OrderEdge(&m_graph, m_activeSenVxp, m_logicVxp, WEIGHT_NORMAL); } nodep->user1p(m_modp); nodep->iterateChildren(*this); m_logicVxp = NULL; } } OrderVarVertex* newVarUserVertex(AstVarScope* varscp, WhichVertex type, bool* createdp=NULL) { if (!varscp->user1p()) { OrderUser* newup = new OrderUser(); m_orderUserps.push_back(newup); varscp->user1p(newup); } OrderUser* up = (OrderUser*)(varscp->user1p()); OrderVarVertex* varVxp = up->newVarUserVertex(&m_graph, m_scopep, varscp, type, createdp); return varVxp; } V3GraphEdge* findEndEdge(V3GraphVertex* vertexp, AstNode* errnodep, OrderLoopEndVertex*& evertexpr) { // Given a vertex, find the end block corresponding to it // Every vertex should have a pointer to the end block (one hopes) for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { if (OrderLoopEndVertex* evertexp = dynamic_cast(edgep->top())) { evertexpr = evertexp; return edgep; } } errnodep->v3fatalSrc("Loop-broken vertex doesn't have pointer to LoopEndVertex: "<lhsp()->castVarRef()) { if (varrefp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) { return true; } } return false; } void process(); void processCircular(); typedef deque VertexVec; void processInputs(); void processInputsInIterate(OrderEitherVertex* vertexp, VertexVec& todoVec); void processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec& todoVec); void processSensitive(); void processDomains(); void processDomainsIterate(OrderEitherVertex* vertexp); void processEdgeReport(); void processMove(); void processMoveClear(); void processMoveBuildGraph(); void processMoveBuildGraphIterate (OrderMoveVertex* moveVxp, V3GraphVertex* vertexp, int weightmin); void processMovePrepScopes(); void processMovePrepReady(); void processMoveReadyOne(OrderMoveVertex* vertexp); void processMoveDoneOne(OrderMoveVertex* vertexp); void processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* domScopep, int level); void processMoveLoopPush(OrderLoopBeginVertex* beginp); void processMoveLoopPop(OrderLoopBeginVertex* beginp); void processMoveLoopStmt(AstNode* newSubnodep); OrderLoopId processMoveLoopCurrent(); string cfuncName(AstNodeModule* modp, AstSenTree* domainp, AstScope* scopep, AstNode* forWhatp) { modp->user3Inc(); int funcnum = modp->user3(); string name = (domainp->hasCombo() ? "_combo" : (domainp->hasInitial() ? "_initial" : (domainp->hasSettle() ? "_settle" : (domainp->isMulti() ? "_multiclk" : "_sequent")))); name = name+"__"+scopep->nameDotless()+"__"+cvtToStr(funcnum); if (v3Global.opt.profileCFuncs()) { name += "__PROF__"+forWhatp->fileline()->profileFuncname(); } return name; } void nodeMarkCircular(OrderVarVertex* vertexp, OrderEdge* edgep) { AstVarScope* nodep = vertexp->varScp(); OrderLogicVertex* fromLVtxp = NULL; OrderLogicVertex* toLVtxp = NULL; if (edgep) { fromLVtxp = dynamic_cast(edgep->fromp()); toLVtxp = dynamic_cast(edgep->top()); } // if ((fromLVtxp && fromLVtxp->nodep()->castInitial()) || (toLVtxp && toLVtxp->nodep()->castInitial())) { // IEEE does not specify ordering between initial blocks, so we can do whatever we want // We especially do not want to evaluate multiple times, so do not mark the edge circular } else { nodep->circular(true); ++m_statCut[vertexp->type()]; if (edgep) ++m_statCut[edgep->type()]; // if (vertexp->isClock()) { // Seems obvious; no warning yet //nodep->v3warn(GENCLK,"Signal unoptimizable: Generated clock: "<prettyName()); } else if (nodep->varp()->isSigPublic()) { nodep->v3warn(UNOPT,"Signal unoptimizable: Feedback to public clock or circular logic: "<prettyName()); if (!nodep->fileline()->warnIsOff(V3ErrorCode::UNOPT)) { nodep->fileline()->modifyWarnOff(V3ErrorCode::UNOPT, true); // Complain just once // Give the user an example. bool tempWeight = (edgep && edgep->weight()==0); if (tempWeight) edgep->weight(1); // Else the below loop detect can't see the loop m_graph.reportLoops(&OrderEdge::followComboConnected, vertexp); // calls OrderGraph::loopsVertexCb if (tempWeight) edgep->weight(0); } } else { // We don't use UNOPT, as there are lots of V2 places where it was needed, that aren't any more // First v3warn not inside warnIsOff so we can see the suppressions with --debug nodep->v3warn(UNOPTFLAT,"Signal unoptimizable: Feedback to clock or circular logic: "<prettyName()); if (!nodep->fileline()->warnIsOff(V3ErrorCode::UNOPTFLAT)) { nodep->fileline()->modifyWarnOff(V3ErrorCode::UNOPTFLAT, true); // Complain just once // Give the user an example. bool tempWeight = (edgep && edgep->weight()==0); if (tempWeight) edgep->weight(1); // Else the below loop detect can't see the loop m_graph.reportLoops(&OrderEdge::followComboConnected, vertexp); // calls OrderGraph::loopsVertexCb if (tempWeight) edgep->weight(0); if (v3Global.opt.reportUnoptflat()) { // Report candidate variables for splitting reportLoopVars(vertexp); // Do a subgraph for the UNOPTFLAT loop OrderGraph loopGraph; m_graph.subtreeLoops(&OrderEdge::followComboConnected, vertexp, &loopGraph); loopGraph.dumpDotFilePrefixedAlways("unoptflat"); } } } } } //! Find all variables in an UNOPTFLAT loop //! //! Ignore vars that are 1-bit wide and don't worry about generated //! variables (PRE and POST vars, __Vdly__, __Vcellin__ and __VCellout). //! What remains are candidates for splitting to break loops. //! //! node->user3 is used to mark if we have done a particular variable. //! vertex->user is used to mark if we have seen this vertex before. //! //! @todo We could be cleverer in the future and consider just //! the width that is generated/consumed. void reportLoopVars(OrderVarVertex* vertexp) { m_graph.userClearVertices(); AstNode::user3ClearTree(); m_unoptflatVars.clear(); reportLoopVarsIterate (vertexp, vertexp->color()); AstNode::user3ClearTree(); m_graph.userClearVertices(); // May be very large vector, so only report the "most important" // elements. Up to 10 of the widest cerr<varScp()->varp(); cerr<fileline()<<" "<prettyName()<width()<<", fanout " <fanout()<varScp()->varp(); cerr<fileline()<<" "<prettyName() <<", width "<width() <<", fanout "<fanout()<user()) return; // Already done vertexp->user(1); if (OrderVarStdVertex* vsvertexp = dynamic_cast(vertexp)) { // Only reporting on standard variable vertices AstVar* varp = vsvertexp->varScp()->varp(); if (!varp->user3()) { string name = varp->prettyName(); if ((varp->width() != 1) && (name.find("__Vdly") == string::npos) && (name.find("__Vcell") == string::npos)) { // Variable to report on and not yet done m_unoptflatVars.push_back(vsvertexp); } varp->user3Inc(); } } // Iterate through all the to and from vertices of the same color for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { if (edgep->top()->color() == color) { reportLoopVarsIterate(edgep->top(), color); } } for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { if (edgep->fromp()->color() == color) { reportLoopVarsIterate(edgep->fromp(), color); } } } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { { AstUser4InUse m_inuser4; // Used only when building tree, so below nodep->iterateChildren(*this); } // We're finished, complete the topscopes if (m_topScopep) { process(); m_topScopep=NULL; } } virtual void visit(AstTopScope* nodep, AstNUser*) { // Process the last thing we're finishing if (m_topScopep) nodep->v3fatalSrc("Only one topscope should ever be created"); UINFO(2," Loading tree...\n"); //VV***** We reset userp() AstNode::user1ClearTree(); AstNode::user3ClearTree(); m_graph.clear(); m_activep = NULL; m_topScopep = nodep; m_scopetopp = nodep->scopep(); // Find sentree's m_finder.main(m_topScopep); // ProcessDomainsIterate will use these when it needs to move // something to a combodomain. This saves a ton of find() operations. AstSenTree* combp = new AstSenTree (nodep->fileline(), // Gets cloned() so ok if goes out of scope new AstSenItem(nodep->fileline(), AstSenItem::Combo())); m_comboDomainp = m_finder.getSenTree(nodep->fileline(), combp); pushDeletep(combp); // Cleanup when done AstSenTree* settlep = new AstSenTree (nodep->fileline(), // Gets cloned() so ok if goes out of scope new AstSenItem(nodep->fileline(), AstSenItem::Settle())); m_settleDomainp = m_finder.getSenTree(nodep->fileline(), settlep); pushDeletep(settlep); // Cleanup when done // Fake AstSenTree we set domainp to indicate needs deletion m_deleteDomainp = new AstSenTree (nodep->fileline(), new AstSenItem(nodep->fileline(), AstSenItem::Settle())); pushDeletep(m_deleteDomainp); // Cleanup when done UINFO(5," DeleteDomain = "<iterateChildren(*this); // Done topscope, erase extra user information // user1p passed to next process() operation AstNode::user3ClearTree(); AstNode::user4ClearTree(); } virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstScope* nodep, AstNUser*) { UINFO(4," SCOPE "<user1p(m_modp); // Iterate nodep->iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstActive* nodep, AstNUser*) { // Create required activation blocks and add to module UINFO(4," ACTIVE "<hasClocked(); // Grab the sensitivity list if (nodep->sensesStorep()) nodep->v3fatalSrc("Senses should have been activeTop'ed to be global!"); nodep->sensesp()->accept(*this); // Collect statements under it nodep->iterateChildren(*this); m_activep = NULL; } virtual void visit(AstVarScope* nodep, AstNUser*) { // Create links to all input signals if (m_modp->isTop() && nodep->varp()->isInput()) { OrderVarVertex* varVxp = newVarUserVertex(nodep, WV_STD); new OrderEdge(&m_graph, m_inputsVxp, varVxp, WEIGHT_INPUT); } } virtual void visit(AstNodeVarRef* nodep, AstNUser*) { if (m_scopep) { AstVarScope* varscp = nodep->varScopep(); if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n"); if (m_inSenTree) { // Add CLOCK dependency... This is a root of the tree we'll trace if (nodep->lvalue()) nodep->v3fatalSrc("How can a sensitivity be setting a var?\n"); OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD); varVxp->isClock(true); new OrderEdge(&m_graph, varVxp, m_activeSenVxp, WEIGHT_MEDIUM); } else { if (!m_logicVxp) nodep->v3fatalSrc("Var ref not under a logic block\n"); // What new directions is this used // We don't want to add extra edges if the logic block has many usages of same var bool gen = false; bool con = false; if (nodep->lvalue()) { gen = !(varscp->user4() & VU_GEN); } else { con = !(varscp->user4() & VU_CON); if ((varscp->user4() & VU_GEN) && !m_inClocked) { // Dangerous assumption: // If a variable is used in the same activation which defines it first, // consider it something like: // foo = 1 // foo = foo + 1 // and still optimize. This is the rule verilog-mode assumes for /*AS*/ // Note this will break though: // if (sometimes) foo = 1 // foo = foo + 1 con = false; } if (varscp->varp()->attrClockEn() && !m_inPre && !m_inPost && !m_inClocked) { // clock_enable attribute: user's worring about it for us con = false; } if (m_inClkAss && (varscp->varp()->attrClocker()) != AstVarAttrClocker::CLOCKER_YES) { con = false; UINFO(4, "nodep used as clock_enable "<nodep()<user4(varscp->user4() | VU_GEN); if (con) varscp->user4(varscp->user4() | VU_CON); // Add edges if (!m_inClocked || m_inPost ) { // Combo logic { // not settle and (combo or inPost) if (gen) { // Add edge logic_vertex->logic_generated_var OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD); if (m_inPost) { new OrderPostCutEdge(&m_graph, m_logicVxp, varVxp); // Mark the vertex. Used to control marking // internal clocks circular, which must only // happen if they are generated by delayed // assignment. UINFO(5, " Found delayed assignment (post) " << varVxp << endl); varVxp->isDelayed(true); } else { // If the lhs is a clocker, avoid marking that as circular by // putting a hard edge instead of normal cuttable if (varscp->varp()->attrClocker() == AstVarAttrClocker::CLOCKER_YES) new OrderEdge(&m_graph, m_logicVxp, varVxp, WEIGHT_NORMAL); else new OrderComboCutEdge(&m_graph, m_logicVxp, varVxp); } // For m_inPost: // Add edge consumed_var_POST->logic_vertex // This prevents a consumer of the "early" value to be scheduled // after we've changed to the next-cycle value // ALWAYS do it: // There maybe a wire a=b; between the two blocks OrderVarVertex* postVxp = newVarUserVertex(varscp, WV_POST); new OrderEdge(&m_graph, postVxp, m_logicVxp, WEIGHT_POST); } if (con) { // Add edge logic_consumed_var->logic_vertex OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD); new OrderEdge(&m_graph, varVxp, m_logicVxp, WEIGHT_MEDIUM); } } } else if (m_inPre) { // AstAssignPre logic if (gen) { // Add edge logic_vertex->generated_var_PREORDER OrderVarVertex* ordVxp = newVarUserVertex(varscp, WV_PORD); new OrderEdge(&m_graph, m_logicVxp, ordVxp, WEIGHT_NORMAL); // Add edge logic_vertex->logic_generated_var (same as if comb) OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD); new OrderEdge(&m_graph, m_logicVxp, varVxp, WEIGHT_NORMAL); } if (con) { // Add edge logic_consumed_var_PREVAR->logic_vertex // This one is cutable (vs the producer) as there's only one of these, but many producers OrderVarVertex* preVxp = newVarUserVertex(varscp, WV_PRE); new OrderPreCutEdge(&m_graph, preVxp, m_logicVxp); } } else { // Seq logic if (gen) { // Add edge logic_generated_var_PREORDER->logic_vertex OrderVarVertex* ordVxp = newVarUserVertex(varscp, WV_PORD); new OrderEdge(&m_graph, ordVxp, m_logicVxp, WEIGHT_NORMAL); // Add edge logic_vertex->logic_generated_var (same as if comb) OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD); new OrderEdge(&m_graph, m_logicVxp, varVxp, WEIGHT_NORMAL); } if (con) { // Add edge logic_vertex->consumed_var_PREVAR // Generation of 'pre' because we want to indicate it should be before AstAssignPre OrderVarVertex* preVxp = newVarUserVertex(varscp, WV_PRE); new OrderEdge(&m_graph, m_logicVxp, preVxp, WEIGHT_NORMAL); // Add edge logic_vertex->consumed_var_POST OrderVarVertex* postVxp = newVarUserVertex(varscp, WV_POST); new OrderEdge(&m_graph, m_logicVxp, postVxp, WEIGHT_POST); } } } } } virtual void visit(AstSenTree* nodep, AstNUser*) { // Having a node derived from the sentree isn't required for // correctness, it mearly makes the graph better connected // and improves graph algorithmic performance if (m_scopep) { // Else TOPSCOPE's SENTREE list m_inSenTree = true; if (nodep->hasClocked()) { if (!m_activeSenVxp) { m_activeSenVxp = new OrderLogicVertex(&m_graph, m_scopep, nodep, m_activep); } nodep->iterateChildren(*this); } m_inSenTree = false; } } virtual void visit(AstAlways* nodep, AstNUser*) { iterateNewStmt(nodep); } virtual void visit(AstAlwaysPost* nodep, AstNUser*) { m_inPost = true; iterateNewStmt(nodep); m_inPost = false; } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { iterateNewStmt(nodep); } virtual void visit(AstAssignAlias* nodep, AstNUser*) { iterateNewStmt(nodep); } virtual void visit(AstAssignW* nodep, AstNUser*) { OrderClkAssVisitor visitor(nodep); m_inClkAss = visitor.isClkAss(); iterateNewStmt(nodep); m_inClkAss = false; } virtual void visit(AstAssignPre* nodep, AstNUser*) { OrderClkAssVisitor visitor(nodep); m_inClkAss = visitor.isClkAss(); m_inPre = true; iterateNewStmt(nodep); m_inPre = false; m_inClkAss = false; } virtual void visit(AstAssignPost* nodep, AstNUser*) { OrderClkAssVisitor visitor(nodep); m_inClkAss = visitor.isClkAss(); m_inPost = true; iterateNewStmt(nodep); m_inPost = false; m_inClkAss = false; } virtual void visit(AstCoverToggle* nodep, AstNUser*) { iterateNewStmt(nodep); } virtual void visit(AstInitial* nodep, AstNUser*) { // We use initials to setup parameters and static consts's which may be referenced // in user initial blocks. So use ordering to sort them all out. iterateNewStmt(nodep); } virtual void visit(AstCFunc*, AstNUser*) { // Ignore for now // We should detect what variables are set in the function, and make // settlement code for them, then set a global flag, so we call "settle" // on the next evaluation loop. } //-------------------- // Default virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS OrderVisitor() { m_topScopep = NULL; m_scopetopp = NULL; m_modp = NULL; m_scopep = NULL; m_activep = NULL; m_inSenTree = false; m_inClocked = false; m_inClkAss = false; m_inPre = m_inPost = false; m_comboDomainp = NULL; m_deleteDomainp = NULL; m_settleDomainp = NULL; m_settleVxp = NULL; m_inputsVxp = NULL; m_activeSenVxp = NULL; m_logicVxp = NULL; m_pomNewFuncp = NULL; m_loopIdMax = LOOPID_FIRST; m_pomNewStmts = 0; if (debug()) m_graph.debug(5); // 3 is default if global debug; we want acyc debugging } virtual ~OrderVisitor() { // Stats for (int type=0; type::iterator it=m_orderUserps.begin(); it!=m_orderUserps.end(); ++it) { delete *it; } m_graph.debug(V3Error::debugDefault()); } void main(AstNode* nodep) { nodep->accept(*this); } }; //###################################################################### // Clock propagation void OrderVisitor::processInputs() { m_graph.userClearVertices(); // Vertex::user() // 1 if input recursed, 2 if marked as input, 3 if out-edges recursed // Start at input vertex, process from input-to-output order VertexVec todoVec; // List of newly-input marked vectors we need to process todoVec.push_front(m_inputsVxp); m_inputsVxp->isFromInput(true); // By definition while (!todoVec.empty()) { OrderEitherVertex* vertexp = todoVec.back(); todoVec.pop_back(); processInputsOutIterate(vertexp, todoVec); } } void OrderVisitor::processInputsInIterate(OrderEitherVertex* vertexp, VertexVec& todoVec) { // Propagate PrimaryIn through simple assignments if (vertexp->user()) return; // Already processed if (0 && debug()>=9) { UINFO(9," InIIter "<(vertexp)) { vvertexp->nodep()->dumpTree(cout,"- TT: "); } } vertexp->user(1); // Processing // First handle all inputs to this vertex, in most cases they'll be already processed earlier // Also, determine if this vertex is an input int inonly = 1; // 0=no, 1=maybe, 2=yes until a no for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { OrderEitherVertex* frVertexp = (OrderEitherVertex*)edgep->fromp(); processInputsInIterate(frVertexp, todoVec); if (frVertexp->isFromInput()) { if (inonly==1) inonly = 2; } else if (dynamic_cast(frVertexp)) { // Ignore post assignments, just for ordering } else { //UINFO(9," InItStopDueTo "<user()<2) { // Set it. Note may have already been set earlier, too UINFO(9," Input reassignment: "<isFromInput(true); vertexp->user(2); // 2 means on list // Can't work on out-edges of a node we know is an input immediately, // as it might visit other nodes before their input state is resolved. // So push to list and work on it later when all in-edges known resolved todoVec.push_back(vertexp); } //UINFO(9," InIdone "<user()==3) return; // Already out processed //UINFO(9," InOIter "<isFromInput()) v3fatalSrc("processInputsOutIterate only for input marked vertexes"); vertexp->user(3); // out-edges processed { // Propagate PrimaryIn through simple assignments, followint target of vertex for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { OrderEitherVertex* toVertexp = (OrderEitherVertex*)edgep->top(); if (OrderVarStdVertex* vvertexp = dynamic_cast(toVertexp)) { processInputsInIterate(vvertexp, todoVec); } if (OrderLogicVertex* vvertexp = dynamic_cast(toVertexp)) { if (vvertexp->nodep()->castNodeAssign()) { processInputsInIterate(vvertexp, todoVec); } } } } } //###################################################################### // Circular detection void OrderVisitor::processCircular() { // Take broken edges and add circular flags // The change detect code will use this to force changedets for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (OrderVarStdVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->isClock() && !vvertexp->isFromInput()) { // If a clock is generated internally, we need to do another // loop through the entire evaluation. This fixes races; see // t_clk_dpulse test. // // This all seems to hinge on how the clock is generated. If // it is generated by delayed assignment, we need the loop. If // it is combinatorial, we do not (and indeed it will break // other tests such as t_gated_clk_1. if (!v3Global.opt.orderClockDly()) { UINFO(5,"Circular Clock, no-order-clock-delay "<isDelayed()) { UINFO(5,"Circular Clock, delayed "<outBeginp(); edgep; edgep=edgep->outNextp()) { if (edgep->weight()==0) { // was cut OrderEdge* oedgep = dynamic_cast(edgep); if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type"); UINFO(6," CutCircularO: "<name()<inBeginp(); edgep; edgep = edgep->inNextp()) { if (edgep->weight()==0) { // was cut OrderEdge* oedgep = dynamic_cast(edgep); if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type"); UINFO(6," CutCircularI: "<name()<verticesNextp()) { if (OrderVarStdVertex* vvertexp = dynamic_cast(itp)) { if (vvertexp->varScp()->varp()->isInput()) { //UINFO(0," scsen "<outBeginp(); edgep; edgep=edgep->outNextp()) { if (OrderEitherVertex* toVertexp = dynamic_cast(edgep->top())) { if (edgep->weight() && toVertexp->domainp()) { //UINFO(0," "<domainp()<domainp()->hasCombo()) { vvertexp->varScp()->varp()->scSensitive(true); } } } } } } } } void OrderVisitor::processDomains() { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { OrderEitherVertex* vertexp = dynamic_cast(itp); UASSERT(vertexp, "Null or vertex not derived from EitherVertex\n"); processDomainsIterate(vertexp); } } void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) { // The graph routines have already sorted the vertexes and edges into best->worst order // Assign clock domains to each signal. // Sequential logic is forced into the same sequential domain. // Combo logic may be pushed into a seq domain if all its inputs are the same domain, // else, if all inputs are from flops, it's end-of-sequential code // else, it's full combo code if (!vertexp->inLoop()) vertexp->inLoop(LOOPID_NOTLOOPED); if (vertexp->domainp()) return; // Already processed, or sequential logic UINFO(5," pdi: "<(vertexp); AstSenTree* domainp = NULL; UASSERT(m_comboDomainp, "not preset"); if (vvertexp && vvertexp->varScp()->varp()->isInput()) { domainp = m_comboDomainp; } if (vvertexp && vvertexp->varScp()->isCircular()) { domainp = m_comboDomainp; } if (!domainp) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { OrderEitherVertex* fromVertexp = (OrderEitherVertex*)edgep->fromp(); if (edgep->weight() && fromVertexp->domainMatters() ) { UINFO(9," from d="<<(void*)fromVertexp->domainp()<<" "<hasSettle() // or, we can ignore being in the settle domain || domainp->hasInitial()) { domainp = fromVertexp->domainp(); } else if (domainp->hasCombo()) { // Once in combo, keep in combo; already as severe as we can get } else if (fromVertexp->domainp()->hasCombo()) { // Any combo input means this vertex must remain combo domainp = m_comboDomainp; } else if (fromVertexp->domainp()->hasSettle() || fromVertexp->domainp()->hasInitial()) { // Ignore that we have a constant (initial) input } else if (domainp != fromVertexp->domainp()) { // Make a domain that merges the two domains bool ddebug = debug()>=9; if (ddebug) { cout<addSensesp(newtree2p); newtree2p=NULL; // Below edit may replace it V3Const::constifyExpensiveEdit(newtreep); // Remove duplicates newtreep->multi(true); // Comment that it was made from 2 clock domains domainp = m_finder.getSenTree(domainp->fileline(), newtreep); if (ddebug) { UINFO(0," dnew ="<dumpTree(cout); UINFO(0," find ="<dumpTree(cout); cout<deleteTree(); newtreep=NULL; } } } // next input edgep // Default the domain // This is a node which has only constant inputs, or is otherwise indeterminate. // It should have already been copied into the settle domain. Presumably it has // inputs which we never trigger, or nothing it's sensitive to, so we can rip it out. if (!domainp && vertexp->scopep()) { domainp = m_deleteDomainp; } } // vertexp->domainp(domainp); if (vertexp->domainp()) { UINFO(5," done d="<<(void*)vertexp->domainp() <<(vertexp->domainp()->hasCombo()?" [COMB]":"") <<(vertexp->domainp()->isMulti()?" [MULT]":"") <<" "< logp (V3File::new_ofstream(filename)); if (logp->fail()) v3fatalSrc("Can't write "< report; for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (OrderVarVertex* vvertexp = dynamic_cast(itp)) { string name (vvertexp->varScp()->prettyName()); if (dynamic_cast(itp)) name += " {PRE}"; else if (dynamic_cast(itp)) name += " {POST}"; else if (dynamic_cast(itp)) name += " {PORD}"; else if (dynamic_cast(itp)) name += " {STL}"; ostringstream os; os.setf(ios::left); os<<" "<<(void*)(vvertexp->varScp())<<" "<domainp(); if (sentreep) V3EmitV::verilogForTree(sentreep, os); report.push_back(os.str()); } } *logp<<"Signals and their clock domains:"<::iterator it=report.begin(); it!=report.end(); ++it) { *logp<<(*it)<verticesNextp()) { if (OrderLogicVertex* lvertexp = dynamic_cast(itp)) { OrderMoveVertex* moveVxp = new OrderMoveVertex(&m_pomGraph, lvertexp); moveVxp->m_pomWaitingE.pushBack(m_pomWaiting, moveVxp); // Cross link so we can find it later lvertexp->moveVxp(moveVxp); } } // Build edges between logic vertices for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (OrderLogicVertex* lvertexp = dynamic_cast(itp)) { OrderMoveVertex* moveVxp = lvertexp->moveVxp(); processMoveBuildGraphIterate(moveVxp, lvertexp, 0); } } } void OrderVisitor::processMoveBuildGraphIterate (OrderMoveVertex* moveVxp, V3GraphVertex* vertexp, int weightmin) { // Search forward from given logic vertex, making new edges based on moveVxp for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (edgep->weight()!=0) { // was cut int weight = weightmin; if (weight==0 || weight>edgep->weight()) weight=edgep->weight(); if (OrderLogicVertex* toLVertexp = dynamic_cast(edgep->top())) { // Path from vertexp to a logic vertex; new edge // Note we use the last edge's weight, not some function of multiple edges new OrderEdge(&m_pomGraph, moveVxp, toLVertexp->moveVxp(), weight); } else { // Keep hunting forward for a logic node processMoveBuildGraphIterate(moveVxp, edgep->top(), weight); } } } } //###################################################################### // Moving void OrderVisitor::processMove() { // The graph routines have already sorted the vertexes and edges into best->worst order // Make a new waiting graph with only OrderLogicVertex's // (Order is preserved in the recreation so the sorting is preserved) // Move any node with all inputs ready to a "ready" graph mapped by domain and then scope // While waiting graph ! empty (and also known: something in ready graph) // For all scopes in domain of top ready vertex // For all vertexes in domain&scope of top ready vertex // Make ordered activation block for this module // Add that new activation to the list of calls to make. // Move logic to ordered active // Any children that have all inputs now ready move from waiting->ready graph // (This may add nodes the for loop directly above needs to detext) processMovePrepScopes(); processMovePrepReady(); // New domain... another loop UINFO(5," MoveIterate\n"); while (!m_pomReadyDomScope.empty()) { // Start with top node on ready list's domain & scope OrderMoveDomScope* domScopep = m_pomReadyDomScope.begin(); OrderMoveVertex* topVertexp = domScopep->readyVertices().begin(); // lintok-begin-on-ref UASSERT(topVertexp, "domScope on ready list without any nodes ready under it"); // Work on all scopes ready inside this domain while (domScopep) { UINFO(6," MoveDomain l="<domainp()<readyVertices().begin()) { // lintok-begin-on-ref processMoveOne(vertexp, domScopep, 1); } // Done with scope/domain pair, pick new scope under same domain, or NULL if none left OrderMoveDomScope* domScopeNextp = NULL; for (OrderMoveDomScope* huntp = m_pomReadyDomScope.begin(); huntp; huntp = huntp->readyDomScopeNextp()) { if (huntp->domainp() == domScopep->domainp()) { domScopeNextp = huntp; break; } } domScopep = domScopeNextp; } } UASSERT (m_pomWaiting.empty(), "Didn't converge; nodes waiting, none ready, perhaps some input activations lost."); // Cleanup memory processMoveClear(); } void OrderVisitor::processMovePrepScopes() { UINFO(5," MovePrepScopes\n"); // Create a OrderMoveDomScope every domain/scope pairing for (OrderMoveVertex* vertexp = m_pomWaiting.begin(); vertexp; vertexp=vertexp->pomWaitingNextp()) { AstSenTree* domainp = vertexp->logicp()->domainp(); AstScope* scopep = vertexp->logicp()->scopep(); OrderLoopId inLoop = vertexp->logicp()->inLoop(); // Create the dom pairing for later lookup OrderMoveDomScope* domScopep = OrderMoveDomScope::findCreate(inLoop, domainp, scopep); vertexp->domScopep(domScopep); } } void OrderVisitor::processMovePrepReady() { // Make list of ready nodes UINFO(5," MovePrepReady\n"); for (OrderMoveVertex* vertexp = m_pomWaiting.begin(); vertexp; ) { OrderMoveVertex* nextp = vertexp->pomWaitingNextp(); if (vertexp->isWait() && vertexp->inEmpty()) { processMoveReadyOne(vertexp); } vertexp = nextp; } } void OrderVisitor::processMoveReadyOne(OrderMoveVertex* vertexp) { // Recursive! // Move one node from waiting to ready list vertexp->setReady(); // Remove node from waiting list vertexp->m_pomWaitingE.unlink(m_pomWaiting, vertexp); // Add to ready list (indexed by domain and scope) vertexp->m_readyVerticesE.pushBack(vertexp->domScopep()->m_readyVertices, vertexp); vertexp->domScopep()->ready (this); } void OrderVisitor::processMoveDoneOne(OrderMoveVertex* vertexp) { // Move one node from ready to completion vertexp->setMoved(); // Unlink from ready lists vertexp->m_readyVerticesE.unlink(vertexp->domScopep()->m_readyVertices, vertexp); vertexp->domScopep()->movedVertex (this, vertexp); // Don't need to add it to another list, as we're done with it // Mark our outputs as one closer to ready for (V3GraphEdge* edgep = vertexp->outBeginp(), *nextp; edgep; edgep=nextp) { nextp = edgep->outNextp(); OrderMoveVertex* toVertexp = (OrderMoveVertex*)edgep->top(); UINFO(9," Clear to "<<(toVertexp->inEmpty()?"[EMP] ":" ") <unlinkDelete(); edgep=NULL; if (toVertexp->inEmpty()) { // If destination node now has all inputs resolved; recurse to move that vertex // This is thus depth first (before width) which keeps the resulting executable's d-cache happy. processMoveReadyOne(toVertexp); } } } void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* domScopep, int level) { UASSERT(vertexp->domScopep() == domScopep, "Domain mismatch; list misbuilt?\n"); OrderLogicVertex* lvertexp = vertexp->logicp(); AstScope* scopep = lvertexp->scopep(); UINFO(5," POSmove l"<domainp(); AstNode* nodep = lvertexp->nodep(); AstNodeModule* modp = scopep->user1p()->castNode()->castNodeModule(); UASSERT(modp,"NULL"); // Stashed by visitor func if (nodep->castUntilStable()) { nodep->v3fatalSrc("Not implemented"); } else if (nodep->castSenTree()) { // Just ignore sensitivities, we'll deal with them when we move statements that need them } else { // Normal logic // Make or borrow a CFunc to contain the new statements if (v3Global.opt.profileCFuncs() || (v3Global.opt.outputSplitCFuncs() && v3Global.opt.outputSplitCFuncs() < m_pomNewStmts)) { // Put every statement into a unique function to ease profiling or reduce function size m_pomNewFuncp = NULL; } if (!m_pomNewFuncp && domainp != m_deleteDomainp) { string name = cfuncName(modp, domainp, scopep, nodep); m_pomNewFuncp = new AstCFunc(nodep->fileline(), name, scopep); m_pomNewFuncp->argTypes(EmitCBaseVisitor::symClassVar()); m_pomNewFuncp->symProlog(true); m_pomNewStmts = 0; if (domainp->hasInitial() || domainp->hasSettle()) m_pomNewFuncp->slow(true); scopep->addActivep(m_pomNewFuncp); // Where will we be adding the call? AstActive* callunderp = new AstActive(nodep->fileline(), name, domainp); processMoveLoopStmt(callunderp); // Add a top call to it AstCCall* callp = new AstCCall(nodep->fileline(), m_pomNewFuncp); callp->argTypes("vlSymsp"); callunderp->addStmtsp(callp); UINFO(6," New "<unlinkFrBack(); if (domainp == m_deleteDomainp) { UINFO(4," Ordering deleting pre-settled "<addStmtsp(nodep); if (v3Global.opt.outputSplitCFuncs()) { // Add in the number of nodes we're adding EmitCBaseCounterVisitor visitor(nodep); m_pomNewStmts += visitor.count(); } } } processMoveDoneOne (vertexp); } inline void OrderVisitor::processMoveLoopPush(OrderLoopBeginVertex* beginp) { UINFO(6," LoopPush "<nodep()->v3fatalSrc("processMoveLoopPop with no push'ed loops"); OrderLoopBeginVertex* topBeginp = m_pomLoopMoveps.back(); if (topBeginp != beginp) beginp->nodep()->v3fatalSrc("processMoveLoopPop had different vertex then one expected, got="<m_pomReadyDomScope, this); } } inline void OrderMoveDomScope::movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp) { // Mark one vertex as finished, remove from ready list if done UASSERT(m_onReadyList, "Moving vertex from ready when nothing was on que as ready."); if (m_readyVertices.empty()) { // Else more work to get to later m_onReadyList = false; m_readyDomScopeE.unlink(ovp->m_pomReadyDomScope, this); } } //###################################################################### // Top processing void OrderVisitor::process() { // Dump data m_graph.dumpDotFilePrefixed("orderg_pre"); // Break cycles. Each strongly connected subgraph (including cutable // edges) will have its own color, and corresponds to a loop in the // original graph. However the new graph will be acyclic (the removed // edges are actually still there, just with weight 0). UINFO(2," Acyclic & Order...\n"); m_graph.acyclic(&V3GraphEdge::followAlwaysTrue); m_graph.dumpDotFilePrefixed("orderg_acyc"); // Assign ranks so we know what to follow // Then, sort vertices and edges by that ordering m_graph.order(); m_graph.dumpDotFilePrefixed("orderg_order"); // This finds everything that can be traced from an input (which by // definition are the source clocks). After this any vertex which was // traced has isFromInput() true. UINFO(2," Process Clocks...\n"); processInputs(); // must be before processCircular UINFO(2," Process Circulars...\n"); processCircular(); // must be before processDomains // Assign logic verticesto new domains UINFO(2," Domains...\n"); processDomains(); m_graph.dumpDotFilePrefixed("orderg_domain"); if (debug() && v3Global.opt.dumpTree()) processEdgeReport(); UINFO(2," Construct Move Graph...\n"); processMoveBuildGraph(); if (debug()>=4) m_pomGraph.dumpDotFilePrefixed("ordermv_start"); // Different prefix (ordermv) as it's not the same graph m_pomGraph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); m_pomGraph.dumpDotFilePrefixed("ordermv_simpl"); UINFO(2," Move...\n"); processMove(); // Any SC inputs feeding a combo domain must be marked, so we can make them sc_sensitive UINFO(2," Sensitive...\n"); processSensitive(); // must be after processDomains // Dump data m_graph.dumpDotFilePrefixed("orderg_done"); if (0 && debug()) { string dfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_INT_order.tree"; const auto_ptr logp (V3File::new_ofstream(dfilename)); if (logp->fail()) v3fatalSrc("Can't write "<= 3); } verilator-3.874/src/V3EmitXml.h0000664000177100017500000000221312525171733016257 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit XML code // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EMITXML_H_ #define _V3EMITXML_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3EmitXml { public: static void emitxml(); }; #endif // Guard verilator-3.874/src/V3Life.h0000664000177100017500000000223412525171733015562 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Variable life analysis // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LIFE_H_ #define _V3LIFE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Life { public: static void lifeAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3AssertPre.cpp0000664000177100017500000001055412525171733017152 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Collect and print statistics // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // Pre steps: // Attach clocks to each assertion //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3AssertPre.h" #include "V3Ast.h" //###################################################################### // Assert class functions class AssertPreVisitor : public AstNVisitor { // Removes clocks and other pre-optimizations // Eventually inlines calls to sequences, properties, etc. // We're not parsing the tree, or anything more complicated. private: // NODE STATE/TYPES // STATE // Reset each module: AstNodeSenItem* m_seniDefaultp; // Default sensitivity (from AstDefClock) // Reset each assertion: AstNodeSenItem* m_senip; // Last sensitivity // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } AstSenTree* newSenTree(AstNode* nodep) { // Create sentree based on clocked or default clock // Return NULL for always AstSenTree* newp = NULL; AstNodeSenItem* senip = m_senip ? m_senip : m_seniDefaultp; if (!senip) { nodep->v3error("Unsupported: Unclocked assertion"); newp = new AstSenTree(nodep->fileline(), NULL); } else { newp = new AstSenTree(nodep->fileline(), senip->cloneTree(true)); } return newp; } void clearAssertInfo() { m_senip = NULL; } // VISITORS //========== Statements virtual void visit(AstClocking* nodep, AstNUser*) { UINFO(8," CLOCKING"<sensesp(); // Trash it, keeping children if (nodep->bodysp()) { nodep->replaceWith(nodep->bodysp()->unlinkFrBack()); } else { nodep->unlinkFrBack(); } pushDeletep(nodep); nodep=NULL; } virtual void visit(AstPslCover* nodep, AstNUser*) { if (nodep->sentreep()) return; // Already processed clearAssertInfo(); nodep->iterateChildren(*this); nodep->sentreep(newSenTree(nodep)); clearAssertInfo(); } virtual void visit(AstPslClocked* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_senip) { nodep->v3error("Unsupported: Only one PSL clock allowed per assertion"); } // Block is the new expression to evaluate AstNode* blockp = nodep->propp()->unlinkFrBack(); if (nodep->disablep()) { blockp = new AstAnd(nodep->disablep()->fileline(), new AstNot(nodep->disablep()->fileline(), nodep->disablep()->unlinkFrBack()), blockp); } // Unlink and just keep a pointer to it, convert to sentree as needed m_senip = nodep->sensesp(); nodep->replaceWith(blockp); pushDeletep(nodep); nodep=NULL; } virtual void visit(AstNodeModule* nodep, AstNUser*) { nodep->iterateChildren(*this); // Reset defaults m_seniDefaultp = NULL; } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS AssertPreVisitor(AstNetlist* nodep) { m_seniDefaultp = NULL; clearAssertInfo(); // Process nodep->accept(*this); } virtual ~AssertPreVisitor() {} }; //###################################################################### // Top Assert class void V3AssertPre::assertPreAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3LanguageWords.h0000664000177100017500000001073512525171733017452 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Language rules // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LANGUAGEWORDS_H_ #define _V3LANGUAGEWORDS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include //============================================================================ class V3LanguageWords { // List of common reserved keywords private: map m_kwdMap; // List of keywords, and what language applies void addKwd(const string& kwd, const string& why) { m_kwdMap.insert(make_pair(kwd,why)); } public: string isKeyword(const string& kwd) { map::iterator it = m_kwdMap.find(kwd); if (it == m_kwdMap.end()) return ""; return it->second; } public: V3LanguageWords() { // C++ keywords addKwd("asm", "C++ reserved word"); addKwd("auto", "C++ reserved word"); addKwd("catch", "C++ reserved word"); addKwd("cdecl", "C++ reserved word"); addKwd("char", "C++ reserved word"); addKwd("const_cast", "C++ reserved word"); addKwd("delete", "C++ reserved word"); addKwd("double", "C++ reserved word"); addKwd("dynamic_cast", "C++ reserved word"); addKwd("explicit", "C++ reserved word"); addKwd("far", "C++ reserved word"); addKwd("float", "C++ reserved word"); addKwd("friend", "C++ reserved word"); addKwd("goto", "C++ reserved word"); addKwd("huge", "C++ reserved word"); addKwd("inline", "C++ reserved word"); addKwd("interrupt", "C++ reserved word"); addKwd("long", "C++ reserved word"); addKwd("mutable", "C++ reserved word"); addKwd("near", "C++ reserved word"); addKwd("operator", "C++ reserved word"); addKwd("pascal", "C++ reserved word"); addKwd("private", "C++ reserved word"); addKwd("public", "C++ reserved word"); addKwd("register", "C++ reserved word"); addKwd("reinterpret_cast ", "C++ reserved word"); addKwd("restrict", "C++ reserved word"); addKwd("short", "C++ reserved word"); addKwd("sizeof", "C++ reserved word"); addKwd("static_cast", "C++ reserved word"); addKwd("switch", "C++ reserved word"); addKwd("template", "C++ reserved word"); addKwd("throw", "C++ reserved word"); addKwd("try", "C++ reserved word"); addKwd("typeid", "C++ reserved word"); addKwd("typename", "C++ reserved word"); addKwd("unsigned", "C++ reserved word"); addKwd("using", "C++ reserved word"); addKwd("volatile", "C++ reserved word"); // C++ addKwd("NULL", "C++ common word"); addKwd("abort", "C++ common word"); addKwd("bit_vector", "C++ common word"); addKwd("bool", "C++ common word"); addKwd("complex", "C++ common word"); addKwd("const_iterator", "C++ common word"); addKwd("const_reference ", "C++ common word"); addKwd("deque", "C++ common word"); addKwd("false", "C++ common word"); addKwd("iterator", "C++ common word"); addKwd("list", "C++ common word"); addKwd("map", "C++ common word"); addKwd("multimap", "C++ common word"); addKwd("multiset", "C++ common word"); addKwd("queue", "C++ common word"); addKwd("reference", "C++ common word"); addKwd("set", "C++ common word"); addKwd("stack", "C++ common word"); addKwd("true", "C++ common word"); addKwd("type_info", "C++ common word"); addKwd("uint16_t", "C++ common word"); addKwd("uint32_t", "C++ common word"); addKwd("uint8_t", "C++ common word"); addKwd("vector", "C++ common word"); // SystemC addKwd("sc_clock", "SystemC common word"); addKwd("sc_in", "SystemC common word"); addKwd("sc_inout", "SystemC common word"); addKwd("sc_out", "SystemC common word"); addKwd("sc_signal", "SystemC common word"); addKwd("sensitive", "SystemC common word"); addKwd("sensitive_neg", "SystemC common word"); addKwd("sensitive_pos", "SystemC common word"); } }; #endif // Guard verilator-3.874/src/V3Graph.cpp0000664000177100017500000002753112525171733016306 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph optimizations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3File.h" #include "V3Graph.h" int V3Graph::s_debug = 0; int V3Graph::debug() { return max(V3Error::debugDefault(), s_debug); } //###################################################################### //###################################################################### // Vertices V3GraphVertex::V3GraphVertex(V3Graph* graphp, const V3GraphVertex& old) : m_fanout(old.m_fanout), m_color(old.m_color), m_rank(old.m_rank) { m_userp = NULL; verticesPushBack(graphp); } V3GraphVertex::V3GraphVertex(V3Graph* graphp) : m_fanout(0), m_color(0), m_rank(0) { m_userp = NULL; verticesPushBack(graphp); } void V3GraphVertex::verticesPushBack(V3Graph* graphp) { m_vertices.pushBack(graphp->m_vertices, this); } void V3GraphVertex::unlinkEdges(V3Graph* graphp) { for (V3GraphEdge* edgep = outBeginp(); edgep; /*BELOW*/) { V3GraphEdge* nextp = edgep->outNextp(); edgep->unlinkDelete(); edgep = nextp; } for (V3GraphEdge* edgep = inBeginp(); edgep; /*BELOW*/) { V3GraphEdge* nextp = edgep->inNextp(); edgep->unlinkDelete(); edgep = nextp; } } void V3GraphVertex::unlinkDelete(V3Graph* graphp) { // Delete edges unlinkEdges(graphp); // Unlink from vertex list m_vertices.unlink(graphp->m_vertices, this); // Delete delete this; //this=NULL; } void V3GraphVertex::rerouteEdges(V3Graph* graphp) { // Make new edges for each from/to pair for (V3GraphEdge* iedgep = inBeginp(); iedgep; iedgep=iedgep->inNextp()) { for (V3GraphEdge* oedgep = outBeginp(); oedgep; oedgep=oedgep->outNextp()) { new V3GraphEdge (graphp, iedgep->fromp(), oedgep->top(), min(iedgep->weight(),oedgep->weight()), iedgep->cutable() && oedgep->cutable()); } } // Remove old edges unlinkEdges(graphp); } bool V3GraphVertex::inSize1() const { return !inEmpty() && inBeginp()->inNextp()==NULL; } bool V3GraphVertex::outSize1() const { return !outEmpty() && outBeginp()->outNextp()==NULL; } uint32_t V3GraphVertex::inHash() const { // We want the same hash ignoring the order of edges. // So we need an associative operator, like XOR. // However with XOR multiple edges to the same source will cancel out, // so we use ADD. (Generally call this only after removing duplicates though) uint32_t hash=0; for (V3GraphEdge* edgep = this->inBeginp(); edgep; edgep=edgep->inNextp()) { hash += cvtToHash(edgep->fromp()); } return hash; } uint32_t V3GraphVertex::outHash() const { uint32_t hash=0; for (V3GraphEdge* edgep = this->outBeginp(); edgep; edgep=edgep->outNextp()) { hash += cvtToHash(edgep->top()); } return hash; } ostream& operator<<(ostream& os, V3GraphVertex* vertexp) { os<<" VERTEX="<name(); if (vertexp->rank()) os<<" r"<rank(); if (vertexp->fanout()) os<<" f"<fanout(); if (vertexp->color()) os<<" c"<color(); return os; } //###################################################################### //###################################################################### // Edges void V3GraphEdge::init(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable) { UASSERT(fromp, "Null from pointer\n"); UASSERT(top, "Null to pointer\n"); m_fromp = fromp; m_top = top; m_weight = weight; m_cutable = cutable; m_userp = NULL; // Link vertices to this edge outPushBack(); inPushBack(); } V3GraphEdge* V3GraphEdge::relinkFromp(V3GraphVertex* newFromp) { V3GraphEdge *oldNxt = outNextp(); m_outs.unlink(m_fromp->m_outs, this); m_fromp = newFromp; outPushBack(); return oldNxt; } void V3GraphEdge::unlinkDelete() { // Unlink from side m_outs.unlink(m_fromp->m_outs, this); // Unlink to side m_ins.unlink(m_top->m_ins, this); // Delete delete this; //this=NULL; } void V3GraphEdge::outPushBack() { // m_fromp->m_outsp.push_back(this); m_outs.pushBack(m_fromp->m_outs, this); } void V3GraphEdge::inPushBack() { // m_top->m_insp.push_back(this); m_ins.pushBack(m_top->m_ins, this); } //###################################################################### //###################################################################### // Graph top level // Constructors V3Graph::V3Graph() { // Anything here is probably needed in clear() also verticesUnlink(); } V3Graph::~V3Graph() { clear(); } void V3Graph::clear() { // Empty it of all points, as if making a new object // Delete the old edges for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; /*BELOW*/) { V3GraphEdge* nextp = edgep->outNextp(); delete edgep; edgep = nextp; } vertexp->outUnlink(); } // Delete the old vertices for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; /*BELOW*/) { V3GraphVertex* nextp = vertexp->verticesNextp(); delete vertexp; vertexp = nextp; } verticesUnlink(); } void V3Graph::userClearVertices() { // Clear user() in all of tree // We may use the userCnt trick in V3Ast later... (but gblCnt would be // in V3Graph instead of static - which has the complication of finding // the graph pointer given a vertex.) For now we don't call this often, and // the extra code on each read of user() would probably slow things // down more than help. for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertexp->user(0); vertexp->userp(NULL); // Its a union, but might be different size than user() } } void V3Graph::userClearEdges() { // Clear user() in all of tree for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { edgep->user(0); edgep->userp(NULL); // Its a union, but might be different size than user() } } } void V3Graph::clearColors() { // Reset colors for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertexp->m_color = 0; } } //====================================================================== // Dumping void V3Graph::loopsVertexCb(V3GraphVertex* vertexp) { // Needed here as V3GraphVertex<< isn't defined until later in header cerr<<"-Info-Loop: "<<(void*)(vertexp)<<" "<verticesNextp()) { os<<"\tNode: "<name(); if (vertexp->color()) os<<" color="<color(); os<inBeginp(); edgep; edgep=edgep->inNextp()) { dumpEdge (os, vertexp, edgep); } for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { dumpEdge (os, vertexp, edgep); } } } void V3Graph::dumpEdge(ostream& os, V3GraphVertex* vertexp, V3GraphEdge* edgep) { if (edgep->weight() && (edgep->fromp() == vertexp || edgep->top() == vertexp)) { os<<"\t\t"; if (edgep->fromp() == vertexp) os << "-> "<top()->name(); if (edgep->top() == vertexp) os << "<- "<fromp()->name(); if (edgep->cutable()) os<<" [CUTABLE]"; os< logp (V3File::new_ofstream(filename)); if (logp->fail()) v3fatalSrc("Can't write "< SubgraphMmap; SubgraphMmap subgraphs; for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { string vertexSubgraph = (colorAsSubgraph && vertexp->color()) ? cvtToStr(vertexp->color()) : ""; subgraphs.insert(make_pair(vertexSubgraph, vertexp)); } // We use a map here, as we don't want to corrupt anything (userp) in the graph, // and we don't care if this is slow. map numMap; // Print vertices int n=0; string subgr; for (SubgraphMmap::iterator it = subgraphs.begin(); it!=subgraphs.end(); ++it) { string vertexSubgraph = it->first; V3GraphVertex* vertexp = it->second; numMap[vertexp] = n; if (subgr != vertexSubgraph) { if (subgr!="") *logp<<"\t};\n"; subgr = vertexSubgraph; if (subgr!="") *logp<<"\tsubgraph cluster_"<dotName()<<(n++) <<"\t[fontsize=8 " <<"label=\""<<(vertexp->name()!="" ? vertexp->name() : "\\N"); if (vertexp->rank()) *logp<<" r"<rank(); if (vertexp->fanout()) *logp<<" f"<fanout(); if (vertexp->color()) *logp<<"\\n c"<color(); *logp<<"\""; *logp<<", color="<dotColor(); if (vertexp->dotStyle()!="") *logp<<", style="<dotStyle(); if (vertexp->dotShape()!="") *logp<<", shape="<dotShape(); *logp<<"];\n"; } if (subgr!="") *logp<<"\t};\n"; // Print edges for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (edgep->weight()) { int fromVnum = numMap[edgep->fromp()]; int toVnum = numMap[edgep->top()]; *logp<<"\tn"<fromp()->dotName()< n"<top()->dotName()<name()!="" ? edgep->name() : "\\E")<<"\"" <<"fontsize=8 label=\""<<(edgep->dotLabel()!="" ? edgep->dotLabel() : "")<<"\"" <<" weight="<weight() <<" color="<dotColor(); if (edgep->dotStyle()!="") *logp<<" style="<dotStyle(); //if (edgep->cutable()) { *logp<<",constraint=false"; } // to rank without following edges *logp<<"];\n"; } } } // Vertex::m_user end, now unused // Trailer *logp << "}\n"; logp->close(); cout << "dot -Tpdf -o ~/a.pdf "< #include #include //###################################################################### // VlcOptions void VlcOptions::addReadFile(const string& filename) { if (m_readFiles.find(filename) == m_readFiles.end()) { m_readFiles.insert(filename); } } string VlcOptions::version() { string ver = DTVERSION; ver += " rev "+cvtToStr(DTVERSION_rev); return ver; } bool VlcOptions::onoff(const char* sw, const char* arg, bool& flag) { // if sw==arg, then return true (found it), and flag=true // if sw=="-no-arg", then return true (found it), and flag=false // if sw=="-noarg", then return true (found it), and flag=false // else return false if (arg[0]!='-') v3fatalSrc("OnOff switches must have leading dash.\n"); if (0==strcmp(sw,arg)) { flag=true; return true; } else if (0==strncmp(sw,"-no",3) && (0==strcmp(sw+3,arg+1))) { flag=false; return true; } else if (0==strncmp(sw,"-no-",4) && (0==strcmp(sw+4,arg+1))) { flag=false; return true; } return false; } void VlcOptions::parseOptsList(int argc, char** argv) { // Parse parameters // Note argc and argv DO NOT INCLUDE the filename in [0]!!! // May be called recursively when there are -f files. #define shift { ++i; } for (int i=0; i= 9) { top.tests().dump(true); top.points().dump(); } V3Error::abortIfWarnings(); if (top.opt.annotateOut() != "") { top.annotate(top.opt.annotateOut()); } if (top.opt.rank()) { top.rank(); top.tests().dump(false); } if (top.opt.writeFile() != "") { top.writeCoverage(top.opt.writeFile()); V3Error::abortIfWarnings(); if (top.opt.unlink()) { const VlStringSet& readFiles = top.opt.readFiles(); for (VlStringSet::iterator it = readFiles.begin(); it != readFiles.end(); ++it) { string filename = *it; unlink(filename.c_str()); } } } // Final writing shouldn't throw warnings, but... V3Error::abortIfWarnings(); UINFO(1,"Done, Exiting...\n"); } // Local Variables: // compile-command: "v4make bin/verilator_coverage --debugi 9 test_regress/t/t_vlcov_data_*.dat" // End: verilator-3.874/src/V3Options.h0000664000177100017500000003726312525172036016345 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Command line options // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3OPTIONS_H_ #define _V3OPTIONS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3LangCode.h" //###################################################################### // V3Options - Command line options class V3OptionsImp; class FileLine; struct stat; typedef vector V3StringList; typedef set V3StringSet; class V3Options { // TYPES typedef map DebugSrcMap; // MEMBERS (general options) V3OptionsImp* m_impp; // Slow hidden options V3StringSet m_cppFiles; // argument: C++ files to link against V3StringSet m_cFlags; // argument: user CFLAGS V3StringSet m_ldLibs; // argument: user LDFLAGS V3StringSet m_futures; // argument: -Wfuture- list V3StringSet m_libraryFiles; // argument: Verilog -v files V3StringSet m_clockers; // argument: Verilog -clk signals V3StringSet m_noClockers; // argument: Verilog -noclk signals V3StringList m_vFiles; // argument: Verilog files to read DebugSrcMap m_debugSrcs; // argument: --debugi-= DebugSrcMap m_dumpTrees; // argument: --dump-treei-= bool m_preprocOnly; // main switch: -E bool m_makeDepend; // main switch: -MMD bool m_makePhony; // main switch: -MP bool m_preprocNoLine;// main switch: -P bool m_assert; // main switch: --assert bool m_autoflush; // main switch: --autoflush bool m_bboxSys; // main switch: --bbox-sys bool m_bboxUnsup; // main switch: --bbox-unsup bool m_cdc; // main switch: --cdc bool m_coverageLine; // main switch: --coverage-block bool m_coverageToggle;// main switch: --coverage-toggle bool m_coverageUnderscore;// main switch: --coverage-underscore bool m_coverageUser; // main switch: --coverage-func bool m_debugCheck; // main switch: --debug-check bool m_exe; // main switch: --exe bool m_ignc; // main switch: --ignc bool m_inhibitSim; // main switch: --inhibit-sim bool m_l2Name; // main switch: --l2name bool m_lintOnly; // main switch: --lint-only bool m_orderClockDly;// main switch: --order-clock-delay bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified bool m_pinsScUint; // main switch: --pins-sc-uint bool m_pinsScBigUint;// main switch: --pins-sc-biguint bool m_pinsUint8; // main switch: --pins-uint8 bool m_profileCFuncs;// main switch: --profile-cfuncs bool m_public; // main switch: --public bool m_savable; // main switch: --savable bool m_systemC; // main switch: --sc: System C instead of simple C++ bool m_skipIdentical;// main switch: --skip-identical bool m_systemPerl; // main switch: --sp: System Perl instead of SystemC (m_systemC also set) bool m_stats; // main switch: --stats bool m_statsVars; // main switch: --stats-vars bool m_trace; // main switch: --trace bool m_traceDups; // main switch: --trace-dups bool m_traceParams; // main switch: --trace-params bool m_traceStructs; // main switch: --trace-structs bool m_traceUnderscore;// main switch: --trace-underscore bool m_underlineZero;// main switch: --underline-zero; undocumented old Verilator 2 bool m_reportUnoptflat; // main switch: --report-unoptflat bool m_xInitialEdge; // main switch: --x-initial-edge bool m_xmlOnly; // main switch: --xml-netlist int m_convergeLimit;// main switch: --converge-limit int m_dumpTree; // main switch: --dump-tree int m_ifDepth; // main switch: --if-depth int m_inlineMult; // main switch: --inline-mult int m_outputSplit; // main switch: --output-split int m_outputSplitCFuncs;// main switch: --output-split-cfuncs int m_outputSplitCTrace;// main switch: --output-split-ctrace int m_pinsBv; // main switch: --pins-bv int m_traceDepth; // main switch: --trace-depth int m_traceMaxArray;// main switch: --trace-max-array int m_traceMaxWidth;// main switch: --trace-max-width int m_unrollCount; // main switch: --unroll-count int m_unrollStmts; // main switch: --unroll-stmts int m_compLimitBlocks; // compiler selection options int m_compLimitParens; // compiler selection options string m_bin; // main switch: --bin {binary} string m_exeName; // main switch: -o {name} string m_flags; // main switch: -f {name} string m_makeDir; // main switch: -Mdir string m_modPrefix; // main switch: --mod-prefix string m_pipeFilter; // main switch: --pipe-filter string m_prefix; // main switch: --prefix string m_topModule; // main switch: --top-module string m_unusedRegexp; // main switch: --unused-regexp string m_xAssign; // main switch: --x-assign // Language is now held in FileLine, on a per-node basis. However we still // have a concept of the default language at a global level. V3LangCode m_defaultLanguage; // main switch: --language // MEMBERS (optimizations) // // main switch: -Op: --public bool m_oAcycSimp; // main switch: -Oy: acyclic pre-optimizations bool m_oCase; // main switch: -Oe: case tree conversion bool m_oCombine; // main switch: -Ob: common icode packing bool m_oConst; // main switch: -Oc: constant folding bool m_oDedupe; // main switch: -Od: logic deduplication bool m_oAssemble; // main switch: -Om: assign assemble bool m_oExpand; // main switch: -Ox: expansion of C macros bool m_oFlopGater; // main switch: -Of: flop gater detection bool m_oGate; // main switch: -Og: gate wire elimination bool m_oLife; // main switch: -Ol: variable lifetime bool m_oLifePost; // main switch: -Ot: delayed assignment elimination bool m_oLocalize; // main switch: -Oz: convert temps to local variables bool m_oInline; // main switch: -Oi: module inlining bool m_oReorder; // main switch: -Or: reorder assignments in blocks bool m_oSplit; // main switch: -Os: always assignment splitting bool m_oSubst; // main switch: -Ou: substitute expression temp values bool m_oSubstConst; // main switch: -Ok: final constant substitution bool m_oTable; // main switch: -Oa: lookup table creation private: // METHODS void addArg(const string& flag); void addDefine(const string& defline, bool allowPlus); void addFuture(const string& flag); void addIncDirUser(const string& incdir); // User requested void addIncDirFallback(const string& incdir); // Low priority if not found otherwise void addLangExt(const string& langext, const V3LangCode& lc); void addLibExtV(const string& libext); void optimize(int level); void showVersion(bool verbose); void coverage(bool flag) { m_coverageLine = m_coverageToggle = m_coverageUser = flag; } bool onoff(const char* sw, const char* arg, bool& flag); bool suffixed(const char* sw, const char* arg); string parseFileArg(const string& optdir, const string& relfilename); bool parseLangExt(const char* swp, const char* langswp, const V3LangCode& lc); string filePathCheckOneDir(const string& modname, const string& dirname); static string getenvSYSTEMPERLGuts(); public: // CREATORS V3Options(); ~V3Options(); void setDebugMode(int level); void setDebugSrcLevel(const string& srcfile, int level); int debugSrcLevel(const string& srcfile, int default_level=V3Error::debugDefault()); void setDumpTreeLevel(const string& srcfile, int level); int dumpTreeLevel(const string& srcfile); // METHODS void addCppFile(const string& filename); void addCFlags(const string& filename); void addLdLibs(const string& filename); void addLibraryFile(const string& filename); void addClocker(const string& signame); void addNoClocker(const string& signame); void addVFile(const string& filename); // ACCESSORS (options) bool preprocOnly() const { return m_preprocOnly; } bool makeDepend() const { return m_makeDepend; } bool makePhony() const { return m_makePhony; } bool preprocNoLine() const { return m_preprocNoLine; } bool underlineZero() const { return m_underlineZero; } string bin() const { return m_bin; } string flags() const { return m_flags; } bool systemC() const { return m_systemC; } bool systemPerl() const { return m_systemPerl; } bool usingSystemCLibs() const { return !lintOnly() && (systemPerl() || systemC()); } bool usingSystemPerlLibs() const { return !lintOnly() && systemPerl(); } bool savable() const { return m_savable; } bool skipIdentical() const { return m_skipIdentical; } bool stats() const { return m_stats; } bool statsVars() const { return m_statsVars; } bool assertOn() const { return m_assert; } // assertOn as __FILE__ may be defined bool autoflush() const { return m_autoflush; } bool bboxSys() const { return m_bboxSys; } bool bboxUnsup() const { return m_bboxUnsup; } bool cdc() const { return m_cdc; } bool coverage() const { return m_coverageLine || m_coverageToggle || m_coverageUser; } bool coverageLine() const { return m_coverageLine; } bool coverageToggle() const { return m_coverageToggle; } bool coverageUnderscore() const { return m_coverageUnderscore; } bool coverageUser() const { return m_coverageUser; } bool debugCheck() const { return m_debugCheck; } bool exe() const { return m_exe; } bool trace() const { return m_trace; } bool traceDups() const { return m_traceDups; } bool traceParams() const { return m_traceParams; } bool traceStructs() const { return m_traceStructs; } bool traceUnderscore() const { return m_traceUnderscore; } bool orderClockDly() const { return m_orderClockDly; } bool outFormatOk() const { return m_outFormatOk; } bool keepTempFiles() const { return (V3Error::debugDefault()!=0); } bool pinsScUint() const { return m_pinsScUint; } bool pinsScBigUint() const { return m_pinsScBigUint; } bool pinsUint8() const { return m_pinsUint8; } bool profileCFuncs() const { return m_profileCFuncs; } bool allPublic() const { return m_public; } bool l2Name() const { return m_l2Name; } bool lintOnly() const { return m_lintOnly; } bool ignc() const { return m_ignc; } bool inhibitSim() const { return m_inhibitSim; } bool reportUnoptflat() const { return m_reportUnoptflat; } bool xInitialEdge() const { return m_xInitialEdge; } bool xmlOnly() const { return m_xmlOnly; } int convergeLimit() const { return m_convergeLimit; } int dumpTree() const { return m_dumpTree; } int ifDepth() const { return m_ifDepth; } int inlineMult() const { return m_inlineMult; } int outputSplit() const { return m_outputSplit; } int outputSplitCFuncs() const { return m_outputSplitCFuncs; } int outputSplitCTrace() const { return m_outputSplitCTrace; } int pinsBv() const { return m_pinsBv; } int traceDepth() const { return m_traceDepth; } int traceMaxArray() const { return m_traceMaxArray; } int traceMaxWidth() const { return m_traceMaxWidth; } int unrollCount() const { return m_unrollCount; } int unrollStmts() const { return m_unrollStmts; } int compLimitBlocks() const { return m_compLimitBlocks; } int compLimitParens() const { return m_compLimitParens; } string exeName() const { return m_exeName!="" ? m_exeName : prefix(); } string makeDir() const { return m_makeDir; } string modPrefix() const { return m_modPrefix; } string pipeFilter() const { return m_pipeFilter; } string prefix() const { return m_prefix; } string topModule() const { return m_topModule; } string unusedRegexp() const { return m_unusedRegexp; } string xAssign() const { return m_xAssign; } const V3StringSet& cppFiles() const { return m_cppFiles; } const V3StringSet& cFlags() const { return m_cFlags; } const V3StringSet& ldLibs() const { return m_ldLibs; } const V3StringSet& libraryFiles() const { return m_libraryFiles; } const V3StringList& vFiles() const { return m_vFiles; } const V3LangCode& defaultLanguage() const { return m_defaultLanguage; } bool isFuture(const string& flag) const; bool isLibraryFile(const string& filename) const; bool isClocker(const string& signame) const; bool isNoClocker(const string& signame) const; // ACCESSORS (optimization options) bool oAcycSimp() const { return m_oAcycSimp; } bool oCase() const { return m_oCase; } bool oCombine() const { return m_oCombine; } bool oConst() const { return m_oConst; } bool oDedupe() const { return m_oDedupe; } bool oAssemble() const { return m_oAssemble; } bool oExpand() const { return m_oExpand; } bool oFlopGater() const { return m_oFlopGater; } bool oGate() const { return m_oGate; } bool oDup() const { return oLife(); } bool oLife() const { return m_oLife; } bool oLifePost() const { return m_oLifePost; } bool oLocalize() const { return m_oLocalize; } bool oInline() const { return m_oInline; } bool oReorder() const { return m_oReorder; } bool oSplit() const { return m_oSplit; } bool oSubst() const { return m_oSubst; } bool oSubstConst() const { return m_oSubstConst; } bool oTable() const { return m_oTable; } // METHODS (uses above) string traceClassBase() const { return systemPerl() ? "SpTraceVcd" : "VerilatedVcd"; } // METHODS (from main) static string version(); static string argString(int argc, char** argv); ///< Return list of arguments as simple string string allArgsString(); ///< Return all passed arguments as simple string void bin(const string& flag) { m_bin = flag; } void parseOpts(FileLine* fl, int argc, char** argv); void parseOptsList (FileLine* fl, const string& optdir, int argc, char** argv); void parseOptsFile (FileLine* fl, const string& filename, bool rel); // METHODS (environment) // Most of these may be built into the executable with --enable-defenv, // see the README. If adding new variables, also see src/Makefile_obj.in // Also add to V3Options::showVersion() static string getenvPERL(); static string getenvSYSTEMC(); static string getenvSYSTEMC_ARCH(); static string getenvSYSTEMC_INCLUDE(); static string getenvSYSTEMC_LIBDIR(); static string getenvSYSTEMPERL(); static string getenvSYSTEMPERL_INCLUDE(); static string getenvVERILATOR_ROOT(); // METHODS (file utilities using these options) string fileExists (const string& filename); string filePath (FileLine* fl, const string& modname, const string& errmsg); void filePathLookedMsg(FileLine* fl, const string& modname); V3LangCode fileLanguage(const string &filename); static bool fileStatDir (const string& filename); static bool fileStatNormal (const string& filename); static void fileNfsFlush(const string& filename); // METHODS (other OS) static void throwSigsegv(); }; //###################################################################### #endif // guard verilator-3.874/src/V3LinkJump.h0000664000177100017500000000226512525171733016440 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Replace return/continue with jumps // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LINKJUMP_H_ #define _V3LINKJUMP_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3LinkJump { public: static void linkJump(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3LinkLValue.cpp0000664000177100017500000002035312525171733017246 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: LValue module/signal name references // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LinkLValue TRANSFORMATIONS: // Top-down traversal // Set lvalue() attributes on appropriate VARREFs. //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3LinkLValue.h" #include "V3Ast.h" //###################################################################### // Link state, as a visitor of each AstNode class LinkLValueVisitor : public AstNVisitor { private: // NODE STATE // STATE bool m_setRefLvalue; // Set VarRefs to lvalues for pin assignments AstNodeFTask* m_ftaskp; // Function or task we're inside // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITs // Result handing virtual void visit(AstNodeVarRef* nodep, AstNUser*) { // VarRef: LValue its reference if (m_setRefLvalue) { nodep->lvalue(true); } if (nodep->varp()) { if (nodep->lvalue() && nodep->varp()->isInOnly()) { if (!m_ftaskp) { nodep->v3warn(ASSIGNIN,"Assigning to input variable: "<prettyName()); } } } nodep->iterateChildren(*this); } // Nodes that start propagating down lvalues virtual void visit(AstPin* nodep, AstNUser*) { if (nodep->modVarp() && nodep->modVarp()->isOutput()) { // When the varref's were created, we didn't know the I/O state // Now that we do, and it's from a output, we know it's a lvalue m_setRefLvalue = true; nodep->iterateChildren(*this); m_setRefLvalue = false; } else { nodep->iterateChildren(*this); } } virtual void visit(AstNodeAssign* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->lhsp()->iterateAndNext(*this); m_setRefLvalue = false; nodep->rhsp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstFOpen* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->filep()->iterateAndNext(*this); m_setRefLvalue = false; nodep->filenamep()->iterateAndNext(*this); nodep->modep()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstFClose* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->filep()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstFFlush* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->filep()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstFGetC* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->filep()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstFGetS* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->filep()->iterateAndNext(*this); nodep->strgp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstFScanF* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->filep()->iterateAndNext(*this); nodep->exprsp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstSScanF* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->exprsp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstSysIgnore* nodep, AstNUser*) { // Can't know if lvalue or not; presume so as stricter bool last_setRefLvalue = m_setRefLvalue; nodep->iterateChildren(*this); m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstReadMem* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->memp()->iterateAndNext(*this); m_setRefLvalue = false; nodep->filenamep()->iterateAndNext(*this); nodep->lsbp()->iterateAndNext(*this); nodep->msbp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstValuePlusArgs* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->exprsp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstSFormat* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { m_setRefLvalue = true; nodep->lhsp()->iterateAndNext(*this); m_setRefLvalue = false; nodep->fmtp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } // Nodes that change LValue state virtual void visit(AstSel* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { nodep->lhsp()->iterateAndNext(*this); // Only set lvalues on the from m_setRefLvalue = false; nodep->rhsp()->iterateAndNext(*this); nodep->thsp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstNodeSel* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { // Only set lvalues on the from nodep->lhsp()->iterateAndNext(*this); m_setRefLvalue = false; nodep->rhsp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstNodePreSel* nodep, AstNUser*) { bool last_setRefLvalue = m_setRefLvalue; { // Only set lvalues on the from nodep->lhsp()->iterateAndNext(*this); m_setRefLvalue = false; nodep->rhsp()->iterateAndNext(*this); nodep->thsp()->iterateAndNext(*this); } m_setRefLvalue = last_setRefLvalue; } virtual void visit(AstNodeFTask* nodep, AstNUser*) { m_ftaskp = nodep; nodep->iterateChildren(*this); m_ftaskp = NULL; } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { AstNode* pinp = nodep->pinsp(); AstNodeFTask* taskp = nodep->taskp(); // We'll deal with mismatching pins later if (!taskp) return; for (AstNode* stmtp = taskp->stmtsp(); stmtp && pinp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO()) { if (portp->isInput()) { pinp->iterate(*this); } else { // Output or Inout m_setRefLvalue = true; pinp->iterate(*this); m_setRefLvalue = false; } // Advance pin pinp = pinp->nextp(); } } } } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkLValueVisitor(AstNode* nodep, bool start) { m_setRefLvalue = start; m_ftaskp = NULL; nodep->accept(*this); } virtual ~LinkLValueVisitor() {} }; //###################################################################### // Link class functions void V3LinkLValue::linkLValue(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<= 6); } void V3LinkLValue::linkLValueSet(AstNode* nodep) { // Called by later link functions when it is known a node needs // to be converted to a lvalue. UINFO(9,__FUNCTION__<<": "< #include #include #include #include "V3Global.h" #include "V3Inst.h" #include "V3Ast.h" #include "V3Changed.h" //###################################################################### // Inst state, as a visitor of each AstNode class InstVisitor : public AstNVisitor { private: // NODE STATE // Cleared each Cell: // AstPin::user1p() -> bool. True if created assignment already AstUser1InUse m_inuser1; // STATE AstNodeModule* m_modp; // Current module AstCell* m_cellp; // Current cell static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } //int m_debug; int debug() { return m_debug; } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { UINFO(4," MOD "<name() == "t_chg") m_debug = 9; else m_debug=0; m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCell* nodep, AstNUser*) { UINFO(4," CELL "<iterateChildren(*this); m_cellp = NULL; } virtual void visit(AstPin* nodep, AstNUser*) { // PIN(p,expr) -> ASSIGNW(VARXREF(p),expr) (if sub's input) // or ASSIGNW(expr,VARXREF(p)) (if sub's output) UINFO(4," PIN "<exprp()) return; // No-connect if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: "); if (nodep->modVarp()->isOutOnly() && nodep->exprp()->castConst()) nodep->v3error("Output port is connected to a constant pin, electrical short"); // Use user1p on the PIN to indicate we created an assign for this pin if (!nodep->user1SetOnce()) { // Simplify it V3Inst::pinReconnectSimple(nodep, m_cellp, m_modp, false); // Make a ASSIGNW (expr, pin) AstNode* exprp = nodep->exprp()->cloneTree(false); if (exprp->width() != nodep->modVarp()->width()) nodep->v3fatalSrc("Width mismatch, should have been handled in pinReconnectSimple\n"); if (nodep->modVarp()->isInout()) { nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator"); } else if (nodep->modVarp()->isOutput()) { AstNode* rhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false); AstAssignW* assp = new AstAssignW (exprp->fileline(), exprp, rhsp); m_modp->addStmtp(assp); } else if (nodep->modVarp()->isInput()) { // Don't bother moving constants now, // we'll be pushing the const down to the cell soon enough. AstNode* assp = new AstAssignW (exprp->fileline(), new AstVarXRef(exprp->fileline(), nodep->modVarp(), m_cellp->name(), true), exprp); m_modp->addStmtp(assp); if (debug()>=9) assp->dumpTree(cout," _new: "); } else if (nodep->modVarp()->isIfaceRef()) { // Create an AstAssignVarScope for Vars to Cells so we can link with their scope later AstNode* lhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false); AstVarRef* refp = exprp->castVarRef(); if (!refp) exprp->v3fatalSrc("Interfaces: Pin is not connected to a VarRef"); AstAssignVarScope* assp = new AstAssignVarScope(exprp->fileline(), lhsp, refp); m_modp->addStmtp(assp); } else { nodep->v3error("Assigned pin is neither input nor output"); } } // We're done with the pin nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } virtual void visit(AstUdpTable* nodep, AstNUser*) { if (!v3Global.opt.bboxUnsup()) { // If we support primitives, update V3Undriven to remove special case nodep->v3error("Unsupported: Verilog 1995 UDP Tables. Use --bbox-unsup to ignore tables."); } } // Save some time virtual void visit(AstNodeAssign*, AstNUser*) {} virtual void visit(AstAlways*, AstNUser*) {} //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS InstVisitor(AstNode* nodep) { m_modp=NULL; m_cellp=NULL; // nodep->accept(*this); } virtual ~InstVisitor() {} }; //###################################################################### class InstDeVisitor : public AstNVisitor { // Find all cells with arrays, and convert to non-arrayed private: // STATE AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations int m_instNum; // Current instantiation number int m_instLsb; // Current instantiation number static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstCell* nodep, AstNUser*) { if (nodep->rangep()) { m_cellRangep = nodep->rangep(); UINFO(4," CELL "<lsbConst(); for (m_instNum = m_instLsb; m_instNum<=m_cellRangep->msbConst(); m_instNum++) { AstCell* newp = nodep->cloneTree(false); nodep->addNextHere(newp); // Remove ranging and fix name newp->rangep()->unlinkFrBack()->deleteTree(); // Somewhat illogically, we need to rename the orignal name of the cell too. // as that is the name users expect for dotting // The spec says we add [x], but that won't work in C... newp->name(newp->name()+"__BRA__"+cvtToStr(m_instNum)+"__KET__"); newp->origName(newp->origName()+"__BRA__"+cvtToStr(m_instNum)+"__KET__"); // Fixup pins newp->pinsp()->iterateAndNext(*this); if (debug()==9) { newp->dumpTree(cout,"newcell: "); cout<unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } } virtual void visit(AstPin* nodep, AstNUser*) { // Any non-direct pins need reconnection with a part-select if (!nodep->exprp()) return; // No-connect if (m_cellRangep) { UINFO(4," PIN "<modVarp()->width(); int expwidth = nodep->exprp()->width(); if (expwidth == pinwidth) { // NOP: Arrayed instants: widths match so connect to each instance } else if (expwidth == pinwidth*m_cellRangep->elementsConst()) { // Arrayed instants: one bit for each of the instants (each assign is 1 pinwidth wide) AstNode* exprp = nodep->exprp()->unlinkFrBack(); bool inputPin = nodep->modVarp()->isInput(); if (!inputPin && !exprp->castVarRef() && !exprp->castConcat() // V3Const will collapse the SEL with the one we're about to make && !exprp->castSel()) { // V3Const will collapse the SEL with the one we're about to make nodep->v3error("Unsupported: Per-bit array instantiations with output connections to non-wires."); // Note spec allows more complicated matches such as slices and such } exprp = new AstSel (exprp->fileline(), exprp, pinwidth*(m_instNum-m_instLsb), pinwidth); nodep->exprp(exprp); } else { nodep->v3fatalSrc("Width mismatch; V3Width should have errored out."); } } } // Save some time virtual void visit(AstNodeMath*, AstNUser*) {} //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS InstDeVisitor(AstNode* nodep) { m_cellRangep=NULL; m_instNum=0; m_instLsb=0; // nodep->accept(*this); } virtual ~InstDeVisitor() {} }; //###################################################################### // Inst static function class InstStatic { private: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } InstStatic() {} // Static class static AstNode* extendOrSel(FileLine* fl, AstNode* rhsp, AstNode* cmpWidthp) { if (cmpWidthp->width() > rhsp->width()) { rhsp = (rhsp->isSigned() ? (new AstExtendS(fl, rhsp))->castNode() : (new AstExtend (fl, rhsp))->castNode()); rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above } else if (cmpWidthp->width() < rhsp->width()) { rhsp = new AstSel (fl, rhsp, 0, cmpWidthp->width()); rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above } // else don't change dtype, as might be e.g. array of something return rhsp; } public: static AstAssignW* pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule*, bool forTristate, bool alwaysCvt) { // If a pin connection is "simple" leave it as-is // Else create a intermediate wire to perform the interconnect // Return the new assignment, if one was made // Note this module calles cloneTree() via new AstVar AstVar* pinVarp = pinp->modVarp(); AstVarRef* connectRefp = pinp->exprp()->castVarRef(); AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL AstBasicDType* connBasicp = NULL; AstAssignW* assignp = NULL; if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->basicp(); // if (!alwaysCvt && connectRefp && connectRefp->varp()->dtypep()->sameTree(pinVarp->dtypep()) && !connectRefp->varp()->isSc()) { // Need the signal as a 'shell' to convert types // Done. Same data type } else if (!alwaysCvt && connectRefp && connectRefp->varp()->isIfaceRef()) { // Done. Interface } else if (!alwaysCvt && connBasicp && pinBasicp && connBasicp->width() == pinBasicp->width() && connBasicp->lsb() == pinBasicp->lsb() && !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types && connBasicp->width() == pinVarp->width() && 1) { // Done. One to one interconnect won't need a temporary variable. } else if (!alwaysCvt && !forTristate && pinp->exprp()->castConst()) { // Done. Constant. } else { // Make a new temp wire //if (1||debug()>=9) { pinp->dumpTree(cout,"-in_pin:"); } AstNode* pinexprp = pinp->exprp()->unlinkFrBack(); string newvarname = ((string)(pinVarp->isOutput() ? "__Vcellout" : "__Vcellinp") +(forTristate?"t":"") // Prevent name conflict if both tri & non-tri add signals +"__"+cellp->name()+"__"+pinp->name()); AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp); // Important to add statement next to cell, in case there is a generate with same named cell cellp->addNextHere(newvarp); if (pinVarp->isInout()) { pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)"); } else if (pinVarp->isOutput()) { // See also V3Inst AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false); UINFO(5,"pinRecon width "<width()<<" >? "<width()<<" >? "<width()<fileline(), rhsp, pinVarp); pinp->exprp(new AstVarRef (newvarp->fileline(), newvarp, true)); AstNode* rhsSelp = extendOrSel (pinp->fileline(), rhsp, pinexprp); assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsSelp); } else { // V3 width should have range/extended to make the widths correct assignp = new AstAssignW (pinp->fileline(), new AstVarRef(pinp->fileline(), newvarp, true), pinexprp); pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false)); } if (assignp) cellp->addNextHere(assignp); //if (debug()) { pinp->dumpTree(cout,"- out:"); } //if (debug()) { assignp->dumpTree(cout,"- aout:"); } } return assignp; } }; //###################################################################### // Inst class functions AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* modp, bool forTristate, bool alwaysCvt) { return InstStatic::pinReconnectSimple(pinp, cellp, modp, forTristate, alwaysCvt); } //###################################################################### // Inst class visitor void V3Inst::instAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Inst::dearrayAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.874/src/V3Assert.cpp0000664000177100017500000002716712525171733016513 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Collect and print statistics // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Assert.h" #include "V3Ast.h" #include "V3GraphDfa.h" #include "V3Stats.h" //###################################################################### // Assert class functions class AssertVisitor : public AstNVisitor { private: // NODE STATE/TYPES // Cleared on netlist // AstNode::user() -> bool. True if processed AstUser1InUse m_inuser1; // STATE AstNodeModule* m_modp; // Last module AstBegin* m_beginp; // Last begin V3Double0 m_statAsCover; // Statistic tracking V3Double0 m_statAsPsl; // Statistic tracking V3Double0 m_statAsFull; // Statistic tracking V3Double0 m_statAsSV; // Statistic tracking // METHODS string assertDisplayMessage(AstNode* nodep, const string& prefix, const string& message) { return (string("[%0t] "+prefix+": ")+nodep->fileline()->filebasename() +":"+cvtToStr(nodep->fileline()->lineno()) +": Assertion failed in %m" +((message != "")?": ":"")+message +"\n"); } void replaceDisplay(AstDisplay* nodep, const string& prefix) { nodep->displayType(AstDisplayType::DT_WRITE); nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text())); // cppcheck-suppress nullPointer AstNode* timenewp = new AstTime(nodep->fileline()); if (AstNode* timesp = nodep->fmtp()->exprsp()) { timesp->unlinkFrBackWithNext(); timenewp->addNext(timesp); } nodep->fmtp()->exprsp(timenewp); if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) { nodep->fmtp()->scopeNamep(new AstScopeName(nodep->fileline())); } } AstNode* newIfAssertOn(AstNode* nodep) { // Add a internal if to check assertions are on. // Don't make this a AND term, as it's unlikely to need to test this. AstNode* newp = new AstIf (nodep->fileline(), // If assertions are off, have constant propagation rip them out later // This allows syntax errors and such to be detected normally. (v3Global.opt.assertOn() ? (AstNode*)(new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1)) : (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))), nodep, NULL); newp->user1(true); // Don't assert/cover this if return newp; } AstNode* newFireAssert(AstNode* nodep, const string& message) { AstDisplay* dispp = new AstDisplay (nodep->fileline(), AstDisplayType::DT_ERROR, message, NULL, NULL); AstNode* bodysp = dispp; replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format bodysp->addNext(new AstStop (nodep->fileline())); bodysp = newIfAssertOn(bodysp); return bodysp; } void newPslAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep, AstNode* stmtsp, const string& message) { propp->unlinkFrBack(); sentreep->unlinkFrBack(); if (stmtsp) stmtsp->unlinkFrBack(); // AstNode* bodysp = NULL; bool selfDestruct = false; if (AstPslCover* snodep = nodep->castPslCover()) { if (!v3Global.opt.coverageUser()) { selfDestruct = true; } else { // V3Coverage assigned us a bucket to increment. AstCoverInc* covincp = snodep->coverincp()->castCoverInc(); if (!covincp) snodep->v3fatalSrc("Missing AstCoverInc under assertion"); covincp->unlinkFrBack(); if (message!="") covincp->declp()->comment(message); bodysp = covincp; } } else { nodep->v3fatalSrc("Unknown node type"); } if (stmtsp) bodysp = bodysp->addNext(stmtsp); AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL); bodysp = ifp; if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY); // AstNode* newp = new AstAlways (nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, bodysp); // Install it if (selfDestruct) { // Delete it after making the tree. This way we can tell the user // if it wasn't constructed nicely or has other errors without needing --coverage. newp->deleteTree(); nodep->unlinkFrBack(); } else { nodep->replaceWith(newp); } // Bye pushDeletep(nodep); nodep=NULL; } void newVAssertion(AstVAssert* nodep, AstNode* propp) { propp->unlinkFrBackWithNext(); AstNode* passsp = nodep->passsp(); if (passsp) passsp->unlinkFrBackWithNext(); AstNode* failsp = nodep->failsp(); if (failsp) failsp->unlinkFrBackWithNext(); // if (nodep->castVAssert()) { if (passsp) passsp = newIfAssertOn(passsp); if (failsp) failsp = newIfAssertOn(failsp); } else { nodep->v3fatalSrc("Unknown node type"); } AstIf* ifp = new AstIf (nodep->fileline(), propp, passsp, failsp); AstNode* newp = ifp; if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY); // // Install it nodep->replaceWith(newp); // Bye pushDeletep(nodep); nodep=NULL; } virtual void visit(AstIf* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; if (nodep->uniquePragma() || nodep->unique0Pragma()) { AstNodeIf* ifp = nodep; AstNode* propp = NULL; bool hasDefaultElse = false; do { // If this statement ends with 'else if', then nextIf will point to the // nextIf statement. Otherwise it will be null. AstNodeIf* nextifp = dynamic_cast(ifp->elsesp()); ifp->condp()->iterateAndNext(*this); // Recurse into the true case. ifp->ifsp()->iterateAndNext(*this); // If the last else is not an else if, recurse into that too. if (ifp->elsesp() && !nextifp) { ifp->elsesp()->iterateAndNext(*this); } // Build a bitmask of the true predicates AstNode* predp = ifp->condp()->cloneTree(false); if (propp) { propp = new AstConcat(nodep->fileline(), predp, propp); } else { propp = predp; } // Record if this ends with an 'else' that does not have an if if (ifp->elsesp() && !nextifp) { hasDefaultElse = true; } ifp = nextifp; } while (ifp); AstNode *newifp = nodep->cloneTree(false); bool allow_none = nodep->unique0Pragma(); // Note: if this ends with an 'else', then we don't need to validate that one of the // predicates evaluates to true. AstNode* ohot = ((allow_none || hasDefaultElse) ? (new AstOneHot0(nodep->fileline(), propp))->castNode() : (new AstOneHot (nodep->fileline(), propp))->castNode()); AstIf* checkifp = new AstIf (nodep->fileline(), new AstLogNot (nodep->fileline(), ohot), newFireAssert(nodep, "'unique if' statement violated"), newifp); checkifp->branchPred(AstBranchPred::BP_UNLIKELY); nodep->replaceWith(checkifp); pushDeletep(nodep); } else { nodep->iterateChildren(*this); } } // VISITORS //========== Case assertions virtual void visit(AstCase* nodep, AstNUser*) { nodep->iterateChildren(*this); if (!nodep->user1SetOnce()) { bool has_default=false; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { if (itemp->isDefault()) has_default=true; } if (nodep->fullPragma() || nodep->priorityPragma()) { // Simply need to add a default if there isn't one already ++m_statAsFull; if (!has_default) { nodep->addItemsp(new AstCaseItem(nodep->fileline(), NULL/*DEFAULT*/, newFireAssert(nodep, "synthesis full_case, but non-match found"))); } } if (nodep->parallelPragma() || nodep->uniquePragma() || nodep->unique0Pragma()) { // Need to check that one, and only one of the case items match at any moment // If there's a default, we allow none to match, else exactly one must match ++m_statAsFull; if (!has_default && !nodep->itemsp()) { // Not parallel, but harmlessly so. } else { AstNode* propp = NULL; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) { AstNode* onep = new AstEq(icondp->fileline(), nodep->exprp()->cloneTree(false), icondp->cloneTree(false)); if (propp) propp = new AstConcat(icondp->fileline(), onep, propp); else propp = onep; } } bool allow_none = has_default || nodep->unique0Pragma(); AstNode* ohot = (allow_none ? (new AstOneHot0(nodep->fileline(), propp))->castNode() : (new AstOneHot (nodep->fileline(), propp))->castNode()); AstIf* ifp = new AstIf (nodep->fileline(), new AstLogNot (nodep->fileline(), ohot), newFireAssert(nodep, "synthesis parallel_case, but multiple matches found"), NULL); ifp->branchPred(AstBranchPred::BP_UNLIKELY); nodep->addNotParallelp(ifp); } } } } // VISITORS //========== Statements virtual void visit(AstDisplay* nodep, AstNUser*) { nodep->iterateChildren(*this); // Replace the special types with standard text if (nodep->displayType()==AstDisplayType::DT_INFO) { replaceDisplay(nodep, "-Info"); } else if (nodep->displayType()==AstDisplayType::DT_WARNING) { replaceDisplay(nodep, "%%Warning"); } else if (nodep->displayType()==AstDisplayType::DT_ERROR || nodep->displayType()==AstDisplayType::DT_FATAL) { replaceDisplay(nodep, "%%Error"); } } virtual void visit(AstPslCover* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name()); newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->stmtsp(), nodep->name()); nodep=NULL; ++m_statAsCover; } virtual void visit(AstVAssert* nodep, AstNUser*) { nodep->iterateChildren(*this); newVAssertion(nodep, nodep->propp()); nodep=NULL; ++m_statAsSV; } virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; // nodep->iterateChildren(*this); // Reset defaults m_modp = NULL; } virtual void visit(AstBegin* nodep, AstNUser*) { // This code is needed rather than a visitor in V3Begin, // because V3Assert is called before V3Begin AstBegin* lastp = m_beginp; { m_beginp = nodep; nodep->iterateChildren(*this); } m_beginp = lastp; } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS AssertVisitor(AstNetlist* nodep) { m_beginp = NULL; m_modp = NULL; // Process nodep->accept(*this); } virtual ~AssertVisitor() { V3Stats::addStat("Assertions, PSL asserts", m_statAsPsl); V3Stats::addStat("Assertions, SystemVerilog asserts", m_statAsSV); V3Stats::addStat("Assertions, cover statements", m_statAsCover); V3Stats::addStat("Assertions, full/parallel case", m_statAsFull); } }; //###################################################################### // Top Assert class void V3Assert::assertAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/.gdbinit0000664000177100017500000000134612525171733015745 0ustar wsnyderwsnyder# DESCRIPTION: Verilator: GDB startup file with useful defines # # Copyright 2012-2015 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. define pn call $arg0->dumpGdb() end document pn Verilator: Print single AstNode NODEP end define pnt call $arg0->dumpTreeGdb() end document pnt Verilator: Print AstNode NODEP's tree end define dtf call AstNode::dumpTreeFileGdb(0) end document dtf Verilator: Dump AstNode tree to file end define watchedit watch AstNode::s_editCntGbl==$arg0 end document watchedit Verilator: Create watch on where a edit number is made end verilator-3.874/src/V3PreProc.h0000664000177100017500000001000012525172076016244 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilog::Preproc: Preprocess verilog code // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2000-2015 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. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3PREPROC_H_ #define _V3PREPROC_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3FileLine.h" #include #include #include #include // Compatibility with Verilog-Perl's preprocessor #define fatalSrc(msg) v3fatalSrc(msg) class V3InFilter; class V3PreProc { // This defines a preprocessor. Functions are virtual so implementation can be hidden. // After creating, call open(), then getline() in a loop. The class will to the rest... protected: // STATE int m_debug; // Debugging public: // CONSTANTS enum MiscConsts { DEFINE_RECURSION_LEVEL_MAX = 1000, // How many `def substitutions before an error INCLUDE_DEPTH_MAX = 500, // How many `includes deep before an error STREAM_DEPTH_LEVEL_MAX = 2000, // How many streams deep (sometimes `def deep) before an error // // Set more than DEFINE_RECURSION_LEVEL_MAX or INCLUDE_DEPTH_MAX NEWLINES_VS_TICKLINE = 20 // Use `line in place of this many newlines }; // ACCESSORS // Insert given file into this point in input stream virtual void openFile(FileLine* fileline, V3InFilter* filterp, const string& filename)=0; virtual string getline()=0; // Return next line/lines. (Null if done.) virtual bool isEof() const =0; // Return true on EOF. virtual void insertUnreadback(const string& text) = 0; int debug() const { return m_debug; } void debug(int level) { m_debug = level; } FileLine* fileline(); ///< File/Line number for last getline call // CONTROL METHODS // These options control how the parsing proceeds static int keepComments() { return 2; } // Return comments, 0=no, 1=yes, 2=callback static bool keepWhitespace() { return false; } static bool lineDirectives() { // Insert `line directives return !(v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine()); } static bool pedantic() { return false; } // Obey standard; Don't substitute `error // CALLBACK METHODS // This probably will want to be overridden for given child users of this class. virtual void comment(const string& cmt)=0; // Comment detected (if keepComments==2) virtual void include(const string& filename)=0; // Request a include file be processed virtual void undef(const string& name)=0; // Remove a definition virtual void define(FileLine* fileline, const string& name, const string& value, const string& params="", bool cmdline=false)=0; // `define without any parameters virtual void defineCmdLine(FileLine* fileline, const string& name, const string& value) { // `define without any parameters define(fileline, name, value, "", true); } virtual string removeDefines(const string& text)=0; // Remove defines in a text string // UTILITIES void error(string msg) { fileline()->v3error(msg); } ///< Report a error void fatal(string msg) { fileline()->v3fatalSrc(msg); } ///< Report a fatal error protected: // CONSTUCTORS V3PreProc() { m_debug=0; }; void configure(FileLine* fl); public: static V3PreProc* createPreProc(FileLine* fileline); virtual ~V3PreProc() {} }; #endif // Guard verilator-3.874/src/V3Subst.cpp0000664000177100017500000003156712525171733016351 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Substitute constants and expressions in expr temp's // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Subst's Transformations: // // Each module: // Search all ASSIGN(WORDSEL(...)) and build what it's assigned to // Later usages of that word may then be replaced as long as // the RHS hasn't changed value. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Subst.h" #include "V3Const.h" #include "V3Stats.h" #include "V3Ast.h" //###################################################################### // Common debugging baseclass class SubstBaseVisitor : public AstNVisitor { public: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### // Class for each word of a multi-word variable class SubstVarWord { protected: // MEMBERS AstNodeAssign* m_assignp; // Last assignment to each word of this var int m_step; // Step number of last assignment bool m_use; // True if each word was consumed bool m_complex; // True if each word is complex friend class SubstVarEntry; // METHODS void clear() { m_assignp = NULL; m_step = 0; m_use = false; m_complex = false; } }; //###################################################################### // Class for every variable we may process class SubstVarEntry { // MEMBERS AstVar* m_varp; // Variable this tracks bool m_wordAssign; // True if any word assignments bool m_wordUse; // True if any individual word usage SubstVarWord m_whole; // Data for whole vector used at once vector m_words; // Data for every word, if multi word variable int debug() { return SubstBaseVisitor::debug(); } public: // CONSTRUCTORS SubstVarEntry (AstVar* varp) { // Construction for when a var is used m_varp = varp; m_whole.m_use = false; m_wordAssign = false; m_wordUse = false; m_words.resize(varp->widthWords()); m_whole.clear(); for (int i=0; iwidthWords(); i++) { m_words[i].clear(); } } ~SubstVarEntry() {} private: // METHODS bool wordNumOk(int word) const { return word < m_varp->widthWords(); } AstNodeAssign* getWordAssignp(int word) const { if (!wordNumOk(word)) return NULL; else return m_words[word].m_assignp; } public: void assignWhole (int step, AstNodeAssign* assp) { if (m_whole.m_assignp) m_whole.m_complex = true; m_whole.m_assignp = assp; m_whole.m_step = step; } void assignWord (int step, int word, AstNodeAssign* assp) { if (!wordNumOk(word) || getWordAssignp(word) || m_words[word].m_complex) m_whole.m_complex = true; m_wordAssign = true; if (wordNumOk(word)) { m_words[word].m_assignp = assp; m_words[word].m_step = step; } } void assignWordComplex (int step, int word) { if (!wordNumOk(word) || getWordAssignp(word) || m_words[word].m_complex) m_whole.m_complex = true; m_words[word].m_complex = true; } void assignComplex(int step) { m_whole.m_complex = true; } void consumeWhole() { //==consumeComplex as we don't know the difference m_whole.m_use = true; } void consumeWord(int word) { m_words[word].m_use = true; m_wordUse = true; } // ACCESSORS AstNode* substWhole(AstNode* errp) { if (!m_varp->isWide() && !m_whole.m_complex && m_whole.m_assignp && !m_wordAssign) { AstNodeAssign* assp = m_whole.m_assignp; if (!assp) errp->v3fatalSrc("Reading whole that was never assigned"); return (assp->rhsp()); } else { return NULL; } } AstNode* substWord(AstNode* errp, int word) { // Return what to substitute given word number for if (!m_whole.m_complex && !m_whole.m_assignp && !m_words[word].m_complex) { AstNodeAssign* assp = getWordAssignp(word); if (!assp) errp->v3fatalSrc("Reading a word that was never assigned, or bad word #"); return (assp->rhsp()); } else { return NULL; } } int getWholeStep() const { return m_whole.m_step; } int getWordStep(int word) const { if (!wordNumOk(word)) return 0; else return m_words[word].m_step; } void deleteAssign (AstNodeAssign* nodep) { UINFO(5, "Delete "<unlinkFrBack()->deleteTree(); nodep=NULL; } void deleteUnusedAssign() { // If there are unused assignments in this var, kill them if (!m_whole.m_use && !m_wordUse && m_whole.m_assignp) { deleteAssign (m_whole.m_assignp); m_whole.m_assignp=NULL; } for (unsigned i=0; ivarp()->user1p()); // Might be NULL } // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { SubstVarEntry* entryp = findEntryp (nodep); if (entryp) { // Don't sweat it. We assign a new temp variable for every new assignment, // so there's no way we'd ever replace a old value. } else { // A simple variable; needs checking. if (m_origStep < nodep->varp()->user2()) { if (m_ok) UINFO(9," RHS variable changed since subst recorded: "<iterateChildren(*this); } public: // CONSTUCTORS SubstUseVisitor(AstNode* nodep, int origStep) { UINFO(9, " SubstUseVisitor "<accept(*this); } virtual ~SubstUseVisitor() {} // METHODS bool ok() const { return m_ok; } }; //###################################################################### // Subst state, as a visitor of each AstNode class SubstVisitor : public SubstBaseVisitor { private: // NODE STATE // Passed to SubstUseVisitor // AstVar::user1p -> SubstVar* for usage var, 0=not set yet // AstVar::user2 -> int step number for last assignment, 0=not set yet AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // STATE vector m_entryps; // Nodes to delete when we are finished int m_ops; // Number of operators on assign rhs int m_assignStep; // Assignment number to determine var lifetime V3Double0 m_statSubsts; // Statistic tracking enum { SUBST_MAX_OPS_SUBST = 30, // Maximum number of ops to substitute in SUBST_MAX_OPS_NA = 9999 }; // Not allowed to substitute // METHODS SubstVarEntry* getEntryp(AstVarRef* nodep) { if (!nodep->varp()->user1p()) { SubstVarEntry* entryp = new SubstVarEntry (nodep->varp()); m_entryps.push_back(entryp); nodep->varp()->user1p(entryp); return entryp; } else { SubstVarEntry* entryp = (SubstVarEntry*)(nodep->varp()->user1p()); return entryp; } } inline bool isSubstVar(AstVar* nodep) { return nodep->isStatementTemp() && !nodep->noSubst(); } // VISITORS virtual void visit(AstNodeAssign* nodep, AstNUser*) { m_ops = 0; m_assignStep++; nodep->rhsp()->iterateAndNext(*this); bool hit=false; if (AstVarRef* varrefp = nodep->lhsp()->castVarRef()) { if (isSubstVar(varrefp->varp())) { SubstVarEntry* entryp = getEntryp(varrefp); hit = true; if (m_ops > SUBST_MAX_OPS_SUBST) { UINFO(8," ASSIGNtooDeep "<assignComplex(m_assignStep); } else { UINFO(8," ASSIGNwhole "<assignWhole(m_assignStep, nodep); } } } else if (AstWordSel* wordp = nodep->lhsp()->castWordSel()) { if (AstVarRef* varrefp = wordp->lhsp()->castVarRef()) { if (wordp->rhsp()->castConst() && isSubstVar(varrefp->varp())) { int word = wordp->rhsp()->castConst()->toUInt(); SubstVarEntry* entryp = getEntryp(varrefp); hit = true; if (m_ops > SUBST_MAX_OPS_SUBST) { UINFO(8," ASSIGNtooDeep "<assignWordComplex(m_assignStep, word); } else { UINFO(8," ASSIGNword"<assignWord(m_assignStep, word, nodep); } } } } if (!hit) { nodep->lhsp()->accept(*this); } } void replaceSubstEtc(AstNode* nodep, AstNode* substp) { if (debug()>5) nodep->dumpTree(cout," substw_old: "); AstNode* newp = substp->cloneTree(true); if (!nodep->isQuad() && newp->isQuad()) { newp = new AstCCast (newp->fileline(), newp, nodep); } if (debug()>5) newp->dumpTree(cout," w_new: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; ++m_statSubsts; } virtual void visit(AstWordSel* nodep, AstNUser*) { nodep->rhsp()->accept(*this); AstVarRef* varrefp = nodep->lhsp()->castVarRef(); AstConst* constp = nodep->rhsp()->castConst(); if (varrefp && isSubstVar(varrefp->varp()) && !varrefp->lvalue() && constp) { // Nicely formed lvalues handled in NodeAssign // Other lvalues handled as unknown mess in AstVarRef int word = constp->toUInt(); UINFO(8," USEword"<substWord (nodep, word)) { // Check that the RHS hasn't changed value since we recorded it. SubstUseVisitor visitor (substp, entryp->getWordStep(word)); if (visitor.ok()) { replaceSubstEtc(nodep, substp); nodep=NULL; } else { entryp->consumeWord(word); } } else { entryp->consumeWord(word); } } else { nodep->lhsp()->accept(*this); } } virtual void visit(AstVarRef* nodep, AstNUser*) { // Any variable if (nodep->lvalue()) { m_assignStep++; nodep->varp()->user2(m_assignStep); UINFO(9, " ASSIGNstep u2="<varp()->user2()<<" "<varp())) { SubstVarEntry* entryp = getEntryp (nodep); if (nodep->lvalue()) { UINFO(8," ASSIGNcpx "<assignComplex(m_assignStep); } else if (AstNode* substp = entryp->substWhole(nodep)) { // Check that the RHS hasn't changed value since we recorded it. SubstUseVisitor visitor (substp, entryp->getWholeStep()); if (visitor.ok()) { UINFO(8," USEwhole "<consumeWhole(); } } else { // Consumed w/o substitute UINFO(8," USEwtf "<consumeWhole(); } } } virtual void visit(AstVar* nodep, AstNUser*) {} virtual void visit(AstConst* nodep, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { m_ops++; if (!nodep->isSubstOptimizable()) { m_ops = SUBST_MAX_OPS_NA; } nodep->iterateChildren(*this); } public: // CONSTUCTORS SubstVisitor(AstNode* nodep) { AstNode::user1ClearTree(); // user1p() used on entire tree AstNode::user2ClearTree(); // user2p() used on entire tree m_ops = 0; m_assignStep = 0; nodep->accept(*this); } virtual ~SubstVisitor() { V3Stats::addStat("Optimizations, Substituted temps", m_statSubsts); for (vector::iterator it = m_entryps.begin(); it != m_entryps.end(); ++it) { (*it)->deleteUnusedAssign(); delete (*it); } } }; //###################################################################### // Subst class functions void V3Subst::substituteAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3EmitMk.cpp0000664000177100017500000002172512525172036016427 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit Makefile // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3Os.h" #include "V3EmitMk.h" #include "V3EmitCBase.h" //###################################################################### // Emit statements and math operators class EmitMkVisitor : public EmitCBaseVisitor { public: // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void putMakeClassEntry(V3OutMkFile& of, const string& name) { of.puts("\t"+V3Os::filenameNonDirExt(name)+" \\\n"); } void emitClassMake() { // Generate the makefile V3OutMkFile of (v3Global.opt.makeDir()+"/"+ v3Global.opt.prefix() + "_classes.mk"); of.putsHeader(); of.puts("# DESCR" "IPTION: Verilator output: Make include file with class lists\n"); of.puts("#\n"); of.puts("# This file lists generated Verilated files, for including in higher level makefiles.\n"); of.puts("# See "+v3Global.opt.prefix()+".mk"+" for the caller.\n"); of.puts("\n### Switches...\n"); of.puts("# Coverage output mode? 0/1 (from --coverage)\n"); of.puts("VM_COVERAGE = "); of.puts(v3Global.opt.coverage()?"1":"0"); of.puts("\n"); of.puts("# Tracing output mode? 0/1 (from --trace)\n"); of.puts("VM_TRACE = "); of.puts(v3Global.opt.trace()?"1":"0"); of.puts("\n"); of.puts("\n### Object file lists...\n"); for (int support=0; support<3; support++) { for (int slow=0; slow<2; slow++) { if (support==2) of.puts("# Global classes, need linked once per executable"); else if (support) of.puts("# Generated support classes"); else of.puts("# Generated module classes"); if (slow) of.puts(", non-fast-path, compile with low/medium optimization\n"); else of.puts(", fast-path, compile with highest optimization\n"); of.puts(support==2?"VM_GLOBAL":support==1?"VM_SUPPORT":"VM_CLASSES"); of.puts(slow?"_SLOW":"_FAST"); of.puts(" += \\\n"); if (support==2 && !slow) { putMakeClassEntry(of, "verilated.cpp"); if (v3Global.dpi()) { putMakeClassEntry(of, "verilated_dpi.cpp"); } if (v3Global.opt.savable()) { putMakeClassEntry(of, "verilated_save.cpp"); } if (v3Global.opt.coverage()) { putMakeClassEntry(of, "verilated_cov.cpp"); } if (v3Global.opt.systemPerl()) { putMakeClassEntry(of, "Sp.cpp"); // Note Sp.cpp includes SpTraceVcdC } else { if (v3Global.opt.trace()) { putMakeClassEntry(of, "verilated_vcd_c.cpp"); if (v3Global.opt.systemC()) { putMakeClassEntry(of, "verilated_vcd_sc.cpp"); } } } } else if (support==2 && slow) { } else { for (AstCFile* nodep = v3Global.rootp()->filesp(); nodep; nodep=nodep->nextp()->castCFile()) { if (nodep->source() && nodep->slow()==slow && nodep->support()==support) { putMakeClassEntry(of, nodep->name()); } } } of.puts("\n"); } } of.puts("\n"); of.putsHeader(); } void emitOverallMake() { // Generate the makefile V3OutMkFile of (v3Global.opt.makeDir()+"/"+ v3Global.opt.prefix() + ".mk"); of.putsHeader(); of.puts("# DESCR" "IPTION: Verilator output: Makefile for building Verilated archive or executable\n"); of.puts("#\n"); of.puts("# Execute this makefile from the object directory:\n"); of.puts("# make -f "+v3Global.opt.prefix()+".mk"+"\n"); of.puts("\n"); if (v3Global.opt.exe()) { of.puts("default: "+v3Global.opt.exeName()+"\n"); } else { of.puts("default: "+v3Global.opt.prefix()+"__ALL.a\n"); } of.puts("\n### Constants...\n"); of.puts("# Perl executable (from $PERL)\n"); of.puts("PERL = "+V3Options::getenvPERL()+"\n"); of.puts("# Path to Verilator kit (from $VERILATOR_ROOT)\n"); of.puts("VERILATOR_ROOT = "+V3Options::getenvVERILATOR_ROOT()+"\n"); of.puts("# Path to SystemPerl kit top (from $SYSTEMPERL)\n"); of.puts("SYSTEMPERL = "+V3Options::getenvSYSTEMPERL()+"\n"); of.puts("# Path to SystemPerl kit includes (from $SYSTEMPERL_INCLUDE)\n"); of.puts("SYSTEMPERL_INCLUDE = "+V3Options::getenvSYSTEMPERL_INCLUDE()+"\n"); of.puts("# SystemC include directory with systemc.h (from $SYSTEMC_INCLUDE)\n"); of.puts(string("SYSTEMC_INCLUDE ?= ")+V3Options::getenvSYSTEMC_INCLUDE()+"\n"); of.puts("# SystemC library directory with libsystemc.a (from $SYSTEMC_LIBDIR)\n"); of.puts(string("SYSTEMC_LIBDIR ?= ")+V3Options::getenvSYSTEMC_LIBDIR()+"\n"); of.puts("\n### Switches...\n"); of.puts("# SystemPerl output mode? 0/1 (from --sp)\n"); of.puts(string("VM_SP = ")+(v3Global.opt.systemPerl()?"1":"0")+"\n"); of.puts("# SystemC output mode? 0/1 (from --sc)\n"); of.puts(string("VM_SC = ")+((v3Global.opt.systemC()&&!v3Global.opt.systemPerl())?"1":"0")+"\n"); of.puts("# SystemPerl or SystemC output mode? 0/1 (from --sp/--sc)\n"); of.puts(string("VM_SP_OR_SC = ")+(v3Global.opt.systemC()?"1":"0")+"\n"); of.puts("# Deprecated\n"); of.puts(string("VM_PCLI = ")+(v3Global.opt.systemC()?"0":"1")+"\n"); of.puts("# Deprecated: SystemC architecture to find link library path (from $SYSTEMC_ARCH)\n"); of.puts(string("VM_SC_TARGET_ARCH = ")+V3Options::getenvSYSTEMC_ARCH()+"\n"); of.puts("\n### Vars...\n"); of.puts("# Design prefix (from --prefix)\n"); of.puts(string("VM_PREFIX = ")+v3Global.opt.prefix()+"\n"); of.puts("# Module prefix (from --prefix)\n"); of.puts(string("VM_MODPREFIX = ")+v3Global.opt.modPrefix()+"\n"); of.puts("# User CFLAGS (from -CFLAGS on Verilator command line)\n"); of.puts("VM_USER_CFLAGS = \\\n"); const V3StringSet& cFlags = v3Global.opt.cFlags(); for (V3StringSet::const_iterator it = cFlags.begin(); it != cFlags.end(); ++it) { of.puts("\t"+*it+" \\\n"); } of.puts("\n"); of.puts("# User LDLIBS (from -LDFLAGS on Verilator command line)\n"); of.puts("VM_USER_LDLIBS = \\\n"); const V3StringSet& ldLibs = v3Global.opt.ldLibs(); for (V3StringSet::const_iterator it = ldLibs.begin(); it != ldLibs.end(); ++it) { of.puts("\t"+*it+" \\\n"); } of.puts("\n"); V3StringSet dirs; of.puts("# User .cpp files (from .cpp's on Verilator command line)\n"); of.puts("VM_USER_CLASSES = \\\n"); const V3StringSet& cppFiles = v3Global.opt.cppFiles(); for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) { string cppfile = *it; of.puts("\t"+V3Os::filenameNonExt(cppfile)+" \\\n"); string dir = V3Os::filenameDir(cppfile); if (dirs.find(dir) == dirs.end()) dirs.insert(dir); } of.puts("\n"); of.puts("# User .cpp directories (from .cpp's on Verilator command line)\n"); of.puts("VM_USER_DIR = \\\n"); for (V3StringSet::iterator it = dirs.begin(); it!=dirs.end(); ++it) { of.puts("\t"+*it+" \\\n"); } of.puts("\n"); of.puts("\n### Default rules...\n"); of.puts("# Include list of all generated classes\n"); of.puts("include "+v3Global.opt.prefix()+"_classes.mk\n"); of.puts("# Include global rules\n"); of.puts("include $(VERILATOR_ROOT)/include/verilated.mk\n"); if (v3Global.opt.exe()) { of.puts("\n### Executable rules... (from --exe)\n"); of.puts("VPATH += $(VM_USER_DIR)\n"); of.puts("\n"); for (V3StringSet::const_iterator it = cppFiles.begin(); it != cppFiles.end(); ++it) { string cppfile = *it; string basename = V3Os::filenameNonExt(cppfile); of.puts(basename+".o: "+cppfile+"\n"); of.puts("\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<\n"); } of.puts("\n### Link rules... (from --exe)\n"); of.puts(v3Global.opt.exeName()+": $(VK_USER_OBJS) $(VK_GLOBAL_OBJS) $(VM_PREFIX)__ALL.a\n"); of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) $(SC_LIBS) 2>&1 | c++filt\n"); of.puts("\n"); } of.puts("\n"); of.putsHeader(); } //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->v3fatalSrc("No visitors implemented."); } public: EmitMkVisitor(AstNetlist*) { emitClassMake(); emitOverallMake(); } virtual ~EmitMkVisitor() {} }; //###################################################################### // Gate class functions void V3EmitMk::emitmk(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<length() calculate the number of clones needed. // VARREF // Check the dimensions of the Var for an implicit slice. // Replace with ArraySel nodes if needed. // SEL, EXTEND // We might be assigning a 1-D packed array to a 2-D packed array, // this is unsupported. // SliceCloneVisitor (called if this node is a slice): // NODEASSIGN // Clone and iterate the clone: // ARRAYSEL // Modify bitp() for the new value and set ->length(1) //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3Slice.h" #include "V3Ast.h" #include class SliceCloneVisitor : public AstNVisitor { // NODE STATE // Inputs: // AstArraySel::user1p() -> AstVarRef. The VarRef that the final ArraySel points to // AstNodeAssign::user2() -> int. The number of clones needed for this assign // AstArraySel::user3() -> bool. Error detected // STATE vector > m_selBits; // Indexes of the ArraySel we are expanding int m_vecIdx; // Current vector index unsigned m_depth; // Number of ArraySel's from the VarRef AstVarRef* m_refp; // VarRef under this ArraySel // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstArraySel* nodep, AstNUser*) { if (!nodep->backp()->castArraySel()) { // This is the top of an ArraySel, setup for iteration m_refp = nodep->user1p()->castNode()->castVarRef(); m_vecIdx += 1; if (m_vecIdx == (int)m_selBits.size()) { m_selBits.push_back(vector()); AstVar* varp = m_refp->varp(); pair arrDim = varp->dtypep()->dimensions(false); uint32_t dimensions = arrDim.second; // for 3-dimensions we want m_selBits[m_vecIdx]=[0,0,0] for (uint32_t i = 0; i < dimensions; ++i) { m_selBits[m_vecIdx].push_back(0); } } } nodep->iterateChildren(*this); if (nodep->fromp()->castVarRef()) { m_depth = 0; } else { ++m_depth; } // Check if m_selBits has overflowed if (m_selBits[m_vecIdx][m_depth] >= nodep->length()) { m_selBits[m_vecIdx][m_depth] = 0; if (m_depth + 1 < m_selBits[m_vecIdx].size()) m_selBits[m_vecIdx][m_depth+1] += 1; } // Reassign the bitp() if (nodep->length() > 1) { if (AstConst* bitp = nodep->bitp()->castConst()) { unsigned idx = nodep->start() + m_selBits[m_vecIdx][m_depth]; AstNode* constp = new AstConst(bitp->fileline(), V3Number(bitp->fileline(), bitp->castConst()->num().width(), idx)); bitp->replaceWith(constp); } else { nodep->v3error("Unsupported: Only constants supported in slices"); } } if (!nodep->backp()->castArraySel()) { // Top ArraySel, increment m_selBits m_selBits[m_vecIdx][0] += 1; } nodep->length(1); } virtual void visit(AstNodeAssign* nodep, AstNUser*) { if (nodep->user2() < 2) return; // Don't need clones m_selBits.clear(); UINFO(4, "Cloning "<user2()<<" times: "<user2(); ++i) { // Clone the node and iterate over the clone m_vecIdx = -1; AstNodeAssign* clonep = nodep->cloneTree(false)->castNodeAssign(); clonep->iterateChildren(*this); nodep->addNextHere(clonep); } nodep->unlinkFrBack()->deleteTree(); nodep = NULL; } // Not all Uniop nodes should be cloned down to a single bit void cloneUniop(AstNodeUniop* nodep) { if (nodep->user2() < 2) return; // Don't need clones m_selBits.clear(); UINFO(4, "Cloning "<user2()<<" times: "<user2(); ++i) { // Clone the node and iterate over the clone m_vecIdx = -1; AstNodeUniop* clonep = nodep->cloneTree(false)->castNodeUniop(); clonep->iterateChildren(*this); if (!lhsp) lhsp = clonep; else rhsp = clonep; if (lhsp && rhsp) { switch (nodep->type()) { case AstType::atREDOR: lhsp = new AstOr(nodep->fileline(), lhsp, rhsp); break; case AstType::atREDAND: lhsp = new AstAnd(nodep->fileline(), lhsp, rhsp); break; case AstType::atREDXOR: lhsp = new AstXor(nodep->fileline(), lhsp, rhsp); break; case AstType::atREDXNOR: lhsp = new AstXnor(nodep->fileline(), lhsp, rhsp); break; default: nodep->v3fatalSrc("Unsupported: Unary operation on multiple packed dimensions"); break; } rhsp = NULL; } } nodep->addNextHere(lhsp); nodep->unlinkFrBack()->deleteTree(); nodep = NULL; } virtual void visit(AstRedOr* nodep, AstNUser*) { cloneUniop(nodep); } virtual void visit(AstRedAnd* nodep, AstNUser*) { cloneUniop(nodep); } virtual void visit(AstRedXor* nodep, AstNUser*) { cloneUniop(nodep); } virtual void visit(AstRedXnor* nodep, AstNUser*) { cloneUniop(nodep); } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS SliceCloneVisitor(AstNode* nodep) { nodep->accept(*this); } virtual ~SliceCloneVisitor() {} }; //************************************************************************* class SliceVisitor : public AstNVisitor { // NODE STATE // Cleared on netlist // AstNodeAssign::user1() -> bool. True if find is complete // AstUniop::user1() -> bool. True if find is complete // AstArraySel::user1p() -> AstVarRef. The VarRef that the final ArraySel points to // AstNode::user2() -> int. The number of clones needed for this node AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; // TYPEDEFS typedef pair ArrayDimensions; // Array Dimensions (packed, unpacked) // STATE AstNode* m_assignp; // Assignment we are under AstNodeVarRef* m_lhsVarRefp; // Var on the LHS bool m_extend; // We have found an extend node bool m_assignError; // True if the current assign already has an error // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } unsigned explicitDimensions(AstArraySel* nodep) { // Find out how many explicit dimensions are in a given ArraySel. unsigned dim = 0; AstNode* fromp = nodep; AstArraySel* selp; do { selp = fromp->castArraySel(); if (!selp) { nodep->user1p(fromp->castVarRef()); selp = NULL; break; } else { fromp = selp->fromp(); if (fromp) ++dim; } } while (fromp && selp); if (!nodep->user1p()) nodep->v3fatalSrc("Couldn't find VarRef under the ArraySel"); return dim; } int countClones(AstArraySel* nodep) { // Count how many clones we need to make from this ArraySel int clones = 1; AstNode* fromp = nodep; AstArraySel* selp; do { selp = fromp->castArraySel(); fromp = (selp) ? selp->fromp() : NULL; if (fromp && selp) clones *= selp->length(); } while (fromp && selp); return clones; } AstArraySel* insertImplicit(AstNode* nodep, unsigned start, unsigned count) { // Insert any implicit slices as explicit slices (ArraySel nodes). // Return a new pointer to replace nodep() in the ArraySel. UINFO(9," insertImplicit (start="<user1p()->castNode()->castVarRef(); if (!refp) nodep->v3fatalSrc("No VarRef in user1 of node "<varp(); AstNode* topp = nodep; for (unsigned i = start; i < start + count; ++i) { AstNodeDType* dtypep = varp->dtypep()->dtypeDimensionp(i-1); AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType(); if (!adtypep) nodep->v3fatalSrc("insertImplicit tried to expand an array without an ArrayDType"); vlsint32_t msb = adtypep->msb(); vlsint32_t lsb = adtypep->lsb(); if (lsb > msb) { // Below code assumes big bit endian; just works out if we swap int x = msb; msb = lsb; lsb = x; } UINFO(9," ArraySel-child: "<fileline(), topp, new AstConst(nodep->fileline(),lsb)); if (!newp->dtypep()) { newp->v3fatalSrc("ArraySel dtyping failed when resolving slice"); // see ArraySel constructor } newp->user1p(refp); newp->start(lsb); newp->length(msb - lsb + 1); topp = newp; } return topp->castArraySel(); } // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { // The LHS/RHS of an Assign may be to a Var that is an array. In this // case we need to create a slice across the entire Var if (m_assignp && !nodep->backp()->castArraySel()) { pair arrDim = nodep->varp()->dtypep()->dimensions(false); uint32_t dimensions = arrDim.second; // unpacked only if (dimensions > 0) { AstVarRef* clonep = nodep->cloneTree(false); clonep->user1p(nodep); AstNode* newp = insertImplicit(clonep, 1, dimensions); nodep->replaceWith(newp); nodep = NULL; newp->accept(*this); } } } virtual void visit(AstExtend* nodep, AstNUser*) { m_extend = true; if (m_assignp && m_assignp->user2() > 1 && !m_assignError) { m_assignp->v3error("Unsupported: Assignment between unpacked arrays of different dimensions"); m_assignError = true; } nodep->iterateChildren(*this); } virtual void visit(AstConst* nodep, AstNUser*) { m_extend = true; if (m_assignp && m_assignp->user2() > 1 && !m_assignError) { m_assignp->v3error("Unsupported: Assignment between a constant and an array slice"); m_assignError = true; } } virtual void visit(AstArraySel* nodep, AstNUser*) { if (!m_assignp) return; if (nodep->user3()) return; // Prevent recursion on just created nodes unsigned dim = explicitDimensions(nodep); AstVarRef* refp = nodep->user1p()->castNode()->castVarRef(); pair arrDim = refp->varp()->dtypep()->dimensions(false); uint32_t implicit = (arrDim.second) - dim; if (implicit > 0) { AstArraySel* newp = insertImplicit(nodep->cloneTree(false), dim+1, implicit); nodep->replaceWith(newp); nodep = newp; nodep->user3(true); } int clones = countClones(nodep); if (m_assignp->user2() > 0 && m_assignp->user2() != clones) { m_assignp->v3error("Slices of arrays in assignments must have the same unpacked dimensions"); } else if (!m_assignp->user2()) { if (m_extend && clones > 1 && !m_assignError) { m_assignp->v3error("Unsupported: Assignment between unpacked arrays of different dimensions"); m_assignError = true; } if (clones > 1 && !refp->lvalue() && refp->varp() == m_lhsVarRefp->varp() && !m_assignp->castAssignDly() && !m_assignError) { // LHS Var != RHS Var for a non-delayed assignment m_assignp->v3error("Unsupported: Slices in a non-delayed assignment with the same Var on both sides"); m_assignError = true; } m_assignp->user2(clones); } } virtual void visit(AstSel* nodep, AstNUser*) { m_extend = true; if (m_assignp && m_assignp->user2() > 1 && !m_assignError) { m_assignp->v3error("Unsupported: Assignment between unpacked arrays of different dimensions"); m_assignError = true; } nodep->iterateChildren(*this); } virtual void visit(AstNodeCond* nodep, AstNUser*) { // The conditional must be a single bit so only look at the expressions nodep->expr1p()->accept(*this); nodep->expr2p()->accept(*this); } // Return the first AstVarRef under the node AstVarRef* findVarRefRecurse(AstNode* nodep) { AstVarRef* refp = nodep->castVarRef(); if (refp) return refp; if (nodep->op1p()) { refp = findVarRefRecurse(nodep->op1p()); if (refp) return refp; } if (nodep->op2p()) { refp = findVarRefRecurse(nodep->op2p()); if (refp) return refp; } if (nodep->op3p()) { refp = findVarRefRecurse(nodep->op3p()); if (refp) return refp; } if (nodep->op4p()) { refp = findVarRefRecurse(nodep->op4p()); if (refp) return refp; } if (nodep->nextp()) { refp = findVarRefRecurse(nodep->nextp()); if (refp) return refp; } return NULL; } void findImplicit(AstNodeAssign* nodep) { if (m_assignp) nodep->v3fatalSrc("Found a NodeAssign under another NodeAssign"); m_assignp = nodep; m_assignError = false; m_extend = false; nodep->user1(true); // Record the LHS Var so we can check if the Var on the RHS is the same m_lhsVarRefp = findVarRefRecurse(nodep->lhsp()); if (!m_lhsVarRefp) nodep->v3fatalSrc("Couldn't find a VarRef on the LHSP of an Assign"); // Iterate children looking for ArraySel nodes. From that we get the number of elements // in the array so we know how many times we need to clone this assignment. nodep->iterateChildren(*this); if (nodep->user2() > 1) SliceCloneVisitor scv(nodep); m_assignp = NULL; } virtual void visit(AstNodeAssign* nodep, AstNUser*) { if (!nodep->user1()) { // Cleanup initArrays if (AstInitArray* initp = nodep->rhsp()->castInitArray()) { //if (debug()>=9) nodep->dumpTree(cout, "-InitArrayIn: "); AstNode* newp = NULL; int index = 0; while (AstNode* subp=initp->initsp()) { AstNode* lhsp = new AstArraySel(nodep->fileline(), nodep->lhsp()->cloneTree(false), index++); // cppcheck-suppress nullPointer newp = newp->addNext(nodep->cloneType(lhsp, subp->unlinkFrBack())); } //if (debug()>=9) newp->dumpTreeAndNext(cout, "-InitArrayOut: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; return; // WIll iterate in a moment } // Hasn't been searched for implicit slices yet findImplicit(nodep); } } void expandUniOp(AstNodeUniop* nodep) { nodep->user1(true); unsigned dim = 0; if (AstArraySel* selp = nodep->lhsp()->castArraySel()) { // We have explicit dimensions, either packed or unpacked dim = explicitDimensions(selp); } if (dim == 0 && !nodep->lhsp()->castVarRef()) { // No ArraySel nor VarRef, not something we can expand nodep->iterateChildren(*this); } else { AstVarRef* refp = findVarRefRecurse(nodep->lhsp()); ArrayDimensions varDim = refp->varp()->dtypep()->dimensions(false); if ((int)(dim - varDim.second) < 0) { // Unpacked dimensions are referenced first, make sure we have them all nodep->v3error("Unary operator used across unpacked dimensions"); } else if ((int)(dim - (varDim.second)) < 0) { // Implicit packed dimensions are allowed, make them explicit uint32_t newDim = (varDim.second) - dim; AstNode* clonep = nodep->lhsp()->cloneTree(false); clonep->user1p(refp); AstNode* newp = insertImplicit(clonep, dim+1, newDim); nodep->lhsp()->replaceWith(newp); refp = NULL; int clones = countClones(nodep->lhsp()->castArraySel()); nodep->user2(clones); SliceCloneVisitor scv(nodep); } } } virtual void visit(AstRedOr* nodep, AstNUser*) { if (!nodep->user1()) { expandUniOp(nodep); } } virtual void visit(AstRedAnd* nodep, AstNUser*) { if (!nodep->user1()) { expandUniOp(nodep); } } virtual void visit(AstRedXor* nodep, AstNUser*) { if (!nodep->user1()) { expandUniOp(nodep); } } virtual void visit(AstRedXnor* nodep, AstNUser*) { if (!nodep->user1()) { expandUniOp(nodep); } } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS SliceVisitor(AstNetlist* rootp) { m_assignp = NULL; m_lhsVarRefp = NULL; rootp->accept(*this); } virtual ~SliceVisitor() {} }; //###################################################################### // Link class functions void V3Slice::sliceAll(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3EmitV.cpp0000664000177100017500000006060112525171733016264 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit Verilog from tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3EmitV.h" #include "V3EmitCBase.h" //###################################################################### // Emit statements and math operators class EmitVBaseVisitor : public EmitCBaseVisitor { // MEMBERS bool m_suppressSemi; AstSenTree* m_sensesp; // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual void puts(const string& str) = 0; virtual void putbs(const string& str) = 0; virtual void putfs(AstNode* nodep, const string& str) = 0; // Fileline and node %% mark virtual void putqs(AstNode* nodep, const string& str) = 0; // Fileline quiet w/o %% mark virtual void putsNoTracking(const string& str) = 0; virtual void putsQuoted(const string& str) { // Quote \ and " for use inside C programs // Don't use to quote a filename for #include - #include doesn't \ escape. // Duplicate in V3File - here so we can print to string putsNoTracking("\""); putsNoTracking(V3Number::quoteNameControls(str)); putsNoTracking("\""); } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { nodep->iterateChildren(*this); } virtual void visit(AstNodeModule* nodep, AstNUser*) { putfs(nodep, nodep->verilogKwd()+" "+modClassName(nodep)+";\n"); nodep->iterateChildren(*this); putqs(nodep, "end"+nodep->verilogKwd()+"\n"); } virtual void visit(AstNodeFTask* nodep, AstNUser*) { putfs(nodep, nodep->isFunction() ? "function":"task"); puts(" "); puts(nodep->prettyName()); puts(";\n"); putqs(nodep, "begin\n"); // Only putfs the first time for each visitor; later for same node is putqs nodep->stmtsp()->iterateAndNext(*this); putqs(nodep, "end\n"); } virtual void visit(AstBegin* nodep, AstNUser*) { if (nodep->unnamed()) { putbs("begin\n"); } else { putbs("begin : "+nodep->name()+"\n"); } nodep->iterateChildren(*this); puts("end\n"); } virtual void visit(AstGenerate* nodep, AstNUser*) { putfs(nodep, "generate\n"); nodep->iterateChildren(*this); putqs(nodep, "end\n"); } virtual void visit(AstFinal* nodep, AstNUser*) { putfs(nodep, "final begin\n"); nodep->iterateChildren(*this); putqs(nodep, "end\n"); } virtual void visit(AstInitial* nodep, AstNUser*) { putfs(nodep,"initial begin\n"); nodep->iterateChildren(*this); putqs(nodep, "end\n"); } virtual void visit(AstAlways* nodep, AstNUser*) { putfs(nodep,"always "); if (m_sensesp) m_sensesp->iterateAndNext(*this); // In active else nodep->sensesp()->iterateAndNext(*this); putbs(" begin\n"); nodep->bodysp()->iterateAndNext(*this); putqs(nodep,"end\n"); } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { putfs(nodep,"/*verilator public_flat_rw "); if (m_sensesp) m_sensesp->iterateAndNext(*this); // In active else nodep->sensesp()->iterateAndNext(*this); putqs(nodep," "); nodep->bodysp()->iterateAndNext(*this); putqs(nodep,"*/\n"); } virtual void visit(AstNodeAssign* nodep, AstNUser*) { nodep->lhsp()->iterateAndNext(*this); putfs(nodep," "+nodep->verilogKwd()+" "); nodep->rhsp()->iterateAndNext(*this); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstAssignDly* nodep, AstNUser*) { nodep->lhsp()->iterateAndNext(*this); putfs(nodep," <= "); nodep->rhsp()->iterateAndNext(*this); puts(";\n"); } virtual void visit(AstAssignAlias* nodep, AstNUser*) { putbs("alias "); nodep->lhsp()->iterateAndNext(*this); putfs(nodep," = "); nodep->rhsp()->iterateAndNext(*this); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstAssignW* nodep, AstNUser*) { putfs(nodep,"assign "); nodep->lhsp()->iterateAndNext(*this); putbs(" = "); nodep->rhsp()->iterateAndNext(*this); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstBreak* nodep, AstNUser*) { putbs("break"); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstSenTree* nodep, AstNUser*) { // AstSenItem is called for dumping in isolation by V3Order putfs(nodep,"@("); for (AstNode* expp=nodep->sensesp(); expp; expp = expp->nextp()) { expp->accept(*this); if (expp->nextp()) putqs(expp->nextp()," or "); } puts(")"); } virtual void visit(AstSenGate* nodep, AstNUser*) { emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->sensesp(), nodep->rhsp()); } virtual void visit(AstSenItem* nodep, AstNUser*) { putfs(nodep,""); puts(nodep->edgeType().verilogKwd()); if (nodep->sensp()) puts(" "); nodep->iterateChildren(*this); } virtual void visit(AstNodeCase* nodep, AstNUser*) { putfs(nodep,""); if (AstCase* casep = nodep->castCase()) { if (casep->priorityPragma()) puts("priority "); if (casep->uniquePragma()) puts("unique "); if (casep->unique0Pragma()) puts("unique0 "); } puts(nodep->verilogKwd()); puts(" ("); nodep->exprp()->iterateAndNext(*this); puts(")\n"); if (AstCase* casep = nodep->castCase()) { if (casep->fullPragma() || casep->parallelPragma()) { puts(" // synopsys"); if (casep->fullPragma()) puts(" full_case"); if (casep->parallelPragma()) puts(" parallel_case"); } } nodep->itemsp()->iterateAndNext(*this); putqs(nodep,"endcase\n"); } virtual void visit(AstCaseItem* nodep, AstNUser*) { if (nodep->condsp()) { nodep->condsp()->iterateAndNext(*this); } else putbs("default"); putfs(nodep,": begin "); nodep->bodysp()->iterateAndNext(*this); putqs(nodep,"end\n"); } virtual void visit(AstComment* nodep, AstNUser*) { puts((string)"// "+nodep->name()+"\n"); nodep->iterateChildren(*this); } virtual void visit(AstContinue* nodep, AstNUser*) { putbs("continue"); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstCoverDecl*, AstNUser*) {} // N/A virtual void visit(AstCoverInc*, AstNUser*) {} // N/A virtual void visit(AstCoverToggle*, AstNUser*) {} // N/A void visitNodeDisplay(AstNode* nodep, AstNode* fileOrStrgp, const string& text, AstNode* exprsp) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (fileOrStrgp) { fileOrStrgp->iterateAndNext(*this); putbs(","); } putsQuoted(text); for (AstNode* expp=exprsp; expp; expp = expp->nextp()) { puts(","); expp->iterateAndNext(*this); } puts(");\n"); } virtual void visit(AstDisable* nodep, AstNUser*) { putbs("disable "+nodep->name()+";\n"); } virtual void visit(AstDisplay* nodep, AstNUser*) { visitNodeDisplay(nodep, nodep->filep(), nodep->fmtp()->text(), nodep->fmtp()->exprsp()); } virtual void visit(AstFScanF* nodep, AstNUser*) { visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp()); } virtual void visit(AstSScanF* nodep, AstNUser*) { visitNodeDisplay(nodep, nodep->fromp(), nodep->text(), nodep->exprsp()); } virtual void visit(AstSFormat* nodep, AstNUser*) { visitNodeDisplay(nodep, nodep->lhsp(), nodep->fmtp()->text(), nodep->fmtp()->exprsp()); } virtual void visit(AstSFormatF* nodep, AstNUser*) { visitNodeDisplay(nodep, NULL, nodep->text(), nodep->exprsp()); } virtual void visit(AstValuePlusArgs* nodep, AstNUser*) { visitNodeDisplay(nodep, NULL, nodep->text(), nodep->exprsp()); } virtual void visit(AstFOpen* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filep()) nodep->filep()->iterateAndNext(*this); putbs(","); if (nodep->filenamep()) nodep->filenamep()->iterateAndNext(*this); putbs(","); if (nodep->modep()) nodep->modep()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstFClose* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filep()) nodep->filep()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstFFlush* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filep()) nodep->filep()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstJumpGo* nodep, AstNUser*) { putbs("disable "+cvtToStr((void*)(nodep->labelp()))+";\n"); } virtual void visit(AstJumpLabel* nodep, AstNUser*) { putbs("begin : "+cvtToStr((void*)(nodep))+"\n"); if (nodep->stmtsp()) nodep->stmtsp()->iterateAndNext(*this); puts("end\n"); } virtual void visit(AstReadMem* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); if (nodep->filenamep()) nodep->filenamep()->iterateAndNext(*this); putbs(","); if (nodep->memp()) nodep->memp()->iterateAndNext(*this); if (nodep->lsbp()) { putbs(","); nodep->lsbp()->iterateAndNext(*this); } if (nodep->msbp()) { putbs(","); nodep->msbp()->iterateAndNext(*this); } puts(");\n"); } virtual void visit(AstSysIgnore* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); putbs(" ("); nodep->exprsp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstNodeFor* nodep, AstNUser*) { putfs(nodep,"for ("); m_suppressSemi = true; nodep->initsp()->iterateAndNext(*this); puts(";"); nodep->condp()->iterateAndNext(*this); puts(";"); nodep->incsp()->iterateAndNext(*this); m_suppressSemi = false; puts(") begin\n"); nodep->bodysp()->iterateAndNext(*this); putqs(nodep,"end\n"); } virtual void visit(AstRepeat* nodep, AstNUser*) { putfs(nodep,"repeat ("); nodep->countp()->iterateAndNext(*this); puts(") begin\n"); nodep->bodysp()->iterateAndNext(*this); putfs(nodep,"end\n"); } virtual void visit(AstWhile* nodep, AstNUser*) { nodep->precondsp()->iterateAndNext(*this); putfs(nodep,"while ("); nodep->condp()->iterateAndNext(*this); puts(") begin\n"); nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); nodep->precondsp()->iterateAndNext(*this); // Need to recompute before next loop putfs(nodep,"end\n"); } virtual void visit(AstNodeIf* nodep, AstNUser*) { putfs(nodep,""); if (AstIf* ifp = nodep->castIf()) { if (ifp->priorityPragma()) puts("priority "); if (ifp->uniquePragma()) puts("unique "); if (ifp->unique0Pragma()) puts("unique0 "); } puts("if ("); nodep->condp()->iterateAndNext(*this); puts(") begin\n"); nodep->ifsp()->iterateAndNext(*this); if (nodep->elsesp()) { putqs(nodep,"end\n"); putqs(nodep,"else begin\n"); nodep->elsesp()->iterateAndNext(*this); } putqs(nodep,"end\n"); } virtual void visit(AstReturn* nodep, AstNUser*) { putfs(nodep,"return "); nodep->lhsp()->iterateAndNext(*this); puts(";\n"); } virtual void visit(AstStop* nodep, AstNUser*) { putfs(nodep,"$stop;\n"); } virtual void visit(AstFinish* nodep, AstNUser*) { putfs(nodep,"$finish;\n"); } virtual void visit(AstText* nodep, AstNUser*) { putsNoTracking(nodep->text()); } virtual void visit(AstScopeName* nodep, AstNUser*) { } virtual void visit(AstCStmt* nodep, AstNUser*) { putfs(nodep,"$_CSTMT("); nodep->bodysp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstCMath* nodep, AstNUser*) { putfs(nodep,"$_CMATH("); nodep->bodysp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstUCStmt* nodep, AstNUser*) { putfs(nodep,"$c("); nodep->bodysp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstUCFunc* nodep, AstNUser*) { putfs(nodep,"$c("); nodep->bodysp()->iterateAndNext(*this); puts(")"); } // Operators virtual void emitVerilogFormat(AstNode* nodep, const string& format, AstNode* lhsp=NULL, AstNode* rhsp=NULL, AstNode* thsp=NULL) { // Look at emitVerilog() format for term/uni/dual/triops, // and write out appropriate text. // %f Potential fileline-if-change and line break // %l lhsp - if appropriate // %r rhsp - if appropriate // %t thsp - if appropriate // %d dtypep - if appropriate // %k Potential line break bool inPct = false; putbs(""); for (string::const_iterator pos = format.begin(); pos != format.end(); ++pos) { if (pos[0]=='%') { inPct = true; } else if (!inPct) { // Normal text string s; s+=pos[0]; puts(s); } else { // Format character inPct = false; switch (*pos) { case '%': puts("%"); break; case 'f': putfs(nodep,""); break; case 'k': putbs(""); break; case 'l': { if (!lhsp) { nodep->v3fatalSrc("emitVerilog() references undef node"); } else lhsp->iterateAndNext(*this); break; } case 'r': { if (!rhsp) { nodep->v3fatalSrc("emitVerilog() references undef node"); } else rhsp->iterateAndNext(*this); break; } case 't': { if (!thsp) { nodep->v3fatalSrc("emitVerilog() references undef node"); } else thsp->iterateAndNext(*this); break; } case 'd': { if (!nodep->dtypep()) { nodep->v3fatalSrc("emitVerilog() references undef node"); } else nodep->dtypep()->iterateAndNext(*this); break; } default: nodep->v3fatalSrc("Unknown emitVerilog format code: %"<emitVerilog()); } virtual void visit(AstNodeUniop* nodep, AstNUser*) { emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->lhsp()); } virtual void visit(AstNodeBiop* nodep, AstNUser*) { emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->lhsp(), nodep->rhsp()); } virtual void visit(AstNodeTriop* nodep, AstNUser*) { emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->lhsp(), nodep->rhsp(), nodep->thsp()); } virtual void visit(AstAttrOf* nodep, AstNUser*) { putfs(nodep,"$_ATTROF("); nodep->fromp()->iterateAndNext(*this); if (nodep->dimp()) { putbs(","); nodep->dimp()->iterateAndNext(*this); } puts(")"); } virtual void visit(AstInitArray* nodep, AstNUser*) { putfs(nodep,"`{"); for (AstNode* subp = nodep->initsp(); subp; subp=subp->nextp()) { subp->accept(*this); if (subp->nextp()) putbs(","); } puts("}"); } virtual void visit(AstNodeCond* nodep, AstNUser*) { putbs("("); nodep->condp()->iterateAndNext(*this); putfs(nodep," ? "); nodep->expr1p()->iterateAndNext(*this); putbs(" : "); nodep->expr2p()->iterateAndNext(*this); puts(")"); } virtual void visit(AstRange* nodep, AstNUser*) { puts("["); if (nodep->msbp()->castConst() && nodep->lsbp()->castConst()) { // Looks nicer if we print [1:0] rather than [32'sh1:32sh0] puts(cvtToStr(nodep->leftp()->castConst()->toSInt())); puts(":"); puts(cvtToStr(nodep->rightp()->castConst()->toSInt())); puts("]"); } else { nodep->leftp()->iterateAndNext(*this); puts(":"); nodep->rightp()->iterateAndNext(*this); puts("]"); } } virtual void visit(AstSel* nodep, AstNUser*) { nodep->fromp()->iterateAndNext(*this); puts("["); if (nodep->lsbp()->castConst()) { if (nodep->widthp()->isOne()) { if (nodep->lsbp()->castConst()) { puts(cvtToStr(nodep->lsbp()->castConst()->toSInt())); } else { nodep->lsbp()->iterateAndNext(*this); } } else { puts(cvtToStr(nodep->lsbp()->castConst()->toSInt() +nodep->widthp()->castConst()->toSInt() -1)); puts(":"); puts(cvtToStr(nodep->lsbp()->castConst()->toSInt())); } } else { nodep->lsbp()->iterateAndNext(*this); putfs(nodep,"+:"); nodep->widthp()->iterateAndNext(*this); puts("]"); } puts("]"); } virtual void visit(AstTypedef* nodep, AstNUser*) { putfs(nodep,"typedef "); nodep->dtypep()->iterateAndNext(*this); puts(" "); puts(nodep->prettyName()); puts(";\n"); } virtual void visit(AstBasicDType* nodep, AstNUser*) { if (nodep->isSigned()) putfs(nodep,"signed "); putfs(nodep,nodep->prettyName()); if (nodep->rangep()) { puts(" "); nodep->rangep()->iterateAndNext(*this); puts(" "); } else if (nodep->isRanged()) { puts(" ["); puts(cvtToStr(nodep->msb())); puts(":0] "); } } virtual void visit(AstConstDType* nodep, AstNUser*) { putfs(nodep,"const "); nodep->subDTypep()->accept(*this); } virtual void visit(AstNodeArrayDType* nodep, AstNUser*) { nodep->subDTypep()->accept(*this); nodep->rangep()->iterateAndNext(*this); } virtual void visit(AstNodeClassDType* nodep, AstNUser*) { puts(nodep->verilogKwd()+" "); if (nodep->packed()) puts("packed "); puts("\n"); nodep->membersp()->iterateAndNext(*this); puts("}"); } virtual void visit(AstMemberDType* nodep, AstNUser*) { nodep->subDTypep()->accept(*this); puts(" "); puts(nodep->name()); puts("}"); } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { if (nodep->dotted()!="") { putfs(nodep,nodep->dotted()); puts("."); puts(nodep->prettyName()); } else { putfs(nodep,nodep->prettyName()); } puts("("); nodep->pinsp()->iterateAndNext(*this); puts(")"); } virtual void visit(AstArg* nodep, AstNUser*) { nodep->exprp()->iterateAndNext(*this); } // Terminals virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->varScopep()) putfs(nodep,nodep->varScopep()->prettyName()); else { putfs(nodep,nodep->hiername()); puts(nodep->varp()->prettyName()); } } virtual void visit(AstVarXRef* nodep, AstNUser*) { putfs(nodep,nodep->dotted()); puts("."); puts(nodep->varp()->prettyName()); } virtual void visit(AstConst* nodep, AstNUser*) { putfs(nodep,nodep->num().ascii(true,true)); } // Just iterate virtual void visit(AstTopScope* nodep, AstNUser*) { nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep, AstNUser*) { nodep->iterateChildren(*this); } virtual void visit(AstVar* nodep, AstNUser*) { putfs(nodep,nodep->verilogKwd()); puts(" "); nodep->dtypep()->iterate(*this); puts(" "); puts(nodep->prettyName()); puts(";\n"); } virtual void visit(AstActive* nodep, AstNUser*) { m_sensesp = nodep->sensesp(); nodep->stmtsp()->iterateAndNext(*this); m_sensesp = NULL; } virtual void visit(AstVarScope*, AstNUser*) {} virtual void visit(AstNodeText*, AstNUser*) {} virtual void visit(AstTraceDecl*, AstNUser*) {} virtual void visit(AstTraceInc*, AstNUser*) {} // NOPs virtual void visit(AstPragma*, AstNUser*) {} virtual void visit(AstCell*, AstNUser*) {} // Handled outside the Visit class // Default virtual void visit(AstNode* nodep, AstNUser*) { puts((string)"\n???? // "+nodep->prettyTypeName()+"\n"); nodep->iterateChildren(*this); // Not v3fatalSrc so we keep processing nodep->v3error("Internal: Unknown node type reached emitter: "<prettyTypeName()); } public: EmitVBaseVisitor(AstSenTree* domainp=NULL) { // Domain for printing one a ALWAYS under a ACTIVE m_suppressSemi = false; m_sensesp = domainp; } virtual ~EmitVBaseVisitor() {} }; //###################################################################### // Emit to an output file class EmitVFileVisitor : public EmitVBaseVisitor { // MEMBERS V3OutFile* m_ofp; // METHODS V3OutFile* ofp() const { return m_ofp; } virtual void puts(const string& str) { ofp()->puts(str); } virtual void putbs(const string& str) { ofp()->putbs(str); } virtual void putfs(AstNode*, const string& str) { putbs(str); } virtual void putqs(AstNode*, const string& str) { putbs(str); } virtual void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); } public: EmitVFileVisitor(AstNode* nodep, V3OutFile* ofp) { m_ofp = ofp; nodep->accept(*this); } virtual ~EmitVFileVisitor() {} }; //###################################################################### // Emit to a stream (perhaps stringstream) class EmitVStreamVisitor : public EmitVBaseVisitor { // MEMBERS ostream& m_os; // METHODS virtual void putsNoTracking(const string& str) { m_os<accept(*this); } virtual ~EmitVStreamVisitor() {} }; //###################################################################### // Emit to a stream (perhaps stringstream) class EmitVPrefixedFormatter : public V3OutFormatter { ostream& m_os; string m_prefix; // What to print at beginning of each line int m_flWidth; // Padding of fileline int m_column; // Rough location; need just zero or non-zero FileLine* m_prefixFl; // METHODS virtual void putcOutput(char chr) { if (chr == '\n') { m_column = 0; m_os<ascii()+":"; m_os<ascii().length()+1)); m_os<<" "; m_os<fileline(); // NETLIST's fileline instead of NULL to avoid NULL checks } virtual ~EmitVPrefixedFormatter() { if (m_column) puts("\n"); } }; class EmitVPrefixedVisitor : public EmitVBaseVisitor { // MEMBERS EmitVPrefixedFormatter m_formatter; // Special verilog formatter (Way down the inheritance is another unused V3OutFormatter) // METHODS virtual void putsNoTracking(const string& str) { m_formatter.putsNoTracking(str); } virtual void puts(const string& str) { m_formatter.puts(str); } // We don't use m_formatter's putbs because the tokens will change filelines // and insert returns at the proper locations virtual void putbs(const string& str) { m_formatter.puts(str); } virtual void putfs(AstNode* nodep, const string& str) { putfsqs(nodep,str,false); } virtual void putqs(AstNode* nodep, const string& str) { putfsqs(nodep,str,true); } void putfsqs(AstNode* nodep, const string& str, bool quiet) { if (m_formatter.prefixFl() != nodep->fileline()) { m_formatter.prefixFl(nodep->fileline()); if (m_formatter.column()) puts("\n"); // This in turn will print the m_prefixFl } if (!quiet && nodep->user3()) puts("%%"); putbs(str); } public: EmitVPrefixedVisitor(AstNode* nodep, ostream& os, const string& prefix, int flWidth, AstSenTree* domainp, bool user3mark) : EmitVBaseVisitor(domainp), m_formatter(os, prefix, flWidth) { if (user3mark) { AstUser3InUse::check(); } nodep->accept(*this); } virtual ~EmitVPrefixedVisitor() {} }; //###################################################################### // EmitV class functions void V3EmitV::emitv() { UINFO(2,__FUNCTION__<<": "<modulesp(); modp; modp=modp->nextp()->castNodeModule()) { V3OutVFile of (v3Global.opt.makeDir() +"/"+EmitCBaseVisitor::modClassName(modp)+"__Vout.v"); of.putsHeader(); EmitVFileVisitor visitor (modp, &of); } } } void V3EmitV::verilogForTree(AstNode* nodep, ostream& os) { EmitVStreamVisitor(nodep, os); } void V3EmitV::verilogPrefixedTree(AstNode* nodep, ostream& os, const string& prefix, int flWidth, AstSenTree* domainp, bool user3mark) { EmitVPrefixedVisitor(nodep, os, prefix, flWidth, domainp, user3mark); } verilator-3.874/src/V3EmitMk.h0000664000177100017500000000223012525171733016065 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit Makefile // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EMITMK_H_ #define _V3EMITMK_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3EmitMk { public: static void emitmk(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Expand.h0000664000177100017500000000227612525171733016130 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Expansion of wide operator macros to C operators // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EXPAND_H_ #define _V3EXPAND_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Expand { public: static void expandAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Case.cpp0000664000177100017500000004532412525171733016120 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break case statements up and add Unknown assigns // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Case's Transformations: // // Each module: // TBD: Eliminate tristates by adding __in, __inen, __en wires in parallel // Need __en in changed list if a signal is on the LHS of a assign // Cases: // CASE(v) CASEITEM(items,body) -> IF (OR (EQ (AND v mask) // (AND item1 mask)) // (other items)) // body // Or, converts to a if/else tree. // FUTURES: // Large 16+ bit tables with constants and no masking (address muxes) // Enter all into multimap, sort by value and use a tree of < and == compares. // "Diagonal" find of {rightmost,leftmost} bit {set,clear} // Ignoring mask, check each value is unique (using multimap as above?) // Each branch is then mask-and-compare operation (IE <000000001_000000000 at midpoint.) // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Case.h" #include "V3Ast.h" #include "V3Stats.h" #define CASE_OVERLAP_WIDTH 12 // Maximum width we can check for overlaps in #define CASE_BARF 999999 // Magic width when non-constant #define CASE_ENCODER_GROUP_DEPTH 8 // Levels of priority to be ORed together in top IF tree //###################################################################### class CaseLintVisitor : public AstNVisitor { private: AstNodeCase* m_caseExprp; // Under a CASE value node, if so the relevant case statement static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual void visit(AstNodeCase* nodep, AstNUser*) { if (nodep->castCase() && nodep->castCase()->casex()) { nodep->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)"); } // Detect multiple defaults bool hitDefault = false; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { if (itemp->isDefault()) { if (hitDefault) { nodep->v3error("Multiple default statements in case statement."); } hitDefault = true; } } // Check for X/Z in non-casex statements { m_caseExprp = nodep; nodep->exprp()->accept(*this); for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { itemp->condsp()->iterateAndNext(*this); } m_caseExprp = NULL; } } virtual void visit(AstConst* nodep, AstNUser*) { // See also neverItem if (m_caseExprp && nodep->num().isFourState()) { if (m_caseExprp->castGenCase()) { nodep->v3error("Use of x/? constant in generate case statement, (no such thing as 'generate casez')"); } else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casex()) { // Don't sweat it, we already complained about casex in general } else if (m_caseExprp->castCase() && (m_caseExprp->castCase()->casez() || m_caseExprp->castCase()->caseInside())) { if (nodep->num().isUnknown()) { nodep->v3warn(CASEWITHX, "Use of x constant in casez statement, (perhaps intended ?/z in constant)"); } } else { nodep->v3warn(CASEWITHX, "Use of x/? constant in case statement, (perhaps intended casex/casez)"); } } } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS CaseLintVisitor(AstNodeCase* nodep) { m_caseExprp = NULL; nodep->accept(*this); } virtual ~CaseLintVisitor() {} }; //###################################################################### // Case state, as a visitor of each AstNode class CaseVisitor : public AstNVisitor { private: // NODE STATE // Cleared each Case // AstIf::user3() -> bool. Set true to indicate clone not needed AstUser3InUse m_inuser3; // STATE V3Double0 m_statCaseFast; // Statistic tracking V3Double0 m_statCaseSlow; // Statistic tracking // Per-CASE int m_caseWidth; // Width of valueItems int m_caseItems; // Number of caseItem unique values bool m_caseNoOverlapsAllCovered; // Proven to be synopsys parallel_case compliant AstNode* m_valueItem[1<itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) { if (icondp->width() > width) width = icondp->width(); if (icondp->isDouble()) opaque = true; if (!icondp->castConst()) width = CASE_BARF; // Can't parse; not a constant m_caseItems++; } } m_caseWidth = width; if (width==0 || width > CASE_OVERLAP_WIDTH || opaque) { m_caseNoOverlapsAllCovered = false; return false; // Too wide for analysis } UINFO(8,"Simple case statement: "<itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) { //if (debug()>=9) icondp->dumpTree(cout," caseitem: "); AstConst* iconstp = icondp->castConst(); if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this\n"); if (neverItem(nodep, iconstp)) { // X in casez can't ever be executed } else { V3Number nummask (itemp->fileline(), iconstp->width()); nummask.opBitsNonX(iconstp->num()); uint32_t mask = nummask.toUInt(); V3Number numval (itemp->fileline(), iconstp->width()); numval.opBitsOne(iconstp->num()); uint32_t val = numval.toUInt(); for (uint32_t i=0; i<(1UL<ignoreOverlap() && !bitched) { itemp->v3warn(CASEOVERLAP,"Case values overlap (example pattern 0x"<isDefault()) { // Case statement's default... Fill the table for (uint32_t i=0; i<(1UL<v3warn(CASEINCOMPLETE,"Case values incompletely covered (example pattern 0x"<castCaseItem()->bodysp(); } return true; // All is fine } AstNode* replaceCaseFastRecurse(AstNode* cexprp, int msb, uint32_t upperValue) { if (msb<0) { // There's no space for a IF. We know upperValue is thus down to a specific // exact value, so just return the tree value // Note can't clone here, as we're going to check for equivelence above return m_valueItem[upperValue]; } else { // Make left and right subtrees // cexpr[msb:lsb] == 1 AstNode* tree0p = replaceCaseFastRecurse(cexprp, msb-1, upperValue | 0); AstNode* tree1p = replaceCaseFastRecurse(cexprp, msb-1, upperValue | (1UL<deleteTree(); tree1p=NULL; return tree0p; } // Must have differing logic, so make a selection // Case expressions can't be linked twice, so clone them if (tree0p && !tree0p->user3()) tree0p = tree0p->cloneTree(true); if (tree1p && !tree1p->user3()) tree1p = tree1p->cloneTree(true); // Alternate scheme if we ever do multiple bits at a time: //V3Number nummask (cexprp->fileline(), cexprp->width(), (1UL<fileline(), cexprp->cloneTree(false), // new AstConst(cexprp->fileline(), nummask)); AstNode* and1p = new AstSel(cexprp->fileline(), cexprp->cloneTree(false), msb, 1); AstNode* eqp = new AstNeq(cexprp->fileline(), new AstConst(cexprp->fileline(), 0), and1p); AstIf* ifp = new AstIf(cexprp->fileline(), eqp, tree1p, tree0p); ifp->user3(1); // So we don't bother to clone it return ifp; } } void replaceCaseFast(AstCase* nodep) { // CASEx(cexpr,.... // -> tree of IF(msb, IF(msb-1, 11, 10) // IF(msb-1, 01, 00)) AstNode* cexprp = nodep->exprp()->unlinkFrBack(); if (debug()>=9) { for (uint32_t i=0; i<(1UL<user3()) ifrootp = ifrootp->cloneTree(true); if (ifrootp) nodep->replaceWith(ifrootp); else nodep->unlinkFrBack(); nodep->deleteTree(); nodep=NULL; cexprp->deleteTree(); cexprp=NULL; if (debug()>=9) ifrootp->dumpTree(cout," _simp: "); } void replaceCaseComplicated(AstCase* nodep) { // CASEx(cexpr,ITEM(icond1,istmts1),ITEM(icond2,istmts2),ITEM(default,istmts3)) // -> IF((cexpr==icond1),istmts1, // IF((EQ (AND MASK cexpr) (AND MASK icond1) // ,istmts2, istmts3 AstNode* cexprp = nodep->exprp()->unlinkFrBack(); // We'll do this in two stages. First stage, convert the conditions to // the appropriate IF AND terms. if (debug()>=9) nodep->dumpTree(cout," _comp_IN: "); bool hadDefault = false; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { if (!itemp->condsp()) { // Default clause. Just make true, we'll optimize it away later itemp->condsp(new AstConst(itemp->fileline(), AstConst::LogicTrue())); hadDefault = true; } else { // Expressioned clause AstNode* icondNextp = NULL; AstNode* ifexprp = NULL; // If expression to test for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondNextp) { icondNextp = icondp->nextp(); icondp->unlinkFrBack(); AstNode* condp = NULL; // Default is to use and1p/and2p AstConst* iconstp = icondp->castConst(); if (iconstp && neverItem(nodep, iconstp)) { // X in casez can't ever be executed icondp->deleteTree(); icondp=NULL; iconstp=NULL; // For simplicity, make expression that is not equal, and let later // optimizations remove it condp = new AstConst(itemp->fileline(), AstConst::LogicFalse()); } else if (AstInsideRange* irangep = icondp->castInsideRange()) { // Similar logic in V3Width::visit(AstInside) AstNode* ap = AstGte::newTyped(itemp->fileline(), cexprp->cloneTree(false), irangep->lhsp()->unlinkFrBack()); AstNode* bp = AstLte::newTyped(itemp->fileline(), cexprp->cloneTree(false), irangep->rhsp()->unlinkFrBack()); condp = new AstAnd(itemp->fileline(), ap, bp); } else if (iconstp && iconstp->num().isFourState() && (nodep->casex() || nodep->casez() || nodep->caseInside())) { V3Number nummask (itemp->fileline(), iconstp->width()); nummask.opBitsNonX(iconstp->num()); V3Number numval (itemp->fileline(), iconstp->width()); numval.opBitsOne(iconstp->num()); AstNode* and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false), new AstConst(itemp->fileline(), nummask)); AstNode* and2p = new AstAnd(itemp->fileline(), new AstConst(itemp->fileline(), numval), new AstConst(itemp->fileline(), nummask)); icondp->deleteTree(); icondp=NULL; iconstp=NULL; condp = AstEq::newTyped(itemp->fileline(), and1p, and2p); } else { // Not a caseX mask, we can simply build CASEEQ(cexpr icond) AstNode* and1p = cexprp->cloneTree(false); AstNode* and2p = icondp; condp = AstEq::newTyped(itemp->fileline(), and1p, and2p); } if (!ifexprp) { ifexprp = condp; } else { ifexprp = new AstLogOr(itemp->fileline(), ifexprp, condp); } } // Replace expression in tree itemp->condsp(ifexprp); } } cexprp->deleteTree(); cexprp=NULL; if (!hadDefault) { // If there was no default, add a empty one, this greatly simplifies below code // and constant propagation will just eliminate it for us later. nodep->addItemsp(new AstCaseItem(nodep->fileline(), new AstConst(nodep->fileline(), AstConst::LogicTrue()), NULL)); } if (debug()>=9) nodep->dumpTree(cout," _comp_COND: "); // Now build the IF statement tree // The tree can be quite huge. Pull ever group of 8 out, and make a OR tree. // This reduces the depth for the bottom elements, at the cost of some of the top elements. // If we ever have profiling data, we should pull out the most common item from here and // instead make it the first IF branch. int depth = 0; AstNode* grouprootp = NULL; AstIf* groupnextp = NULL; AstIf* itemnextp = NULL; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action. if (istmtsp) istmtsp->unlinkFrBackWithNext(); // Expressioned clause AstNode* ifexprp = itemp->condsp()->unlinkFrBack(); { // Prepare for next group if (++depth > CASE_ENCODER_GROUP_DEPTH) depth = 1; if (depth == 1) { // First group or starting new group itemnextp = NULL; AstIf* newp = new AstIf(itemp->fileline(), ifexprp->cloneTree(true), NULL, NULL); if (groupnextp) groupnextp->addElsesp(newp); else grouprootp = newp; groupnextp = newp; } else { // Continue group, modify if condition to OR in this new condition AstNode* condp = groupnextp->condp()->unlinkFrBack(); groupnextp->condp(new AstOr(ifexprp->fileline(), condp, ifexprp->cloneTree(true))); } } { // Make the new lower IF and attach in the tree AstNode* itemexprp = ifexprp; ifexprp=NULL; if (depth == (CASE_ENCODER_GROUP_DEPTH)) { // End of group - can skip the condition itemexprp->deleteTree(); itemexprp=NULL; // cppcheck-suppress redundantAssignment itemexprp = new AstConst(itemp->fileline(), AstConst::LogicTrue()); } AstIf* newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, NULL); if (itemnextp) itemnextp->addElsesp(newp); else groupnextp->addIfsp(newp); // First in a new group itemnextp = newp; } } if (debug()>=9) nodep->dumpTree(cout," _comp_TREE: "); // Handle any assertions replaceCaseParallel(nodep, false); // Replace the CASE... with IF... if (debug()>=9) grouprootp->dumpTree(cout," _new: "); if (grouprootp) nodep->replaceWith(grouprootp); else nodep->unlinkFrBack(); nodep->deleteTree(); nodep=NULL; } void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) { // Take the notParallelp tree under the case statement created by V3Assert // If the statement was proven to have no overlaps and all cases covered, we're done with it. // Else, convert to a normal statement parallel with the case statement. if (nodep->notParallelp() && !noOverlapsAllCovered) { AstNode* parp = nodep->notParallelp()->unlinkFrBackWithNext(); nodep->addNextHere(parp); } } bool neverItem(AstCase* casep, AstConst* itemp) { // Xs in case or casez are impossible due to two state simulations if (casep->casex()) { } else if (casep->casez() || casep->caseInside()) { if (itemp->num().isUnknown()) return true; } else { if (itemp->num().isFourState()) return true; } return false; } // VISITORS virtual void visit(AstCase* nodep, AstNUser*) { V3Case::caseLint(nodep); nodep->iterateChildren(*this); if (debug()>=9) nodep->dumpTree(cout," case_old: "); if (isCaseTreeFast(nodep) && v3Global.opt.oCase()) { // It's a simple priority encoder or complete statement // we can make a tree of statements to avoid extra comparisons ++m_statCaseFast; replaceCaseFast(nodep); nodep=NULL; } else { ++m_statCaseSlow; // cppcheck-supporess uselessAssignmentPtrArg replaceCaseComplicated(nodep); nodep=NULL; } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS CaseVisitor(AstNetlist* nodep) { m_caseNoOverlapsAllCovered = false; nodep->accept(*this); } virtual ~CaseVisitor() { V3Stats::addStat("Optimizations, Cases parallelized", m_statCaseFast); V3Stats::addStat("Optimizations, Cases complex", m_statCaseSlow); } }; //###################################################################### // Case class functions void V3Case::caseAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Case::caseLint(AstNodeCase* nodep) { UINFO(4,__FUNCTION__<<": "< #include "V3Global.h" #include "V3Graph.h" class DfaGraph; class DfaVertex; class DfaEdge; //============================================================================= // NFA/DFA Graphs /// The NFA graph consists of: /// DfaVertex(START) The starting point /// DfaVertex() Interior states /// DfaVertex(ACCEPT) The completion point /// /// Transitions include a list of all inputs (arbitrary user pointers), /// or epsilon, represented as a empty list of inputs. /// /// We're only looking for matches, so the only accepting states are /// at the end of the transformations. (If we want the complement, we /// call complement and the algorithm makes a REJECT state, then flips /// accept and reject for you.) /// /// Common transforms: /// /// "*": DfaVertex(START) --> [epsilon] -->DfaVertex(ACCEPT) /// /// "L": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT) /// /// "LR": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT) /// ->[ON_R]-->DfaVtx-->[epsilon]-/ /// /// "L|R": ...->DfaVtx-->[epsilon]-->DfaVtx-->[ON_L]-->DfaVtx()->[epsilon]-->DfaVtx(ACCEPT) /// \->[epsilon]-->DfaVtx-->[ON_R]-->DfaVtx()->[epsilon]-/ /// /// "L*": ...->DfaVtx-->[epsilon]-->DfaVtx-->[ON_L]-->DfaVtx()->[epsilon]-->DfaVtx(ACCEPT) /// | ^\----[epsilon]<-------/ | /// \->[epsilon]-----------------------------------------/ class DfaGraph : public V3Graph { // STATE public: DfaGraph() {} virtual ~DfaGraph() {} // METHODS /// Find start node DfaVertex* findStart(); /// Convert automata: NFA to DFA void nfaToDfa(); /// Simplify a DFA automata void dfaReduce(); /// Complement result (must already be dfa) void dfaComplement(); }; //============================================================================= // Vertex class DfaVertex : public V3GraphVertex { // Each DFA state is captured in this vertex. // Start and accepting are members, rather than the more intuitive // subclasses, as subclassing them would make it harder to inherit from here. bool m_start; // Start state bool m_accepting; // Accepting state? public: // CONSTRUCTORS DfaVertex(DfaGraph* graphp, bool start=false, bool accepting=false) : V3GraphVertex(graphp) , m_start(start), m_accepting(accepting) {} using V3GraphVertex::clone; // We are overriding, not overloading clone(V3Graph*) virtual DfaVertex* clone(DfaGraph* graphp) { return new DfaVertex(graphp, start(), accepting()); } virtual ~DfaVertex() {} // ACCESSORS virtual string dotShape() const { return (accepting()?"doublecircle":""); } virtual string dotColor() const { return start()?"blue":(color()?"red":"black"); } bool start() const { return m_start; } void start(bool flag) { m_start=flag; } bool accepting() const { return m_accepting; } void accepting(bool flag) { m_accepting=flag; } }; //============================================================================ /// Abstract type indicating a specific "input" to the NFA typedef AstNUser* DfaInput; //============================================================================ // Edge types class DfaEdge : public V3GraphEdge { DfaInput m_input; bool m_complement; // Invert value when doing compare public: static DfaInput EPSILON() { return NULL; } static DfaInput NA() { return AstNUser::fromInt(1); } // as in not-applicable // CONSTRUCTORS DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, DfaInput input) : V3GraphEdge(graphp, fromp, top, 1) , m_input(input), m_complement(false) {} DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaEdge* copyfrom) : V3GraphEdge(graphp, fromp, top, copyfrom->weight()) , m_input(copyfrom->input()), m_complement(copyfrom->complement()) {} virtual ~DfaEdge() {} // METHODS virtual string dotColor() const { return (na() ? "yellow" : epsilon() ? "green" : "black"); } virtual string dotLabel() const { return (na() ? "" : epsilon() ? "e" : complement() ? ("not "+cvtToStr((void*)(input()))) : cvtToStr((void*)(input()))); } virtual string dotStyle() const { return (na()||cutable())?"dashed":""; } bool epsilon() const { return input()==EPSILON(); } bool na() const { return input()==NA(); } bool complement() const { return m_complement; } void complement(bool value) { m_complement=value; } DfaInput input() const { return m_input; } }; //============================================================================ #endif // Guard verilator-3.874/src/V3LinkCells.h0000664000177100017500000000240012525171733016556 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Link modules/signals together // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LINKCELLS_H_ #define _V3LINKCELLS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" class V3InFilter; class V3ParseSym; //============================================================================ class V3LinkCells { public: static void link(AstNetlist* nodep, V3InFilter* filterp, V3ParseSym* parseSymp); }; #endif // Guard verilator-3.874/src/V3Param.cpp0000664000177100017500000005512312525171733016303 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Replicate modules for parameterization // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // PARAM TRANSFORMATIONS: // Top down traversal: // For each cell: // If parameterized, // Determine all parameter widths, constant values. // (Interfaces also matter, as if an interface is parameterized // this effectively changes the width behavior of all that // reference the iface.) // Clone module cell calls, renaming with __{par1}_{par2}_... // Substitute constants for cell's module's parameters. // Relink pins and cell and ifacerefdtype to point to new module. // // For interface Parent's we have the AstIfaceRefDType::cellp() // pointing to this module. If that parent cell's interface // module gets parameterized, AstIfaceRefDType::cloneRelink // will update AstIfaceRefDType::cellp(), and AstLinkDot will // see the new interface. // // However if a submodule's AstIfaceRefDType::ifacep() points // to the old (unparameterized) interface and needs correction. // To detect this we must walk all pins looking for interfaces // that the parent has changed and propagate down. // // Then process all modules called by that cell. // (Cells never referenced after parameters expanded must be ignored.) // // After we complete parameters, the varp's will be wrong (point to old module) // and must be relinked. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Param.h" #include "V3Ast.h" #include "V3Case.h" #include "V3Const.h" #include "V3Width.h" #include "V3Unroll.h" //###################################################################### // Param state, as a visitor of each AstNode class ParamVisitor : public AstNVisitor { private: // NODE STATE // AstNodeModule::user5() // bool True if processed // AstGenFor::user5() // bool True if processed // AstVar::user5() // bool True if constant propagated // AstVar::user4() // int Global parameter number (for naming new module) // // (0=not processed, 1=iterated, but no number, 65+ parameter numbered) AstUser4InUse m_inuser4; AstUser5InUse m_inuser5; // User1/2/3 used by constant function simulations // TYPES typedef deque > IfaceRefRefs; // Note may have duplicate entries // STATE typedef map VarCloneMap; struct ModInfo { AstNodeModule* m_modp; // Module with specified name VarCloneMap m_cloneMap; // Map of old-varp -> new cloned varp ModInfo(AstNodeModule* modp) { m_modp=modp; } }; typedef map ModNameMap; ModNameMap m_modNameMap; // Hash of created module flavors by name typedef map LongMap; LongMap m_longMap; // Hash of very long names to unique identity number int m_longId; typedef map ValueMap; typedef map NextValueMap; ValueMap m_valueMap; // Hash of node to param value NextValueMap m_nextValueMap;// Hash of param value to next value to be used typedef multimap LevelModMap; LevelModMap m_todoModps; // Modules left to process typedef deque CellList; CellList m_cellps; // Cells left to process (in this module) // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void makeSmallNames(AstNodeModule* modp) { vector usedLetter; usedLetter.resize(256); // Pass 1, assign first letter to each gparam's name for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* varp = stmtp->castVar()) { if (varp->isGParam()||varp->isIfaceRef()) { char ch = varp->name()[0]; ch = toupper(ch); if (ch<'A' || ch>'Z') ch='Z'; varp->user4(usedLetter[static_cast(ch)]*256 + ch); usedLetter[static_cast(ch)]++; } } } } string paramSmallName(AstNodeModule* modp, AstVar* varp) { if (varp->user4()<=1) { makeSmallNames(modp); } int index = varp->user4()/256; char ch = varp->user4()&255; string st = cvtToStr(ch); while (index) { st += cvtToStr(char((index%26)+'A')); index /= 26; } return st; } string paramValueNumber(AstNode* nodep) { // Given a compilcated object create a number to use for param module assignment // Ideally would be relatively stable if design changes (not use pointer value), // and must return same value given same input node // Return must presently be numberic so doesn't collide with 'small' alphanumeric parameter names ValueMap::iterator it = m_valueMap.find(nodep); if (it != m_valueMap.end()) { return cvtToStr(it->second); } else { static int BUCKETS = 1000; V3Hash hash (nodep->name()); int bucket = hash.hshval() % BUCKETS; int offset = 0; NextValueMap::iterator it = m_nextValueMap.find(bucket); if (it != m_nextValueMap.end()) { offset = it->second; it->second = offset + 1; } else { m_nextValueMap.insert(make_pair(bucket, offset + 1)); } int num = bucket + offset * BUCKETS; m_valueMap.insert(make_pair(nodep, num)); return cvtToStr(num); } } void relinkPins(VarCloneMap* clonemapp, AstPin* startpinp) { for (AstPin* pinp = startpinp; pinp; pinp=pinp->nextp()->castPin()) { if (!pinp->modVarp()) pinp->v3fatalSrc("Not linked?\n"); // Find it in the clone structure //UINFO(8,"Clone find 0x"<modVarp()<find(pinp->modVarp()); UASSERT(cloneiter != clonemapp->end(), "Couldn't find pin in clone list"); pinp->modVarp(cloneiter->second); } } void visitCell(AstCell* nodep); void visitModules() { // Loop on all modules left to process // Hitting a cell adds to the appropriate level of this level-sorted list, // so since cells originally exist top->bottom we process in top->bottom order too. while (!m_todoModps.empty()) { LevelModMap::iterator it = m_todoModps.begin(); AstNodeModule* nodep = it->second; m_todoModps.erase(it); if (!nodep->user5SetOnce()) { // Process once; note clone() must clear so we do it again UINFO(4," MOD "<iterateChildren(*this); // Note above iterate may add to m_todoModps // // Process interface cells, then non-interface which may ref an interface cell for (int nonIf=0; nonIf<2; ++nonIf) { for (CellList::iterator it=m_cellps.begin(); it!=m_cellps.end(); ++it) { AstCell* nodep = *it; if ((nonIf==0 && nodep->modp()->castIface()) || (nonIf==1 && !nodep->modp()->castIface())) { visitCell(nodep); } } } m_cellps.clear(); } } } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { // Modules must be done in top-down-order nodep->iterateChildren(*this); } virtual void visit(AstNodeModule* nodep, AstNUser*) { if (nodep->dead()) { UINFO(4," MOD-dead. "<level() <= 2 // Haven't added top yet, so level 2 is the top || nodep->castPackage()) { // Likewise haven't done wrapTopPackages yet // Add request to END of modules left to process m_todoModps.insert(make_pair(nodep->level(),nodep)); visitModules(); } else if (nodep->user5()) { UINFO(4," MOD-done "<user5SetOnce()) { // Process once nodep->iterateChildren(*this); if (nodep->isParam()) { if (!nodep->valuep()) { nodep->v3fatalSrc("Parameter without initial value"); } V3Const::constifyParamsEdit(nodep); // The variable, not just the var->init() if (!nodep->valuep()->castConst()) { // Complex init, like an array // Make a new INITIAL to set the value. // This allows the normal array/struct handling code to properly initialize the parameter nodep->addNext(new AstInitial(nodep->fileline(), new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, true), nodep->valuep()->cloneTree(true)))); } } } } // Make sure varrefs cause vars to constify before things above virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->varp()) nodep->varp()->iterate(*this); } // Generate Statements virtual void visit(AstGenerate* nodep, AstNUser*) { if (debug()>=9) nodep->dumpTree(cout,"-genin: "); nodep->iterateChildren(*this); // After expanding the generate, all statements under it can be moved // up, and the generate block deleted as it's not relevant if (AstNode* stmtsp = nodep->stmtsp()) { stmtsp->unlinkFrBackWithNext(); nodep->replaceWith(stmtsp); if (debug()>=9) stmtsp->dumpTree(cout,"-genout: "); } else { nodep->unlinkFrBack(); } nodep->deleteTree(); nodep=NULL; } virtual void visit(AstGenIf* nodep, AstNUser*) { UINFO(9," GENIF "<condp()->iterateAndNext(*this); // We suppress errors when widthing params since short-circuiting in // the conditional evaluation may mean these error can never occur. We // then make sure that short-circuiting is used by constifyParamsEdit. V3Width::widthGenerateParamsEdit(nodep); // Param typed widthing will // NOT recurse the body. V3Const::constifyGenerateParamsEdit(nodep->condp()); // condp may change if (AstConst* constp = nodep->condp()->castConst()) { AstNode* keepp = (constp->isZero() ? nodep->elsesp() : nodep->ifsp()); if (keepp) { keepp->unlinkFrBackWithNext(); nodep->replaceWith(keepp); } else { nodep->unlinkFrBack(); } nodep->deleteTree(); nodep=NULL; // Normal edit rules will now recurse the replacement } else { nodep->condp()->v3error("Generate If condition must evaluate to constant"); } } //! Parameter subsitution for generated for loops. //! @todo Unlike generated IF, we don't have to worry about short-circuiting the conditional //! expression, since this is currently restricted to simple comparisons. If we ever do //! move to more generic constant expressions, such code will be needed here. virtual void visit(AstBegin* nodep, AstNUser*) { if (nodep->genforp()) { AstGenFor* forp = nodep->genforp()->castGenFor(); if (!forp) nodep->v3fatalSrc("Non-GENFOR under generate-for BEGIN"); // We should have a GENFOR under here. We will be replacing the begin, // so process here rather than at the generate to avoid iteration problems UINFO(9," BEGIN "<name(); // Leave the original Begin, as need a container for the (possible) GENVAR // Note V3Unroll will replace some AstVarRef's to the loop variable with constants V3Unroll::unrollGen(forp, beginName); forp=NULL; // Blocks were constructed under the special begin, move them up // Note forp is null, so grab statements again if (AstNode* stmtsp = nodep->genforp()) { stmtsp->unlinkFrBackWithNext(); nodep->addNextHere(stmtsp); // Note this clears nodep->genforp(), so begin is no longer special } } else { nodep->iterateChildren(*this); } } virtual void visit(AstGenFor* nodep, AstNUser*) { nodep->v3fatalSrc("GENFOR should have been wrapped in BEGIN"); } virtual void visit(AstGenCase* nodep, AstNUser*) { UINFO(9," GENCASE "<exprp()->iterateAndNext(*this); V3Case::caseLint(nodep); V3Width::widthParamsEdit(nodep); // Param typed widthing will NOT recurse the body, // don't trigger errors yet. V3Const::constifyParamsEdit(nodep->exprp()); // exprp may change AstConst* exprp = nodep->exprp()->castConst(); // Constify for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* ep = itemp->condsp(); ep; ) { AstNode* nextp = ep->nextp(); //May edit list ep->iterateAndNext(*this); V3Const::constifyParamsEdit(ep); ep=NULL; // ep may change // cppcheck-suppress redundantAssignment ep = nextp; } } // Item match for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { if (!itemp->isDefault()) { for (AstNode* ep = itemp->condsp(); ep; ep=ep->nextp()) { if (AstConst* ccondp = ep->castConst()) { V3Number match (nodep->fileline(), 1); match.opEq(ccondp->num(), exprp->num()); if (!keepp && match.isNeqZero()) { keepp = itemp->bodysp(); } } else { itemp->v3error("Generate Case item does not evaluate to constant"); } } } } // Else default match for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { if (itemp->isDefault()) { if (!keepp) keepp=itemp->bodysp(); } } // Replace if (keepp) { keepp->unlinkFrBackWithNext(); nodep->replaceWith(keepp); } else nodep->unlinkFrBack(); nodep->deleteTree(); nodep=NULL; } // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ParamVisitor(AstNetlist* nodep) { m_longId = 0; // nodep->accept(*this); } virtual ~ParamVisitor() {} }; //---------------------------------------------------------------------- // VISITs void ParamVisitor::visitCell(AstCell* nodep) { // Cell: Check for parameters in the instantiation. nodep->iterateChildren(*this); if (!nodep->modp()) nodep->v3fatalSrc("Not linked?"); if (nodep->paramsp() || 1 // Need to look for interfaces; could track when one exists, but should be harmless to always do this ) { UINFO(4,"De-parameterize: "<=10) nodep->dumpTree(cout,"-cell:\t"); // Evaluate all module constants V3Const::constifyParamsEdit(nodep); // Make sure constification worked // Must be a separate loop, as constant conversion may have changed some pointers. //if (debug()) nodep->dumpTree(cout,"-cel2:\t"); string longname = nodep->modp()->name(); bool any_overrides = false; longname += "_"; if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t"); for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) { if (!pinp->exprp()) continue; // No-connect AstVar* modvarp = pinp->modVarp(); if (!modvarp) { pinp->v3error("Parameter not found in sub-module: Param "<name()<<" of "<prettyName()); } else if (!modvarp->isGParam()) { pinp->v3error("Attempted parameter setting of non-parameter: Param "<name()<<" of "<prettyName()); } else { AstConst* constp = pinp->exprp()->castConst(); AstConst* origconstp = modvarp->valuep()->castConst(); if (!constp) { //if (debug()) pinp->dumpTree(cout,"error:"); pinp->v3error("Can't convert defparam value to constant: Param "<name()<<" of "<prettyName()); pinp->exprp()->replaceWith(new AstConst(pinp->fileline(), V3Number(pinp->fileline(), modvarp->width(), 0))); } else if (origconstp && constp->sameTree(origconstp)) { // Setting parameter to its default value. Just ignore it. // This prevents making additional modules, and makes coverage more // obvious as it won't show up under a unique module page name. } else { longname += "_" + paramSmallName(nodep->modp(),pinp->modVarp())+constp->num().ascii(false); any_overrides = true; } } } IfaceRefRefs ifaceRefRefs; for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { AstVar* modvarp = pinp->modVarp(); if (modvarp->isIfaceRef()) { AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType(); //UINFO(9," portIfaceRef "<exprp() || !pinp->exprp()->castVarRef() || !pinp->exprp()->castVarRef()->varp() || !pinp->exprp()->castVarRef()->varp()->subDTypep() || !pinp->exprp()->castVarRef()->varp()->subDTypep()->castIfaceRefDType()) { pinp->v3error("Interface port '"<prettyName()<<"' is not connected to interface/modport pin expression"); } else { AstIfaceRefDType* pinIrefp = pinp->exprp()->castVarRef()->varp()->subDTypep()->castIfaceRefDType(); //UINFO(9," pinIfaceRef "<ifaceViaCellp() != pinIrefp->ifaceViaCellp()) { UINFO(9," IfaceRefDType needs reconnect "<modp(),pinp->modVarp())+paramValueNumber(pinIrefp); any_overrides = true; ifaceRefRefs.push_back(make_pair(portIrefp,pinIrefp)); } } } } if (!any_overrides) { UINFO(8,"Cell parameters all match original values, skipping expansion.\n"); } else { // If the name is very long, we don't want to overwhelm the filename limit // We don't do this always, as it aids debugability to have intuitive naming. string newname = longname; if (longname.length()>30) { LongMap::iterator iter = m_longMap.find(longname); if (iter != m_longMap.end()) { newname = iter->second; } else { newname = nodep->modp()->name(); newname += "__pi"+cvtToStr(++m_longId); // We use all upper case above, so lower here can't conflict m_longMap.insert(make_pair(longname, newname)); } } UINFO(4,"Name: "<modp()->name()<<"->"<"<second.m_modp; if (!modp) { // Deep clone of new module // Note all module internal variables will be re-linked to the new modules by clone // However links outside the module (like on the upper cells) will not. modp = nodep->modp()->cloneTree(false); modp->name(newname); modp->user5(false); // We need to re-recurse this module once changed nodep->modp()->addNextHere(modp); // Keep tree sorted by cell occurrences m_modNameMap.insert(make_pair(modp->name(), ModInfo(modp))); iter = m_modNameMap.find(newname); VarCloneMap* clonemapp = &(iter->second.m_cloneMap); UINFO(4," De-parameterize to new: "<stmtsp(); stmtp; stmtp = stmtp->nextp()) { if (AstVar* varp = stmtp->castVar()) { if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) { // Cloning saved a pointer to the new node for us, so just follow that link. AstVar* oldvarp = varp->clonep()->castVar(); //UINFO(8,"Clone list 0x"< 0x"<<(uint32_t)varp<insert(make_pair(oldvarp, varp)); } } } // Relink parameter vars to the new module relinkPins(clonemapp, nodep->paramsp()); // Fix any interface references for (IfaceRefRefs::iterator it=ifaceRefRefs.begin(); it!=ifaceRefRefs.end(); ++it) { AstIfaceRefDType* portIrefp = it->first; AstIfaceRefDType* pinIrefp = it->second; AstIfaceRefDType* cloneIrefp = portIrefp->clonep()->castIfaceRefDType(); UINFO(8," IfaceOld "<v3fatalSrc("parameter clone didn't hit AstIfaceRefDType"); UINFO(8," IfaceClo "<ifacep(pinIrefp->ifaceViaCellp()); UINFO(8," IfaceNew "<paramsp(); pinp; pinp=pinp->nextp()->castPin()) { AstVar* modvarp = pinp->modVarp(); if (modvarp && pinp->exprp()) { AstConst* constp = pinp->exprp()->castConst(); // Remove any existing parameter if (modvarp->valuep()) modvarp->valuep()->unlinkFrBack()->deleteTree(); // Set this parameter to value requested by cell modvarp->valuep(constp->cloneTree(false)); } } } else { UINFO(4," De-parameterize to old: "<modp(modp); nodep->modName(newname); // We need to relink the pins to the new module VarCloneMap* clonemapp = &(iter->second.m_cloneMap); relinkPins(clonemapp, nodep->pinsp()); UINFO(8," Done with "<paramsp()) nodep->paramsp()->unlinkFrBackWithNext()->deleteTree(); UINFO(8," Done with "<=10) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("param-out.tree")); } // Now remember to process the child module at the end of the module m_todoModps.insert(make_pair(nodep->modp()->level(),nodep->modp())); } //###################################################################### // Param class functions void V3Param::param(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.874/src/V3List.h0000664000177100017500000000751112525171733015621 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: List class with storage in existing classes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LIST_H_ #define _V3LIST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include //============================================================================ template class V3List; template class V3ListEnt; template class V3List { // List container for linked list of elements of type *T (T is a pointer type) private: // STATE T m_headp; // First element T m_tailp; // Last element friend class V3ListEnt; public: V3List() : m_headp(NULL), m_tailp(NULL) {} ~V3List() {} // METHODS T begin() const { return m_headp; } T end() const { return NULL; } bool empty() const { return m_headp==NULL; } void reset() { m_headp=NULL; m_tailp=NULL; } // clear() without walking the list }; //============================================================================ template class V3ListEnt { // List entry for linked list of elements of type *T (T is a pointer type) private: // STATE T m_nextp; // Pointer to next element, NULL=end T m_prevp; // Pointer to previous element, NULL=beginning friend class V3List; static V3ListEnt* baseToListEnt(void* newbasep, size_t offset) { // "this" must be a element inside of *basep // Use that to determine a structure offset, then apply to the new base // to get our new pointer information return (V3ListEnt*) ( ((vluint8_t*)newbasep) + offset); } public: V3ListEnt() : m_nextp(NULL), m_prevp(NULL) {} ~V3ListEnt() { #ifdef VL_DEBUG // Load bogus pointers so we can catch deletion bugs m_nextp = (T)1; m_prevp = (T)1; #endif } T nextp() const { return m_nextp; } // METHODS void pushBack (V3List& listr, T newp) { // "this" must be a element inside of *newp // cppcheck-suppress thisSubtraction size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(newp); m_nextp = NULL; if (!listr.m_headp) listr.m_headp = newp; m_prevp = listr.m_tailp; if (m_prevp) baseToListEnt(m_prevp,offset)->m_nextp = newp; listr.m_tailp = newp; } void pushFront (V3List& listr, T newp) { // "this" must be a element inside of *newp // cppcheck-suppress thisSubtraction size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(newp); m_nextp = listr.m_headp; if (m_nextp) baseToListEnt(m_nextp,offset)->m_prevp = newp; listr.m_headp = newp; m_prevp = NULL; if (!listr.m_tailp) listr.m_tailp = newp; } // Unlink from side void unlink (V3List& listr, T oldp) { // "this" must be a element inside of *oldp // cppcheck-suppress thisSubtraction size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(oldp); if (m_nextp) baseToListEnt(m_nextp,offset)->m_prevp = m_prevp; else listr.m_tailp = m_prevp; if (m_prevp) baseToListEnt(m_prevp,offset)->m_nextp = m_nextp; else listr.m_headp = m_nextp; m_prevp = m_nextp = NULL; } }; //============================================================================ #endif // Guard verilator-3.874/src/V3DepthBlock.cpp0000664000177100017500000001045412525171733017260 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Prevent very deep expressions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3DepthBlock's Transformations: // // Each module: // For each deep block, create cfunc including that block. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3DepthBlock.h" #include "V3Ast.h" #include "V3EmitCBase.h" //###################################################################### class DepthBlockVisitor : public AstNVisitor { private: // NODE STATE // STATE AstNodeModule* m_modp; // Current module AstCFunc* m_funcp; // Current function int m_depth; // How deep in an expression int m_deepNum; // How many functions made // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } AstCFunc* createDeepFunc(AstNode* nodep) { AstNRelinker relinkHandle; nodep->unlinkFrBack(&relinkHandle); // Create function string name = m_funcp->name()+"__deep"+cvtToStr(++m_deepNum); AstCFunc* funcp = new AstCFunc(nodep->fileline(), name, NULL); funcp->argTypes(EmitCBaseVisitor::symClassVar()); funcp->symProlog(true); funcp->slow(m_funcp->slow()); funcp->addStmtsp(nodep); m_modp->addStmtp(funcp); // Call it at the point where the body was removed from AstCCall* callp = new AstCCall(nodep->fileline(), funcp); callp->argTypes("vlSymsp"); UINFO(6," New "<iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCFunc* nodep, AstNUser*) { // We recurse into this. int lastDepth = m_depth; AstCFunc* lastFuncp = m_funcp; { m_depth = 0; m_funcp = nodep; nodep->iterateChildren(*this); } m_depth = lastDepth; m_funcp = lastFuncp; } void visitStmt(AstNodeStmt* nodep) { m_depth++; if (m_depth > v3Global.opt.compLimitBlocks() && !nodep->castCCall()) { // Already done UINFO(4, "DeepBlocks "<backp(); // Only for debug if (debug()>=9) backp->dumpTree(cout,"- pre : "); AstCFunc* funcp = createDeepFunc(nodep); funcp->accept(*this); if (debug()>=9) backp->dumpTree(cout,"- post: "); if (debug()>=9) funcp->dumpTree(cout,"- func: "); } else { nodep->iterateChildren(*this); } m_depth--; } virtual void visit(AstNodeStmt* nodep, AstNUser*) { visitStmt(nodep); } virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate //-------------------- // Default: Just iterate virtual void visit(AstVar* nodep, AstNUser*) {} // Don't hit varrefs under vars virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS DepthBlockVisitor(AstNetlist* nodep) { m_modp=NULL; m_depth=0; // nodep->accept(*this); } virtual ~DepthBlockVisitor() {} }; //###################################################################### // DepthBlock class functions void V3DepthBlock::depthBlockAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3GraphDfa.cpp0000664000177100017500000005112712525171733016717 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph optimizations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3GraphDfa.h" #include "V3GraphAlg.h" //###################################################################### //###################################################################### // Algorithms - find starting node DfaVertex* DfaGraph::findStart() { DfaVertex* startp = NULL; for (V3GraphVertex* vertexp = this->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (DfaVertex* vvertexp = dynamic_cast(vertexp)) { if (vvertexp->start()) { if (startp) v3fatalSrc("Multiple start points in NFA graph"); startp = vvertexp; } } else { v3fatalSrc("Non DfaVertex in DfaGraph\n"); } } if (!startp) v3fatalSrc("No start point in NFA graph"); return startp; } //###################################################################### //###################################################################### // Algorithms - convert NFA to a DFA // Uses the Subset Construction Algorithm class GraphNfaToDfa : GraphAlg { // We have two types of nodes in one graph, NFA and DFA nodes. // Edges from NFA to NFA come from the user, and indicate input or epsilon transitions // Edges from DFA to NFA indicate the NFA from which that DFA was formed. // Edges from DFA to DFA indicate a completed input transition private: // TYPES typedef deque DfaStates; typedef multimap HashMap; // MEMBERS uint32_t m_step; // Processing step, so we can avoid clearUser all the time HashMap m_hashMap; // Dfa Vertex for each set of NFA vertexes static int debug() { return 0; } // METHODS DfaGraph* graphp() { return static_cast(m_graphp); } bool nfaState(V3GraphVertex* vertexp) { return vertexp->color()==0; } //bool dfaState(V3GraphVertex* vertexp) { return vertexp->color()==1; } void nextStep() { m_step++; } bool unseenNfaThisStep(V3GraphVertex* vertexp) { // A nfa node not already seen this processing step return (nfaState(vertexp) && !(vertexp->user()==m_step)); } DfaVertex* newDfaVertex(DfaVertex* nfaTemplatep=NULL) { DfaVertex* vertexp = new DfaVertex (graphp()); vertexp->color(1); // Mark as dfa if (nfaTemplatep && nfaTemplatep->start()) vertexp->start(true); if (nfaTemplatep && nfaTemplatep->accepting()) vertexp->accepting(true); UINFO(9, " New "<outBeginp(); dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) { if (nfaState(dfaEdgep->top())) { DfaVertex* nfaStatep = static_cast(dfaEdgep->top()); hash ^= hashVertex(nfaStatep); if (debug()) { if (nfaStatep->user()==m_step) v3fatalSrc("DFA state points to duplicate NFA state."); nfaStatep->user(m_step); } } } return hash; } uint32_t hashDfaOrigins(const DfaStates& nfasWithInput) { // Find the NFA states this dfa came from, uint32_t hash = 0; for (DfaStates::const_iterator nfaIt=nfasWithInput.begin(); nfaIt!=nfasWithInput.end(); ++nfaIt) { DfaVertex* nfaStatep = *nfaIt; hash ^= hashVertex(nfaStatep); } return hash; } bool compareDfaOrigins(const DfaStates& nfasWithInput, DfaVertex* dfa2p) { // Return true if the NFA nodes both DFAs came from are the same list // Assume there are no duplicates in either input list or NFAs under dfa2 nextStep(); // Mark all input vertexes int num1s = 0; for (DfaStates::const_iterator nfaIt=nfasWithInput.begin(); nfaIt!=nfasWithInput.end(); ++nfaIt) { DfaVertex* nfaStatep = *nfaIt; nfaStatep->user(m_step); num1s++; } if (!num1s) v3fatalSrc("DFA node construction that contains no NFA states"); // Check comparison; must all be marked // (Check all in dfa2p were in dfa1p) int num2s = 0; for (V3GraphEdge* dfaEdgep = dfa2p->outBeginp(); dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) { if (nfaState(dfaEdgep->top())) { if (dfaEdgep->top()->user() != m_step) return false; num2s++; } } // If we saw all of the nodes, then they have the same number of hits // (Else something in dfa1p that wasn't in dfa2p) if (num1s != num2s) return false; // Match return true; } void insertDfaOrigins(DfaVertex* dfaStatep) { // Record the NFA states this dfa came from uint32_t hash = hashDfaOrigins(dfaStatep); m_hashMap.insert(make_pair(hash,dfaStatep)); } DfaVertex* findDfaOrigins(const DfaStates& nfasWithInput) { // Find another DFA state which comes from the identical set of NFA states // The order of the nodes is not deterministic; the hash thus must not depend on order of edges uint32_t hash = hashDfaOrigins(nfasWithInput); pair eqrange = m_hashMap.equal_range(hash); for (HashMap::iterator it = eqrange.first; it != eqrange.second; ++it) { DfaVertex* testp = it->second; if (compareDfaOrigins(nfasWithInput, testp)) { UINFO(9," DFA match for set: "<outBeginp(); dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) { if (nfaState(dfaEdgep->top())) { DfaVertex* nfaStatep = static_cast(dfaEdgep->top()); // Foreach input transition (on this nfaStatep) for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) { DfaEdge* cNfaEdgep = static_cast(nfaEdgep); if (cNfaEdgep->input() == input) { DfaVertex* nextStatep = static_cast(cNfaEdgep->top()); if (unseenNfaThisStep(nextStatep)) { // Not processed? nfasWithInput.push_back(nextStatep); nextStatep->user(m_step); UINFO(9," Reachable "<outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) { DfaEdge* cNfaEdgep = static_cast(nfaEdgep); if (cNfaEdgep->epsilon()) { DfaVertex* nextStatep = static_cast(cNfaEdgep->top()); if (unseenNfaThisStep(nextStatep)) { // Not processed? nfasWithInput.push_back(nextStatep); nextStatep->user(m_step); UINFO(9," Epsilon Reachable "<clearColors(); // Vertex::m_user begin: # indicates processed this m_step number m_graphp->userClearVertices(); if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_nfa"); // Find NFA start DfaVertex* nfaStartp = graphp()->findStart(); // Create new DFA State (start state) from the NFA states DfaVertex* dfaStartp = newDfaVertex(nfaStartp); DfaStates dfaUnprocps; // Unprocessed DFA nodes dfaUnprocps.push_back(dfaStartp); UINFO(5,"Starting state conversion...\n"); // Form DFA starting state from epsilon closure of NFA start nextStep(); DfaStates workps; workps.push_back(nfaStartp); while (!workps.empty()) { // While work DfaVertex* nfaStatep = workps.back(); workps.pop_back(); //UINFO(9," Processing "<user(m_step); // Mark as processed // Add a edge so we can find NFAs from a given DFA. // The NFA will never see this edge, because we only look at TO edges. new DfaEdge(graphp(), dfaStartp, nfaStatep, DfaEdge::NA()); // Find epsilon closure of this nfa node, and destinations to work list for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) { DfaEdge* cNfaEdgep = static_cast(nfaEdgep); DfaVertex* nfaStatep = static_cast(nfaEdgep->top()); //UINFO(9," Consider "<top()<<" EP "<epsilon()<epsilon() && unseenNfaThisStep(nfaStatep)) { // Not processed? workps.push_back(nfaStatep); } } } if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_start"); insertDfaOrigins(dfaStartp); int i=0; UINFO(5,"Main state conversion...\n"); while (!dfaUnprocps.empty()) { DfaVertex* dfaStatep = dfaUnprocps.back(); dfaUnprocps.pop_back(); UINFO(9," On dfaState "< inputs; // Foreach NFA state (this DFA state was formed from) for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp(); dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) { if (nfaState(dfaEdgep->top())) { DfaVertex* nfaStatep = static_cast(dfaEdgep->top()); // Foreach input on this nfaStatep for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) { DfaEdge* cNfaEdgep = static_cast(nfaEdgep); if (!cNfaEdgep->epsilon()) { if (inputs.find(cNfaEdgep->input()) == inputs.end()) { inputs.insert(cNfaEdgep->input()); UINFO(9," Input to "<input())<<" via "<::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) { DfaInput input = *inIt; UINFO(9," ==="<<++i<<"=======================\n"); UINFO(9," On input "<<(void*)(input)<accepting()) toDfaStatep->accepting(true); } insertDfaOrigins(toDfaStatep); } // Add input transition new DfaEdge (graphp(), dfaStatep, toDfaStatep, input); if (debug()>=6) m_graphp->dumpDotFilePrefixed("step"); } } // Remove old NFA states UINFO(5,"Removing NFA states...\n"); if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_withnfa"); for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) { nextp = vertexp->verticesNextp(); if (nfaState(vertexp)) { vertexp->unlinkDelete(m_graphp); vertexp=NULL; } } UINFO(5,"Done.\n"); if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_done"); } public: GraphNfaToDfa(V3Graph* graphp, V3EdgeFuncP edgeFuncp) : GraphAlg(graphp, edgeFuncp) { m_step = 0; main(); } ~GraphNfaToDfa() {} }; void DfaGraph::nfaToDfa() { GraphNfaToDfa (this, &V3GraphEdge::followAlwaysTrue); } //###################################################################### //###################################################################### // Algorithms - optimize a DFA structure // // Scan the DFA, cleaning up trailing states. class DfaGraphReduce : GraphAlg { private: // METHODS static int debug() { return 0; } DfaGraph* graphp() { return static_cast(m_graphp); } bool isDead(DfaVertex* vertexp) { // A state is dead if not accepting, and goes nowhere if (vertexp->accepting() || vertexp->start()) return false; for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (edgep->top() != vertexp) return false; } return true; } void optimize_accepting_out() { // Delete outbound edges from accepting states // (As once we've accepted, we no longer care about anything else.) for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (DfaVertex* vvertexp = dynamic_cast(vertexp)) { if (vvertexp->accepting()) { for (V3GraphEdge* nextp,*edgep = vertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); edgep->unlinkDelete(); edgep=NULL; } } } } } void optimize_orphans() { // Remove states that don't come from start // Presumably the previous optimization orphaned them. // Vertex::m_user begin: 1 indicates on the work list, 2 processed // (Otherwise we might have nodes on the list twice, and reference after deleting them.) m_graphp->userClearVertices(); DfaVertex* startp = graphp()->findStart(); stack workps; workps.push(startp); // Mark all nodes connected to start while (!workps.empty()) { V3GraphVertex* vertexp = workps.top(); workps.pop(); vertexp->user(2); // Processed // Add nodes from here to the work list for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { V3GraphVertex* tovertexp = edgep->top(); if (!tovertexp->user()) { workps.push(tovertexp); tovertexp->user(1); } } } // Delete all nodes not connected for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) { nextp = vertexp->verticesNextp(); if (!vertexp->user()) { vertexp->unlinkDelete(m_graphp); vertexp=NULL; } } } void optimize_no_outbound() { // Non-accepting states with no outbound transitions may be // deleted. Then, any arcs feeding those states, and perhaps those // states... // Vertex::m_user begin: 1 indicates on the work list // (Otherwise we might have nodes on the list twice, and reference after deleting them.) m_graphp->userClearVertices(); // Find all dead vertexes stack workps; for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (DfaVertex* vvertexp = dynamic_cast(vertexp)) { workps.push(vvertexp); vertexp->user(1); } else { // If ever remove this, need dyn cast below v3fatalSrc("Non DfaVertex in dfa graph"); } } // While deadness... Delete and find new dead nodes. while (!workps.empty()) { DfaVertex* vertexp = workps.top(); workps.pop(); vertexp->user(0); if (isDead(vertexp)) { // Add nodes that go here to the work list for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { DfaVertex* fromvertexp = static_cast(edgep->fromp()); if (fromvertexp != vertexp && !fromvertexp->user()) { workps.push(static_cast(fromvertexp)); fromvertexp->user(1); } } // Transitions to this state removed by the unlink function vertexp->unlinkDelete(m_graphp); vertexp=NULL; } } } public: DfaGraphReduce(V3Graph* graphp, V3EdgeFuncP edgeFuncp) : GraphAlg(graphp, edgeFuncp) { if (debug()>=6) m_graphp->dumpDotFilePrefixed("opt_in"); optimize_accepting_out(); if (debug()>=6) m_graphp->dumpDotFilePrefixed("opt_acc"); optimize_orphans(); if (debug()>=6) m_graphp->dumpDotFilePrefixed("opt_orph"); optimize_no_outbound(); if (debug()>=6) m_graphp->dumpDotFilePrefixed("opt_noout"); } ~DfaGraphReduce() {} }; void DfaGraph::dfaReduce() { DfaGraphReduce (this, &V3GraphEdge::followAlwaysTrue); } //###################################################################### //###################################################################### // Algorithms - complement a DFA // // The traditional algorithm is to make a rejecting state, add edges to // reject from all missing values, then swap accept and reject. Rather // than swap at the end, it's faster if we swap up front, then do the edge // changes. // // 1. Since we didn't log rejecting states, make a temp state (this will be // the old accept, and new reject). // // 2. All vertexes except start/accept get edges to NEW accept for any // non-existing case. Weedely we don't have a nice way of representing // this so we just create a edge for each case and mark it "complemented." // // 3. Delete temp vertex (old accept/new reject) and related edges. // The user's old accept is now the new accept. This is imporant as // we want the virtual type of it to be intact. class DfaGraphComplement : GraphAlg { private: // MEMBERS DfaVertex* m_tempNewerReject; // METHODS static int debug() { return 9; } DfaGraph* graphp() { return static_cast(m_graphp); } void add_complement_edges() { // Find accepting vertex DfaVertex* acceptp = NULL; for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (DfaVertex* vvertexp = dynamic_cast(vertexp)) { if (vvertexp->accepting()) { acceptp = vvertexp; break; } } } if (!acceptp) v3fatalSrc("No accepting vertex in DFA\n"); // Remap edges for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (DfaVertex* vvertexp = dynamic_cast(vertexp)) { //UINFO(9, " on vertex "<name()<accepting() && vvertexp != m_tempNewerReject) { for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); if (!edgep->user()) { // Not processed // Old edges to accept now go to new reject DfaEdge* vedgep = static_cast(edgep); DfaVertex* tovertexp = static_cast(edgep->top()); if (tovertexp->accepting()) { new DfaEdge(graphp(), vvertexp, m_tempNewerReject, vedgep); edgep->unlinkDelete(); edgep=NULL; } // NOT of all values goes to accept // We make a edge for each value to OR, IE // edge(complemented,a) edge(complemented,b) means !(a | b) if (!tovertexp->accepting()) { // Note we must include edges moved above to reject DfaEdge* newp = new DfaEdge (graphp(), vvertexp, acceptp, vedgep); newp->complement(!newp->complement()); newp->user(1); } } } } } } } public: DfaGraphComplement(V3Graph* dfagraphp, V3EdgeFuncP edgeFuncp) : GraphAlg(dfagraphp, edgeFuncp) { if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_in"); // Vertex::m_user begin: 1 indicates new edge, no more processing m_graphp->userClearEdges(); m_tempNewerReject = new DfaVertex(graphp()); add_complement_edges(); if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_preswap"); m_tempNewerReject->unlinkDelete(graphp()); m_tempNewerReject=NULL; if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_out"); } ~DfaGraphComplement() {} }; void DfaGraph::dfaComplement() { DfaGraphComplement (this, &V3GraphEdge::followAlwaysTrue); } verilator-3.874/src/config_rev.pl0000775000177100017500000000226612525171734017010 0ustar wsnyderwsnyder#!/usr/bin/perl -w ###################################################################### # # Copyright 2005-2015 by Wilson Snyder. Verilator 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ###################################################################### # DESCRIPTION: Query's subversion to get version number my $dir = $ARGV[0]; defined $dir or die "%Error: No directory argument,"; chdir $dir; my $rev = 'UNKNOWN_REV'; my $data = `git describe`; if ($data =~ /(verilator.*)/i) { $rev = $1; } $data = `git status`; if ($data =~ /Changed but not updated/i || $data =~ /Changes to be committed/i) { $rev .= " (mod)"; } print "static const char* DTVERSION_rev = \"$rev\";\n"; # Die after the print, so at least the header has good contents $rev =~ /UNKNOWN/ and warn "%Warning: No git revision found,"; verilator-3.874/src/cppcheck_filtered0000775000177100017500000001214012525171734017703 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### require 5.006_001; use Getopt::Long; use IO::File; use Pod::Usage; use strict; use vars qw ($Debug $VERSION); $VERSION = '3.857'; #====================================================================== # main our $Opt_Debug; autoflush STDOUT 1; autoflush STDERR 1; Getopt::Long::config ("no_auto_abbrev","pass_through"); our @Opt_Args = ("cppcheck", @ARGV); if (! GetOptions ( # Local options "help" => \&usage, "version" => sub { print "Version $VERSION\n"; system("cppcheck","--version"); exit(0); }, )) { die "%Error: Bad usage, try 'cppcheck_filtered --help'\n"; } process(); #---------------------------------------------------------------------- sub usage { print "Version $VERSION\n"; pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT, -noperldoc=>1); exit (1); } ####################################################################### sub process { my $cmd = join(' ',@Opt_Args); print "\t$cmd\n" if $Debug; my $fh = IO::File->new("$cmd 2>&1 |"); my %uniq; my %errs; while (defined(my $line = $fh->getline())) { $line =~ s/^\s+//; $line =~ s/Checking usage of global functions\.+//; # Sometimes tacked at end-of-line # General gunk next if $uniq{$line}++; next if $line =~ m!^<\?xml version!; next if $line =~ m!^!; next if $line =~ m!^!; next if $line =~ m!^error("Cppcheck errors:\n$all"); #die "%Error: cppcheck_filtered found errors\n"; exit(1); } } ###################################################################### sub _suppress { my $filename = shift; my $linenum = shift; my $id = shift; #print "-Suppression search $filename $linenum $id\n" if $Self->{verbose}; return undef if $filename eq "*"; my $fh = IO::File->new("<$filename"); if (!$fh) { warn "%Warning: $! $filename,"; return undef; } my $l = 0; while (defined(my $line = $fh->getline())) { ++$l; if ($l+1 == $linenum) { if ($line =~ /cppcheck-suppress\s+(\S+)/) { my $supid = $1; if ($supid eq $id) { return 1; } else { warn "%Warning: $filename: $l: Found suppress for id='$supid', not expected id='$id'\n"; } } } if ($l == $linenum) { if ($id eq "uselessAssignmentPtrArg" && $line =~ /(delete|Delete|Edit).*p *= *NULL;/) { # delete(nodep); nodep=NULL; # This is ok, it's how we prevent later using nodep return 1; } } } return undef; } 1; ####################################################################### __END__ =pod =head1 NAME cppcheck_filtered - cppcheck wrapper with post-processing =head1 SYNOPSIS cppcheck_filtered ...normal cpp check flags... =head1 DESCRIPTION Cppcheck_Filtered is a wrapper for cppcheck that filters out unnecessary warnings related to Verilator. =head1 ARGUMENTS Most arguments are passed through to cppcheck =over 4 =item --help Displays this message and program version and exits. =item --version Print the version number and exit. =back =head1 DISTRIBUTION This is part of the L free Verilog EDA software tool suite. The latest version is available from CPAN and from L. Copyright 2014-2015 by Wilson Snyder. This package 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO C =cut ###################################################################### ### Local Variables: ### compile-command: "./cppcheck_filtered --xml V3Width.cpp" ### End: verilator-3.874/src/VlcSource.h0000664000177100017500000000773512525171734016413 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Source file to annotate with line coverage // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCSOURCE_H_ #define _VLCSOURCE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include //******************************************************************** // VlcColumnCount - count at specific source file, line and column class VlcSourceCount { private: // MEMBERS int m_lineno; ///< Line number int m_column; ///< Column number vluint64_t m_count; ///< Count bool m_ok; ///< Coverage is above threshold public: // CONSTRUCTORS VlcSourceCount(int lineno, int column) { m_lineno = lineno; m_column = column; m_count = 0; m_ok = false; } ~VlcSourceCount() {} // ACCESSORS int lineno() const { return m_lineno; } int column() const { return m_column; } vluint64_t count() const { return m_count; } bool ok() const { return m_ok; } // METHODS void incCount(vluint64_t count, bool ok) { m_count += count; if (ok) m_ok = true; } }; //******************************************************************** // VlcSource - source file to annotate class VlcSource { public: // TYPES typedef map ColumnMap; // Map of {column} typedef map LinenoMap; // Map of {lineno}{column} private: // MEMBERS string m_name; //< Name of the source file bool m_needed; //< Need to annotate; has low coverage LinenoMap m_lines; //< Map of each annotated line public: // CONSTRUCTORS VlcSource(const string& name) { m_name = name; m_needed = false; } ~VlcSource() {} // ACCESSORS const string& name() const { return m_name; } void needed(bool flag) { m_needed = flag; } bool needed() const { return m_needed; } LinenoMap& lines() { return m_lines; } // METHODS void incCount(int lineno, int column, vluint64_t count, bool ok) { LinenoMap::iterator lit = m_lines.find(lineno); if (lit == m_lines.end()) { lit = m_lines.insert(make_pair(lineno,ColumnMap())).first; } ColumnMap& cmap = lit->second; ColumnMap::iterator cit = cmap.find(column); if (cit == cmap.end()) { cit = cmap.insert(make_pair(column,VlcSourceCount(lineno, column))).first; } VlcSourceCount& sc = cit->second; sc.incCount(count,ok); } }; //******************************************************************** // VlcSources - Container of all source files class VlcSources { public: // TYPES typedef map NameMap; private: // MEMBERS NameMap m_sources; //< List of all sources public: // ITERATORS typedef NameMap::iterator iterator; NameMap::iterator begin() { return m_sources.begin(); } NameMap::iterator end() { return m_sources.end(); } public: // CONSTRUCTORS VlcSources() {} ~VlcSources() {} // METHODS VlcSource& findNewSource(const string& name) { NameMap::iterator iter = m_sources.find(name); if (iter != m_sources.end()) { return iter->second; } else { iter = m_sources.insert(make_pair(name, VlcSource(name))).first; return iter->second; } } }; //###################################################################### #endif // Guard verilator-3.874/src/V3Clean.cpp0000664000177100017500000002232012525171733016256 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add temporaries, such as for clean nodes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Clean's Transformations: // // Each module: // For each math operator, if it requires a clean operand, // and the operand is dirty, insert a CLEAN node. // Resize operands to C++ 32/64/wide types. // Copy all width() values to widthMin() so RANGE, etc can still see orig widths // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Clean.h" #include "V3Ast.h" //###################################################################### // Clean state, as a visitor of each AstNode class CleanVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstNode::user() -> CleanState. For this node, 0==UNKNOWN // AstNode::user2() -> bool. True indicates widthMin has been propagated // AstNodeDType::user3() -> AstNodeDType*. Alternative node with C size AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; // TYPES enum CleanState { CS_UNKNOWN, CS_CLEAN, CS_DIRTY }; // STATE AstNodeModule* m_modp; // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // Width resetting int cppWidth(AstNode* nodep) { if (nodep->width()<=VL_WORDSIZE) return VL_WORDSIZE; else if (nodep->width()<=VL_QUADSIZE) return VL_QUADSIZE; else return nodep->widthWords()*VL_WORDSIZE; } void setCppWidth (AstNode* nodep) { nodep->user2(true); // Don't resize it again AstNodeDType* old_dtypep = nodep->dtypep(); int width=cppWidth(nodep); // widthMin is unchanged if (old_dtypep->width() != width) { // Since any given dtype's cppWidth() is the same, we can just // remember one convertion for each, and reuse it if (AstNodeDType* new_dtypep = old_dtypep->user3p()->castNode()->castNodeDType()) { nodep->dtypep(new_dtypep); } else { nodep->dtypeChgWidth(width, nodep->widthMin()); AstNodeDType* new_dtypep2 = nodep->dtypep(); if (new_dtypep2 == old_dtypep) nodep->v3fatalSrc("Dtype didn't change when width changed"); old_dtypep->user3p(new_dtypep2); // Remember for next time } } } void computeCppWidth (AstNode* nodep) { if (!nodep->user2() && nodep->hasDType()) { if (nodep->castVar() || nodep->castNodeDType()) { // Don't want to change variable widths! } else { setCppWidth(nodep); } } } // Store the clean state in the userp on each node void setCleanState(AstNode* nodep, CleanState clean) { nodep->user1(clean); } CleanState getCleanState(AstNode* nodep) { return ((CleanState)nodep->user1()); } bool isClean(AstNode* nodep) { CleanState clstate = getCleanState(nodep); if (clstate==CS_CLEAN) return true; if (clstate==CS_DIRTY) return false; nodep->v3fatalSrc("Unknown clean state on node: "+nodep->prettyTypeName()); return false; } void setClean(AstNode* nodep, bool isClean) { computeCppWidth (nodep); // Just to be sure it's in widthMin bool wholeUint = ((nodep->widthMin() % VL_WORDSIZE) == 0); //32,64,... setCleanState(nodep, ((isClean||wholeUint) ? CS_CLEAN:CS_DIRTY)); } // Operate on nodes void insertClean(AstNode* nodep) { // We'll insert ABOVE passed node UINFO(4," NeedClean "<unlinkFrBack(&relinkHandle); // computeCppWidth(nodep); V3Number mask (nodep->fileline(), cppWidth(nodep)); mask.setMask(nodep->widthMin()); AstNode* cleanp = new AstAnd (nodep->fileline(), new AstConst (nodep->fileline(), mask), nodep); cleanp->dtypeFrom(nodep); // Otherwise the AND normally picks LHS relinkHandle.relink(cleanp); } void insureClean(AstNode* nodep) { computeCppWidth(nodep); if (!isClean(nodep)) insertClean(nodep); } void insureCleanAndNext(AstNode* nodep) { // Editing list, careful looping! for (AstNode* exprp = nodep; exprp; ) { AstNode* nextp = exprp->nextp(); insureClean(exprp); exprp = nextp; } } // Base type handling methods void operandBiop(AstNodeBiop* nodep) { nodep->iterateChildren(*this); computeCppWidth(nodep); if (nodep->cleanLhs()) { insureClean(nodep->lhsp()); } if (nodep->cleanRhs()) { insureClean(nodep->rhsp()); } //no setClean.. must do it in each user routine. } void operandTriop(AstNodeTriop* nodep) { nodep->iterateChildren(*this); computeCppWidth(nodep); if (nodep->cleanLhs()) { insureClean(nodep->lhsp()); } if (nodep->cleanRhs()) { insureClean(nodep->rhsp()); } if (nodep->cleanThs()) { insureClean(nodep->thsp()); } //no setClean.. must do it in each user routine. } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstNodeUniop* nodep, AstNUser*) { nodep->iterateChildren(*this); computeCppWidth(nodep); if (nodep->cleanLhs()) { insureClean(nodep->lhsp()); } setClean (nodep, nodep->cleanOut()); } virtual void visit(AstNodeBiop* nodep, AstNUser*) { operandBiop(nodep); setClean (nodep, nodep->cleanOut()); } virtual void visit(AstAnd* nodep, AstNUser*) { operandBiop(nodep); setClean (nodep, isClean(nodep->lhsp()) || isClean(nodep->rhsp())); } virtual void visit(AstXor* nodep, AstNUser*) { operandBiop(nodep); setClean (nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp())); } virtual void visit(AstOr* nodep, AstNUser*) { operandBiop(nodep); setClean (nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp())); } virtual void visit(AstNodeMath* nodep, AstNUser*) { nodep->iterateChildren(*this); computeCppWidth(nodep); setClean (nodep, nodep->cleanOut()); } virtual void visit(AstNodeAssign* nodep, AstNUser*) { nodep->iterateChildren(*this); computeCppWidth(nodep); if (nodep->cleanRhs()) { insureClean(nodep->rhsp()); } } virtual void visit(AstText* nodep, AstNUser*) { setClean (nodep, true); } virtual void visit(AstScopeName* nodep, AstNUser*) { setClean (nodep, true); } virtual void visit(AstSel* nodep, AstNUser*) { operandTriop(nodep); setClean (nodep, nodep->cleanOut()); } virtual void visit(AstUCFunc* nodep, AstNUser*) { nodep->iterateChildren(*this); computeCppWidth(nodep); setClean (nodep, false); // We always clean, as we don't trust those pesky users. if (!nodep->backp()->castAnd()) { insertClean(nodep); } insureCleanAndNext (nodep->bodysp()); } virtual void visit(AstTraceInc* nodep, AstNUser*) { nodep->iterateChildren(*this); insureCleanAndNext (nodep->valuep()); } virtual void visit(AstTypedef* nodep, AstNUser*) { // No cleaning, or would loose pointer to enum nodep->iterateChildren(*this); } // Control flow operators virtual void visit(AstNodeCond* nodep, AstNUser*) { nodep->iterateChildren(*this); insureClean(nodep->condp()); setClean(nodep, isClean(nodep->expr1p()) && isClean(nodep->expr2p())); } virtual void visit(AstWhile* nodep, AstNUser*) { nodep->iterateChildren(*this); insureClean(nodep->condp()); } virtual void visit(AstNodeIf* nodep, AstNUser*) { nodep->iterateChildren(*this); insureClean(nodep->condp()); } virtual void visit(AstSFormatF* nodep, AstNUser*) { nodep->iterateChildren(*this); insureCleanAndNext (nodep->exprsp()); setClean(nodep, true); // generates a string, so not relevant } virtual void visit(AstUCStmt* nodep, AstNUser*) { nodep->iterateChildren(*this); insureCleanAndNext (nodep->bodysp()); } virtual void visit(AstCCall* nodep, AstNUser*) { nodep->iterateChildren(*this); insureCleanAndNext (nodep->argsp()); } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); computeCppWidth(nodep); } public: // CONSTUCTORS CleanVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~CleanVisitor() {} }; //###################################################################### // Clean class functions void V3Clean::cleanAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Localize.h0000664000177100017500000000227312525171733016450 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Convert BLOCKTEMPs to local variables // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LOCALIZE_H_ #define _V3LOCALIZE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Localize { public: static void localizeAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Table.h0000664000177100017500000000223412525171733015732 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Make lookup tables // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3TABLE_H_ #define _V3TABLE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Table { public: static void tableAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Changed.h0000664000177100017500000000225212525171733016234 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Pre C-Emit stage changes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CHANGED_H_ #define _V3CHANGED_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Changed { public: static void changedAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Param.h0000664000177100017500000000224512525171733015745 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Param modules/signals together // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3PARAM_H_ #define _V3PARAM_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Param { public: static void param(AstNetlist* rootp); }; #endif // Guard verilator-3.874/src/V3Descope.h0000664000177100017500000000230412525171733016263 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Rename scope references to module-local references // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3DESCOPE_H_ #define _V3DESCOPE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Descope { public: static void descopeAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Const.h0000664000177100017500000000360712525171733015776 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Propagate constants across AST // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CONST_H_ #define _V3CONST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Const { public: static AstNode* constifyParamsEdit(AstNode* nodep); static AstNode* constifyGenerateParamsEdit(AstNode* nodep); // Only do constant pushing, without removing dead logic static void constifyAllLive(AstNetlist* nodep); // Everything that's possible static void constifyAll(AstNetlist* nodep); // Also, warn static void constifyAllLint(AstNetlist* nodep); // C++ datatypes static void constifyCpp(AstNetlist* nodep); // Only the current node and lower // Return new node that may have replaced nodep static AstNode* constifyEdit(AstNode* nodep); // Only the current node and lower, with special SenTree optimization // Return new node that may have replaced nodep static AstNode* constifyExpensiveEdit(AstNode* nodep); }; #endif // Guard verilator-3.874/src/V3StatsReport.cpp0000664000177100017500000001351412525171733017533 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Collect and print statistics // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Stats.h" #include "V3Ast.h" #include "V3File.h" //###################################################################### // Stats dumping class StatsReport { // TYPES typedef vector StatColl; // STATE ofstream& os; // Output stream static StatColl s_allStats; ///< All statistics void header() { os<<"Verilator Statistics Report\n"; os< ByName; ByName byName; // * is always first for (StatColl::iterator it = s_allStats.begin(); it!=s_allStats.end(); ++it) { V3Statistic* repp = &(*it); byName.insert(make_pair(repp->name(), repp)); } // Process duplicates V3Statistic* lastp = NULL; for (ByName::iterator it = byName.begin(); it!=byName.end(); ++it) { V3Statistic* repp = it->second; if (lastp && lastp->sumit() && lastp->printit() && lastp->name() == repp->name() && lastp->stage() == repp->stage()) { repp->combineWith(lastp); } lastp = repp; } } void stars() { os<<"Global Statistics:\n"; os< ByName; ByName byName; // * is always first for (StatColl::iterator it = s_allStats.begin(); it!=s_allStats.end(); ++it) { const V3Statistic* repp = &(*it); if (repp->stage() == "*" && repp->printit()) { if (maxWidth < repp->name().length()) maxWidth = repp->name().length(); byName.insert(make_pair(repp->name(), repp)); } } // Print organized by stage for (ByName::iterator it = byName.begin(); it!=byName.end(); ++it) { const V3Statistic* repp = it->second; os<<" "<name(); repp->dump(os); os< Stages; Stages stages; map stageInt; typedef multimap ByName; ByName byName; // * is always first for (StatColl::iterator it = s_allStats.begin(); it!=s_allStats.end(); ++it) { const V3Statistic* repp = &(*it); if (repp->stage() != "*" && repp->printit()) { if (maxWidth < repp->name().length()) maxWidth = repp->name().length(); if (stageInt.find(repp->stage()) == stageInt.end()) { stageInt.insert(make_pair(repp->stage(), stage++)); stages.push_back(repp->stage()); } byName.insert(make_pair(repp->name(), repp)); } } // Header os<<" Stat "<second; if (lastName != repp->name()) { lastName = repp->name(); { string commaName = lastName; string::size_type pos; if ((pos=commaName.find(",")) != string::npos) { commaName.erase(pos); } if (lastCommaName != commaName) { lastCommaName = commaName; os<name(); } while (colstage()) { os<dump(os); col++; } os<fail()) v3fatalSrc("Can't write "<close(); delete ofp; ofp = NULL; } verilator-3.874/src/V3Global.h0000664000177100017500000001055012525247644016110 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Common headers // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3GLOBAL_H_ #define _V3GLOBAL_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.h" #include "V3FileLine.h" #include "V3Options.h" class AstNetlist; //====================================================================== // Statics //###################################################################### class VWidthMinUsage { public: enum en { LINT_WIDTH, MATCHES_WIDTH, VERILOG_WIDTH }; enum en m_e; inline VWidthMinUsage () : m_e(LINT_WIDTH) {} inline VWidthMinUsage (en _e) : m_e(_e) {} explicit inline VWidthMinUsage (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (VWidthMinUsage::en lhs, VWidthMinUsage rhs) { return (lhs == rhs.m_e); } //###################################################################### // V3Global - The top level class for the entire program class V3Global { // Globals AstNetlist* m_rootp; // Root of entire netlist VWidthMinUsage m_widthMinUsage; // What AstNode::widthMin() is used for int m_debugFileNumber; // Number to append to debug files created int m_assertWidthsMatch; // Tree should have width()==widthMin() bool m_assertDTypesResolved; // Tree should have dtypep()'s bool m_constRemoveXs; // Const needs to strip any Xs bool m_needHInlines; // Need __Inlines file bool m_needHeavy; // Need verilated_heavy.h include bool m_dpi; // Need __Dpi include files public: // Options V3Options opt; // All options; let user see them directly public: // CREATORS V3Global() { m_debugFileNumber = 0; m_widthMinUsage = VWidthMinUsage::LINT_WIDTH; m_assertDTypesResolved = false; m_constRemoveXs = false; m_needHInlines = false; m_needHeavy = false; m_dpi = false; m_rootp = NULL; // created by makeInitNetlist() so static constructors run first } AstNetlist* makeNetlist(); void boot() { UASSERT(!m_rootp,"call once"); m_rootp = makeNetlist(); } void clear(); // ACCESSORS (general) AstNetlist* rootp() const { return m_rootp; } VWidthMinUsage widthMinUsage() const { return m_widthMinUsage; } bool assertDTypesResolved() const { return m_assertDTypesResolved; } // METHODS void readFiles(); void checkTree(); static void dumpCheckGlobalTree(const string& filename, int newNumber=0, bool doDump=true); void assertDTypesResolved(bool flag) { m_assertDTypesResolved = flag; } void widthMinUsage(const VWidthMinUsage& flag) { m_widthMinUsage = flag; } bool constRemoveXs() const { return m_constRemoveXs; } void constRemoveXs(bool flag) { m_constRemoveXs = flag; } string debugFilename(const string& nameComment, int newNumber=0) { ++m_debugFileNumber; if (newNumber) m_debugFileNumber = newNumber; char digits[100]; sprintf(digits, "%03d", m_debugFileNumber); return opt.makeDir()+"/"+opt.prefix()+"_"+digits+"_"+nameComment; } bool needHInlines() const { return m_needHInlines; } void needHInlines(bool flag) { m_needHInlines=flag; } bool needHeavy() const { return m_needHeavy; } void needHeavy(bool flag) { m_needHeavy=flag; } bool dpi() const { return m_dpi; } void dpi(bool flag) { m_dpi = flag; } }; extern V3Global v3Global; //###################################################################### #endif // guard verilator-3.874/src/V3Width.h0000664000177100017500000000315312525171734015764 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Node attributes/ expression widths // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3WIDTH_H_ #define _V3WIDTH_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Width { public: static int debug(); static void width(AstNetlist* nodep); static AstNode* widthParamsEdit(AstNode* nodep); static AstNode* widthGenerateParamsEdit(AstNode* nodep); // Final step... Mark all widths as equal static void widthCommit(AstNetlist* nodep); // For use only in WidthVisitor // Replace AstSelBit, etc with AstSel/AstArraySel // Returns replacement node if nodep was deleted, or null if none. static AstNode* widthSelNoIterEdit(AstNode* nodep); }; #endif // Guard verilator-3.874/src/V3LinkResolve.h0000664000177100017500000000227412525171733017144 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Link modules/signals together // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LINKRESOLVE_H_ #define _V3LINKRESOLVE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3LinkResolve { public: static void linkResolve(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Assert.h0000664000177100017500000000224112525171733016142 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Assertion expansion // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3ASSERT_H_ #define _V3ASSERT_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Assert { public: static void assertAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/astgen0000775000177100017500000004374212525171734015542 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### #require 5.006_001; use Getopt::Long; use IO::File; use Pod::Usage; use strict; use vars qw ($Debug @Types %Classes %Children %ClassRefs %Stages); #====================================================================== # main $Debug = 0; my $opt_classes; my $opt_report; my @Opt_Cpt; my @Opt_I; Getopt::Long::config ("pass_through", "no_auto_abbrev"); if (! GetOptions ( "help" => \&usage, "debug" => sub { $Debug = 1; }, "classes!" => \$opt_classes, "report!" => \$opt_report, "<>" => \¶meter, )) { usage(); } read_types("$Opt_I[0]/V3Ast.h"); read_types("$Opt_I[0]/V3AstNodes.h"); read_stages("$Opt_I[0]/Verilator.cpp"); read_refs(glob("$Opt_I[0]/*.y"), glob("$Opt_I[0]/*.h"), glob("$Opt_I[0]/*.cpp")); if ($opt_report) { write_report(undef); } if ($opt_classes) { write_report("V3Ast__gen_report.txt"); write_classes("V3Ast__gen_classes.h"); write_visitor("V3Ast__gen_visitor.h"); write_intf("V3Ast__gen_interface.h"); write_impl("V3Ast__gen_impl.h"); write_types("V3Ast__gen_types.h"); } foreach my $cpt (@Opt_Cpt) { Cpt::process(in_filename=>"$Opt_I[0]/${cpt}.cpp", out_filename=>"${cpt}__gen.cpp"); } #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } sub parameter { my $param = shift; if ($param =~ /^-+I(\S+)/) { push @Opt_I, $1; } elsif ($param =~ s/\.cpp$//) { push @Opt_Cpt, $param; } else { die "%Error: Unknown parameter: $param,"; } } ####################################################################### sub read_types { my $filename = shift; my $fh = IO::File->new($filename) or die "%Error: $! $filename,"; while (defined (my $line = $fh->getline())) { $line =~ s/\/\/.*$//; next if $line =~ /^\s*$/; if ($line =~ /^\s*(class|struct)\s*(\S+)/) { my $class = $2; my $inh = ""; $inh = $1 if ($line =~ /:\s*public\s+(\S+)/); print "class $class : $inh\n" if $Debug; $inh = "" if $class eq "AstNode"; if ($inh =~ /Ast/ || $class eq "AstNode") { $class =~ s/^Ast//; $inh =~ s/^Ast//; $Classes{$class} = $inh; $Children{$inh}{$class} = 1; } } } } sub read_stages { my $filename = shift; my $fh = IO::File->new($filename) or die "%Error: $! $filename,"; my $n = 0; while (defined (my $line = $fh->getline())) { $line =~ s/\/\/.*$//; next if $line =~ /^\s*$/; if ($line =~ /^\s*([A-Za-z0-9]+)::/) { my $stage = $1.".cpp"; if (!defined ($Stages{$stage})) { $Stages{$stage} = $n++; } } } } sub read_refs { my @filenames = @_; foreach my $filename (@filenames) { (my $basename = $filename) =~ s!.*/!!; my $fh = IO::File->new($filename) or die "%Error: $! $filename,"; while (defined (my $line = $fh->getline())) { $line =~ s/\/\/.*$//; while ($line =~ /\bnew\s*(Ast[A-Za-z0-9_]+)/g) { $ClassRefs{$1}{newed}{$basename} = 1; } while ($line =~ /\b(Ast[A-Za-z0-9_]+)/g) { $ClassRefs{$1}{used}{$basename} = 1; } } } #use Data::Dumper;print Dumper(\%ClassRefs); } #---------------------------------------------------------------------- sub open_file { my $filename = shift; my $fh = IO::File->new($filename,"w") or die "%Error: $! $filename,"; print $fh '// Generated by astgen // -*- mode: C++; c-file-style: "cc-mode" -*-'."\n"; return $fh; } #---------------------------------------------------------------------- sub subclasses_of { my $type = shift; my @cllist; for (my $subclass = $::Classes{$type}; $subclass; ) { push @cllist, $subclass; $subclass = $::Classes{$subclass}; } return (reverse @cllist); } sub children_of { my $type = shift; my @cllist; my @todo; push @todo, $type; while (my $subclass = shift @todo) { foreach my $child (sort keys %{$::Children{$subclass}}) { push @todo, $child; push @cllist, $child; } } return (@cllist); } #---------------------------------------------------------------------- sub write_report { my $filename = shift; my $fh = defined($filename) ? open_file($filename) : \*STDOUT; $fh->print("Processing stages (approximate, based on order in Verilator.cpp):\n"); foreach my $class (sort {$Stages{$a} <=> $Stages{$b}} keys %Stages) { $fh->print("\t$class\n"); } $fh->print("\nProcessing stages (approximate, based on order in Verilator.cpp):\n"); foreach my $type (sort (keys %Classes)) { printf $fh " class %-20s\n", "Ast${type}"; $fh->print("\tparent:\t"); foreach my $subclass (subclasses_of($type)) { next if $subclass eq 'Node'; printf $fh "Ast%-12s ",$subclass; } printf $fh "\n"; $fh->print("\tchilds:\t"); foreach my $subclass (children_of($type)) { next if $subclass eq 'Node'; printf $fh "Ast%-12s ",$subclass; } printf $fh "\n"; if (my $refs = $ClassRefs{"Ast${type}"}) { $fh->print("\tnewed:\t"); foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)} keys %{$refs->{newed}}) { $fh->print($stage." "); } $fh->print("\n"); $fh->print("\tused:\t"); foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)} keys %{$refs->{used}}) { $fh->print($stage." "); } $fh->print("\n"); } $fh->print("\n"); } } sub write_classes { my $fh = open_file(@_); foreach my $type (sort (keys %Classes)) { printf $fh "class %-20s // ", "Ast${type};"; foreach my $subclass (subclasses_of($type)) { printf $fh "Ast%-12s ",$subclass; } printf $fh "\n"; } $fh->close(); } sub write_visitor { my $fh = open_file(@_); foreach my $type (sort (keys %Classes)) { my $base = $Classes{$type}; if ($base) { printf $fh " virtual void visit(Ast${type}* nodep, AstNUser* vup) { visit((Ast${base}*)(nodep),vup); }\n"; } else { printf $fh " virtual void visit(Ast${type}*, AstNUser*) = 0;\n"; } } $fh->close(); } sub write_intf { my $fh = open_file(@_); foreach my $type (sort (keys %Classes)) { next if $type eq "Node"; # Special, just a return (this); printf $fh " Ast%-16s cast${type}();\n" ,$type."*"; } $fh->close(); } sub write_impl { my $fh = open_file(@_); foreach my $type (sort (keys %Classes)) { next if $type eq "Node"; # Special, just a return (this); printf $fh "inline Ast%-16s AstNode::cast${type}() { return (dynamic_cast(this)); }\n" ,$type."*"; } $fh->close(); } sub write_types { my $fh = open_file(@_); printf $fh " enum en {\n"; # Add "at" prefix to avoid conflicting with FOPEN and other macros in include files foreach my $type (sort (keys %Classes)) { next if $type =~ /^Node/; print $fh "\tat",uc $type,",\n"; } printf $fh "\t_ENUM_END\n"; printf $fh " };\n"; printf $fh " const char* ascii() const {\n"; printf $fh " const char* names[] = {\n"; foreach my $type (sort (keys %Classes)) { next if $type =~ /^Node/; print $fh "\t\"", uc $type, "\",\n"; } printf $fh "\t\"_ENUM_END\"\n"; printf $fh " };\n"; printf $fh " return names[m_e];\n"; printf $fh " };\n"; $fh->close(); } ####################################################################### package Cpt; sub error { my $self = shift; my $txt = join('', @_); die "%Error: $self->{in_filename}:$self->{in_linenum}: $txt\n"; } sub print { my $self = shift; my $txt = join('', @_); push @{$self->{out_lines}}, $txt; } sub output_func { my $self = shift; my $func = shift; push @{$self->{out_lines}}, $func; } sub _output_line { my $self = shift; $self->print("#line ",$self->{out_linenum}+2," \"$self->{out_filename}\"\n"); } sub process { my $self = { in_filename => undef, out_filename => undef, out_lines => [], out_linenum => 1, @_, }; bless $self, __PACKAGE__; my $ln = 1; my $didln; # Read the file and parse into list of functions that generate output my $fhi = IO::File->new($self->{in_filename}) or die "%Error: $! $self->{in_filename},"; while (defined(my $line = $fhi->getline)) { if (!$didln) { $self->print("#line $. \"$self->{in_filename}\"\n"); $didln = 1; } if ($line =~ /^\s+(TREE.*)$/) { my $func = $1; $self->{in_linenum} = $.; $self->print("//$line"); $self->output_func(sub{my $self=shift; $self->_output_line(); }); $self->tree_line ($func); $didln = 0; } elsif ($line !~ /^\s*\/[\/\*]\s*TREE/ && $line =~ /\s+TREE/) { $self->error("Unknown astgen line: $line"); } else { $self->print($line); } } $fhi->close; # Put out the resultant file, if the list has a reference to a # function, then call that func to generate output my $fho = ::open_file($self->{out_filename}); my @togen = @{$self->{out_lines}}; foreach my $line (@togen) { if (ref $line) { $self->{out_lines} = []; &$line($self); } else { $self->{out_lines} = [$line]; } foreach my $out (@{$self->{out_lines}}) { $self->{out_linenum}++ while ($out =~ /\n/smg); print $fho $out; } } $fho->close; } sub tree_line { my $self = shift; my $func = shift; $func =~ s!\s*//.*$!!; $func =~ s!\s*;\s*$!!; # doflag "S" indicates an op specifying short-circuiting for a type. if ($func =~ /TREEOP(1?)([VCS]?)\s*\(\s* \"([^\"]*)\" \s*,\s* \"([^\"]*)\" \s*\)/sx) { my $order = $1; my $doflag = $2; my $from = $3; my $to = $4; #$self->print("// $from $to\n"); if (!$self->{did_out_tree}) { $self->{did_out_tree} = 1; $self->output_func(sub{ my $self=shift; $self->tree_match(); $self->tree_base(); }); } $from =~ /Ast([a-zA-Z0-9]+)\s*\{(.*)\}\s*$/ or $self->error("Can't parse from function: $func"); my $type = $1; my $subnodes = $2; (::subclasses_of($type)) or $self->error("Unknown AstNode type: $type: in $func"); my $mif; if ($doflag eq '') { $mif = "m_doNConst"; } elsif ($doflag eq 'V') { $mif = "m_doV"; } elsif ($doflag eq 'C') { $mif = ""; } elsif ($doflag eq 'S') { $mif = "m_doNConst"; } # Not just for m_doGenerate else { die; } $subnodes =~ s/,,/__ESCAPEDCOMMA__/g; foreach my $subnode (split /\s*,\s*/, $subnodes) { $subnode =~ s/__ESCAPEDCOMMA__/,/g; next if $subnode =~ /^\$([a-z0-9]+)$/gi; # "$lhs" is just a comment that this op has a lhs $mif .= " && " if $mif; my $subnodeif = $subnode; $subnodeif =~ s/\$([a-zA-Z0-9]+)\.([a-zA-Z0-9]+)$/nodep->$1()->$2()/g; $subnodeif = add_nodep($subnodeif); $mif .= $subnodeif; } my $exec_func = treeop_exec_func($self, $to); $self->{treeop}{$type} ||= []; my $n = $#{$self->{treeop}{$type}} + 1; my $typefunc = { order => $order, comment => $func, match_func => "match_${type}_${n}", match_if => $mif, exec_func => $exec_func, uinfo_level => ($to =~ /^!/ ? 0:7), short_circuit => ($doflag eq 'S'), }; ($typefunc->{uinfo} = $func) =~ s/[ \t\"\{\}]+/ /g; push @{$self->{treeop}{$type}}, $typefunc; } elsif ($func =~ /TREE_SKIP_VISIT\s*\(\s* \"([^\"]*)\" \s*\)/sx) { my $type = $1; $self->{tree_skip_visit}{$type} = 1; $::Classes{$type} or $self->error("Unknown node type: $type"); } else { $self->error("Unknown astgen op: $func"); } } sub add_nodep { my $str = shift; $str =~ s/\$([a-zA-Z0-9]+)/nodep->$1()/g; return $str; } our %_Exec_Syms; our $_Exec_Nsyms; sub _exec_syms_recurse { my $aref = shift; foreach my $sym (@{$aref}) { if (ref $sym) { _exec_syms_recurse($sym); } elsif ($sym =~ /^\$.*/) { if (!defined $_Exec_Syms{$sym}) { $_Exec_Syms{$sym} = "arg".($_Exec_Nsyms++)."p"; } } } } sub _exec_new_recurse { my $aref = shift; my $out = "new ".$aref->[0]."(nodep->fileline()"; my $first = 1; foreach my $sym (@{$aref}) { if ($first) { $first=0; next; } $out .= ", "; if (ref $sym) { $out.=_exec_new_recurse($sym); } elsif ($sym =~ /^\$.*/) { $out .= $_Exec_Syms{$sym}; } else { $out .= $sym; } } return $out.")"; } sub treeop_exec_func { my $self = shift; my $func = shift; my $out = ""; $func =~ s/^!//; if ($func =~ /^\s*[a-zA-Z0-9]+\s*\(/) { # Function call (my $outl = $func) =~ s/\$([a-zA-Z0-9]+)/nodep->$1()/g; $out .= $outl.";"; } elsif ($func =~ /^\s*Ast([a-zA-Z0-9]+) \s*\{\s* (.*) \s* \}$/x) { my $nargs = 0; my %argnums; # Number for each argument name my $aref = undef; # Recursive array with structure to form my @astack; my $forming = ""; my $argtext = $func . "\000"; # EOF character #print "FF $func\n" if $Debug; while ($argtext =~ s/^(.)//) { my $tok = $1; #print "TOK: $tok $forming\n" if $tok !~ /[a-zA-Z0-9]/; if ($tok eq "\000") { } elsif ($tok =~ /\s+/) { } elsif ($tok eq "{") { my $newref = [$forming]; push @{$aref}, $newref; push @astack, $aref if $aref; $aref = $newref; $forming = ""; } elsif ($tok eq "}") { push @{$aref}, $forming if $forming; $aref = pop @astack; $aref or $self->error("Too many } in execution function: $func\n"); $forming = ""; } elsif ($tok eq ",") { push @{$aref}, $forming if $forming; $forming = ""; } else { $forming .= $tok; } } ($aref && ref $aref->[0] && !$aref->[1]) or $self->error("Badly formed execution function: $func\n"); $aref = $aref->[0]; #use Data::Dumper; print Dumper($aref),"\n"; # Assign numbers to each $ symbol %_Exec_Syms = (); $_Exec_Nsyms = 0; _exec_syms_recurse($aref); foreach my $sym (sort {$_Exec_Syms{$a} cmp $_Exec_Syms{$b}} (keys %_Exec_Syms)) { my $argnp = $_Exec_Syms{$sym}; my $arg = add_nodep($sym); $out .= "AstNode* ${argnp} = ${arg}->unlinkFrBack();\n"; } $out .= "AstNode* newp = " . _exec_new_recurse($aref).";\n"; $out .= "nodep->replaceWith(newp);"; $out .= "nodep->deleteTree(); nodep=NULL;"; #print "FF $out\n" if $Debug; } elsif ($func eq "NEVER") { $out .= "nodep->v3fatalSrc(\"Executing transform that was NEVERed\");"; } elsif ($func eq "DONE") { } else { $self->error("Unknown execution function format: $func\n"); } return $out; } sub tree_match { my $self = shift; $self->print (" // TREEOP functions, each return true if they matched & transformed\n"); #use Data::Dumper; print Dumper($self); foreach my $base (sort (keys %{$self->{treeop}})) { foreach my $typefunc (@{$self->{treeop}{$base}}) { $self->print(" // Generated by astgen\n"); $self->print(" bool $typefunc->{match_func}(Ast${base}* nodep) {\n", "\t// $typefunc->{comment}\n",); $self->print( "\tif ($typefunc->{match_if}) {\n"); $self->print( "\t UINFO($typefunc->{uinfo_level},(void*)(nodep)<<\" $typefunc->{uinfo}\\n\");\n"); $self->print( "\t $typefunc->{exec_func}\n"); $self->print( "\t return true;\n"); $self->print( "\t}\n"); $self->print( "\treturn false;\n"); $self->print(" }\n",); } } } sub tree_base { my $self = shift; $self->print (" // TREEOP visitors, call each base type's match\n"); $self->print (" // Bottom class up, as more simple transforms are generally better\n"); foreach my $type (sort (keys %::Classes)) { my $base = $::Classes{$type}; my @out_for_type_sc; my @out_for_type; foreach my $base (::subclasses_of($type), $type) { foreach my $typefunc (@{$self->{treeop}{$base}}) { my @lines = (" if ($typefunc->{match_func}(nodep)) return;\n",); if ($typefunc->{short_circuit}) { # short-circuit match fn push @out_for_type_sc, @lines; } else { # Standard match fn if ($typefunc->{order}) { unshift @out_for_type, @lines; # TREEOP1's go in front of others } else { push @out_for_type, @lines; } } } } # We need to deal with two cases. For short circuited functions we # evaluate the LHS, then apply the short-circuit matches, then # evaluate the RHS and possibly THS (ternary operators may # short-circuit) and apply all the other matches. # For types without short-circuits, we just use iterateChildren, which # saves one comparison. if ($out_for_type_sc[0]) { # Short-circuited types $self->print(" // Generated by astgen with short-circuiting\n", " virtual void visit(Ast${type}* nodep, AstNUser*) {\n", " nodep->lhsp()->iterateAndNext(*this);\n", @out_for_type_sc); $self->print(" nodep->rhsp()->iterateAndNext(*this);\n", " AstNodeTriop *tnp = nodep->castNodeTriop();\n", " if (tnp && tnp->thsp()) tnp->thsp()->iterateAndNext(*this);\n", @out_for_type, " }\n") if ($out_for_type[0]); } elsif ($out_for_type[0]) { # Other types with something to print my $skip = $self->{tree_skip_visit}{$type}; my $gen = $skip ? "Gen" : ""; $self->print(" // Generated by astgen\n", " virtual void visit$gen(Ast${type}* nodep, AstNUser*) {\n", ($skip?"": " nodep->iterateChildren(*this);\n"), @out_for_type, " }\n"); } } } ####################################################################### package main; __END__ =pod =head1 NAME astgen - Generate V3Ast headers to reduce C++ code duplication =head1 SYNOPSIS astgen =head1 DESCRIPTION Generates several files for Verilator compilations. =head1 ARGUMENTS =over 4 =item --help Displays this message and program version and exits. =item --classes Makes class declaration files. =item --report Makes a report report. =back =head1 DISTRIBUTION Copyright 2002-2015 by Wilson Snyder. Verilator 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO =cut ###################################################################### ### Local Variables: ### compile-command: "./astgen -I. --report" ### End: verilator-3.874/src/V3Number_test.cpp0000664000177100017500000001070412525171733017526 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Netlist (top level) functions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // CHEAT! #define V3NUMBER_ASCII_BINARY #define _V3ERROR_NO_GLOBAL_ 1 #include "V3Error.cpp" #include "V3FileLine.cpp" #include "V3Number.cpp" #include #include "verilatedos.h" #include #include #include #include "V3Number.h" void test(string lhss, string op, string rhss, string exps) { char* l1 = strdup(lhss.c_str()); char* r1 = strdup(rhss.c_str()); char* e1 = strdup(exps.c_str()); V3Number lhnum (new FileLine ("ck",__LINE__), l1); V3Number rhnum (new FileLine ("ck",__LINE__), r1); V3Number expnum (new FileLine("ck",__LINE__), e1); V3Number gotnum (new FileLine("ck",__LINE__), expnum.width()); if (op=="redOr") gotnum.opRedOr (lhnum); else if (op=="redAnd") gotnum.opRedAnd (lhnum); else if (op=="redXor") gotnum.opRedXor (lhnum); else if (op=="redXnor") gotnum.opRedXnor (lhnum); else if (op=="concat") gotnum.opConcat (lhnum,rhnum); else if (op=="repl") gotnum.opRepl (lhnum,rhnum); else if (op=="~") gotnum.opNot (lhnum); else if (op=="!") gotnum.opLogNot (lhnum); else if (op=="negate") gotnum.opNegate (lhnum); else if (op=="+") gotnum.opAdd (lhnum,rhnum); else if (op=="-") gotnum.opSub (lhnum,rhnum); else if (op=="*") gotnum.opMul (lhnum,rhnum); else if (op=="/") gotnum.opDiv (lhnum,rhnum); else if (op=="%") gotnum.opModDiv (lhnum,rhnum); else if (op=="&") gotnum.opAnd (lhnum,rhnum); else if (op=="|") gotnum.opOr (lhnum,rhnum); else if (op=="<") gotnum.opLt (lhnum,rhnum); else if (op==">") gotnum.opGt (lhnum,rhnum); else if (op==">>") gotnum.opShiftR (lhnum,rhnum); else if (op=="<<") gotnum.opShiftL (lhnum,rhnum); else if (op=="==") gotnum.opEq (lhnum,rhnum); else if (op=="===") gotnum.opCaseEq (lhnum,rhnum); else if (op=="==?") gotnum.opWildEq (lhnum,rhnum); else if (op=="!=") gotnum.opNeq (lhnum,rhnum); else if (op=="!==") gotnum.opCaseNeq (lhnum,rhnum); else if (op=="!=?") gotnum.opWildNeq (lhnum,rhnum); else if (op=="<=") gotnum.opLte (lhnum,rhnum); else if (op==">=") gotnum.opGte (lhnum,rhnum); else if (op=="&&") gotnum.opLogAnd (lhnum,rhnum); else if (op=="||") gotnum.opLogOr (lhnum,rhnum); else v3fatalSrc("Bad opcode: "<= 6); } static void linkDotParamed(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } static void linkDotArrayed(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } static void linkDotScope(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } }; #endif // Guard verilator-3.874/src/V3Unknown.h0000664000177100017500000000224512525171733016344 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add Unknown assigns // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3UNKNOWN_H_ #define _V3UNKNOWN_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Unknown { public: static void unknownAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3String.h0000664000177100017500000000575212525171733016161 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: String manipulation // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3STRING_H_ #define _V3STRING_H_ 1 #include "config_build.h" #include "verilatedos.h" #include //###################################################################### // VString - String manipulation class VString { static bool wildmatchi(const char* s, const char* p); public: // METHODS (generic string utilities) static bool wildmatch(const char* s, const char* p); static string downcase(const string& str); }; //###################################################################### // Compute FNV1a (Fowler/Noll/Vo) hashes // See http://www.isthe.com/chongo/tech/comp/fnv/index.html // Algorithmic basis for these functions was in the public domain, by chongo class VHashFnv { enum { FNV1_64_INIT = 0xcbf29ce484222325ULL }; // Initial value vluint64_t m_hash; inline void hashC(uint8_t c) { m_hash ^= c; // Below is faster than m_hash *= 0x100000001b3ULL; m_hash += ((m_hash << 1) + (m_hash << 4) + (m_hash << 5) + (m_hash << 7) + (m_hash << 8) + (m_hash << 40)); } public: VHashFnv() : m_hash(FNV1_64_INIT) {} ~VHashFnv() {} vluint64_t value() const { return m_hash; } VHashFnv& hash(const void* bufp, size_t len) { // Memory const uint8_t* bp = (const uint8_t*)bufp; const uint8_t* be = bp + len; while (bp < be) hashC((vluint64_t)*bp++); return *this; } VHashFnv& hash(const char* strp) { // String const uint8_t* sp = (const uint8_t*)strp; while (*sp) hashC((vluint64_t)*sp++); return *this; } VHashFnv& hash(const string& str) { return hash(str.c_str()); } VHashFnv& hash(vluint64_t n) { hashC(n>>0); hashC(n>>8); hashC(n>>16); hashC(n>>24); hashC(n>>32); hashC(n>>40); hashC(n>>48); hashC(n>>56); return *this; } VHashFnv& hash(uint32_t n) { hashC(n>>0); hashC(n>>8); hashC(n>>16); hashC(n>>24); return *this; } VHashFnv& hash(uint16_t n) { hashC(n>>0); hashC(n>>8); return *this; } VHashFnv& hash(uint8_t n) { hashC(n); return *this; } VHashFnv& hash(int n) { hashC((vluint64_t)n); return *this; } }; //###################################################################### #endif // guard verilator-3.874/src/V3ParseGrammar.cpp0000664000177100017500000000211612525171733017616 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Parse syntax tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "V3Ast.h" // This must be before V3ParseBison.cpp, as we don't want #defines to conflict //====================================================================== // The guts came from bison #include "V3ParseBison.c" verilator-3.874/src/V3Delayed.h0000664000177100017500000000225212525171733016252 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Pre C-Emit stage changes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3DELAYED_H_ #define _V3DELAYED_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Delayed { public: static void delayedAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3LinkParse.cpp0000664000177100017500000003361612525171733017136 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Parse module/signal name references // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LinkParse TRANSFORMATIONS: // Top-down traversal // Move some attributes around //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3LinkParse.h" #include "V3Ast.h" //###################################################################### // Link state, as a visitor of each AstNode class LinkParseVisitor : public AstNVisitor { private: // NODE STATE // Cleared on netlist // AstNode::user1() -> bool. True if processed // AstNode::user2() -> bool. True if fileline recomputed AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // TYPES typedef map ,AstTypedef*> ImplTypedefMap; typedef set FileLineSet; // STATE AstVar* m_varp; // Variable we're under ImplTypedefMap m_implTypedef; // Created typedefs for each FileLineSet m_filelines; // Filelines that have been seen bool m_inAlways; // Inside an always bool m_inGenerate; // Inside a generate bool m_needStart; // Need start marker on lower AstParse AstNodeModule* m_valueModp; // If set, move AstVar->valuep() initial values to this module AstNodeModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Current task AstNodeDType* m_dtypep; // Current data type // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void cleanFileline(AstNode* nodep) { if (!nodep->user2SetOnce()) { // Process once // We make all filelines unique per AstNode. This allows us to // later turn off messages on a fileline when an issue is found // so that messages on replicated blocks occur only once, // without suppressing other token's messages as a side effect. // We could have verilog.l create a new one on every token, // but that's a lot more structures than only doing AST nodes. if (m_filelines.find(nodep->fileline()) != m_filelines.end()) { nodep->fileline(new FileLine(nodep->fileline())); } m_filelines.insert(nodep->fileline()); } } // VISITs virtual void visit(AstNodeFTask* nodep, AstNUser*) { if (!nodep->user1SetOnce()) { // Process only once. cleanFileline(nodep); m_ftaskp = nodep; nodep->iterateChildren(*this); m_ftaskp = NULL; } } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { if (!nodep->user1SetOnce()) { // Process only once. cleanFileline(nodep); UINFO(5," "<iterateChildren(*this); m_valueModp = upperValueModp; } } virtual void visit(AstNodeDType* nodep, AstNUser*) { if (!nodep->user1SetOnce()) { // Process only once. cleanFileline(nodep); AstNodeDType* upperDtypep = m_dtypep; m_dtypep = nodep; nodep->iterateChildren(*this); m_dtypep = upperDtypep; } } virtual void visit(AstEnumItem* nodep, AstNUser*) { // Expand ranges cleanFileline(nodep); nodep->iterateChildren(*this); if (nodep->rangep()) { if (!nodep->rangep()->msbp()->castConst() || !nodep->rangep()->lsbp()->castConst()) nodep->v3error("Enum ranges must be integral, per spec"); int msb = nodep->rangep()->msbConst(); int lsb = nodep->rangep()->lsbConst(); int increment = (msb > lsb) ? -1 : 1; int offset_from_init = 0; AstNode* addp = NULL; for (int i=msb; i!=(lsb+increment); i+=increment, offset_from_init++) { string name = nodep->name() + cvtToStr(i); AstNode* valuep = NULL; if (nodep->valuep()) valuep = new AstAdd(nodep->fileline(), nodep->valuep()->cloneTree(true), new AstConst(nodep->fileline(), AstConst::Unsized32(), offset_from_init)); addp = addp->addNextNull(new AstEnumItem(nodep->fileline(), name, NULL, valuep)); } nodep->replaceWith(addp); nodep->deleteTree(); } } virtual void visit(AstVar* nodep, AstNUser*) { cleanFileline(nodep); // We used modTrace before leveling, and we may now // want to turn it off now that we know the levelizations if (v3Global.opt.traceDepth() && m_modp && (m_modp->level()-1) > v3Global.opt.traceDepth()) { m_modp->modTrace(false); nodep->trace(false); } m_varp = nodep; nodep->iterateChildren(*this); m_varp = NULL; // temporaries under an always aren't expected to be blocking if (m_inAlways) nodep->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); if (nodep->valuep()) { // A variable with an = value can be three things: FileLine* fl = nodep->valuep()->fileline(); // 1. Parameters and function inputs: It's a default to use if not overridden if (nodep->isParam() || (m_ftaskp && nodep->isInOnly())) { } else if (!m_ftaskp && nodep->isInOnly()) { nodep->v3error("Unsupported: Default value on module input: "<prettyName()); nodep->valuep()->unlinkFrBack()->deleteTree(); } // 2. Under modules, it's an initial value to be loaded at time 0 via an AstInitial else if (m_valueModp) { nodep->addNextHere (new AstInitial (fl, new AstAssign (fl, new AstVarRef(fl, nodep->name(), true), nodep->valuep()->unlinkFrBack()))); } // 3. Under blocks, it's an initial value to be under an assign else { nodep->addNextHere (new AstAssign (fl, new AstVarRef(fl, nodep->name(), true), nodep->valuep()->unlinkFrBack())); } } if (nodep->isIfaceRef() && !nodep->isIfaceParent()) { // Only AstIfaceRefDType's at this point correspond to ports; // haven't made additional ones for interconnect yet, so assert is simple // What breaks later is we don't have a Scope/Cell representing the interface to attach to if (m_modp->level()<=2) nodep->v3error("Unsupported: Interfaced port on top level module"); } } virtual void visit(AstAttrOf* nodep, AstNUser*) { cleanFileline(nodep); nodep->iterateChildren(*this); if (nodep->attrType() == AstAttrType::DT_PUBLIC) { AstTypedef* typep = nodep->backp()->castTypedef(); if (!typep) nodep->v3fatalSrc("Attribute not attached to typedef"); typep->attrPublic(true); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else 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->sigUserRWPublic(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->sigUserRWPublic(true); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RD) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->sigUserRdPublic(true); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RW) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->sigUserRWPublic(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; } else if (nodep->attrType() == AstAttrType::VAR_SFORMAT) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->attrSFormat(true); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else if (nodep->attrType() == AstAttrType::VAR_SC_BV) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->attrScBv(true); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else if (nodep->attrType() == AstAttrType::VAR_CLOCKER) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->attrClocker(AstVarAttrClocker::CLOCKER_YES); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else if (nodep->attrType() == AstAttrType::VAR_NO_CLOCKER) { if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable"); m_varp->attrClocker(AstVarAttrClocker::CLOCKER_NO); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { // AlwaysPublic was attached under a var, but it's a statement that should be // at the same level as the var cleanFileline(nodep); nodep->iterateChildren(*this); if (m_varp) { nodep->unlinkFrBack(); m_varp->addNext(nodep); // lvalue is true, because we know we have a verilator public_flat_rw // but someday we may be more general bool lvalue = m_varp->isSigUserRWPublic(); nodep->addStmtp(new AstVarRef(nodep->fileline(), m_varp, lvalue)); } } virtual void visit(AstDefImplicitDType* nodep, AstNUser*) { cleanFileline(nodep); UINFO(8," DEFIMPLICIT "<containerp(), nodep->name())); if (it != m_implTypedef.end()) { defp = it->second; } else { // Definition must be inserted right after the variable (etc) that needed it // AstVar, AstTypedef, AstNodeFTask are common containers AstNode* backp = nodep->backp(); for (; backp; backp=backp->backp()) { if (backp->castVar()) break; else if (backp->castTypedef()) break; else if (backp->castNodeFTask()) break; } if (!backp) nodep->v3fatalSrc("Implicit enum/struct type created under unexpected node type"); AstNodeDType* dtypep = nodep->childDTypep(); dtypep->unlinkFrBack(); if (backp->castTypedef()) { // A typedef doesn't need us to make yet another level of typedefing // For typedefs just remove the AstRefDType level of abstraction nodep->replaceWith(dtypep); nodep->deleteTree(); nodep=NULL; return; } else { defp = new AstTypedef(nodep->fileline(), nodep->name(), NULL, VFlagChildDType(), dtypep); m_implTypedef.insert(make_pair(make_pair(nodep->containerp(), defp->name()), defp)); backp->addNextHere(defp); } } nodep->replaceWith(new AstRefDType(nodep->fileline(), defp->name())); nodep->deleteTree(); nodep=NULL; } virtual void visit(AstTypedefFwd* nodep, AstNUser*) { // We only needed the forward declaration in order to parse correctly. // We won't even check it was ever really defined, as it might have been in a header // file referring to a module we never needed nodep->unlinkFrBack()->deleteTree(); } virtual void visit(AstNodeModule* nodep, AstNUser*) { // Module: Create sim table for entire module and iterate cleanFileline(nodep); // m_modp = nodep; m_valueModp = nodep; nodep->iterateChildren(*this); m_modp = NULL; m_valueModp = NULL; } void visitIterateNoValueMod(AstNode* nodep) { // Iterate a node which shouldn't have any local variables moved to an Initial cleanFileline(nodep); // AstNodeModule* upperValueModp = m_valueModp; m_valueModp = NULL; nodep->iterateChildren(*this); m_valueModp = upperValueModp; } virtual void visit(AstInitial* nodep, AstNUser*) { visitIterateNoValueMod(nodep); } virtual void visit(AstFinal* nodep, AstNUser*) { visitIterateNoValueMod(nodep); } virtual void visit(AstAlways* nodep, AstNUser*) { m_inAlways = true; visitIterateNoValueMod(nodep); m_inAlways = false; } virtual void visit(AstPslCover* nodep, AstNUser*) { visitIterateNoValueMod(nodep); } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate cleanFileline(nodep); nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkParseVisitor(AstNetlist* rootp) { m_varp = NULL; m_modp = NULL; m_ftaskp = NULL; m_dtypep = NULL; m_inAlways = false; m_inGenerate = false; m_needStart = false; m_valueModp = NULL; rootp->accept(*this); } virtual ~LinkParseVisitor() {} }; //###################################################################### // Link class functions void V3LinkParse::linkParse(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<= 6); } verilator-3.874/src/V3CoverageJoin.cpp0000664000177100017500000001204112525171733017606 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Netlist (top level) functions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // COVERAGEJOIN TRANSFORMATIONS: // If two COVERTOGGLEs have same VARSCOPE, combine them //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3CoverageJoin.h" #include "V3Hashed.h" #include "V3Stats.h" //###################################################################### // CoverageJoin state, as a visitor of each AstNode class CoverageJoinVisitor : public AstNVisitor { private: // NODE STATE // V3Hashed // AstCoverToggle->VarRef::user4() // V3Hashed calculation //AstUser4InUse In V3Hashed // TYPES typedef vector ToggleList; // STATE ToggleList m_toggleps; // List of of all AstCoverToggle's V3Double0 m_statToggleJoins; // Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void detectDuplicates() { UINFO(9,"Finding duplicates\n"); // Note uses user4 V3Hashed hashed; // Duplicate code detection // Hash all of the original signals we toggle cover for (ToggleList::iterator it = m_toggleps.begin(); it != m_toggleps.end(); ++it) { AstCoverToggle* nodep = *it; hashed.hashAndInsert(nodep->origp()); } // Find if there are any duplicates for (ToggleList::iterator it = m_toggleps.begin(); it != m_toggleps.end(); ++it) { AstCoverToggle* nodep = *it; if (nodep->backp()) { // nodep->backp() is null if we already detected it's a duplicate and unlinked it // Want to choose a base node, and keep finding duplicates that are identical // This prevents making chains where a->b, then c->d, then b->c, as we'll find a->b, a->c, a->d directly. while (1) { V3Hashed::iterator dupit = hashed.findDuplicate(nodep->origp()); if (dupit == hashed.end()) break; // AstNode* duporigp = hashed.iteratorNodep(dupit); // Note hashed will point to the original variable (what's duplicated), not the covertoggle, // but we need to get back to the covertoggle which is immediately above, so: AstCoverToggle* removep = duporigp->backp()->castCoverToggle(); if (!removep) nodep->v3fatalSrc("CoverageJoin duplicate of wrong type"); UINFO(8," Orig "<> "<incp()->declp()<> "<incp()->declp()<incp()->declp()->dataDeclThisp(); removep->incp()->declp()->dataDeclp (datadeclp); UINFO(8," new "<incp()->declp()<unlinkFrBack(); pushDeletep(removep); removep=NULL; // Remove node from comparison so don't hit it again hashed.erase(dupit); ++m_statToggleJoins; } } } } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { // Find all Coverage's nodep->iterateChildren(*this); // Simplify detectDuplicates(); } virtual void visit(AstCoverToggle* nodep, AstNUser*) { m_toggleps.push_back(nodep); nodep->iterateChildren(*this); } //-------------------- virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS CoverageJoinVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~CoverageJoinVisitor() { V3Stats::addStat("Coverage, Toggle points joined", m_statToggleJoins); } }; //###################################################################### // Coverage class functions void V3CoverageJoin::coverageJoin(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3LinkResolve.cpp0000664000177100017500000003776612525171733017515 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Resolve module/signal name references // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LinkResolve TRANSFORMATIONS: // Top-down traversal // Extracts: // Add SUB so that we subtract off the "base 0-start" of the array // SelBit: Convert to ArraySel // Add SUB so that we subtract off the "base 0-start" of the array // File operations // Convert normal var to FILE* type // SenItems: Convert pos/negedge of non-simple signals to temporaries //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3LinkResolve.h" #include "V3Ast.h" //###################################################################### // Link state, as a visitor of each AstNode class LinkResolveVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstCaseItem::user2() // bool Moved default caseitems AstUser2InUse m_inuser2; // STATE // Below state needs to be preserved between each module call. AstNodeModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Function or task we're inside AstVAssert* m_assertp; // Current assertion int m_senitemCvtNum; // Temporary signal counter // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITs // TODO: Most of these visitors are here for historical reasons. // TODO: ExpectDecriptor can move to data type resolution, and the rest // TODO: could move to V3LinkParse to get them out of the way of elaboration virtual void visit(AstNodeModule* nodep, AstNUser*) { // Module: Create sim table for entire module and iterate UINFO(8,"MODULE "<dead()) return; m_modp = nodep; m_senitemCvtNum = 0; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstInitial* nodep, AstNUser*) { nodep->iterateChildren(*this); // Initial assignments under function/tasks can just be simple assignments without the initial if (m_ftaskp) { nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()); nodep=NULL; } } virtual void visit(AstVAssert* nodep, AstNUser*) { if (m_assertp) nodep->v3error("Assert not allowed under another assert"); m_assertp = nodep; nodep->iterateChildren(*this); m_assertp = NULL; } virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_ftaskp) nodep->funcLocal(true); if (nodep->isSigModPublic()) { nodep->sigModPublic(false); // We're done with this attribute m_modp->modPublic(true); // Avoid flattening if signals are exposed } } virtual void visit(AstNodeVarRef* nodep, AstNUser*) { // VarRef: Resolve its reference if (nodep->varp()) { nodep->varp()->usedParam(true); } nodep->iterateChildren(*this); } virtual void visit(AstNodeFTask* nodep, AstNUser*) { // NodeTask: Remember its name for later resolution // Remember the existing symbol table scope m_ftaskp = nodep; nodep->iterateChildren(*this); m_ftaskp = NULL; if (nodep->dpiExport()) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); } } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { nodep->iterateChildren(*this); if (nodep->taskp() && (nodep->taskp()->dpiContext() || nodep->taskp()->dpiExport())) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); } } virtual void visit(AstSenItem* nodep, AstNUser*) { // Remove bit selects, and bark if it's not a simple variable nodep->iterateChildren(*this); if (nodep->isClocked()) { // If it's not a simple variable wrap in a temporary // This is a bit unfortunate as we haven't done width resolution // and any width errors will look a bit odd, but it works. AstNode* sensp = nodep->sensp(); if (sensp && !sensp->castNodeVarRef() && !sensp->castConst()) { // Make a new temp wire string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum); AstVar* newvarp = new AstVar (sensp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1); // We can't just add under the module, because we may be inside a generate, begin, etc. // We know a SenItem should be under a SenTree/Always etc, we we'll just hunt upwards AstNode* addwherep = nodep; // Add to this element's next while (addwherep->castSenItem() || addwherep->castSenTree()) { addwherep = addwherep->backp(); } if (!addwherep->castAlways()) { // Assertion perhaps? sensp->v3error("Unsupported: Non-single-bit pos/negedge clock statement under some complicated block"); addwherep = m_modp; } addwherep->addNext(newvarp); sensp->replaceWith(new AstVarRef (sensp->fileline(), newvarp, false)); AstAssignW* assignp = new AstAssignW (sensp->fileline(), new AstVarRef(sensp->fileline(), newvarp, true), sensp); addwherep->addNext(assignp); } } else { // Old V1995 sensitivity list; we'll probably mostly ignore bool did=1; while (did) { did=0; if (AstNodeSel* selp = nodep->sensp()->castNodeSel()) { AstNode* fromp = selp->fromp()->unlinkFrBack(); selp->replaceWith(fromp); selp->deleteTree(); selp=NULL; did=1; } // NodeSel doesn't include AstSel.... if (AstSel* selp = nodep->sensp()->castSel()) { AstNode* fromp = selp->fromp()->unlinkFrBack(); selp->replaceWith(fromp); selp->deleteTree(); selp=NULL; did=1; } if (AstNodePreSel* selp = nodep->sensp()->castNodePreSel()) { AstNode* fromp = selp->lhsp()->unlinkFrBack(); selp->replaceWith(fromp); selp->deleteTree(); selp=NULL; did=1; } } } if (!nodep->sensp()->castNodeVarRef() && !nodep->sensp()->castEnumItemRef()) { // V3Const will cleanup if (debug()) nodep->dumpTree(cout,"-tree: "); nodep->v3error("Unsupported: Complex statement in sensitivity list"); } } virtual void visit(AstSenGate* nodep, AstNUser*) { nodep->v3fatalSrc("SenGates shouldn't be in tree yet"); } virtual void visit(AstNodePreSel* nodep, AstNUser*) { if (!nodep->attrp()) { nodep->iterateChildren(*this); // Constification may change the fromp() to a constant, which will lose the // variable we're extracting from (to determine MSB/LSB/endianness/etc.) // So we replicate it in another node // Note that V3Param knows not to replace AstVarRef's under AstAttrOf's AstNode* basefromp = AstArraySel::baseFromp(nodep); if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { // Maybe varxref - so need to clone nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE, varrefp->cloneTree(false))); } else if (AstMemberSel* fromp = basefromp->castMemberSel()) { nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::MEMBER_BASE, fromp->cloneTree(false))); } else { nodep->v3fatalSrc("Illegal bit select; no signal/member being extracted from"); } } } virtual void visit(AstCaseItem* nodep, AstNUser*) { // Move default caseItems to the bottom of the list // That saves us from having to search each case list twice, for non-defaults and defaults nodep->iterateChildren(*this); if (!nodep->user2() && nodep->isDefault() && nodep->nextp()) { nodep->user2(true); AstNode* nextp = nodep->nextp(); nodep->unlinkFrBack(); nextp->addNext(nodep); } } virtual void visit(AstPragma* nodep, AstNUser*) { if (nodep->pragType() == AstPragmaType::PUBLIC_MODULE) { if (!m_modp) nodep->v3fatalSrc("PUBLIC_MODULE not under a module\n"); m_modp->modPublic(true); nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } else if (nodep->pragType() == AstPragmaType::PUBLIC_TASK) { if (!m_ftaskp) nodep->v3fatalSrc("PUBLIC_TASK not under a task\n"); m_ftaskp->taskPublic(true); m_modp->modPublic(true); // Need to get to the task... nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } else if (nodep->pragType() == AstPragmaType::COVERAGE_BLOCK_OFF) { if (!v3Global.opt.coverageLine()) { // No need for block statements; may optimize better without nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } } else { nodep->iterateChildren(*this); } } void expectFormat(AstNode* nodep, const string& format, AstNode* argp, bool isScan) { // Check display arguments bool inPct = false; for (string::const_iterator it = format.begin(); it != format.end(); ++it) { char ch = tolower(*it); if (!inPct && ch=='%') { inPct = true; } else if (inPct) { inPct = false; switch (tolower(ch)) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': inPct = true; break; case '%': break; // %% - just output a % case 'm': // %m - auto insert "name" if (isScan) nodep->v3error("Unsupported: %m in $fscanf"); break; default: // Most operators, just move to next argument if (!V3Number::displayedFmtLegal(ch)) { nodep->v3error("Unknown $display-like format code: %"<v3error("Missing arguments for $display-like format"); } else { argp = argp->nextp(); } } break; } // switch } } if (argp) { argp->v3error("Extra arguments for $display-like format"); } } void expectDescriptor(AstNode* nodep, AstNodeVarRef* filep) { if (!filep) nodep->v3error("Unsupported: $fopen/$fclose/$f* descriptor must be a simple variable"); if (filep && filep->varp()) filep->varp()->attrFileDescr(true); } virtual void visit(AstFOpen* nodep, AstNUser*) { nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } virtual void visit(AstFClose* nodep, AstNUser*) { nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } virtual void visit(AstFEof* nodep, AstNUser*) { nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } virtual void visit(AstFFlush* nodep, AstNUser*) { nodep->iterateChildren(*this); if (nodep->filep()) { expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } } virtual void visit(AstFGetC* nodep, AstNUser*) { nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } virtual void visit(AstFGetS* nodep, AstNUser*) { nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); } virtual void visit(AstFScanF* nodep, AstNUser*) { nodep->iterateChildren(*this); expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); expectFormat(nodep, nodep->text(), nodep->exprsp(), true); } virtual void visit(AstSScanF* nodep, AstNUser*) { nodep->iterateChildren(*this); expectFormat(nodep, nodep->text(), nodep->exprsp(), true); } virtual void visit(AstSFormatF* nodep, AstNUser*) { nodep->iterateChildren(*this); expectFormat(nodep, nodep->text(), nodep->exprsp(), false); if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking()) || nodep->formatScopeTracking()) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); } } virtual void visit(AstDisplay* nodep, AstNUser* vup) { nodep->iterateChildren(*this); if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef()); if (!m_assertp && (nodep->displayType() == AstDisplayType::DT_INFO || nodep->displayType() == AstDisplayType::DT_WARNING || nodep->displayType() == AstDisplayType::DT_ERROR || nodep->displayType() == AstDisplayType::DT_FATAL)) { nodep->v3error(nodep->verilogKwd()+" only allowed under an assertion."); } } virtual void visit(AstUdpTable* nodep, AstNUser*) { UINFO(5,"UDPTABLE "<stmtsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* varp = stmtp->castVar()) { if (varp->isInput()) { } else if (varp->isOutput()) { if (varoutp) { varp->v3error("Multiple outputs not allowed in udp modules"); } varoutp = varp; // Tie off m_modp->addStmtp(new AstAssignW(varp->fileline(), new AstVarRef(varp->fileline(), varp, true), new AstConst(varp->fileline(), AstConst::LogicFalse()))); } else { varp->v3error("Only inputs and outputs are allowed in udp modules"); } } } nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } } virtual void visit(AstScCtor* nodep, AstNUser*) { // Constructor info means the module must remain public m_modp->modPublic(true); nodep->iterateChildren(*this); } virtual void visit(AstScDtor* nodep, AstNUser*) { // Destructor info means the module must remain public m_modp->modPublic(true); nodep->iterateChildren(*this); } virtual void visit(AstScInt* nodep, AstNUser*) { // Special class info means the module must remain public m_modp->modPublic(true); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkResolveVisitor(AstNetlist* rootp) { m_ftaskp = NULL; m_modp = NULL; m_assertp = NULL; m_senitemCvtNum = 0; // rootp->accept(*this); } virtual ~LinkResolveVisitor() {} }; //###################################################################### // LinkBotupVisitor // Recurses cells backwards, so we can pick up those things that propagate // from child cells up to the top module. class LinkBotupVisitor : public AstNVisitor { private: // STATE AstNodeModule* m_modp; // Current module // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITs virtual void visit(AstNetlist* nodep, AstNUser*) { // Iterate modules backwards, in bottom-up order. nodep->iterateChildrenBackwards(*this); } virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCell* nodep, AstNUser*) { // Parent module inherits child's publicity if (nodep->modp()->modPublic()) m_modp->modPublic(true); //** No iteration for speed } virtual void visit(AstNodeMath* nodep, AstNUser*) { // Speedup } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkBotupVisitor(AstNetlist* rootp) { m_modp = NULL; // rootp->accept(*this); } virtual ~LinkBotupVisitor() {} }; //###################################################################### // Link class functions void V3LinkResolve::linkResolve(AstNetlist* rootp) { UINFO(4,__FUNCTION__<<": "<= 6); } verilator-3.874/src/Makefile.in0000664000177100017500000000563612525171733016377 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator: Makefile for verilog source # # Code available from: http://www.veripool.org/verilator # #***************************************************************************** # # Copyright 2003-2015 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. # # Verilator is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # #****************************************************************************/ #### Start of system configuration section. #### srcdir = @srcdir@ VPATH = @srcdir@ PERL = @PERL@ EXEEXT = @EXEEXT@ #### End of system configuration section. #### default: dbg opt debug: dbg optimize: opt ifneq ($(words $(CURDIR)),1) $(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)') endif UNDER_GIT = $(wildcard ${srcdir}/../.git/logs/HEAD) #********************************************************************* obj_opt: mkdir $@ obj_dbg: mkdir $@ .PHONY: ../verilator_bin ../verilator_bin_dbg ../verilator_coverage_bin_dbg opt: ../verilator_bin ifeq ($(VERILATOR_NO_OPT_BUILD),1) # Faster laptop development... One build ../verilator_bin: ../verilator_bin_dbg -rm -rf $@ $@.exe -cp -p $<$(EXEEXT) $@$(EXEEXT) else ../verilator_bin: obj_opt prefiles cd obj_opt && $(MAKE) -j 1 TGT=../$@ -f ../Makefile_obj serial cd obj_opt && $(MAKE) TGT=../$@ -f ../Makefile_obj endif dbg: ../verilator_bin_dbg ../verilator_coverage_bin_dbg ../verilator_bin_dbg: obj_dbg prefiles cd obj_dbg && $(MAKE) -j 1 TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj serial cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj ../verilator_coverage_bin_dbg: obj_dbg prefiles cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj serial_vlcov cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj prefiles:: prefiles:: config_rev.h ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users # This output goes into srcdir if locally configured, as we need to distribute it as part of the kit. config_rev.h: ${srcdir}/config_rev.pl ${srcdir}/../.git/logs/HEAD $(PERL) ${srcdir}/config_rev.pl ${srcdir} >$@ else config_rev.h: ${srcdir}/config_rev.pl $(PERL) ${srcdir}/config_rev.pl ${srcdir} >$@ endif maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_* *.log *.dmp *.vpd core -rm -f *.o *.d perlxsi.c *_gen_* -rm -f *__gen* -rm -f .objcache* distclean maintainer-clean:: -rm -f Makefile Makefile_obj config_build.h maintainer-clean:: -rm -f config_rev.h verilator-3.874/src/V3GraphAcyc.cpp0000664000177100017500000005370512525171733017110 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph acyclic algorithm // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Graph.h" //###################################################################### //###################################################################### // Algorithms - acyclic // Break the minimal number of backward edges to make the graph acyclic class GraphAcycVertex : public V3GraphVertex { // user() is used for various sub-algorithm pieces V3GraphVertex* m_origVertexp; // Pointer to first vertex this represents protected: friend class GraphAcyc; V3ListEnt m_work; // List of vertices with optimization work left uint32_t m_storedRank; // Rank held until commit to edge placement bool m_onWorkList; // True if already on list of work to do bool m_deleted; // True if deleted public: GraphAcycVertex(V3Graph* graphp, V3GraphVertex* origVertexp) : V3GraphVertex(graphp), m_origVertexp(origVertexp) , m_storedRank(0), m_onWorkList(false), m_deleted(false) { } virtual ~GraphAcycVertex() {} V3GraphVertex* origVertexp() const { return m_origVertexp; } void setDelete() { m_deleted = true; } bool isDelete() const { return m_deleted; } virtual string name() const { return m_origVertexp->name(); } virtual string dotColor() const { return m_origVertexp->dotColor(); } }; //-------------------------------------------------------------------- class GraphAcycEdge : public V3GraphEdge { // userp() is always used to point to the head original graph edge private: typedef list OrigEdgeList; // List of orig edges, see also GraphAcyc's decl V3GraphEdge* origEdgep() const { OrigEdgeList* oEListp = ((OrigEdgeList*)userp()); if (!oEListp) v3fatalSrc("No original edge associated with acyc edge "<front()); } public: GraphAcycEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false) : V3GraphEdge(graphp, fromp, top, weight, cutable) { } virtual ~GraphAcycEdge() {} // yellow=we might still cut it, else oldEdge: yellowGreen=made uncutable, red=uncutable virtual string dotColor() const { return (cutable()?"yellow":origEdgep()->dotColor()); } }; //-------------------------------------------------------------------- struct GraphAcycEdgeCmp { inline bool operator () (const V3GraphEdge* lhsp, const V3GraphEdge* rhsp) const { if (lhsp->weight() > rhsp->weight()) return 1; // LHS goes first if (lhsp->weight() < rhsp->weight()) return 0; // RHS goes first return 0; } }; //-------------------------------------------------------------------- // CLASSES class GraphAcyc { private: typedef list OrigEdgeList; // List of orig edges, see also GraphAcycEdge's decl // GRAPH USERS // origGraph // GraphVertex::user() GraphAycVerted* New graph node // m_breakGraph // GraphEdge::user() OrigEdgeList* Old graph edges // GraphVertex::user bool Detection of loops in simplifyDupIterate // MEMBERS V3Graph* m_origGraphp; // Original graph V3Graph m_breakGraph; // Graph with only breakable edges represented V3List m_work; // List of vertices with optimization work left vector m_origEdgeDelp; // List of deletions to do when done V3EdgeFuncP m_origEdgeFuncp; // Function that says we follow this edge (in original graph) uint32_t m_placeStep; // Number that user() must be equal to to indicate processing static int debug() { return V3Graph::debug(); } // METHODS void buildGraph (V3Graph* origGraphp); void buildGraphIterate (V3GraphVertex* overtexp, GraphAcycVertex* avertexp); void simplify (bool allowCut); void simplifyNone (GraphAcycVertex* vertexp); void simplifyOne (GraphAcycVertex* vertexp); void simplifyOut (GraphAcycVertex* vertexp); void simplifyDup (GraphAcycVertex* vertexp); void cutBasic (GraphAcycVertex* vertexp); void cutBackward (GraphAcycVertex* vertexp); void deleteMarked(); void place(); void placeTryEdge(V3GraphEdge* edgep); bool placeIterate(GraphAcycVertex* vertexp, uint32_t currentRank); inline bool origFollowEdge(V3GraphEdge* edgep) { return (edgep->weight() && (m_origEdgeFuncp)(edgep)); } V3GraphEdge* edgeFromEdge (V3GraphEdge* oldedgep, V3GraphVertex* fromp, V3GraphVertex* top) { // Make new breakGraph edge, with old edge as a template GraphAcycEdge* newEdgep = new GraphAcycEdge (&m_breakGraph, fromp, top, oldedgep->weight(), oldedgep->cutable()); newEdgep->userp(oldedgep->userp()); // Keep pointer to OrigEdgeList return newEdgep; } void addOrigEdgep (V3GraphEdge* toEdgep, V3GraphEdge* addEdgep) { // Add addEdge (or it's list) to list of edges that break edge represents // Note addEdge may already have a bunch of similar linked edge representations. Yuk. UASSERT(addEdgep, "Adding NULL"); if (!toEdgep->userp()) { OrigEdgeList* oep = new OrigEdgeList; m_origEdgeDelp.push_back(oep); toEdgep->userp(oep); } OrigEdgeList* oEListp = (OrigEdgeList*)(toEdgep->userp()); if (OrigEdgeList* addListp = (OrigEdgeList*)(addEdgep->userp())) { for (OrigEdgeList::iterator it = addListp->begin(); it != addListp->end(); ++it) { oEListp->push_back(*it); } addListp->clear(); // Done with it } else { oEListp->push_back(addEdgep); } } void cutOrigEdge (V3GraphEdge* breakEdgep, const char* why) { // From the break edge, cut edges in original graph it represents UINFO(8,why<<" CUT "<fromp()<cut(); OrigEdgeList* oEListp = (OrigEdgeList*)(breakEdgep->userp()); if (!oEListp) v3fatalSrc("No original edge associated with cutting edge "<begin(); it != oEListp->end(); ++it) { V3GraphEdge* origEdgep = *it; origEdgep->cut(); UINFO(8," "<fromp()<<" ->"<top()<m_onWorkList) { avertexp->m_onWorkList = true; avertexp->m_work.pushBack(m_work, avertexp); } } GraphAcycVertex* workBeginp() { return m_work.begin(); } void workPop() { GraphAcycVertex* avertexp = workBeginp(); avertexp->m_onWorkList = false; avertexp->m_work.unlink(m_work, avertexp); } public: // CONSTRUCTORS GraphAcyc(V3Graph* origGraphp, V3EdgeFuncP edgeFuncp) { m_origGraphp = origGraphp; m_origEdgeFuncp = edgeFuncp; m_placeStep = 0; } ~GraphAcyc() { for (vector::iterator it = m_origEdgeDelp.begin(); it != m_origEdgeDelp.end(); ++it) { delete (*it); } m_origEdgeDelp.clear(); } void main(); }; //-------------------------------------------------------------------- void GraphAcyc::buildGraph (V3Graph* origGraphp) { // Presumes the graph has been strongly ordered, // and thus there's a unique color if there are loops in this subgraph. // For each old node, make a new graph node for optimization origGraphp->userClearVertices(); origGraphp->userClearEdges(); for (V3GraphVertex* overtexp = origGraphp->verticesBeginp(); overtexp; overtexp=overtexp->verticesNextp()) { if (overtexp->color()) { GraphAcycVertex* avertexp = new GraphAcycVertex(&m_breakGraph, overtexp); overtexp->userp(avertexp); // Stash so can look up later } } // Build edges between logic vertices for (V3GraphVertex* overtexp = origGraphp->verticesBeginp(); overtexp; overtexp=overtexp->verticesNextp()) { if (overtexp->color()) { GraphAcycVertex* avertexp = (GraphAcycVertex*)(overtexp->userp()); buildGraphIterate(overtexp, avertexp); } } } void GraphAcyc::buildGraphIterate (V3GraphVertex* overtexp, GraphAcycVertex* avertexp) { // Make new edges for (V3GraphEdge* edgep = overtexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (origFollowEdge(edgep)) { // not cut V3GraphVertex* toVertexp = edgep->top(); if (toVertexp->color()) { GraphAcycVertex* toAVertexp = (GraphAcycVertex*)(toVertexp->userp()); // Replicate the old edge into the new graph // There may be multiple edges between same pairs of vertices V3GraphEdge* breakEdgep = new GraphAcycEdge (&m_breakGraph, avertexp, toAVertexp, edgep->weight(), edgep->cutable()); addOrigEdgep (breakEdgep, edgep); // So can find original edge } } } } void GraphAcyc::simplify (bool allowCut) { // Add all nodes to list of work to do for (V3GraphVertex* vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { workPush(vertexp); } // Optimize till everything finished while (GraphAcycVertex* vertexp = workBeginp()) { workPop(); simplifyNone(vertexp); simplifyOne(vertexp); simplifyOut(vertexp); simplifyDup(vertexp); if (allowCut) { // The main algorithm works without these, though slower // So if changing the main algorithm, comment these out for a test run if (v3Global.opt.oAcycSimp()) { cutBasic(vertexp); cutBackward(vertexp); } } } deleteMarked(); } void GraphAcyc::deleteMarked () { // Delete nodes marked for removal for (V3GraphVertex* nextp, *vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=nextp) { nextp = vertexp->verticesNextp(); GraphAcycVertex* avertexp = (GraphAcycVertex*)vertexp; if (avertexp->isDelete()) { avertexp->unlinkDelete(&m_breakGraph); avertexp=NULL; } } } void GraphAcyc::simplifyNone (GraphAcycVertex* avertexp) { // Don't need any vertices with no inputs, There's no way they can have a loop. // Likewise, vertices with no outputs if (avertexp->isDelete()) return; if (avertexp->inEmpty() || avertexp->outEmpty()) { UINFO(9," SimplifyNoneRemove "<setDelete(); // Mark so we won't delete it twice // Remove edges while (V3GraphEdge* edgep = avertexp->outBeginp()) { V3GraphVertex* otherVertexp = edgep->top(); //UINFO(9," out "<unlinkDelete(); edgep = NULL; workPush(otherVertexp); } while (V3GraphEdge* edgep = avertexp->inBeginp()) { V3GraphVertex* otherVertexp = edgep->fromp(); //UINFO(9," in "<unlinkDelete(); edgep = NULL; workPush(otherVertexp); } } } void GraphAcyc::simplifyOne (GraphAcycVertex* avertexp) { // If a node has one input and one output, we can remove it and change the edges if (avertexp->isDelete()) return; if (avertexp->inSize1() && avertexp->outSize1()) { V3GraphEdge* inEdgep = avertexp->inBeginp(); V3GraphEdge* outEdgep = avertexp->outBeginp(); V3GraphVertex* inVertexp = inEdgep->fromp(); V3GraphVertex* outVertexp = outEdgep->top(); // The in and out may be the same node; we'll make a loop // The in OR out may be THIS node; we can't delete it then. if (inVertexp!=avertexp && outVertexp!=avertexp) { UINFO(9," SimplifyOneRemove "<setDelete(); // Mark so we won't delete it twice // Make a new edge connecting the two vertices directly // If both are breakable, we pick the one with less weight, else it's arbitrary // We can forget about the origEdge list for the "non-selected" set of edges, // as we need to break only one set or the other set of edges, not both. // (This is why we must give preference to the cutable set.) V3GraphEdge* templateEdgep = ( (inEdgep->cutable() && (!outEdgep->cutable() || inEdgep->weight()weight() )) ? inEdgep : outEdgep); edgeFromEdge(templateEdgep, inVertexp, outVertexp); // Remove old edge inEdgep->unlinkDelete(); inEdgep = NULL; outEdgep->unlinkDelete(); outEdgep = NULL; templateEdgep=NULL; workPush(inVertexp); workPush(outVertexp); } } } void GraphAcyc::simplifyOut (GraphAcycVertex* avertexp) { // If a node has one output that's not cutable, all its inputs can be reassigned // to the next node in the list if (avertexp->isDelete()) return; if (avertexp->outSize1()) { V3GraphEdge* outEdgep = avertexp->outBeginp(); if (!outEdgep->cutable()) { V3GraphVertex* outVertexp = outEdgep->top(); UINFO(9," SimplifyOutRemove "<setDelete(); // Mark so we won't delete it twice for (V3GraphEdge* nextp, *inEdgep = avertexp->inBeginp(); inEdgep; inEdgep=nextp) { nextp = inEdgep->inNextp(); V3GraphVertex* inVertexp = inEdgep->fromp(); if (inVertexp == avertexp) { if (debug()) v3error("Non-cutable edge forms a loop, vertex="<reportLoops(&V3GraphEdge::followNotCutable, avertexp->origVertexp()); // calls OrderGraph::loopsVertexCb // Things are unlikely to end well at this point, // but we'll try something to get to further errors... inEdgep->cutable(true); return; } // Make a new edge connecting the two vertices directly edgeFromEdge(inEdgep, inVertexp, outVertexp); // Remove old edge inEdgep->unlinkDelete(); inEdgep = NULL; workPush(inVertexp); } outEdgep->unlinkDelete(); outEdgep = NULL; workPush(outVertexp); } } } void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) { // Remove redundant edges if (avertexp->isDelete()) return; // Clear marks for (V3GraphEdge* edgep = avertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { edgep->top()->userp(NULL); } // Mark edges and detect duplications for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); V3GraphVertex* outVertexp = edgep->top(); V3GraphEdge* prevEdgep = (V3GraphEdge*)outVertexp->userp(); if (prevEdgep) { if (!prevEdgep->cutable()) { // !cutable duplicates prev !cutable: we can ignore it, redundant // cutable duplicates prev !cutable: know it's not a relevant loop, ignore it UINFO(8," DelDupEdge "< "<top()<unlinkDelete(); edgep = NULL; } else if (!edgep->cutable()) { // !cutable duplicates prev cutable: delete the earlier cutable UINFO(8," DelDupPrev "< "<top()<unlinkDelete(); prevEdgep = NULL; outVertexp->userp(edgep); } else { // cutable duplicates prev cutable: combine weights UINFO(8," DelDupComb "< "<top()<weight (prevEdgep->weight() + edgep->weight()); addOrigEdgep (prevEdgep, edgep); edgep->unlinkDelete(); edgep = NULL; } workPush(outVertexp); workPush(avertexp); } else { // No previous assignment outVertexp->userp(edgep); } } } void GraphAcyc::cutBasic (GraphAcycVertex* avertexp) { // Detect and cleanup any loops from node to itself if (avertexp->isDelete()) return; for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); if (edgep->cutable() && edgep->top()==avertexp) { cutOrigEdge (edgep, " Cut Basic"); edgep->unlinkDelete(); edgep = NULL; workPush(avertexp); } } } void GraphAcyc::cutBackward (GraphAcycVertex* avertexp) { // If a cutable edge is from A->B, and there's a non-cutable edge B->A, then must cut! if (avertexp->isDelete()) return; // Clear marks for (V3GraphEdge* edgep = avertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { edgep->top()->user(false); } for (V3GraphEdge* edgep = avertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { if (!edgep->cutable()) edgep->fromp()->user(true); } // Detect duplications for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); if (edgep->cutable() && edgep->top()->user()) { cutOrigEdge (edgep, " Cut A->B->A"); edgep->unlinkDelete(); edgep = NULL; workPush(avertexp); } } } void GraphAcyc::place() { // Input is m_breakGraph with ranks already assigned on non-breakable edges // Make a list of all cutable edges in the graph int numEdges = 0; for (V3GraphVertex* vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (edgep->weight() && edgep->cutable()) { numEdges++; } } } UINFO(4, " Cutable edges = "< edges; // List of all edges to be processed edges.reserve(numEdges+1); // Make the vector properly sized right off the bat -- faster than reallocating for (V3GraphVertex* vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertexp->user(0); // Clear in prep of next step for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (edgep->weight() && edgep->cutable()) { edges.push_back(edgep); } } } // Sort by weight, then by vertex (so that we completely process one vertex, when possible) stable_sort(edges.begin(), edges.end(), GraphAcycEdgeCmp()); // Process each edge in weighted order m_placeStep = 10; for (vector::iterator it = edges.begin(); it!=edges.end(); ++it) { V3GraphEdge* edgep = (*it); placeTryEdge(edgep); } } void GraphAcyc::placeTryEdge(V3GraphEdge* edgep) { // Try to make this edge uncutable m_placeStep++; UINFO(8, " PlaceEdge s"<weight()<<" "<fromp()<cutable(false); // Vertex::m_user begin: number indicates this edge was completed // Try to assign ranks, presuming this edge is in place // If we come across user()==placestep, we've detected a loop and must back out bool loop=placeIterate((GraphAcycVertex*)edgep->top(), edgep->fromp()->rank()+1); if (!loop) { // No loop, we can keep it as uncutable // Commit the new ranks we calculated // Just cleanup the list. If this is slow, we can add another set of // user counters to avoid cleaning up the list. while (workBeginp()) { workPop(); } } else { // Adding this edge would cause a loop, kill it edgep->cutable(true); // So graph still looks pretty cutOrigEdge (edgep, " Cut loop"); edgep->unlinkDelete(); edgep = NULL; // Backout the ranks we calculated while (GraphAcycVertex* vertexp = workBeginp()) { workPop(); vertexp->rank(vertexp->m_storedRank); } } } bool GraphAcyc::placeIterate(GraphAcycVertex* vertexp, uint32_t currentRank) { // Assign rank to each unvisited node // rank() is the "committed rank" of the graph known without loops // If larger rank is found, assign it and loop back through // If we hit a back node make a list of all loops if (vertexp->rank() >= currentRank) return false; // Already processed it if (vertexp->user() == m_placeStep) return true; // Loop detected vertexp->user(m_placeStep); // Remember we're changing the rank of this node; might need to back out if (!vertexp->m_onWorkList) { vertexp->m_storedRank = vertexp->rank(); workPush(vertexp); } vertexp->rank(currentRank); // Follow all edges and increase their ranks for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (edgep->weight() && !edgep->cutable()) { if (placeIterate((GraphAcycVertex*)edgep->top(), currentRank+1)) { // We don't need to reset user(); we'll use a different placeStep for the next edge return true; // Loop detected } } } vertexp->user(0); return false; } //----- Main algorithm entry point void GraphAcyc::main () { m_breakGraph.userClearEdges(); // Color based on possible loops m_origGraphp->stronglyConnected(m_origEdgeFuncp); // Make a new graph with vertices that have only a single vertex // for each group of old vertices that are interconnected with unbreakable // edges (and thus can't represent loops - if we did the unbreakable // marking right, anyways) buildGraph (m_origGraphp); if (debug()>=6) m_breakGraph.dumpDotFilePrefixed("acyc_pre"); // Perform simple optimizations before any cuttings simplify(false); if (debug()>=5) m_breakGraph.dumpDotFilePrefixed("acyc_simp"); UINFO(4, " Cutting trivial loops\n"); simplify(true); if (debug()>=6) m_breakGraph.dumpDotFilePrefixed("acyc_mid"); UINFO(4, " Ranking\n"); m_breakGraph.rank(&V3GraphEdge::followNotCutable); if (debug()>=6) m_breakGraph.dumpDotFilePrefixed("acyc_rank"); UINFO(4, " Placement\n"); place(); if (debug()>=6) m_breakGraph.dumpDotFilePrefixed("acyc_place"); UINFO(4, " Final Ranking\n"); // Only needed to assert there are no loops in completed graph m_breakGraph.rank(&V3GraphEdge::followAlwaysTrue); if (debug()>=6) m_breakGraph.dumpDotFilePrefixed("acyc_done"); } void V3Graph::acyclic(V3EdgeFuncP edgeFuncp) { UINFO(4, "Acyclic\n"); GraphAcyc acyc (this, edgeFuncp); acyc.main(); UINFO(4, "Acyclic done\n"); } verilator-3.874/src/V3Tristate.cpp0000664000177100017500000014327312525171733017046 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Deals with tristate logic // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Tristate's Transformations: // // Modify the design to expand tristate logic into its // corresponding two state representation. At the lowest levels, // // In detail: // // Over each module, from child to parent: // Build a graph, connecting signals together so we can propagate tristates // Variable becomes tristate with // VAR->isInout // VAR->isPullup/isPulldown (converted to AstPullup/AstPulldown // BufIf0/1 // All variables on the LHS need to become tristate when there is: // CONST-> with Z value on the RHS of an assignment // AstPin with lower connection a tristate // A tristate signal on the RHS (this can't generally be determined until that signal is resolved) // When LHS becomes tristate, then mark all RHS nodes as tristate // so any tristate varrefs on the right will propagate. // // Walk graph's tristate indication on each logic block with tristates // propagating downstream to every other logic block. // // Expressions that have Z in them are converted into two state // drivers and corresponding output enable signals are generated. // These enable signals get transformed and regenerated through any // logic that they may go through until they hit the module level. At // the module level, all the output enable signals from what can be // many tristate drivers are combined together to produce a single // driver and output enable. If the signal propagates up into higher // modules, then new ports are created with for the signal with // suffixes __en and __out. The original port is turned from an inout // to an input and the __out port carries the output driver signal and // the __en port carried the output enable for that driver. // // Note 1800-2012 adds user defined resolution functions. This suggests // long term this code should be scoped-based and resolve all nodes at once // rather than hierarchically. //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Tristate.h" #include "V3Ast.h" #include "V3Const.h" #include "V3Stats.h" #include "V3Inst.h" #include "V3Stats.h" #include "V3Graph.h" //###################################################################### class TristateBaseVisitor : public AstNVisitor { public: // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### // Graph support classes class TristateVertex : public V3GraphVertex { AstNode* m_nodep; bool m_isTristate; // Logic indicates a tristate bool m_feedsTri; // Propagates to a tristate node (on RHS) bool m_processed; // Tristating was cleaned up public: TristateVertex(V3Graph* graphp, AstNode* nodep) : V3GraphVertex(graphp) , m_nodep(nodep), m_isTristate(false), m_feedsTri(false), m_processed(false) {} virtual ~TristateVertex() {} // Accessors AstNode* nodep() const { return m_nodep; } AstVar* varp() const { return nodep()->castVar(); } virtual string name() const { return ((isTristate() ? "tri\\n" :feedsTri() ? "feed\\n" : "-\\n") +(nodep()->prettyTypeName()+" "+cvtToStr((void*)nodep()))); } virtual string dotColor() const { return (varp() ? (isTristate() ? "darkblue" :feedsTri() ? "blue" : "lightblue") : (isTristate() ? "darkgreen" :feedsTri() ? "green" : "lightgreen")); } void isTristate(bool flag) { m_isTristate = flag; } bool isTristate() const { return m_isTristate; } void feedsTri(bool flag) { m_feedsTri = flag; } bool feedsTri() const { return m_feedsTri; } void processed(bool flag) { m_processed = flag; } bool processed() const { return m_processed; } }; //###################################################################### class TristateGraph { // NODE STATE // AstVar::user5p -> TristateVertex* for variable being built //AstUser5InUse m_inuser5; // In visitor below // TYPES public: typedef std::vector VarVec; private: // MEMBERS V3Graph m_graph; // Logic graph public: // CONSTUCTORS TristateGraph() { clear(); } virtual ~TristateGraph() { clear(); } private: // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } TristateVertex* makeVertex(AstNode* nodep) { TristateVertex* vertexp = (TristateVertex*)(nodep->user5p()); if (!vertexp) { UINFO(6," New vertex "<user5p(vertexp); } return vertexp; } // METHODS - Graph optimization void graphWalkRecurseFwd(TristateVertex* vtxp, int level) { // Propagate tristate forward to all sinks // For example if on a CONST, propagate through CONCATS to ASSIGN to LHS VARREF of signal to tristate if (!vtxp->isTristate()) return; // tristate involved if (vtxp->user() == 1) return; vtxp->user(1); // Recursed UINFO(9," Mark tri "<varp()) { // not a var where we stop the recursion for (V3GraphEdge* edgep = vtxp->outBeginp(); edgep; edgep=edgep->outNextp()) { TristateVertex* vvertexp = dynamic_cast(edgep->top()); // Doesn't hurt to not check if already set, but by doing so when we // print out the debug messages, we'll see this node at level 0 instead. if (!vvertexp->isTristate()) { vvertexp->isTristate(true); graphWalkRecurseFwd(vvertexp, level+1); } } } else { // A variable is tristated. Find all of the LHS VARREFs that drive this signal now need tristate drivers for (V3GraphEdge* edgep = vtxp->inBeginp(); edgep; edgep=edgep->inNextp()) { TristateVertex* vvertexp = dynamic_cast(edgep->fromp()); if (AstVarRef* refp = vvertexp->nodep()->castVarRef()) { if (refp->lvalue() // Doesn't hurt to not check if already set, but by doing so when we // print out the debug messages, we'll see this node at level 0 instead. && !vvertexp->isTristate()) { vvertexp->isTristate(true); graphWalkRecurseFwd(vvertexp, level+1); } } } } } void graphWalkRecurseBack(TristateVertex* vtxp, int level) { // Called only on a tristate node; propagate a feedsTri attribute "backwards" // towards any driving nodes, i.e. from a LHS VARREF back to a driving RHS VARREF // This way if the RHS VARREF is also tristated we'll connect the enables up to the LHS VARREF. // Otherwise if not marked feedsTri() we'll drop the LHS' enables, if any if (!(vtxp->isTristate() || vtxp->feedsTri())) return; // tristate involved if (vtxp->user() == 3) return; vtxp->user(3); // Recursed UINFO(9," Mark feedstri "<varp()) { // not a var where we stop the recursion for (V3GraphEdge* edgep = vtxp->inBeginp(); edgep; edgep=edgep->inNextp()) { TristateVertex* vvertexp = dynamic_cast(edgep->fromp()); // Doesn't hurt to not check if already set, but by doing so when we // print out the debug messages, we'll see this node at level 0 instead. if (!vvertexp->feedsTri()) { vvertexp->feedsTri(true); graphWalkRecurseBack(vvertexp, level+1); } } } } public: // METHODS void clear() { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { TristateVertex* vvertexp = static_cast(itp); if (vvertexp->isTristate() && !vvertexp->processed()) { // Not v3errorSrc as no reason to stop the world vvertexp->nodep()->v3error("Unsupported tristate construct (in graph; not converted): "<nodep()->prettyTypeName()); } } m_graph.clear(); AstNode::user5ClearTree(); // Wipe all node user5p's that point to vertexes } void graphWalk(AstNodeModule* nodep) { //if (debug()>=9) m_graph.dumpDotFilePrefixed("tri_pre__"+nodep->name()); UINFO(9," Walking "<verticesNextp()) { graphWalkRecurseFwd((TristateVertex*)itp, 0); } for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { graphWalkRecurseBack((TristateVertex*)itp, 0); } if (debug()>=9) m_graph.dumpDotFilePrefixed("tri_pos__"+nodep->name()); } void setTristate(AstNode* nodep) { makeVertex(nodep)->isTristate(true); } void associate(AstNode* fromp, AstNode* top) { new V3GraphEdge(&m_graph, makeVertex(fromp), makeVertex(top), 1); } bool isTristate(AstNode* nodep) { TristateVertex* vertexp = (TristateVertex*)(nodep->user5p()); return vertexp && vertexp->isTristate(); } bool feedsTri(AstNode* nodep) { TristateVertex* vertexp = (TristateVertex*)(nodep->user5p()); return vertexp && vertexp->feedsTri(); } void didProcess(AstNode* nodep) { TristateVertex* vertexp = (TristateVertex*)(nodep->user5p()); if (!vertexp) { // Not v3errorSrc as no reason to stop the world nodep->v3error("Unsupported tristate construct (not in propagation graph): "<prettyTypeName()); } else { // We don't warn if no vertexp->isTristate() as the creation process makes midling nodes that don't have it set vertexp->processed(true); } } // ITERATOR METHODS VarVec tristateVars() { // Return all tristate variables VarVec v; for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { TristateVertex* vvertexp = static_cast(itp); if (vvertexp->isTristate()) { if (AstVar* nodep = vvertexp->nodep()->castVar()) { v.push_back(nodep); } } } return v; } }; //###################################################################### // Given a node, flip any VarRef from LValue to RValue (i.e. make it an input) // See also V3LinkLValue::linkLValueSet class TristatePinVisitor : public TristateBaseVisitor { TristateGraph& m_tgraph; bool m_lvalue; // Flip to be an LVALUE // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { if (m_lvalue && !nodep->lvalue()) { UINFO(9," Flip-to-LValue "<lvalue(true); } else if (!m_lvalue && nodep->lvalue()) { UINFO(9," Flip-to-RValue "<lvalue(false); // Mark the ex-output as tristated UINFO(9," setTristate-subpin "<varp()<varp()); } } virtual void visit(AstArraySel* nodep, AstNUser*) { // Doesn't work because we'd set lvalue on the array index's var if (m_lvalue) nodep->v3fatalSrc("ArraySel conversion to output, under tristate node"); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS TristatePinVisitor(AstNode* nodep, TristateGraph& tgraph, bool lvalue) : m_tgraph(tgraph), m_lvalue(lvalue) { nodep->accept(*this); } virtual ~TristatePinVisitor() {} }; //###################################################################### class TristateVisitor : public TristateBaseVisitor { // NODE STATE // *::user1p -> pointer to output enable __en expressions // *::user2 -> int - already visited, see U2_ enum // AstVar::user3p -> AstPull* pullup/pulldown direction (input Var's user3p) // AstVar::user4p -> AstVar* pointer to output __out var (input Var's user2p) // See TristateGraph: // AstVar::user5p -> TristateVertex* for variable being built // AstStmt*::user5p -> TristateVertex* for this statement AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; AstUser4InUse m_inuser4; AstUser5InUse m_inuser5; // TYPES typedef std::vector RefVec; typedef std::map VarMap; enum { U2_GRAPHING=1, // bit[0] if did m_graphing visit U2_NONGRAPH=2, // bit[1] if did !m_graphing visit U2_BOTH=3 }; // Both bits set // MEMBERS bool m_graphing; // Major mode - creating graph // AstNodeModule* m_modp; // Current module AstCell* m_cellp; // current cell VarMap m_lhsmap; // LHS driver map int m_unique; bool m_alhs; // On LHS of assignment AstNode* m_logicp; // Current logic being built TristateGraph m_tgraph; // Logic graph // STATS V3Double0 m_statTriSigs; // stat tracking // METHODS string dbgState() { string o = (m_graphing?" gr ":" ng "); if (m_alhs) o += "alhs "; return o; } void associateLogic(AstNode* fromp, AstNode* top) { if (m_logicp) { m_tgraph.associate(fromp, top); } } AstNode* getEnp(AstNode* nodep) { // checks if user1p() is null, and if so, adds a constant output // enable driver of all 1's. Otherwise returns the user1p() data. if (!nodep->user1p()) { V3Number num(nodep->fileline(), nodep->width()); num.setAllBits1(); AstNode* enp = new AstConst(nodep->fileline(), num); nodep->user1p(enp); } return nodep->user1p()->castNode(); } AstVar* getCreateEnVarp(AstVar* invarp) { // Return the master __en for the specified input variable if (!invarp->user1p()) { AstVar* newp = new AstVar(invarp->fileline(), AstVarType::MODULETEMP, invarp->name()+"__en", invarp); UINFO(9," newenv "<v3error("Unsupported: Creating tristate signal not underneath a module: "<prettyName()); } else m_modp->addStmtp(newp); invarp->user1p(newp); // find envar given invarp } return invarp->user1p()->castNode()->castVar(); } AstVar* getCreateOutVarp(AstVar* invarp) { // Return the master __out for the specified input variable if (!invarp->user4p()) { AstVar* newp = new AstVar(invarp->fileline(), AstVarType::MODULETEMP, invarp->name()+"__out", invarp); UINFO(9," newout "<v3error("Unsupported: Creating tristate signal not underneath a module: "<prettyName()); } else m_modp->addStmtp(newp); invarp->user4p(newp); // find outvar given invarp } return invarp->user4p()->castNode()->castVar(); } AstVar* getCreateUnconnVarp(AstNode* fromp, AstNodeDType* dtypep) { AstVar* newp = new AstVar(fromp->fileline(), AstVarType::MODULETEMP, "__Vtriunconn"+cvtToStr(m_unique++), dtypep); UINFO(9," newunc "<v3error("Unsupported: Creating tristate signal not underneath a module"); } else m_modp->addStmtp(newp); return newp; } void mapInsertLhsVarRef(AstVarRef* nodep) { AstVar* key = nodep->varp(); VarMap::iterator it = m_lhsmap.find(key); UINFO(9," mapInsertLhsVarRef "<push_back(nodep); m_lhsmap.insert(make_pair(key, refs)); } else { (*it).second->push_back(nodep); } } AstNode* newEnableDeposit(AstSel* selp, AstNode* enp) { // Form a "deposit" instruction for given enable, using existing select as a template. // Would be nicer if we made this a new AST type AstNode* newp = new AstShiftL(selp->fileline(), new AstExtend(selp->fileline(), enp, selp->fromp()->width()), selp->lsbp()->cloneTree(false), selp->fromp()->width()); return newp; } void setPullDirection(AstVar* varp, AstPull* pullp) { AstPull* oldpullp = (AstPull*)varp->user3p(); if (!oldpullp) { varp->user3p(pullp); //save off to indicate the pull direction } else { if (oldpullp->direction() != pullp->direction()) { pullp->v3error("Unsupported: Conflicting pull directions."); oldpullp->v3error("... Location of conflicting pull."); } } } void checkUnhandled(AstNode* nodep) { // Check for unsupported tristate constructs. This is not a 100% check. // The best way would be to visit the tree again and find any user1p() // pointers that did not get picked up and expanded. if (m_alhs && nodep->user1p()) { nodep->v3error("Unsupported LHS tristate construct: "<prettyTypeName()); } // Ignore Var's because they end up adjacent to statements if ((nodep->op1p() && nodep->op1p()->user1p() && !nodep->op1p()->castVar()) || (nodep->op2p() && nodep->op2p()->user1p() && !nodep->op1p()->castVar()) || (nodep->op3p() && nodep->op3p()->user1p() && !nodep->op1p()->castVar()) || (nodep->op4p() && nodep->op4p()->user1p() && !nodep->op1p()->castVar())) { nodep->v3error("Unsupported tristate construct: "<prettyTypeName()); } } void insertTristates(AstNodeModule* nodep) { // Go through all the vars and find any that are outputs without drivers // or inouts without high-Z logic and put a 1'bz driver on them and add // them to the lhs map so they get expanded correctly. TristateGraph::VarVec vars = m_tgraph.tristateVars(); for (TristateGraph::VarVec::iterator ii = vars.begin(); ii != vars.end(); ++ii) { AstVar* varp = (*ii); if (m_tgraph.isTristate(varp)) { VarMap::iterator it = m_lhsmap.find(varp); if (it == m_lhsmap.end()) { // set output enable to always be off on this assign statement so that this var is floating UINFO(8," Adding driver to var "<fileline(), varp->width()); zeros.setAllBits0(); AstConst* constp = new AstConst(varp->fileline(), zeros); AstVarRef* varrefp = new AstVarRef(varp->fileline(), varp, true); AstNode* newp = new AstAssignW(varp->fileline(), varrefp, constp); UINFO(9," newoev "<user1p(new AstConst(varp->fileline(),zeros)); nodep->addStmtp(newp); mapInsertLhsVarRef(varrefp); // insertTristates will convert // // to a varref to the __out# variable } } } // Now go through the lhs driver map and generate the output // enable logic for any tristates. // Note there might not be any drivers. for (VarMap::iterator nextit, it = m_lhsmap.begin(); it != m_lhsmap.end(); it = nextit) { nextit = it; ++nextit; AstVar* invarp = (*it).first; RefVec* refs = (*it).second; // Figure out if this var needs tristate expanded. if (!m_tgraph.isTristate(invarp)) { // This var has no tristate logic, so we leave it alone. UINFO(8, " NO TRISTATE ON:" << invarp << endl); m_lhsmap.erase(invarp); delete refs; continue; } ++m_statTriSigs; m_tgraph.didProcess(invarp); UINFO(8, " TRISTATE EXPANDING:" << invarp << endl); // If the lhs var is a port, then we need to create ports for // the output (__out) and output enable (__en) signals. The // original port gets converted to an input. Don't tristate expand // if this is the top level so that we can force the final // tristate resolution at the top. AstVar* envarp = NULL; AstVar* outvarp = NULL; // __out AstVar* lhsp = invarp; // Variable to assign drive-value to ( or __out) if (!nodep->isTop() && invarp->isIO()) { // This var becomes an input invarp->varType2In(); // convert existing port to type input // Create an output port (__out) outvarp = getCreateOutVarp(invarp); outvarp->varType2Out(); lhsp = outvarp; // Must assign to __out, not to normal input signal UINFO(9, " TRISTATE propagates up with "<varType2Out(); // outvarp->user1p(envarp); outvarp->user3p(invarp->user3p()); // AstPull* propagation if (invarp->user3p()) UINFO(9, "propagate pull to "<user1p()) { envarp = invarp->user1p()->castNode()->castVar(); // From CASEEQ, foo === 1'bz } AstNode* orp = NULL; AstNode* enp = NULL; AstNode* undrivenp = NULL; // loop through the lhs drivers to build the driver resolution logic for (RefVec::iterator ii=refs->begin(); ii != refs->end(); ++ii) { AstVarRef* refp = (*ii); int w = lhsp->width(); // create the new lhs driver for this var AstVar* newlhsp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP, lhsp->name()+"__out"+cvtToStr(m_unique), VFlagBitPacked(), w); // 2-state ok; sep enable UINFO(9," newout "<addStmtp(newlhsp); refp->varp(newlhsp); // assign the new var to the varref refp->name(newlhsp->name()); // create a new var for this drivers enable signal AstVar* newenp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP, lhsp->name()+"__en"+cvtToStr(m_unique++), VFlagBitPacked(), w); // 2-state ok UINFO(9," newenp "<addStmtp(newenp); AstNode* enassp = new AstAssignW(refp->fileline(), new AstVarRef(refp->fileline(), newenp, true), getEnp(refp)); UINFO(9," newass "<addStmtp(enassp); // now append this driver to the driver logic. AstNode* ref1p = new AstVarRef(refp->fileline(), newlhsp,false); AstNode* ref2p = new AstVarRef(refp->fileline(), newenp, false); AstNode* andp = new AstAnd(refp->fileline(), ref1p, ref2p); // or this to the others orp = (!orp) ? andp : new AstOr(refp->fileline(), orp, andp); if (envarp) { AstNode* ref3p = new AstVarRef(refp->fileline(), newenp, false); enp = (!enp) ? ref3p : new AstOr(ref3p->fileline(), enp, ref3p); } AstNode* tmp = new AstNot(newenp->fileline(), new AstVarRef(newenp->fileline(), newenp, false)); undrivenp = ((!undrivenp) ? tmp : new AstAnd(refp->fileline(), tmp, undrivenp)); } if (!undrivenp) { // No drivers on the bus V3Number ones(invarp->fileline(), lhsp->width()); ones.setAllBits1(); undrivenp = new AstConst(invarp->fileline(), ones); } if (!outvarp) { // This is the final resolution of the tristate, so we apply // the pull direction to any undriven pins. V3Number pull(invarp->fileline(), lhsp->width()); AstPull* pullp = (AstPull*)lhsp->user3p(); if (pullp && pullp->direction() == 1) { pull.setAllBits1(); UINFO(9,"Has pullup "<fileline(), undrivenp, new AstConst(invarp->fileline(), pull)); orp = new AstOr(invarp->fileline(), orp, undrivenp); } else { undrivenp->deleteTree(); undrivenp=NULL; } if (envarp) { nodep->addStmtp(new AstAssignW(enp->fileline(), new AstVarRef(envarp->fileline(), envarp, true), enp)); } // __out (child) or (parent) = drive-value expression AstNode* assp = new AstAssignW(lhsp->fileline(), new AstVarRef(lhsp->fileline(), lhsp, true), orp); assp->user2(U2_BOTH); // Don't process further; already resolved if (debug()>=9) assp->dumpTree(cout,"-lhsp-eqn: "); nodep->addStmtp(assp); // Delete the map and vector list now that we have expanded it. m_lhsmap.erase(invarp); delete refs; } } // VISITORS virtual void visit(AstConst* nodep, AstNUser*) { UINFO(9,dbgState()<num().hasZ()) { m_tgraph.setTristate(nodep); } } else { // Detect any Z consts and convert them to 0's with an enable that is also 0. if (m_alhs && nodep->user1p()) { // A pin with 1'b0 or similar connection results in an assign with constant on LHS // due to the pinReconnectSimple call in visit AstPin. // We can ignore the output override by making a temporary AstVar* varp = getCreateUnconnVarp(nodep, nodep->dtypep()); AstNode* newp = new AstVarRef(nodep->fileline(), varp, true); UINFO(9," const->"<replaceWith(newp); pushDeletep(nodep); nodep = NULL; } else if (m_tgraph.isTristate(nodep)) { m_tgraph.didProcess(nodep); FileLine* fl = nodep->fileline(); V3Number numz (fl,nodep->width()); numz.opBitsZ(nodep->num()); //Z->1, else 0 V3Number numz0(fl,nodep->width()); numz0.opNot(numz); // Z->0, else 1 V3Number num1 (fl,nodep->width()); num1.opAnd(nodep->num(),numz0); // 01X->01X, Z->0 AstConst* newconstp = new AstConst(fl, num1); AstConst* enp = new AstConst(fl, numz0); nodep->replaceWith(newconstp); pushDeletep(nodep); nodep = NULL; newconstp->user1p(enp); // propagate up constant with non-Z bits as 1 } } } virtual void visit(AstCond* nodep, AstNUser*) { if (m_graphing) { nodep->iterateChildren(*this); if (m_alhs) { associateLogic(nodep, nodep->expr1p()); associateLogic(nodep, nodep->expr2p()); } else { associateLogic(nodep->expr1p(), nodep); associateLogic(nodep->expr2p(), nodep); } } else { if (m_alhs && nodep->user1p()) { nodep->v3error("Unsupported LHS tristate construct: "<prettyTypeName()); return; } nodep->iterateChildren(*this); UINFO(9,dbgState()<condp(); if (condp->user1p()) { condp->v3error("Unsupported: don't know how to deal with tristate logic in the conditional expression"); } AstNode* expr1p = nodep->expr1p(); AstNode* expr2p = nodep->expr2p(); if (expr1p->user1p() || expr2p->user1p()) { // else no tristates m_tgraph.didProcess(nodep); AstNode* en1p = getEnp(expr1p); AstNode* en2p = getEnp(expr2p); // The output enable of a cond is a cond of the output enable of the // two expressions with the same conditional. AstNode* enp = new AstCond(nodep->fileline(), condp->cloneTree(false), en1p, en2p); UINFO(9," newcond "<user1p(enp); // propagate up COND(lhsp->enable, rhsp->enable) expr1p->user1p(NULL); expr2p->user1p(NULL); } } } virtual void visit(AstSel* nodep, AstNUser*) { if (m_graphing) { nodep->iterateChildren(*this); if (m_alhs) { associateLogic(nodep, nodep->fromp()); } else { associateLogic(nodep->fromp(), nodep); } } else { if (m_alhs) { UINFO(9,dbgState()<user1p()) { // Form a "deposit" instruction. Would be nicer if we made this a new AST type AstNode* newp = newEnableDeposit(nodep, nodep->user1p()->castNode()); nodep->fromp()->user1p(newp); // Push to varref (etc) if (debug()>=9) newp->dumpTree(cout,"-assign-sel; "); m_tgraph.didProcess(nodep); } nodep->iterateChildren(*this); } else { nodep->iterateChildren(*this); UINFO(9,dbgState()<lsbp()->user1p()) { nodep->v3error("Unsupported RHS tristate construct: "<prettyTypeName()); } if (nodep->fromp()->user1p()) { // SEL(VARREF,lsb) AstNode* en1p = getEnp(nodep->fromp()); AstNode* enp = new AstSel(nodep->fileline(), en1p, nodep->lsbp()->cloneTree(true), nodep->widthp()->cloneTree(true)); UINFO(9," newsel "<user1p(enp); // propagate up SEL(fromp->enable, value) m_tgraph.didProcess(nodep); } } } } virtual void visit(AstConcat* nodep, AstNUser*) { if (m_graphing) { nodep->iterateChildren(*this); if (m_alhs) { associateLogic(nodep, nodep->lhsp()); associateLogic(nodep, nodep->rhsp()); } else { associateLogic(nodep->lhsp(), nodep); associateLogic(nodep->rhsp(), nodep); } } else { if (m_alhs) { UINFO(9,dbgState()<user1p()) { // Each half of the concat gets a select of the enable expression AstNode* enp = nodep->user1p()->castNode(); nodep->user1p(NULL); nodep->lhsp()->user1p(new AstSel(nodep->fileline(), enp->cloneTree(true), nodep->rhsp()->width(), nodep->lhsp()->width())); nodep->rhsp()->user1p(new AstSel(nodep->fileline(), enp, 0, nodep->rhsp()->width())); m_tgraph.didProcess(nodep); } nodep->iterateChildren(*this); } else { nodep->iterateChildren(*this); UINFO(9,dbgState()<lhsp(); AstNode* expr2p = nodep->rhsp(); if (expr1p->user1p() || expr2p->user1p()) { // else no tristates m_tgraph.didProcess(nodep); AstNode* en1p = getEnp(expr1p); AstNode* en2p = getEnp(expr2p); AstNode* enp = new AstConcat(nodep->fileline(), en1p, en2p); UINFO(9," newconc "<user1p(enp); // propagate up CONCAT(lhsp->enable, rhsp->enable) expr1p->user1p(NULL); expr2p->user1p(NULL); } } } } virtual void visit(AstBufIf1* nodep, AstNUser*) { // For BufIf1, the enable is the LHS expression nodep->iterateChildren(*this); UINFO(9,dbgState()<rhsp(), nodep); m_tgraph.setTristate(nodep); } else { if (debug()>=9) nodep->backp()->dumpTree(cout,"-bufif: "); if (m_alhs) { nodep->v3error("Unsupported LHS tristate construct: "<prettyTypeName()); return; } m_tgraph.didProcess(nodep); AstNode* expr1p = nodep->lhsp()->unlinkFrBack(); AstNode* expr2p = nodep->rhsp()->unlinkFrBack(); AstNode* enp; if (AstNode* en2p = expr2p->user1p()->castNode()) { enp = new AstAnd(nodep->fileline(), expr1p, en2p); } else { enp = expr1p; } expr1p->user1p(NULL); expr2p->user1p(enp); // Becomes new node // Don't need the BufIf any more, can just have the data direct nodep->replaceWith(expr2p); UINFO(9," bufif datap="<prettyTypeName()); return; } // ANDs and Z's have issues. Earlier optimizations convert // expressions like "(COND) ? 1'bz : 1'b0" to "COND & 1'bz". So we // have to define what is means to AND 1'bz with other // expressions. I don't think this is spec, but here I take the // approach that when one expression is 1, that the Z passes. This // makes the COND's work. It is probably better to not perform the // conditional optimization if the bits are Z. // // ORs have the same issues as ANDs. Earlier optimizations convert // expressions like "(COND) ? 1'bz : 1'b1" to "COND | 1'bz". So we // have to define what is means to OR 1'bz with other // expressions. Here I take the approach that when one expression // is 0, that is passes the other. AstNode* expr1p = nodep->lhsp(); AstNode* expr2p = nodep->rhsp(); if (!expr1p->user1p() && !expr2p->user1p()) { return; // no tristates in either expression, so nothing to do } m_tgraph.didProcess(nodep); AstNode* en1p = getEnp(expr1p); AstNode* en2p = getEnp(expr2p); AstNode* subexpr1p = expr1p->cloneTree(false); AstNode* subexpr2p = expr2p->cloneTree(false); if (isAnd) { subexpr1p = new AstNot(nodep->fileline(), subexpr1p); subexpr2p = new AstNot(nodep->fileline(), subexpr2p); } // calc new output enable AstNode* enp = new AstOr(nodep->fileline(), new AstAnd(nodep->fileline(), en1p, en2p), new AstOr(nodep->fileline(), new AstAnd(nodep->fileline(), en1p->cloneTree(false), subexpr1p), new AstAnd(nodep->fileline(), en2p->cloneTree(false), subexpr2p))); UINFO(9," neweqn "<user1p(enp); expr1p->user1p(NULL); expr2p->user1p(NULL); } } virtual void visit(AstAnd* nodep, AstNUser*) { visitAndOr(nodep,true); } virtual void visit(AstOr* nodep, AstNUser*) { visitAndOr(nodep,false); } void visitAssign(AstNodeAssign* nodep) { if (m_graphing) { if (nodep->user2() & U2_GRAPHING) return; nodep->user2(U2_GRAPHING); m_logicp = nodep; nodep->rhsp()->iterateAndNext(*this); m_alhs = true; nodep->lhsp()->iterateAndNext(*this); m_alhs = false; associateLogic(nodep->rhsp(), nodep); associateLogic(nodep, nodep->lhsp()); m_logicp = NULL; } else { if (nodep->user2() & U2_NONGRAPH) return; // Iterated here, or created assignment to ignore nodep->user2(U2_NONGRAPH); nodep->rhsp()->iterateAndNext(*this); UINFO(9,dbgState()<=9) nodep->dumpTree(cout,"-assign: "); // if the rhsp of this assign statement has an output enable driver, // then propage the corresponding output enable assign statement. // down the lvalue tree by recursion for eventual attachment to // the appropriate output signal's VarRef. if (nodep->rhsp()->user1p()) { nodep->lhsp()->user1p(nodep->rhsp()->user1p()); nodep->rhsp()->user1p(NULL); UINFO(9," enp<-rhs "<lhsp()->user1p()<lhsp()->iterateAndNext(*this); m_alhs = false; } } virtual void visit(AstAssignW* nodep, AstNUser*) { visitAssign(nodep); } virtual void visit(AstAssign* nodep, AstNUser*) { visitAssign(nodep); } void visitCaseEq(AstNodeBiop* nodep, bool neq) { if (m_graphing) { nodep->iterateChildren(*this); } else { checkUnhandled(nodep); // Unsupported: A === 3'b000 should compare with the enables, but we don't do // so at present, we only compare if there is a z in the equation. // Otherwise we'd need to attach an enable to every signal, then optimize them // away later when we determine the signal has no tristate nodep->iterateChildren(*this); UINFO(9,dbgState()<lhsp()->castConst(); // Constification always moves const to LHS AstVarRef* varrefp = nodep->rhsp()->castVarRef(); // Input variable if (constp && constp->user1p() && varrefp) { // 3'b1z0 -> ((3'b101 == in__en) && (3'b100 == in)) varrefp->unlinkFrBack(); FileLine* fl = nodep->fileline(); V3Number oneIfEn = constp->user1p()->castNode()->castConst()->num(); // visit(AstConst) already split into en/ones V3Number oneIfEnOne = constp->num(); AstVar* envarp = getCreateEnVarp(varrefp->varp()); AstNode* newp = new AstLogAnd (fl, new AstEq (fl, new AstConst(fl, oneIfEn), new AstVarRef(fl, envarp, false)), // Keep the caseeq if there are X's present new AstEqCase(fl, new AstConst(fl, oneIfEnOne), varrefp)); if (neq) newp = new AstLogNot(fl, newp); UINFO(9," newceq "<=9) nodep->dumpTree(cout,"-caseeq-old: "); if (debug()>=9) newp->dumpTree(cout,"-caseeq-new: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else { checkUnhandled(nodep); } } } void visitEqNeqWild(AstNodeBiop* nodep) { if (!nodep->rhsp()->castConst()) { nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec. // rhs we want to keep X/Z intact, so otherwise ignore } nodep->lhsp()->iterateAndNext(*this); if (nodep->lhsp()->user1p()) { nodep->v3error("Unsupported LHS tristate construct: "<prettyTypeName()); return; } } virtual void visit(AstEqCase* nodep, AstNUser*) { visitCaseEq(nodep,false); } virtual void visit(AstNeqCase* nodep, AstNUser*) { visitCaseEq(nodep,true); } virtual void visit(AstEqWild* nodep, AstNUser*) { visitEqNeqWild(nodep); } virtual void visit(AstNeqWild* nodep, AstNUser*) { visitEqNeqWild(nodep); } virtual void visit(AstPull* nodep, AstNUser*) { UINFO(9,dbgState()<lhsp()->castVarRef()) { lhsp->lvalue(true); m_logicp = nodep; m_tgraph.setTristate(nodep); associateLogic(nodep, lhsp->varp()); m_logicp = NULL; } else { nodep->v3error("Unsupported pullup/down (weak driver) construct."); } } else { // Replace any pullup/pulldowns with assignw logic and set the // direction of the pull in the user3() data on the var. Given // the complexity of merging tristate drivers at any level, the // current limitation of this implementation is that a pullup/down // gets applied to all bits of a bus and a bus cannot have drivers // in opposite directions on indvidual pins. if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) { lhsp->lvalue(true); m_tgraph.didProcess(nodep); m_tgraph.didProcess(lhsp->varp()); AstVar* varp = lhsp->varp(); setPullDirection(varp, nodep); } else { nodep->v3error("Unsupported pullup/down (weak driver) construct."); } nodep->unlinkFrBack(); pushDeletep(nodep); nodep = NULL; // Node must persist as user3p points to it } } void iteratePinGuts(AstPin* nodep) { if (m_graphing) { m_logicp = nodep; if (nodep->exprp()) { associateLogic(nodep->exprp(), nodep); associateLogic(nodep, nodep->exprp()); } nodep->iterateChildren(*this); m_logicp = NULL; } else { // All heavy lifting completed in graph visitor. if (nodep->exprp()) { m_tgraph.didProcess(nodep); } nodep->iterateChildren(*this); } } // .tri(SEL(trisig,x)) becomes // INPUT: -> (VARREF(trisig__pinin)), // trisig__pinin = SEL(trisig,x) // via pinReconnectSimple // OUTPUT: -> (VARREF(trisig__pinout)) // SEL(trisig,x) = trisig__pinout // ^-- ->user1p() == trisig__pinen // ENABLE: -> (VARREF(trisig__pinen) // Added complication is the signal may be an output/inout or just input with tie off (or not) up top // PIN PORT NEW PORTS AND CONNECTIONS // N/C input in(from-resolver), __en(to-resolver-only), __out(to-resolver-only) // N/C inout Spec says illegal // N/C output Unsupported; Illegal? // wire input in(from-resolver-with-wire-value), __en(from-resolver-wire), __out(to-resolver-only) // wire inout in, __en, __out // wire output in, __en, __out // const input in(from-resolver-with-const-value), __en(from-resolver-const), __out(to-resolver-only) // const inout Spec says illegal // const output Unsupported; Illegal? virtual void visit(AstPin* nodep, AstNUser*) { if (m_graphing) { if (nodep->user2() & U2_GRAPHING) return; // This pin is already expanded nodep->user2(U2_GRAPHING); // Find child module's new variables. AstVar* enModVarp = (AstVar*) nodep->modVarp()->user1p(); if (!enModVarp) { if (nodep->exprp()) { // May have an output only that later connects to a tristate, so simplify now. V3Inst::pinReconnectSimple(nodep, m_cellp, m_modp, false); } iteratePinGuts(nodep); return; // No __en signals on this pin } // Tristate exists: UINFO(9,dbgState()<=9) nodep->dumpTree(cout,"-pin-pre: "); // Empty/in-only; need Z to propagate bool inDeclProcessing = (nodep->exprp() && nodep->modVarp()->isInOnly() // Need to consider the original state instead of current state // as we converted tristates to inputs, which do not want to have this. && !nodep->modVarp()->isDeclOutput()); if (!nodep->exprp()) { // No-connect; covert to empty connection UINFO(5,"Unconnected pin terminate "<modVarp()->dtypep()); nodep->exprp(new AstVarRef(nodep->fileline(), ucVarp, nodep->modVarp()->isOutput())); m_tgraph.setTristate(ucVarp); // We don't need a driver on the wire; the lack of one will default to tristate } else if (inDeclProcessing) { // Not an input that was a converted tristate // Input only may have driver in underneath module which would stomp // the input value. So make a temporary connection. AstAssignW* reAssignp = V3Inst::pinReconnectSimple(nodep, m_cellp, m_modp, true, true); UINFO(5,"Input pin buffering: "<lhsp()); } // pinReconnectSimple needs to presume input or output behavior; we need both // Therefore, create the enable, output and separate input pin, then pinReconnectSimple all // Create the output enable pin, connect to new signal AstNode* enrefp; { AstVar* enVarp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP, nodep->name() + "__en" + cvtToStr(m_unique++), VFlagBitPacked(), enModVarp->width()); UINFO(9," newenv "<fileline(), nodep->pinNum(), enModVarp->name(), // should be {var}"__en" new AstVarRef(nodep->fileline(), enVarp, true)); enpinp->modVarp(enModVarp); UINFO(9," newpin "<user2(U2_BOTH); // don't iterate the pin later nodep->addNextHere(enpinp); m_modp->addStmtp(enVarp); enrefp = new AstVarRef(nodep->fileline(), enVarp, false); UINFO(9," newvrf "<=9) enpinp->dumpTree(cout,"-pin-ena: "); } // Create new output pin AstAssignW* outAssignp = NULL; // If reconnected, the related assignment AstPin* outpinp; { AstVar* outModVarp = (AstVar*) nodep->modVarp()->user4p(); AstNode* outexprp = nodep->exprp()->cloneTree(false); // Note has lvalue() set outpinp = new AstPin(nodep->fileline(), nodep->pinNum(), outModVarp->name(), // should be {var}"__out" outexprp); outpinp->modVarp(outModVarp); UINFO(9," newpin "<user2(U2_BOTH); // don't iterate the pin later nodep->addNextHere(outpinp); // Simplify if (inDeclProcessing) { // Not an input that was a converted tristate // The pin is an input, but we need an output // The if() above is needed because the Visitor is simple, it will flip ArraySel's and such, // but if the pin is an input the earlier reconnectSimple made it a VarRef without any ArraySel, etc TristatePinVisitor visitor (outexprp, m_tgraph, true); } if (debug()>=9) outpinp->dumpTree(cout,"-pin-opr: "); outAssignp = V3Inst::pinReconnectSimple(outpinp, m_cellp, m_modp, true); // Note may change outpinp->exprp() if (debug()>=9) outpinp->dumpTree(cout,"-pin-out: "); if (debug()>=9 && outAssignp) outAssignp->dumpTree(cout,"-pin-out: "); // Must still iterate the outAssignp, as need to build output equation } // Existing pin becomes an input, and we mark each resulting signal as tristate TristatePinVisitor visitor (nodep->exprp(), m_tgraph, false); AstNode* inAssignp = V3Inst::pinReconnectSimple(nodep, m_cellp, m_modp, true); // Note may change nodep->exprp() if (debug()>=9) nodep->dumpTree(cout,"-pin-in: "); if (debug()>=9 && inAssignp) inAssignp->dumpTree(cout,"-pin-as: "); // Connect enable to output signal AstVarRef* exprrefp; // Tristate variable that the Pin's expression refers to if (!outAssignp) { exprrefp = outpinp->exprp()->castVarRef(); } else { exprrefp = outAssignp->rhsp()->castVarRef(); // This should be the same var as the output pin } if (!exprrefp) { // deal with simple varref port // pinReconnect should have converted this nodep->v3error("Unsupported tristate port expression: "<exprp()->prettyTypeName()); } else { UINFO(9,"outref "<user1p(enrefp); // Mark as now tristated; iteration will pick it up from there if (!outAssignp) { mapInsertLhsVarRef(exprrefp); // insertTristates will convert // // to a varref to the __out# variable } // else the assignment deals with the connection } // Propagate any pullups/pulldowns upwards if necessary if (exprrefp) { if (AstPull* pullp = (AstPull*) nodep->modVarp()->user3p()) { UINFO(9, "propagate pull on "<varp(), pullp); } } // Don't need to visit the created assigns, as it was added at the end of the next links // and normal iterateChild recursion will come back to them eventually. // Mark the original signal as tristated iteratePinGuts(nodep); } // Not graph building else { if (nodep->user2() & U2_NONGRAPH) return; // This pin is already expanded nodep->user2(U2_NONGRAPH); UINFO(9," "<lvalue()) { associateLogic(nodep, nodep->varp()); } else { associateLogic(nodep->varp(), nodep); } } else { if (nodep->user2() & U2_NONGRAPH) return; // Processed nodep->user2(U2_NONGRAPH); // Detect all var lhs drivers and adds them to the // VarMap so that after the walk through the module we can expand // any tristate logic on the driver. if (nodep->lvalue() && m_tgraph.isTristate(nodep->varp())) { UINFO(9," Ref-to-lvalue "<lvalue() && !nodep->user1p() // Not already processed, nor varref from visit(AstPin) creation // Reference to another tristate variable && m_tgraph.isTristate(nodep->varp()) // and in a position where it feeds upstream to another tristate && m_tgraph.feedsTri(nodep)) { // Then propage the enable from the original variable UINFO(9," Ref-to-tri "<varp()); nodep->user1p(new AstVarRef(nodep->fileline(), enVarp, false)); } if (m_alhs) {} // NOP; user1() already passed down from assignment } } virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); UINFO(9,dbgState()<user2() & U2_GRAPHING) return; // Already processed nodep->user2(U2_GRAPHING); if (nodep->isPulldown() || nodep->isPullup()) { AstNode* newp = new AstPull(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, true), nodep->isPullup()); UINFO(9," newpul "<addNextHere(newp); // We'll iterate on the new AstPull later } if (nodep->isInout() //|| varp->isOutput() // Note unconnected output only changes behavior vs. previous versions and causes outputs // that don't come from anywhere to possibly create connection errors. // One example of problems is this: "output z; task t; z <= {something}; endtask" ) { UINFO(9," setTristate-inout "<isPulldown() || nodep->isPullup() handled in TristateGraphVisitor m_tgraph.didProcess(nodep); } } } virtual void visit(AstNodeModule* nodep, AstNUser*) { UINFO(8, nodep<v3fatalSrc("Modules under modules not supported"); // Lots of per-module state breaks // Clear state m_tgraph.clear(); m_unique = 0; m_logicp = NULL; m_lhsmap.clear(); m_modp = nodep; // Walk the graph, finding all variables and tristate constructs { m_graphing = true; nodep->iterateChildren(*this); m_graphing = false; } // Use graph to find tristate signals m_tgraph.graphWalk(nodep); // Build the LHS drivers map for this module nodep->iterateChildren(*this); // Insert new logic for all tristates insertTristates(nodep); m_modp = NULL; } virtual void visit(AstNodeFTask* nodep, AstNUser*) { // don't deal with functions } virtual void visit(AstCaseItem* nodep, AstNUser*) { // don't deal with casez compare '???? values nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstCell* nodep, AstNUser*) { m_cellp = nodep; m_alhs = false; nodep->iterateChildren(*this); m_cellp = NULL; } virtual void visit(AstNetlist* nodep, AstNUser*) { nodep->iterateChildrenBackwards(*this); } // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); checkUnhandled(nodep); } public: // CONSTUCTORS TristateVisitor(AstNode* nodep) { m_graphing = false; m_modp = NULL; m_cellp = NULL; m_unique = 0; m_alhs = false; m_logicp = NULL; m_tgraph.clear(); nodep->accept(*this); } virtual ~TristateVisitor() { V3Stats::addStat("Tristate, Tristate resolved nets", m_statTriSigs); } }; //###################################################################### // Tristate class functions void V3Tristate::tristateAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Os.h0000664000177100017500000000435512525171733015272 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Os-specific function wrapper // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3OS_H_ #define _V3OS_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include //============================================================================ // V3Os: OS static class class V3Os { public: // METHODS (environment) static string getenvStr(const string& envvar, const string& defaultValue); static void setenvStr(const string& envvar, const string& value, const string& why); // METHODS (generic filename utilities) static string filenameFromDirBase (const string& dir, const string& basename); static string filenameNonDir (const string& filename); ///< Return non-directory part of filename static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename static string filenameDir (const string& filename); ///< Return directory part of filename static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed static bool filenameIsRel (const string& filename); ///< True if relative // METHODS (directory utilities) static void createDir(const string& dirname); static void unlinkRegexp(const string& dir, const string& regexp); }; #endif // Guard verilator-3.874/src/V3LifePost.cpp0000664000177100017500000001525512525171733016772 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: AssignPost Variable assignment elimination // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LIFE TRANSFORMATIONS: // Build control-flow graph with assignments and var usages // All modules: // Delete these // ASSIGN(Vdly, a) // ... {no reads or writes of a after the first write to Vdly} // ... {no reads of a after the first write to Vdly} // ASSIGNPOST(Vdly,tmp) // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3LifePost.h" #include "V3Stats.h" #include "V3Ast.h" //###################################################################### // LifePost state, as a visitor of each AstNode class LifePostBaseVisitor : public AstNVisitor { protected: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### // LifePost class functions class LifePostElimVisitor : public LifePostBaseVisitor { private: // NODE STATE // INPUT: // AstVarScope::user4p() -> AstVarScope*, If set, replace this varscope with specified new one // STATE // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { AstVarScope* vscp = nodep->varScopep(); if (!vscp) nodep->v3fatalSrc("Scope not assigned"); if (AstVarScope* newvscp = (AstVarScope*)vscp->user4p()) { UINFO(9, " Replace "<fileline(), newvscp, nodep->lvalue()); nodep->replaceWith(newrefp); nodep->deleteTree(); nodep=NULL; } } virtual void visit(AstNodeModule* nodep, AstNUser*) { // Only track the top scopes, not lower level functions if (nodep->isTop()) nodep->iterateChildren(*this); } virtual void visit(AstCCall* nodep, AstNUser*) { nodep->iterateChildren(*this); // Enter the function and trace it nodep->funcp()->accept(*this); } virtual void visit(AstVar*, AstNUser*) {} // Don't want varrefs under it virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS LifePostElimVisitor(AstTopScope* nodep) { nodep->accept(*this); } virtual ~LifePostElimVisitor() {} }; //###################################################################### // LifePostlicate delay elimination class LifePostDlyVisitor : public LifePostBaseVisitor { private: // NODE STATE // Cleared on entire tree // AstVarScope::user() -> Sequence # of first virtex setting this var. // AstVarScope::user2() -> Sequence # of last consumption of this var // AstVarScope::user4() -> AstVarScope*: Passed to LifePostElim to substitute this var AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser4InUse m_inuser4; // STATE uint32_t m_sequence; // Sequence number of assignments/varrefs V3Double0 m_statAssnDel; // Statistic tracking // VISITORS virtual void visit(AstTopScope* nodep, AstNUser*) { AstNode::user1ClearTree(); // user1p() used on entire tree AstNode::user2ClearTree(); // user2p() used on entire tree AstNode::user4ClearTree(); // user4p() used on entire tree m_sequence = 0; nodep->iterateChildren(*this); // Replace any node4p varscopes with the new scope LifePostElimVisitor visitor (nodep); } virtual void visit(AstVarRef* nodep, AstNUser*) { // Consumption/generation of a variable, AstVarScope* vscp = nodep->varScopep(); if (!vscp) nodep->v3fatalSrc("Scope not assigned"); m_sequence++; if (nodep->lvalue()) { // First generator if (!vscp->user1()) vscp->user1(m_sequence); } else { // Last consumer vscp->user2(m_sequence); } } virtual void visit(AstAssignPost* nodep, AstNUser*) { if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) { if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) { // Scrunch these: // __Vdly__q = __PVT__clk_clocks; // ... {no reads or writes of __PVT__q after the first write to __Vdly__q} // ... {no reads of __Vdly__q after the first write to __Vdly__q} // __PVT__q = __Vdly__q; UINFO(9," POST "<varScopep()->user1(); uint32_t lastRead = rhsp->varScopep()->user2(); uint32_t lastRead2 = lhsp->varScopep()->user2(); UINFO(9," first "<varScopep()->user4p(lhsp->varScopep()); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; ++m_statAssnDel; } } } } virtual void visit(AstNodeModule* nodep, AstNUser*) { // Only track the top scopes, not lower level functions if (nodep->isTop()) nodep->iterateChildren(*this); } virtual void visit(AstCCall* nodep, AstNUser*) { nodep->iterateChildren(*this); // Enter the function and trace it nodep->funcp()->accept(*this); } //----- virtual void visit(AstVar*, AstNUser*) {} // Don't want varrefs under it virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS LifePostDlyVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~LifePostDlyVisitor() { V3Stats::addStat("Optimizations, Lifetime postassign deletions", m_statAssnDel); } }; //###################################################################### // LifePost class functions void V3LifePost::lifepostAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/VlcTop.h0000664000177100017500000000413712525171734015706 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Top global container // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCTOP_H_ #define _VLCTOP_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "VlcOptions.h" #include "VlcTest.h" #include "VlcPoint.h" #include "VlcSource.h" //###################################################################### // VlcTop - Top level options container class VlcTop { public: // PUBLIC MEMBERS VlcOptions opt; //< Runtime options private: // MEMBERS VlcTests m_tests; //< List of all tests (all coverage files) VlcPoints m_points; //< List of all points VlcSources m_sources; //< List of all source files to annotate // METHODS void createDir(const string& dirname); void annotateCalc(); void annotateCalcNeeded(); void annotateOutputFiles(const string& dirname); public: // CONSTRUCTORS VlcTop() {} ~VlcTop() {} // ACCESSORS VlcTests& tests() { return m_tests; } VlcPoints& points() { return m_points; } VlcSources& sources() { return m_sources; } // METHODS void annotate(const string& dirname); void readCoverage(const string& filename, bool nonfatal=false); void writeCoverage(const string& filename); void rank(); }; //###################################################################### #endif // guard verilator-3.874/src/V3Error.cpp0000664000177100017500000001726012525171733016334 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Error handling // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include #include #include #include #include "V3Error.h" #ifndef _V3ERROR_NO_GLOBAL_ # include "V3Ast.h" # include "V3Global.h" # include "V3Stats.h" #endif //====================================================================== // Statics int V3Error::s_errCount = 0; int V3Error::s_warnCount = 0; int V3Error::s_debugDefault = 0; int V3Error::s_errorLimit = V3Error::MAX_ERRORS; bool V3Error::s_warnFatal = true; int V3Error::s_tellManual = 0; ostringstream V3Error::s_errorStr; // Error string being formed V3ErrorCode V3Error::s_errorCode = V3ErrorCode::EC_FATAL; bool V3Error::s_errorSuppressed = false; bool V3Error::s_describedEachWarn[V3ErrorCode::_ENUM_MAX]; bool V3Error::s_describedWarnings = false; bool V3Error::s_pretendError[V3ErrorCode::_ENUM_MAX]; V3Error::MessagesSet V3Error::s_messages; V3Error::ErrorExitCb V3Error::s_errorExitCb = NULL; struct v3errorIniter { v3errorIniter() { V3Error::init(); } }; v3errorIniter v3errorInit; //###################################################################### // ErrorCode class functions V3ErrorCode::V3ErrorCode(const char* msgp) { // Return error encoding for given string, or ERROR, which is a bad code for (int codei=V3ErrorCode::EC_MIN; codei20) numsp = 20; out<<(spaces + numsp); return out.str(); } void V3Error::incErrors() { s_errCount++; if (errorCount() == errorLimit()) { // Not >= as would otherwise recurse v3fatal ("Exiting due to too many errors encountered; --error-limit="<=V3ErrorCode::EC_MIN) { #ifndef _V3ERROR_NO_GLOBAL_ V3Stats::addStatSum(string("Warnings, Suppressed ")+s_errorCode.ascii(), 1); #endif s_errorSuppressed = true; } } string V3Error::warnMore() { return msgPrefix(); } void V3Error::v3errorEnd (ostringstream& sstr) { #if defined(__COVERITY__) || defined(__cppcheck__) if (s_errorCode==V3ErrorCode::EC_FATAL) __coverity_panic__(x); #endif // Skip suppressed messages if (s_errorSuppressed // On debug, show only non default-off warning to prevent pages of warnings && (!debug() || s_errorCode.defaultsOff())) return; string msg = msgPrefix()+sstr.str(); if (msg[msg.length()-1] != '\n') msg += '\n'; // Suppress duplicates if (s_messages.find(msg) != s_messages.end()) return; s_messages.insert(msg); // Output cerr<=V3ErrorCode::EC_FIRST_WARN && !s_describedWarnings) { cerr<dumpTreeFile(v3Global.debugFilename("final.tree",990)); if (s_errorExitCb) s_errorExitCb(); V3Stats::statsFinalAll(v3Global.rootp()); V3Stats::statsReport(); } #endif } vlAbort(); } else if (isError(s_errorCode, s_errorSuppressed)) { // We don't dump tree on any error because a Visitor may be in middle of // a tree cleanup and cause a false broken problem. if (s_errorExitCb) s_errorExitCb(); } } } verilator-3.874/src/V3GenClk.h0000664000177100017500000000224512525171733016050 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Generated Clock Repairs // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3GENCLK_H_ #define _V3GENCLK_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3GenClk { public: static void genClkAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/Verilator.cpp0000664000177100017500000004674512525247644017020 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: main() // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "V3Global.h" #include "V3Ast.h" #include #include #include "V3Active.h" #include "V3ActiveTop.h" #include "V3Assert.h" #include "V3AssertPre.h" #include "V3Begin.h" #include "V3Branch.h" #include "V3Case.h" #include "V3Cast.h" #include "V3Changed.h" #include "V3Clean.h" #include "V3ClkGater.h" #include "V3Clock.h" #include "V3Combine.h" #include "V3Const.h" #include "V3Coverage.h" #include "V3CoverageJoin.h" #include "V3Dead.h" #include "V3Delayed.h" #include "V3Depth.h" #include "V3DepthBlock.h" #include "V3Descope.h" #include "V3EmitC.h" #include "V3EmitMk.h" #include "V3EmitV.h" #include "V3EmitXml.h" #include "V3Expand.h" #include "V3File.h" #include "V3Cdc.h" #include "V3Gate.h" #include "V3GenClk.h" #include "V3Graph.h" #include "V3Inline.h" #include "V3Inst.h" #include "V3Life.h" #include "V3LifePost.h" #include "V3LinkCells.h" #include "V3LinkDot.h" #include "V3LinkJump.h" #include "V3LinkLValue.h" #include "V3LinkLevel.h" #include "V3LinkParse.h" #include "V3LinkResolve.h" #include "V3Localize.h" #include "V3Name.h" #include "V3Order.h" #include "V3Os.h" #include "V3Param.h" #include "V3Parse.h" #include "V3ParseSym.h" #include "V3PreShell.h" #include "V3Premit.h" #include "V3Scope.h" #include "V3Slice.h" #include "V3Split.h" #include "V3SplitAs.h" #include "V3Stats.h" #include "V3Subst.h" #include "V3Table.h" #include "V3Task.h" #include "V3Trace.h" #include "V3TraceDecl.h" #include "V3Tristate.h" #include "V3Undriven.h" #include "V3Unknown.h" #include "V3Unroll.h" #include "V3Width.h" V3Global v3Global; //###################################################################### // V3 Class -- top level AstNetlist* V3Global::makeNetlist() { AstNetlist* newp = new AstNetlist(); newp->addTypeTablep(new AstTypeTable(newp->fileline())); return newp; } void V3Global::checkTree() { rootp()->checkTree(); } void V3Global::clear() { if (m_rootp) m_rootp->deleteTree(); m_rootp=NULL; } void V3Global::readFiles() { // NODE STATE // AstNode::user4p() // VSymEnt* Package and typedef symbol names AstUser4InUse inuser4; V3InFilter filter (v3Global.opt.pipeFilter()); V3ParseSym parseSyms (v3Global.rootp()); // Symbol table must be common across all parsing V3Parse parser (v3Global.rootp(), &filter, &parseSyms); // Read top module const V3StringList& vFiles = v3Global.opt.vFiles(); for (V3StringList::const_iterator it = vFiles.begin(); it != vFiles.end(); ++it) { string filename = *it; parser.parseFile(new FileLine("COMMAND_LINE",0), filename, false, "Cannot find file containing module: "); } // Read libraries // To be compatible with other simulators, // this needs to be done after the top file is read const V3StringSet& libraryFiles = v3Global.opt.libraryFiles(); for (V3StringSet::const_iterator it = libraryFiles.begin(); it != libraryFiles.end(); ++it) { string filename = *it; parser.parseFile(new FileLine("COMMAND_LINE",0), filename, true, "Cannot find file containing library module: "); } //v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("parse.tree")); V3Error::abortIfErrors(); if (!v3Global.opt.preprocOnly()) { // Resolve all modules cells refer to V3LinkCells::link(v3Global.rootp(), &filter, &parseSyms); } } void V3Global::dumpCheckGlobalTree(const string& filename, int newNumber, bool doDump) { v3Global.rootp()->dumpTreeFile(v3Global.debugFilename(filename, newNumber), false, doDump); } //###################################################################### void process () { // Sort modules by level so later algorithms don't need to care V3LinkLevel::modSortByLevel(); V3Error::abortIfErrors(); // Convert parseref's to varrefs, and other directly post parsing fixups V3LinkParse::linkParse(v3Global.rootp()); // Cross-link signal names // Cross-link dotted hierarchical references V3LinkDot::linkDotPrimary(v3Global.rootp()); v3Global.checkTree(); // Force a check, as link is most likely place for problems // Correct state we couldn't know at parse time, repair SEL's V3LinkResolve::linkResolve(v3Global.rootp()); // Set Lvalue's in variable refs V3LinkLValue::linkLValue(v3Global.rootp()); // Convert return/continue/disable to jumps V3LinkJump::linkJump(v3Global.rootp()); V3Error::abortIfErrors(); if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Link"); // Remove parameters by cloning modules to de-parameterized versions // This requires some width calculations and constant propagation V3Param::param(v3Global.rootp()); V3LinkDot::linkDotParamed(v3Global.rootp()); // Cleanup as made new modules V3Error::abortIfErrors(); // Remove any modules that were parameterized and are no longer referenced. V3Dead::deadifyModules(v3Global.rootp()); v3Global.checkTree(); // Calculate and check widths, edit tree to TRUNC/EXTRACT any width mismatches V3Width::width(v3Global.rootp()); V3Error::abortIfErrors(); // Commit to the widths we've chosen; Make widthMin==width V3Width::widthCommit(v3Global.rootp()); v3Global.assertDTypesResolved(true); v3Global.widthMinUsage(VWidthMinUsage::MATCHES_WIDTH); // Coverage insertion // Before we do dead code elimination and inlining, or we'll lose it. if (v3Global.opt.coverage()) { V3Coverage::coverage(v3Global.rootp()); } // Push constants, but only true constants preserving liveness // so V3Undriven sees variables to be eliminated, ie "if (0 && foo) ..." V3Const::constifyAllLive(v3Global.rootp()); // Signal based lint checks, no change to structures // Must be before first constification pass drops dead code V3Undriven::undrivenAll(v3Global.rootp()); // Assertion insertion // After we've added block coverage, but before other nasty transforms V3AssertPre::assertPreAll(v3Global.rootp()); // V3Assert::assertAll(v3Global.rootp()); if (!v3Global.opt.xmlOnly()) { // Add top level wrapper with instance pointing to old top // Move packages to under new top // Must do this after we know parameters and dtypes (as don't clone dtype decls) V3LinkLevel::wrapTop(v3Global.rootp()); } // Propagate constants into expressions V3Const::constifyAllLint(v3Global.rootp()); if (!v3Global.opt.xmlOnly()) { // Remove cell arrays (must be between V3Width and scoping) V3Inst::dearrayAll(v3Global.rootp()); } if (!v3Global.opt.xmlOnly()) { // Expand inouts, stage 2 // Also simplify pin connections to always be AssignWs in prep for V3Unknown V3Tristate::tristateAll(v3Global.rootp()); // Task inlining & pushing BEGINs names to variables/cells // Begin processing must be after Param, before module inlining V3Begin::debeginAll(v3Global.rootp()); // Flatten cell names, before inliner // Move assignments from X into MODULE temps. // (Before flattening, so each new X variable is shared between all scopes of that module.) V3Unknown::unknownAll(v3Global.rootp()); v3Global.constRemoveXs(true); // Module inlining // Cannot remove dead variables after this, as alias information for final // V3Scope's V3LinkDot is in the AstVar. if (v3Global.opt.oInline()) { V3Inline::inlineAll(v3Global.rootp()); V3LinkDot::linkDotArrayed(v3Global.rootp()); // Cleanup as made new modules } } //--PRE-FLAT OPTIMIZATIONS------------------ // Initial const/dead to reduce work for ordering code V3Const::constifyAll(v3Global.rootp()); v3Global.checkTree(); V3Dead::deadifyDTypes(v3Global.rootp()); v3Global.checkTree(); V3Error::abortIfErrors(); //--FLATTENING--------------- if (!v3Global.opt.xmlOnly()) { // We're going to flatten the hierarchy, so as many optimizations that // can be done as possible should be before this.... // Convert instantiations to wassigns and always blocks V3Inst::instAll(v3Global.rootp()); // Inst may have made lots of concats; fix them V3Const::constifyAll(v3Global.rootp()); // Flatten hierarchy, creating a SCOPE for each module's usage as a cell V3Scope::scopeAll(v3Global.rootp()); V3LinkDot::linkDotScope(v3Global.rootp()); } //--SCOPE BASED OPTIMIZATIONS-------------- if (!v3Global.opt.xmlOnly()) { // Cleanup V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyDTypes(v3Global.rootp()); v3Global.checkTree(); // Convert case statements to if() blocks. Must be after V3Unknown // Must be before V3Task so don't need to deal with task in case value compares V3Case::caseAll(v3Global.rootp()); // Inline all tasks V3Task::taskAll(v3Global.rootp()); // Add __PVT's // After V3Task so task internal variables will get renamed V3Name::nameAll(v3Global.rootp()); // Loop unrolling & convert FORs to WHILEs V3Unroll::unrollAll(v3Global.rootp()); // Expand slices of arrays V3Slice::sliceAll(v3Global.rootp()); // Push constants across variables and remove redundant assignments V3Const::constifyAll(v3Global.rootp()); if (v3Global.opt.oLife()) { V3Life::lifeAll(v3Global.rootp()); } // Make large low-fanin logic blocks into lookup tables // This should probably be done much later, once we have common logic elimination. if (!v3Global.opt.lintOnly() && v3Global.opt.oTable()) { V3Table::tableAll(v3Global.rootp()); } // Cleanup V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyDTypes(v3Global.rootp()); v3Global.checkTree(); // Detect clock enables and mode into sensitives, and split always based on clocks // (so this is a good prelude to splitAlways.) if (v3Global.opt.oFlopGater()) { V3ClkGater::clkGaterAll(v3Global.rootp()); } // Move assignments/sensitives into a SBLOCK for each unique sensitivity list // (May convert some ALWAYS to combo blocks, so should be before V3Gate step.) V3Active::activeAll(v3Global.rootp()); // Split single ALWAYS blocks into multiple blocks for better ordering chances if (v3Global.opt.oSplit()) { V3Split::splitAlwaysAll(v3Global.rootp()); } V3SplitAs::splitAsAll(v3Global.rootp()); // Create tracing sample points, before we start eliminating signals if (v3Global.opt.trace()) { V3TraceDecl::traceDeclAll(v3Global.rootp()); } // Gate-based logic elimination; eliminate signals and push constant across cell boundaries // Instant propagation makes lots-o-constant reduction possibilities. if (v3Global.opt.oGate()) { V3Gate::gateAll(v3Global.rootp()); // V3Gate calls constant propagation itself. } else { v3info("Command Line disabled gate optimization with -Og/-O0. This may cause ordering problems."); } // Combine COVERINCs with duplicate terms if (v3Global.opt.coverage()) { V3CoverageJoin::coverageJoin(v3Global.rootp()); } // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyAll(v3Global.rootp()); // Clock domain crossing analysis if (v3Global.opt.cdc()) { V3Cdc::cdcAll(v3Global.rootp()); V3Error::abortIfErrors(); return; } // Reorder assignments in pipelined blocks if (v3Global.opt.oReorder()) { V3Split::splitReorderAll(v3Global.rootp()); } // Create delayed assignments // This creates lots of duplicate ACTIVES so ActiveTop needs to be after this step V3Delayed::delayedAll(v3Global.rootp()); // Make Active's on the top level // Differs from V3Active, because identical clocks may be pushed down to a module and now be identical V3ActiveTop::activeTopAll(v3Global.rootp()); if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "PreOrder"); // Order the code; form SBLOCKs and BLOCKCALLs V3Order::orderAll(v3Global.rootp()); // Change generated clocks to look at delayed signals V3GenClk::genClkAll(v3Global.rootp()); // Convert sense lists into IF statements. V3Clock::clockAll(v3Global.rootp()); // Cleanup any dly vars or other temps that are simple assignments // Life must be done before Subst, as it assumes each CFunc under _eval is called only once. if (v3Global.opt.oLife()) { V3Const::constifyAll(v3Global.rootp()); V3Life::lifeAll(v3Global.rootp()); } if (v3Global.opt.oLifePost()) { V3LifePost::lifepostAll(v3Global.rootp()); } // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyAll(v3Global.rootp()); // Detect change loop V3Changed::changedAll(v3Global.rootp()); // Create tracing logic, since we ripped out some signals the user might want to trace // Note past this point, we presume traced variables won't move between CFuncs // (It's OK if untraced temporaries move around, or vars "effectively" activate the same way.) if (v3Global.opt.trace()) { V3Trace::traceAll(v3Global.rootp()); } if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Scoped"); // Remove scopes; make varrefs/funccalls relative to current module V3Descope::descopeAll(v3Global.rootp()); } //--MODULE OPTIMIZATIONS-------------- if (!v3Global.opt.xmlOnly()) { // Split deep blocks to appease MSVC++. Must be before Localize. if (!v3Global.opt.lintOnly() && v3Global.opt.compLimitBlocks()) { V3DepthBlock::depthBlockAll(v3Global.rootp()); } // Move BLOCKTEMPS from class to local variables if (v3Global.opt.oLocalize()) { V3Localize::localizeAll(v3Global.rootp()); } // Icache packing; combine common code in each module's functions into subroutines if (v3Global.opt.oCombine()) { V3Combine::combineAll(v3Global.rootp()); } } V3Error::abortIfErrors(); //--GENERATION------------------ if (!v3Global.opt.xmlOnly()) { // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyAll(v3Global.rootp()); // Here down, widthMin() is the Verilog width, and width() is the C++ width // Bits between widthMin() and width() are irrelevant, but may be non zero. v3Global.widthMinUsage(VWidthMinUsage::VERILOG_WIDTH); // Make all math operations either 8, 16, 32 or 64 bits V3Clean::cleanAll(v3Global.rootp()); // Move wide constants to BLOCK temps. V3Premit::premitAll(v3Global.rootp()); } // Expand macros and wide operators into C++ primitives if (!v3Global.opt.xmlOnly() && v3Global.opt.oExpand()) { V3Expand::expandAll(v3Global.rootp()); } // Propagate constants across WORDSEL arrayed temporaries if (!v3Global.opt.xmlOnly() && v3Global.opt.oSubst()) { // Constant folding of expanded stuff V3Const::constifyCpp(v3Global.rootp()); V3Subst::substituteAll(v3Global.rootp()); } if (!v3Global.opt.xmlOnly() && v3Global.opt.oSubstConst()) { // Constant folding of substitutions V3Const::constifyCpp(v3Global.rootp()); V3Dead::deadifyAll(v3Global.rootp()); } if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly()) { // Fix very deep expressions // Mark evaluation functions as member functions, if needed. V3Depth::depthAll(v3Global.rootp()); // Branch prediction V3Branch::branchAll(v3Global.rootp()); // Add C casts when longs need to become long-long and vice-versa // Note depth may insert something needing a cast, so this must be last. V3Cast::castAll(v3Global.rootp()); } V3Error::abortIfErrors(); // Output the text if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly()) { // emitcInlines is first, as it may set needHInlines which other emitters read V3EmitC::emitcInlines(); V3EmitC::emitcSyms(); V3EmitC::emitcTrace(); } if (!v3Global.opt.xmlOnly()) { // Unfortunately we have some lint checks in emitc. V3EmitC::emitc(); } if (v3Global.opt.xmlOnly() // Check XML when debugging to make sure no missing node types || (v3Global.opt.debugCheck() && !v3Global.opt.lintOnly())) { V3EmitXml::emitxml(); } // Statistics if (v3Global.opt.stats()) { V3Stats::statsFinalAll(v3Global.rootp()); V3Stats::statsReport(); } if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly()) { // Makefile must be after all other emitters V3EmitMk::emitmk(v3Global.rootp()); } // Note early return above when opt.cdc() } //###################################################################### int main(int argc, char** argv, char** env) { // General initialization ios::sync_with_stdio(); time_t randseed; time(&randseed); srand( (int) randseed); // Post-constructor initialization of netlists v3Global.boot(); // Preprocessor // Before command parsing so we can handle -Ds on command line. V3PreShell::boot(env); // Command option parsing v3Global.opt.bin(argv[0]); string argString = V3Options::argString(argc-1, argv+1); v3Global.opt.parseOpts(new FileLine("COMMAND_LINE",0), argc-1, argv+1); if (!v3Global.opt.outFormatOk() && !v3Global.opt.preprocOnly() && !v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly() && !v3Global.opt.cdc()) { v3fatal("verilator: Need --cc, --sc, --cdc, --lint-only, --xml_only or --E option"); } // Check environment V3Options::getenvSYSTEMC(); V3Options::getenvSYSTEMC_ARCH(); V3Options::getenvSYSTEMC_INCLUDE(); V3Options::getenvSYSTEMC_LIBDIR(); V3Options::getenvSYSTEMPERL(); V3Options::getenvSYSTEMPERL_INCLUDE(); V3Error::abortIfErrors(); // Can we skip doing everything if times are ok? V3File::addSrcDepend(v3Global.opt.bin()); if (v3Global.opt.skipIdentical() && !v3Global.opt.preprocOnly() && !v3Global.opt.lintOnly() && !v3Global.opt.cdc() && V3File::checkTimes(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__verFiles.dat", argString)) { UINFO(1,"--skip-identical: No change to any source files, exiting\n"); exit(0); } // Internal tests (after option parsing as need debug() setting) AstBasicDTypeKwd::test(); V3Graph::test(); //--FRONTEND------------------ // Cleanup V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.tree"); V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.dot"); V3Os::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.txt"); // Read first filename v3Global.readFiles(); // Link, etc, if needed if (!v3Global.opt.preprocOnly()) { process(); } // Final steps V3Global::dumpCheckGlobalTree("final.tree", 990, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); V3Error::abortIfWarnings(); if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc() && v3Global.opt.makeDepend()) { V3File::writeDepend(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__ver.d"); } if (!v3Global.opt.lintOnly() && !v3Global.opt.cdc() && (v3Global.opt.skipIdentical() || v3Global.opt.makeDepend())) { V3File::writeTimes(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__verFiles.dat", argString); } // Final writing shouldn't throw warnings, but... V3Error::abortIfWarnings(); #ifdef VL_LEAK_CHECKS // Cleanup memory for valgrind leak analysis v3Global.clear(); #endif FileLine::deleteAllRemaining(); UINFO(1,"Done, Exiting...\n"); } verilator-3.874/src/verilog.y0000664000177100017500000046571212525171734016201 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Bison grammer file // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // Original code here by Paul Wasson and Duane Galbi //************************************************************************* %{ #include #include #include #include #include "V3Ast.h" #include "V3Global.h" #include "V3Config.h" #include "V3ParseImp.h" // Defines YYTYPE; before including bison header #define YYERROR_VERBOSE 1 #define YYINITDEPTH 10000 // Older bisons ignore YYMAXDEPTH #define YYMAXDEPTH 10000 // Pick up new lexer #define yylex PARSEP->lexToBison #define GATEUNSUP(fl,tok) { if (!v3Global.opt.bboxUnsup()) { (fl)->v3error("Unsupported: Verilog 1995 gate primitive: "<<(tok)); } } extern void yyerror(const char* errmsg); extern void yyerrorf(const char* format, ...); //====================================================================== // Statics (for here only) #define PARSEP V3ParseImp::parsep() #define SYMP PARSEP->symp() #define GRAMMARP V3ParseGrammar::singletonp() class V3ParseGrammar { public: bool m_impliedDecl; // Allow implied wire declarations AstVarType m_varDecl; // Type for next signal declaration (reg/wire/etc) AstVarType m_varIO; // Type for next signal declaration (input/output/etc) AstVar* m_varAttrp; // Current variable for attribute adding AstRange* m_gateRangep; // Current range for gate declarations AstCase* m_caseAttrp; // Current case statement for attribute adding AstNodeDType* m_varDTypep; // Pointer to data type for next signal declaration AstNodeDType* m_memDTypep; // Pointer to data type for next member declaration int m_pinNum; // Pin number currently parsing string m_instModule; // Name of module referenced for instantiations AstPin* m_instParamp; // Parameters for instantiations bool m_tracingParse; // Tracing disable for parser static int s_modTypeImpNum; // Implicit type number, incremented each module // CONSTRUCTORS V3ParseGrammar() { m_impliedDecl = false; m_varDecl = AstVarType::UNKNOWN; m_varIO = AstVarType::UNKNOWN; m_varDTypep = NULL; m_gateRangep = NULL; m_memDTypep = NULL; m_pinNum = -1; m_instModule = ""; m_instParamp = NULL; m_varAttrp = NULL; m_caseAttrp = NULL; m_tracingParse = true; } static V3ParseGrammar* singletonp() { static V3ParseGrammar singleton; return &singleton; } // METHODS void argWrapList(AstNodeFTaskRef* nodep); bool allTracingOn(FileLine* fl) { return v3Global.opt.trace() && m_tracingParse && fl->tracingOn(); } AstNodeDType* createArray(AstNodeDType* basep, AstRange* rangep, bool isPacked); AstVar* createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp); AstNode* createSupplyExpr(FileLine* fileline, string name, int value); AstText* createTextQuoted(FileLine* fileline, string text) { string newtext = deQuote(fileline, text); return new AstText(fileline, newtext); } AstDisplay* createDisplayError(FileLine* fileline) { AstDisplay* nodep = new AstDisplay(fileline,AstDisplayType::DT_ERROR, "", NULL,NULL); nodep->addNext(new AstStop(fileline)); return nodep; } AstNode* createGatePin(AstNode* exprp) { AstRange* rangep = m_gateRangep; if (!rangep) return exprp; else return new AstGatePin(rangep->fileline(), exprp, rangep->cloneTree(true)); } void endLabel(FileLine* fl, AstNode* nodep, string* endnamep) { endLabel(fl, nodep->prettyName(), endnamep); } void endLabel(FileLine* fl, string name, string* endnamep) { if (fl && endnamep && *endnamep != "" && name != *endnamep && name != AstNode::prettyName(*endnamep)) { fl->v3warn(ENDLABEL,"End label '"<<*endnamep<<"' does not match begin label '"<deleteTree(); m_varDTypep=NULL; } // It was cloned, so this is safe. m_varDTypep = dtypep; } AstPackage* unitPackage(FileLine* fl) { // Find one made earlier? AstPackage* pkgp = SYMP->symRootp()->findIdFlat(AstPackage::dollarUnitName())->nodep()->castPackage(); if (!pkgp) { pkgp = PARSEP->rootp()->dollarUnitPkgAddp(); SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global } return pkgp; } AstNodeDType* addRange(AstBasicDType* dtypep, AstRange* rangesp, bool isPacked) { // If dtypep isn't basic, don't use this, call createArray() instead if (!rangesp) { return dtypep; } else { // If rangesp is "wire [3:3][2:2][1:1] foo [5:5][4:4]" // then [1:1] becomes the basicdtype range; everything else is arraying // the final [5:5][4:4] will be passed in another call to createArray AstRange* rangearraysp = NULL; if (dtypep->isRanged()) { rangearraysp = rangesp; // Already a range; everything is an array } else { AstRange* finalp = rangesp; while (finalp->nextp()) finalp=finalp->nextp()->castRange(); if (finalp != rangesp) { finalp->unlinkFrBack(); rangearraysp = rangesp; } if (dtypep->implicit()) { // It's no longer implicit but a real logic type AstBasicDType* newp = new AstBasicDType(dtypep->fileline(), AstBasicDTypeKwd::LOGIC, dtypep->numeric(), dtypep->width(), dtypep->widthMin()); dtypep->deleteTree(); dtypep=NULL; dtypep = newp; } dtypep->rangep(finalp); } return createArray(dtypep, rangearraysp, isPacked); } } string deQuote(FileLine* fileline, string text); void checkDpiVer(FileLine* fileline, const string& str) { if (str != "DPI-C" && !v3Global.opt.bboxSys()) { fileline->v3error("Unsupported DPI type '"<copyOrSameFileLine()) // Only use in empty rules, so lines point at beginnings #define VARRESET_LIST(decl) { GRAMMARP->m_pinNum=1; VARRESET(); VARDECL(decl); } // Start of pinlist #define VARRESET_NONLIST(decl) { GRAMMARP->m_pinNum=0; VARRESET(); VARDECL(decl); } // Not in a pinlist #define VARRESET() { VARDECL(UNKNOWN); VARIO(UNKNOWN); VARDTYPE(NULL); } #define VARDECL(type) { GRAMMARP->m_varDecl = AstVarType::type; } #define VARIO(type) { GRAMMARP->m_varIO = AstVarType::type; } #define VARDTYPE(dtypep) { GRAMMARP->setDType(dtypep); } #define VARDONEA(fl,name,array,attrs) GRAMMARP->createVariable((fl),(name),(array),(attrs)) #define VARDONEP(portp,array,attrs) GRAMMARP->createVariable((portp)->fileline(),(portp)->name(),(array),(attrs)) #define PINNUMINC() (GRAMMARP->m_pinNum++) #define GATERANGE(rangep) { GRAMMARP->m_gateRangep = rangep; } #define INSTPREP(modname,paramsp) { GRAMMARP->m_impliedDecl = true; GRAMMARP->m_instModule = modname; GRAMMARP->m_instParamp = paramsp; } #define DEL(nodep) { if (nodep) nodep->deleteTree(); } static void ERRSVKWD(FileLine* fileline, const string& tokname) { static int toldonce = 0; fileline->v3error((string)"Unexpected \""+tokname+"\": \""+tokname+"\" is a SystemVerilog keyword misused as an identifier."); if (!toldonce++) fileline->v3error("Modify the Verilog-2001 code to avoid SV keywords, or use `begin_keywords or --language."); } //====================================================================== class AstSenTree; %} // When writing Bison patterns we use yTOKEN instead of "token", // so Bison will error out on unknown "token"s. // Generic lexer tokens, for example a number // IEEE: real_number %token yaFLOATNUM "FLOATING-POINT NUMBER" // IEEE: identifier, class_identifier, class_variable_identifier, // covergroup_variable_identifier, dynamic_array_variable_identifier, // enum_identifier, interface_identifier, interface_instance_identifier, // package_identifier, type_identifier, variable_identifier, %token yaID__ETC "IDENTIFIER" %token yaID__LEX "IDENTIFIER-in-lex" %token yaID__aPACKAGE "PACKAGE-IDENTIFIER" %token yaID__aTYPE "TYPE-IDENTIFIER" // Can't predecode aFUNCTION, can declare after use // Can't predecode aINTERFACE, can declare after use // Can't predecode aTASK, can declare after use // IEEE: integral_number %token yaINTNUM "INTEGER NUMBER" // IEEE: time_literal + time_unit %token yaTIMENUM "TIME NUMBER" // IEEE: string_literal %token yaSTRING "STRING" %token yaSTRING__IGNORE "STRING-ignored" // Used when expr:string not allowed %token yaTIMINGSPEC "TIMING SPEC ELEMENT" %token yaTABLELINE "TABLE LINE" %token yaSCHDR "`systemc_header BLOCK" %token yaSCINT "`systemc_ctor BLOCK" %token yaSCIMP "`systemc_dtor BLOCK" %token yaSCIMPH "`systemc_interface BLOCK" %token yaSCCTOR "`systemc_implementation BLOCK" %token yaSCDTOR "`systemc_imp_header BLOCK" %token yVLT_COVERAGE_OFF "coverage_off" %token yVLT_LINT_OFF "lint_off" %token yVLT_TRACING_OFF "tracing_off" %token yVLT_D_FILE "--file" %token yVLT_D_LINES "--lines" %token yVLT_D_MSG "--msg" %token yaD_IGNORE "${ignored-bbox-sys}" %token yaD_DPI "${dpi-sys}" // is the fileline, abbreviated to shorten "$1" references %token '!' %token '#' %token '%' %token '&' %token '(' %token ')' %token '*' %token '+' %token ',' %token '-' %token '.' %token '/' %token ':' %token ';' %token '<' %token '=' %token '>' %token '?' %token '@' %token '[' %token ']' %token '^' %token '{' %token '|' %token '}' %token '~' // Specific keywords // yKEYWORD means match "keyword" // Other cases are yXX_KEYWORD where XX makes it unique, // for example yP_ for punctuation based operators. // Double underscores "yX__Y" means token X followed by Y, // and "yX__ETC" means X folled by everything but Y(s). %token yALWAYS "always" %token yALWAYS_FF "always_ff" %token yALWAYS_COMB "always_comb" %token yALWAYS_LATCH "always_latch" %token yAND "and" %token yASSERT "assert" %token yASSIGN "assign" %token yAUTOMATIC "automatic" %token yBEGIN "begin" %token yBIND "bind" %token yBIT "bit" %token yBREAK "break" %token yBUF "buf" %token yBUFIF0 "bufif0" %token yBUFIF1 "bufif1" %token yBYTE "byte" %token yCASE "case" %token yCASEX "casex" %token yCASEZ "casez" %token yCHANDLE "chandle" %token yCLOCKING "clocking" %token yCONST__ETC "const" %token yCONST__LEX "const-in-lex" %token yCMOS "cmos" %token yCONTEXT "context" %token yCONTINUE "continue" %token yCOVER "cover" %token yDEFAULT "default" %token yDEFPARAM "defparam" %token yDISABLE "disable" %token yDO "do" %token yEDGE "edge" %token yELSE "else" %token yEND "end" %token yENDCASE "endcase" %token yENDCLOCKING "endclocking" %token yENDFUNCTION "endfunction" %token yENDGENERATE "endgenerate" %token yENDINTERFACE "endinterface" %token yENDMODULE "endmodule" %token yENDPACKAGE "endpackage" %token yENDPRIMITIVE "endprimitive" %token yENDPROGRAM "endprogram" %token yENDPROPERTY "endproperty" %token yENDSPECIFY "endspecify" %token yENDTABLE "endtable" %token yENDTASK "endtask" %token yENUM "enum" %token yEXPORT "export" %token yFINAL "final" %token yFOR "for" %token yFOREVER "forever" %token yFUNCTION "function" %token yGENERATE "generate" %token yGENVAR "genvar" %token yGLOBAL__CLOCKING "global-then-clocking" %token yGLOBAL__LEX "global-in-lex" %token yIF "if" %token yIFF "iff" %token yIMPORT "import" %token yINITIAL "initial" %token yINOUT "inout" %token yINPUT "input" %token yINSIDE "inside" %token yINT "int" %token yINTEGER "integer" %token yINTERFACE "interface" %token yLOCALPARAM "localparam" %token yLOGIC "logic" %token yLONGINT "longint" %token yMODPORT "modport" %token yMODULE "module" %token yNAND "nand" %token yNEGEDGE "negedge" %token yNMOS "nmos" %token yNOR "nor" %token yNOT "not" %token yNOTIF0 "notif0" %token yNOTIF1 "notif1" %token yOR "or" %token yOUTPUT "output" %token yPACKAGE "package" %token yPACKED "packed" %token yPARAMETER "parameter" %token yPMOS "pmos" %token yPOSEDGE "posedge" %token yPRIMITIVE "primitive" %token yPRIORITY "priority" %token yPROGRAM "program" %token yPROPERTY "property" %token yPULLDOWN "pulldown" %token yPULLUP "pullup" %token yPURE "pure" %token yRAND "rand" %token yRANDC "randc" %token yRCMOS "rcmos" %token yREAL "real" %token yREALTIME "realtime" %token yREG "reg" %token yREPEAT "repeat" %token yRETURN "return" %token yRNMOS "rnmos" %token yRPMOS "rpmos" %token yRTRAN "rtran" %token yRTRANIF0 "rtranif0" %token yRTRANIF1 "rtranif1" %token ySCALARED "scalared" %token ySHORTINT "shortint" %token ySIGNED "signed" %token ySPECIFY "specify" %token ySPECPARAM "specparam" %token ySTATIC "static" %token ySTRING "string" %token ySTRUCT "struct" %token ySUPPLY0 "supply0" %token ySUPPLY1 "supply1" %token yTABLE "table" %token yTASK "task" %token yTIME "time" %token yTIMEPRECISION "timeprecision" %token yTIMEUNIT "timeunit" %token yTRAN "tran" %token yTRANIF0 "tranif0" %token yTRANIF1 "tranif1" %token yTRI "tri" %token yTRI0 "tri0" %token yTRI1 "tri1" %token yTRUE "true" %token yTYPEDEF "typedef" %token yUNION "union" %token yUNIQUE "unique" %token yUNIQUE0 "unique0" %token yUNSIGNED "unsigned" %token yVAR "var" %token yVECTORED "vectored" %token yVOID "void" %token yWHILE "while" %token yWIRE "wire" %token yWREAL "wreal" %token yXNOR "xnor" %token yXOR "xor" %token yD_BITS "$bits" %token yD_BITSTOREAL "$bitstoreal" %token yD_C "$c" %token yD_CEIL "$ceil" %token yD_CLOG2 "$clog2" %token yD_COUNTONES "$countones" %token yD_DIMENSIONS "$dimensions" %token yD_DISPLAY "$display" %token yD_ERROR "$error" %token yD_EXP "$exp" %token yD_FATAL "$fatal" %token yD_FCLOSE "$fclose" %token yD_FDISPLAY "$fdisplay" %token yD_FEOF "$feof" %token yD_FFLUSH "$fflush" %token yD_FGETC "$fgetc" %token yD_FGETS "$fgets" %token yD_FINISH "$finish" %token yD_FLOOR "$floor" %token yD_FOPEN "$fopen" %token yD_FSCANF "$fscanf" %token yD_FWRITE "$fwrite" %token yD_HIGH "$high" %token yD_INCREMENT "$increment" %token yD_INFO "$info" %token yD_ISUNKNOWN "$isunknown" %token yD_ITOR "$itor" %token yD_LEFT "$left" %token yD_LN "$ln" %token yD_LOG10 "$log10" %token yD_LOW "$low" %token yD_ONEHOT "$onehot" %token yD_ONEHOT0 "$onehot0" %token yD_POW "$pow" %token yD_RANDOM "$random" %token yD_READMEMB "$readmemb" %token yD_READMEMH "$readmemh" %token yD_REALTIME "$realtime" %token yD_REALTOBITS "$realtobits" %token yD_RIGHT "$right" %token yD_RTOI "$rtoi" %token yD_SFORMAT "$sformat" %token yD_SIGNED "$signed" %token yD_SIZE "$size" %token yD_SQRT "$sqrt" %token yD_SSCANF "$sscanf" %token yD_STIME "$stime" %token yD_STOP "$stop" %token yD_SWRITE "$swrite" %token yD_SYSTEM "$system" %token yD_TESTPLUSARGS "$test$plusargs" %token yD_TIME "$time" %token yD_UNIT "$unit" %token yD_UNPACKED_DIMENSIONS "$unpacked_dimensions" %token yD_UNSIGNED "$unsigned" %token yD_VALUEPLUSARGS "$value$plusargs" %token yD_WARNING "$warning" %token yD_WRITE "$write" %token yVL_CLOCK "/*verilator sc_clock*/" %token yVL_CLOCKER "/*verilator clocker*/" %token yVL_NO_CLOCKER "/*verilator no_clocker*/" %token yVL_CLOCK_ENABLE "/*verilator clock_enable*/" %token yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/" %token yVL_FULL_CASE "/*verilator full_case*/" %token yVL_INLINE_MODULE "/*verilator inline_module*/" %token yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/" %token yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/" %token yVL_NO_INLINE_TASK "/*verilator no_inline_task*/" %token yVL_SC_BV "/*verilator sc_bv*/" %token yVL_SFORMAT "/*verilator sformat*/" %token yVL_PARALLEL_CASE "/*verilator parallel_case*/" %token yVL_PUBLIC "/*verilator public*/" %token yVL_PUBLIC_FLAT "/*verilator public_flat*/" %token yVL_PUBLIC_FLAT_RD "/*verilator public_flat_rd*/" %token yVL_PUBLIC_FLAT_RW "/*verilator public_flat_rw*/" %token yVL_PUBLIC_MODULE "/*verilator public_module*/" %token yP_TICK "'" %token yP_TICKBRA "'{" %token yP_OROR "||" %token yP_ANDAND "&&" %token yP_NOR "~|" %token yP_XNOR "^~" %token yP_NAND "~&" %token yP_EQUAL "==" %token yP_NOTEQUAL "!=" %token yP_CASEEQUAL "===" %token yP_CASENOTEQUAL "!==" %token yP_WILDEQUAL "==?" %token yP_WILDNOTEQUAL "!=?" %token yP_GTE ">=" %token yP_LTE "<=" %token yP_LTE__IGNORE "<=-ignored" // Used when expr:<= means assignment %token yP_SLEFT "<<" %token yP_SRIGHT ">>" %token yP_SSRIGHT ">>>" %token yP_POW "**" %token yP_PLUSCOLON "+:" %token yP_MINUSCOLON "-:" %token yP_MINUSGT "->" %token yP_MINUSGTGT "->>" %token yP_EQGT "=>" %token yP_ASTGT "*>" %token yP_ANDANDAND "&&&" %token yP_POUNDPOUND "##" %token yP_DOTSTAR ".*" %token yP_ATAT "@@" %token yP_COLONCOLON "::" %token yP_COLONEQ ":=" %token yP_COLONDIV ":/" %token yP_ORMINUSGT "|->" %token yP_OREQGT "|=>" %token yP_BRASTAR "[*" %token yP_BRAEQ "[=" %token yP_BRAMINUSGT "[->" %token yP_PLUSPLUS "++" %token yP_MINUSMINUS "--" %token yP_PLUSEQ "+=" %token yP_MINUSEQ "-=" %token yP_TIMESEQ "*=" %token yP_DIVEQ "/=" %token yP_MODEQ "%=" %token yP_ANDEQ "&=" %token yP_OREQ "|=" %token yP_XOREQ "^=" %token yP_SLEFTEQ "<<=" %token yP_SRIGHTEQ ">>=" %token yP_SSRIGHTEQ ">>>=" %token yP_LOGIFF // [* is not a operator, as "[ * ]" is legal // [= and [-> could be repitition operators, but to match [* we don't add them. // '( is not a operator, as "' (" is legal //******************** // PSL op precedence %right yP_MINUSGT yP_LOGIFF %right yP_ORMINUSGT yP_OREQGT // Verilog op precedence %right '?' ':' %left yP_OROR %left yP_ANDAND %left '|' yP_NOR %left '^' yP_XNOR %left '&' yP_NAND %left yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL %left '>' '<' yP_GTE yP_LTE yP_LTE__IGNORE yINSIDE %left yP_SLEFT yP_SRIGHT yP_SSRIGHT %left '+' '-' %left '*' '/' '%' %left yP_POW %left prUNARYARITH yP_MINUSMINUS yP_PLUSPLUS prREDUCTION prNEGATION %left '.' // Not in IEEE, but need to avoid conflicts; TICK should bind tightly just lower than COLONCOLON %left yP_TICK //%left '(' ')' '[' ']' yP_COLONCOLON '.' %nonassoc prLOWER_THAN_ELSE %nonassoc yELSE //BISONPRE_TYPES // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion // Blank lines for type insertion %start source_text %% //********************************************************************** // Files source_text: // ==IEEE: source_text /* empty */ { } // // timeunits_declaration moved into description:package_item | descriptionList { } ; descriptionList: // IEEE: part of source_text description { } | descriptionList description { } ; description: // ==IEEE: description module_declaration { } // // udp_declaration moved into module_declaration | interface_declaration { } | program_declaration { } | package_declaration { } | package_item { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); } | bind_directive { if ($1) GRAMMARP->unitPackage($1->fileline())->addStmtp($1); } // unsupported // IEEE: config_declaration // // Verilator only | vltItem { } | error { } ; timeunits_declaration: // ==IEEE: timeunits_declaration yTIMEUNIT yaTIMENUM ';' { $$ = NULL; } | yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';' { $$ = NULL; } | yTIMEPRECISION yaTIMENUM ';' { $$ = NULL; } ; //********************************************************************** // Packages package_declaration: // ==IEEE: package_declaration packageFront package_itemListE yENDPACKAGE endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); SYMP->popScope($1); GRAMMARP->endLabel($4,$1,$4); } ; packageFront: yPACKAGE idAny ';' { $$ = new AstPackage($1,*$2); $$->inLibrary(true); // packages are always libraries; don't want to make them a "top" $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; package_itemListE: // IEEE: [{ package_item }] /* empty */ { $$ = NULL; } | package_itemList { $$ = $1; } ; package_itemList: // IEEE: { package_item } package_item { $$ = $1; } | package_itemList package_item { $$ = $1->addNextNull($2); } ; package_item: // ==IEEE: package_item package_or_generate_item_declaration { $$ = $1; } //UNSUP anonymous_program { $$ = $1; } //UNSUP package_export_declaration { $$ = $1; } | timeunits_declaration { $$ = $1; } ; package_or_generate_item_declaration: // ==IEEE: package_or_generate_item_declaration net_declaration { $$ = $1; } | data_declaration { $$ = $1; } | task_declaration { $$ = $1; } | function_declaration { $$ = $1; } //UNSUP checker_declaration { $$ = $1; } | dpi_import_export { $$ = $1; } //UNSUP extern_constraint_declaration { $$ = $1; } //UNSUP class_declaration { $$ = $1; } // // class_constructor_declaration is part of function_declaration | local_parameter_declaration ';' { $$ = $1; } | parameter_declaration ';' { $$ = $1; } //UNSUP covergroup_declaration { $$ = $1; } //UNSUP overload_declaration { $$ = $1; } //UNSUP assertion_item_declaration { $$ = $1; } | ';' { $$ = NULL; } ; package_import_declarationList: package_import_declaration { $$ = $1; } | package_import_declarationList package_import_declaration { $$ = $1->addNextNull($2); } ; package_import_declaration: // ==IEEE: package_import_declaration yIMPORT package_import_itemList ';' { $$ = $2; } ; package_import_itemList: package_import_item { $$ = $1; } | package_import_itemList ',' package_import_item { $$ = $1->addNextNull($3); } ; package_import_item: // ==IEEE: package_import_item yaID__aPACKAGE yP_COLONCOLON package_import_itemObj { $$ = new AstPackageImport($1, $1->castPackage(), *$3); SYMP->import($1,*$3); } ; package_import_itemObj: // IEEE: part of package_import_item idAny { $$=$1; $$=$1; } | '*' { $$=$1; static string star="*"; $$=☆ } ; //********************************************************************** // Module headers module_declaration: // ==IEEE: module_declaration // // timeunits_declaration instead in module_item // // IEEE: module_nonansi_header + module_ansi_header modFront importsAndParametersE portsStarE ';' module_itemListE yENDMODULE endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); SYMP->popScope($1); GRAMMARP->endLabel($7,$1,$7); } | udpFront parameter_port_listE portsStarE ';' module_itemListE yENDPRIMITIVE endLabelE { $1->modTrace(false); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); GRAMMARP->m_tracingParse = true; SYMP->popScope($1); GRAMMARP->endLabel($7,$1,$7); } // //UNSUP yEXTERN modFront parameter_port_listE portsStarE ';' //UNSUP { UNSUP } ; modFront: // // General note: all *Front functions must call symPushNew before // // any formal arguments, as the arguments must land in the new scope. yMODULE lifetimeE idAny { $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine()); $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; importsAndParametersE: // IEEE: common part of module_declaration, interface_declaration, program_declaration // // { package_import_declaration } [ parameter_port_list ] parameter_port_listE { $$ = $1; } | package_import_declarationList parameter_port_listE { $$ = $1->addNextNull($2); } ; udpFront: yPRIMITIVE lifetimeE idAny { $$ = new AstPrimitive($1,*$3); $$->inLibrary(true); $$->modTrace(false); $$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE)); GRAMMARP->m_tracingParse = false; PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; parameter_value_assignmentE: // IEEE: [ parameter_value_assignment ] /* empty */ { $$ = NULL; } | '#' '(' cellpinList ')' { $$ = $3; } // // Parentheses are optional around a single parameter | '#' yaINTNUM { $$ = new AstPin($1,1,"",new AstConst($1,*$2)); } | '#' yaFLOATNUM { $$ = new AstPin($1,1,"",new AstConst($1,AstConst::Unsized32(),(int)(($2<0)?($2-0.5):($2+0.5)))); } | '#' idClassSel { $$ = new AstPin($1,1,"",$2); } // // Not needed in Verilator: // // Side effect of combining *_instantiations // // '#' delay_value { UNSUP } ; parameter_port_listE: // IEEE: parameter_port_list + empty == parameter_value_assignment /* empty */ { $$ = NULL; } | '#' '(' ')' { $$ = NULL; } // // IEEE: '#' '(' list_of_param_assignments { ',' parameter_port_declaration } ')' // // IEEE: '#' '(' parameter_port_declaration { ',' parameter_port_declaration } ')' // // Can't just do that as "," conflicts with between vars and between stmts, so // // split into pre-comma and post-comma parts | '#' '(' {VARRESET_LIST(GPARAM);} paramPortDeclOrArgList ')' { $$ = $4; VARRESET_NONLIST(UNKNOWN); } // // Note legal to start with "a=b" with no parameter statement ; paramPortDeclOrArgList: // IEEE: list_of_param_assignments + { parameter_port_declaration } paramPortDeclOrArg { $$ = $1; } | paramPortDeclOrArgList ',' paramPortDeclOrArg { $$ = $1->addNext($3); } ; paramPortDeclOrArg: // IEEE: param_assignment + parameter_port_declaration // // We combine the two as we can't tell which follows a comma parameter_port_declarationFrontE param_assignment { $$ = $2; } ; portsStarE: // IEEE: .* + list_of_ports + list_of_port_declarations + empty /* empty */ { $$ = NULL; } | '(' ')' { $$ = NULL; } // // .* expanded from module_declaration //UNSUP '(' yP_DOTSTAR ')' { UNSUP } | '(' {VARRESET_LIST(PORT);} list_of_ports ')' { $$ = $3; VARRESET_NONLIST(UNKNOWN); } ; list_of_ports: // IEEE: list_of_ports + list_of_port_declarations port { $$ = $1; } | list_of_ports ',' port { $$ = $1->addNextNull($3); } ; port: // ==IEEE: port // // Though not type for interfaces, we factor out the port direction and type // // so we can simply handle it in one place // // // IEEE: interface_port_header port_identifier { unpacked_dimension } // // Expanded interface_port_header // // We use instantCb here because the non-port form looks just like a module instantiation portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE { $$ = $3; VARDECL(AstVarType::IFACEREF); VARIO(UNKNOWN); VARDTYPE(new AstIfaceRefDType($2,"",*$2)); $$->addNextNull(VARDONEP($$,$4,$5)); } | portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig rangeListE sigAttrListE { $$ = $5; VARDECL(AstVarType::IFACEREF); VARIO(UNKNOWN); VARDTYPE(new AstIfaceRefDType($2,"",*$2,*$4)); $$->addNextNull(VARDONEP($$,$6,$7)); } | portDirNetE yINTERFACE portSig rangeListE sigAttrListE { $2->v3error("Unsupported: virtual interfaces"); $$=NULL; } | portDirNetE yINTERFACE '.' idAny/*modport*/ portSig rangeListE sigAttrListE { $2->v3error("Unsupported: virtual interfaces"); $$=NULL; } // // // IEEE: ansi_port_declaration, with [port_direction] removed // // IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension } [ '=' constant_expression ] // // IEEE: [ net_port_header | variable_port_header ] '.' port_identifier '(' [ expression ] ')' // // IEEE: [ variable_port_header ] port_identifier { variable_dimension } [ '=' constant_expression ] // // Substitute net_port_header = [ port_direction ] net_port_type // // Substitute variable_port_header = [ port_direction ] variable_port_type // // Substitute net_port_type = [ net_type ] data_type_or_implicit // // Substitute variable_port_type = var_data_type // // Substitute var_data_type = data_type | yVAR data_type_or_implicit // // [ [ port_direction ] net_port_type | interface_port_header ] port_identifier { unpacked_dimension } // // [ [ port_direction ] var_data_type ] port_identifier variable_dimensionListE [ '=' constant_expression ] // // [ [ port_direction ] net_port_type | [ port_direction ] var_data_type ] '.' port_identifier '(' [ expression ] ')' // // // Remove optional '[...] id' is in portAssignment // // Remove optional '[port_direction]' is in port // // net_port_type | interface_port_header port_identifier { unpacked_dimension } // // net_port_type | interface_port_header port_identifier { unpacked_dimension } // // var_data_type port_identifier variable_dimensionListE [ '=' constExpr ] // // net_port_type | [ port_direction ] var_data_type '.' port_identifier '(' [ expr ] ')' // // Expand implicit_type // // // variable_dimensionListE instead of rangeListE to avoid conflicts // // // Note implicit rules looks just line declaring additional followon port // // No VARDECL("port") for implicit, as we don't want to declare variables for them //UNSUP portDirNetE data_type '.' portSig '(' portAssignExprE ')' sigAttrListE //UNSUP { UNSUP } //UNSUP portDirNetE yVAR data_type '.' portSig '(' portAssignExprE ')' sigAttrListE //UNSUP { UNSUP } //UNSUP portDirNetE yVAR implicit_type '.' portSig '(' portAssignExprE ')' sigAttrListE //UNSUP { UNSUP } //UNSUP portDirNetE signingE rangeList '.' portSig '(' portAssignExprE ')' sigAttrListE //UNSUP { UNSUP } //UNSUP portDirNetE /*implicit*/ '.' portSig '(' portAssignExprE ')' sigAttrListE //UNSUP { UNSUP } // | portDirNetE data_type portSig variable_dimensionListE sigAttrListE { $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); } | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); } | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); } | portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE(GRAMMARP->addRange(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $2), $3,true)); $$->addNextNull(VARDONEP($$,$5,$6)); } | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE { $$=$2; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); } // | portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARDTYPE($2); AstVar* vp=VARDONEP($$,$4,$5); $$->addNextNull(vp); vp->valuep($7); } | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$4; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); } | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$4; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); } | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$2; /*VARDTYPE-same*/ AstVar* vp=VARDONEP($$,$3,$4); $$->addNextNull(vp); vp->valuep($6); } ; portDirNetE: // IEEE: part of port, optional net type and/or direction /* empty */ { } // // Per spec, if direction given default the nettype. // // The higher level rule may override this VARDTYPE with one later in the parse. | port_direction { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); } | port_direction { VARDECL(PORT); } net_type { VARDTYPE(NULL/*default_nettype*/); } // net_type calls VARNET | net_type { } // net_type calls VARNET ; port_declNetE: // IEEE: part of port_declaration, optional net type /* empty */ { } | net_type { } // net_type calls VARNET ; portSig: id/*port*/ { $$ = new AstPort($1,PINNUMINC(),*$1); } | idSVKwd { $$ = new AstPort($1,PINNUMINC(),*$1); } ; //********************************************************************** // Interface headers interface_declaration: // IEEE: interface_declaration + interface_nonansi_header + interface_ansi_header: // // timeunits_delcarationE is instead in interface_item intFront parameter_port_listE portsStarE ';' interface_itemListE yENDINTERFACE endLabelE { if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); SYMP->popScope($1); } //UNSUP yEXTERN intFront parameter_port_listE portsStarE ';' { } ; intFront: yINTERFACE lifetimeE idAny/*new_interface*/ { $$ = new AstIface($1,*$3); $$->inLibrary(true); PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; interface_itemListE: /* empty */ { $$ = NULL; } | interface_itemList { $$ = $1; } ; interface_itemList: interface_item { $$ = $1; } | interface_itemList interface_item { $$ = $1->addNextNull($2); } ; interface_item: // IEEE: interface_item + non_port_interface_item port_declaration ';' { $$ = $1; } // // IEEE: non_port_interface_item // // IEEE: generate_region | interface_generate_region { $$ = $1; } | interface_or_generate_item { $$ = $1; } //UNSUP program_declaration { $$ = $1; } //UNSUP interface_declaration { $$ = $1; } | timeunits_declaration { $$ = $1; } // // See note in interface_or_generate item | module_common_item { $$ = $1; } ; interface_generate_region: // ==IEEE: generate_region yGENERATE interface_itemList yENDGENERATE { $$ = new AstGenerate($1, $2); } | yGENERATE yENDGENERATE { $$ = NULL; } ; interface_or_generate_item: // ==IEEE: interface_or_generate_item // // module_common_item in interface_item, as otherwise duplicated // // with module_or_generate_item's module_common_item modport_declaration { $$ = $1; } //UNSUP extern_tf_declaration { $$ = $1; } ; //********************************************************************** // Program headers program_declaration: // IEEE: program_declaration + program_nonansi_header + program_ansi_header: // // timeunits_delcarationE is instead in program_item pgmFront parameter_port_listE portsStarE ';' program_itemListE yENDPROGRAM endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); SYMP->popScope($1); GRAMMARP->endLabel($7,$1,$7); } //UNSUP yEXTERN pgmFront parameter_port_listE portsStarE ';' //UNSUP { PARSEP->symPopScope(VAstType::PROGRAM); } ; pgmFront: yPROGRAM lifetimeE idAny/*new_program*/ { $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine()); $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); PARSEP->rootp()->addModulep($$); SYMP->pushNew($$); } ; program_itemListE: // ==IEEE: [{ program_item }] /* empty */ { $$ = NULL; } | program_itemList { $$ = $1; } ; program_itemList: // ==IEEE: { program_item } program_item { $$ = $1; } | program_itemList program_item { $$ = $1->addNextNull($2); } ; program_item: // ==IEEE: program_item port_declaration ';' { $$ = $1; } | non_port_program_item { $$ = $1; } ; non_port_program_item: // ==IEEE: non_port_program_item continuous_assign { $$ = $1; } | module_or_generate_item_declaration { $$ = $1; } | initial_construct { $$ = $1; } | final_construct { $$ = $1; } | concurrent_assertion_item { $$ = $1; } | timeunits_declaration { $$ = $1; } | program_generate_item { $$ = $1; } ; program_generate_item: // ==IEEE: program_generate_item loop_generate_construct { $$ = $1; } | conditional_generate_construct { $$ = $1; } | generate_region { $$ = $1; } //UNSUP elaboration_system_task { $$ = $1; } ; modport_declaration: // ==IEEE: modport_declaration yMODPORT modport_itemList ';' { $$ = $2; } ; modport_itemList: // IEEE: part of modport_declaration modport_item { $$ = $1; } | modport_itemList ',' modport_item { $$ = $1->addNextNull($3); } ; modport_item: // ==IEEE: modport_item id/*new-modport*/ '(' modportPortsDeclList ')' { $$ = new AstModport($2,*$1,$3); } ; modportPortsDeclList: modportPortsDecl { $$ = $1; } | modportPortsDeclList ',' modportPortsDecl { $$ = $1->addNextNull($3); } ; // IEEE: modport_ports_declaration + modport_simple_ports_declaration // + (modport_tf_ports_declaration+import_export) + modport_clocking_declaration // We've expanded the lists each take to instead just have standalone ID ports. // We track the type as with the V2k series of defines, then create as each ID is seen. modportPortsDecl: // // IEEE: modport_simple_ports_declaration port_direction modportSimplePort { $$ = new AstModportVarRef($1,*$2,GRAMMARP->m_varIO); } // // IEEE: modport_clocking_declaration | yCLOCKING idAny/*clocking_identifier*/ { $1->v3error("Unsupported: Modport clocking"); } // // IEEE: yIMPORT modport_tf_port // // IEEE: yEXPORT modport_tf_port // // modport_tf_port expanded here | yIMPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef($1,*$2,false); } | yEXPORT id/*tf_identifier*/ { $$ = new AstModportFTaskRef($1,*$2,true); } | yIMPORT method_prototype { $1->v3error("Unsupported: Modport import with prototype"); } | yEXPORT method_prototype { $1->v3error("Unsupported: Modport export with prototype"); } // Continuations of above after a comma. // // IEEE: modport_simple_ports_declaration | modportSimplePort { $$ = new AstModportVarRef($1,*$1,AstVarType::INOUT); } ; modportSimplePort: // IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier id { $$ = $1; } //UNSUP '.' idAny '(' ')' { } //UNSUP '.' idAny '(' expr ')' { } ; //************************************************ // Variable Declarations genvar_declaration: // ==IEEE: genvar_declaration yGENVAR list_of_genvar_identifiers ';' { $$ = $2; } ; list_of_genvar_identifiers: // IEEE: list_of_genvar_identifiers (for declaration) genvar_identifierDecl { $$ = $1; } | list_of_genvar_identifiers ',' genvar_identifierDecl { $$ = $1->addNext($3); } ; genvar_identifierDecl: // IEEE: genvar_identifier (for declaration) id/*new-genvar_identifier*/ sigAttrListE { VARRESET_NONLIST(GENVAR); VARDTYPE(new AstBasicDType($1,AstBasicDTypeKwd::INTEGER)); $$ = VARDONEA($1, *$1, NULL, $2); } ; local_parameter_declaration: // IEEE: local_parameter_declaration // // See notes in parameter_declaration local_parameter_declarationFront list_of_param_assignments { $$ = $2; } ; parameter_declaration: // IEEE: parameter_declaration // // IEEE: yPARAMETER yTYPE list_of_type_assignments ';' // // Instead of list_of_type_assignments // // we use list_of_param_assignments because for port handling // // it already must accept types, so simpler to have code only one place parameter_declarationFront list_of_param_assignments { $$ = $2; } ; local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); } | varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); } //UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE($2); } ; parameter_declarationFront: // IEEE: parameter_declaration w/o assignment varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } | varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } //UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } ; parameter_port_declarationFrontE: // IEEE: parameter_port_declaration w/o assignment // // IEEE: parameter_declaration (minus assignment) varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } | varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } | implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($1); } | data_type { /*VARRESET-in-varGParam*/ VARDTYPE($1); } //UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } //UNSUP data_type { VARDTYPE($1); } //UNSUP yTYPE { VARDTYPE($1); } ; net_declaration: // IEEE: net_declaration - excluding implict net_declarationFront netSigList ';' { $$ = $2; } ; net_declarationFront: // IEEE: beginning of net_declaration net_declRESET net_type strengthSpecE net_scalaredE net_dataType { VARDTYPE($5); } ; net_declRESET: /* empty */ { VARRESET_NONLIST(UNKNOWN); } ; net_scalaredE: /* empty */ { } //UNSUP: ySCALARED/yVECTORED ignored | ySCALARED { } | yVECTORED { } ; net_dataType: // // If there's a SV data type there shouldn't be a delay on this wire // // Otherwise #(...) can't be determined to be a delay or parameters // // Submit this as a footnote to the committee var_data_type { $$ = $1; } | signingE rangeList delayE { $$ = GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC, $1),$2,true); } // not implicit | signing { $$ = new AstBasicDType($1, LOGIC, $1); } // not implicit | /*implicit*/ delayE { $$ = new AstBasicDType(CRELINE(), LOGIC); } // not implicit ; net_type: // ==IEEE: net_type ySUPPLY0 { VARDECL(SUPPLY0); } | ySUPPLY1 { VARDECL(SUPPLY1); } | yTRI { VARDECL(TRIWIRE); } | yTRI0 { VARDECL(TRI0); } | yTRI1 { VARDECL(TRI1); } //UNSUP yTRIAND { VARDECL(TRIAND); } //UNSUP yTRIOR { VARDECL(TRIOR); } //UNSUP yTRIREG { VARDECL(TRIREG); } //UNSUP yWAND { VARDECL(WAND); } | yWIRE { VARDECL(WIRE); } //UNSUP yWOR { VARDECL(WOR); } ; varGParamReset: yPARAMETER { VARRESET_NONLIST(GPARAM); } ; varLParamReset: yLOCALPARAM { VARRESET_NONLIST(LPARAM); } ; port_direction: // ==IEEE: port_direction + tf_port_direction // // IEEE 19.8 just "input" FIRST forces type to wire - we'll ignore that here yINPUT { VARIO(INPUT); } | yOUTPUT { VARIO(OUTPUT); } | yINOUT { VARIO(INOUT); } //UNSUP yREF { VARIO(REF); } //UNSUP yCONST__REF yREF { VARIO(CONSTREF); } ; port_directionReset: // IEEE: port_direction that starts a port_declaraiton // // Used only for declarations outside the port list yINPUT { VARRESET_NONLIST(UNKNOWN); VARIO(INPUT); } | yOUTPUT { VARRESET_NONLIST(UNKNOWN); VARIO(OUTPUT); } | yINOUT { VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); } //UNSUP yREF { VARRESET_NONLIST(UNKNOWN); VARIO(REF); } //UNSUP yCONST__REF yREF { VARRESET_NONLIST(UNKNOWN); VARIO(CONSTREF); } ; port_declaration: // ==IEEE: port_declaration // // Used inside block; followed by ';' // // SIMILAR to tf_port_declaration // // // IEEE: inout_declaration // // IEEE: input_declaration // // IEEE: output_declaration // // IEEE: ref_declaration port_directionReset port_declNetE data_type { VARDTYPE($3); } list_of_variable_decl_assignments { $$ = $5; } | port_directionReset port_declNetE yVAR data_type { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; } | port_directionReset port_declNetE yVAR implicit_typeE { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; } | port_directionReset port_declNetE signingE rangeList { VARDTYPE(GRAMMARP->addRange(new AstBasicDType($4->fileline(), LOGIC_IMPLICIT, $3),$4,true)); } list_of_variable_decl_assignments { $$ = $6; } | port_directionReset port_declNetE signing { VARDTYPE(new AstBasicDType($3, LOGIC_IMPLICIT, $3)); } list_of_variable_decl_assignments { $$ = $5; } | port_directionReset port_declNetE /*implicit*/ { VARDTYPE(NULL);/*default_nettype*/} list_of_variable_decl_assignments { $$ = $4; } // // IEEE: interface_declaration // // Looks just like variable declaration unless has a period // // See etcInst ; tf_port_declaration: // ==IEEE: tf_port_declaration // // Used inside function; followed by ';' // // SIMILAR to port_declaration // port_directionReset data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } | port_directionReset implicit_typeE { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } | port_directionReset yVAR data_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } | port_directionReset yVAR implicit_typeE { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } ; integer_atom_type: // ==IEEE: integer_atom_type yBYTE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BYTE); } | ySHORTINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::SHORTINT); } | yINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INT); } | yLONGINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LONGINT); } | yINTEGER { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INTEGER); } | yTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::TIME); } ; integer_vector_type: // ==IEEE: integer_atom_type yBIT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BIT); } | yLOGIC { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); } | yREG { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); } // logic==reg ; non_integer_type: // ==IEEE: non_integer_type yREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); } | yREALTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); } //UNSUP ySHORTREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::FLOAT); } // // VAMS - somewhat hackish | yWREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); VARDECL(WIRE); } ; signingE: // IEEE: signing - plus empty /*empty*/ { $$ = signedst_NOSIGN; } | signing { $$ = $1; } ; signing: // ==IEEE: signing ySIGNED { $$ = $1; $$ = signedst_SIGNED; } | yUNSIGNED { $$ = $1; $$ = signedst_UNSIGNED; } ; //************************************************ // Data Types casting_type: // IEEE: casting_type simple_type { $$ = $1; } // // IEEE: constant_primary // // In expr:cast this is expanded to just "expr" // // // IEEE: signing //See where casting_type used //^^ ySIGNED { $$ = new AstSigned($1,$3); } //^^ yUNSIGNED { $$ = new AstUnsigned($1,$3); } //UNSUP ySTRING { $$ = $1; } //UNSUP yCONST__ETC/*then `*/ { $$ = $1; } ; simple_type: // ==IEEE: simple_type // // IEEE: integer_type integer_atom_type { $$ = $1; } | integer_vector_type { $$ = $1; } | non_integer_type { $$ = $1; } // // IEEE: ps_type_identifier // // IEEE: ps_parameter_identifier (presumably a PARAMETER TYPE) | ps_type { $$ = $1; } // // { generate_block_identifer ... } '.' // // Need to determine if generate_block_identifier can be lex-detected ; data_type: // ==IEEE: data_type // // This expansion also replicated elsewhere, IE data_type__AndID data_typeNoRef { $$ = $1; } // // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension } | ps_type packed_dimensionListE { $$ = GRAMMARP->createArray($1,$2,true); } //UNSUP class_scope_type packed_dimensionListE { UNSUP } // // IEEE: class_type //UNSUP class_typeWithoutId { $$ = $1; } // // IEEE: ps_covergroup_identifier // // we put covergroups under ps_type, so can ignore this ; data_typeBasic: // IEEE: part of data_type integer_vector_type signingE rangeListE { $1->setSignedState($2); $$ = GRAMMARP->addRange($1,$3,true); } | integer_atom_type signingE { $1->setSignedState($2); $$ = $1; } | non_integer_type { $$ = $1; } ; data_typeNoRef: // ==IEEE: data_type, excluding class_type etc references data_typeBasic { $$ = $1; } | struct_unionDecl packed_dimensionListE { $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->s_modTypeImpNum++), SYMP,VFlagChildDType(),$1),$2,true); } | enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->s_modTypeImpNum++), SYMP,VFlagChildDType(),$1); } | ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); } | yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); } //UNSUP yEVENT { UNSUP } //UNSUP yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ { UNSUP } //UNSUP yVIRTUAL__anyID id/*interface*/ { UNSUP } //UNSUP type_reference { UNSUP } // // IEEE: class_scope: see data_type above // // IEEE: class_type: see data_type above // // IEEE: ps_covergroup: see data_type above ; data_type_or_void: // ==IEEE: data_type_or_void data_type { $$ = $1; } //UNSUP yVOID { UNSUP } // No yTAGGED structures ; var_data_type: // ==IEEE: var_data_type data_type { $$ = $1; } | yVAR data_type { $$ = $2; } | yVAR implicit_typeE { $$ = $2; } ; struct_unionDecl: // IEEE: part of data_type // // packedSigningE is NOP for unpacked ySTRUCT packedSigningE '{' { $$ = new AstStructDType($1, $2); SYMP->pushNew($$); } /*cont*/ struct_union_memberList '}' { $$=$4; $$->addMembersp($5); SYMP->popScope($$); } | yUNION taggedE packedSigningE '{' { $$ = new AstUnionDType($1, $3); SYMP->pushNew($$); } /*cont*/ struct_union_memberList '}' { $$=$5; $$->addMembersp($6); SYMP->popScope($$); } ; struct_union_memberList: // IEEE: { struct_union_member } struct_union_member { $$ = $1; } | struct_union_memberList struct_union_member { $$ = $1->addNextNull($2); } ; struct_union_member: // ==IEEE: struct_union_member random_qualifierE data_type_or_void { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member. /*cont*/ list_of_member_decl_assignments ';' { $$ = $4; GRAMMARP->m_memDTypep = NULL; } ; list_of_member_decl_assignments: // Derived from IEEE: list_of_variable_decl_assignments member_decl_assignment { $$ = $1; } | list_of_member_decl_assignments ',' member_decl_assignment { $$ = $1->addNextNull($3); } ; member_decl_assignment: // 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($1, *$1, VFlagChildDType(), GRAMMARP->m_memDTypep->cloneTree(true)); } | id variable_dimensionListE '=' variable_declExpr { $4->v3error("Unsupported: Initial values in struct/union members."); } | idSVKwd { $$ = NULL; } // // // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]" // // Matches above with variable_dimensionE = "[]" // // IEEE: "class_variable_identifier [ '=' class_new ]" // // variable_dimensionE must be empty // // Pushed into variable_declExpr:dynamic_array_new // // // IEEE: "[ covergroup_variable_identifier ] '=' class_new // // Pushed into variable_declExpr:class_new //UNSUP '=' class_new { UNSUP } ; list_of_variable_decl_assignments: // ==IEEE: list_of_variable_decl_assignments variable_decl_assignment { $$ = $1; } | list_of_variable_decl_assignments ',' variable_decl_assignment { $$ = $1->addNextNull($3); } ; variable_decl_assignment: // ==IEEE: variable_decl_assignment id variable_dimensionListE sigAttrListE { $$ = VARDONEA($1,*$1,$2,$3); } | id variable_dimensionListE sigAttrListE '=' variable_declExpr { $$ = VARDONEA($1,*$1,$2,$3); $$->valuep($5); } | idSVKwd { $$ = NULL; } // // // IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]" // // Matches above with variable_dimensionE = "[]" // // IEEE: "class_variable_identifier [ '=' class_new ]" // // variable_dimensionE must be empty // // Pushed into variable_declExpr:dynamic_array_new // // // IEEE: "[ covergroup_variable_identifier ] '=' class_new // // Pushed into variable_declExpr:class_new //UNSUP '=' class_new { UNSUP } ; list_of_tf_variable_identifiers: // ==IEEE: list_of_tf_variable_identifiers tf_variable_identifier { $$ = $1; } | list_of_tf_variable_identifiers ',' tf_variable_identifier { $$ = $1->addNext($3); } ; tf_variable_identifier: // IEEE: part of list_of_tf_variable_identifiers id variable_dimensionListE sigAttrListE { $$ = VARDONEA($1,*$1, $2, $3); } | id variable_dimensionListE sigAttrListE '=' expr { $$ = VARDONEA($1,*$1, $2, $3); $$->addNext(new AstAssign($4, new AstVarRef($4, *$1, true), $5)); } ; variable_declExpr: // IEEE: part of variable_decl_assignment - rhs of expr expr { $$ = $1; } //UNSUP dynamic_array_new { $$ = $1; } //UNSUP class_new { $$ = $1; } ; variable_dimensionListE: // IEEE: variable_dimension + empty /*empty*/ { $$ = NULL; } | variable_dimensionList { $$ = $1; } ; variable_dimensionList: // IEEE: variable_dimension + empty variable_dimension { $$ = $1; } | variable_dimensionList variable_dimension { $$ = $1->addNext($2)->castRange(); } ; variable_dimension: // ==IEEE: variable_dimension // // IEEE: unsized_dimension //UNSUP '[' ']' { UNSUP } // // IEEE: unpacked_dimension anyrange { $$ = $1; } | '[' constExpr ']' { $$ = new AstRange($1, new AstConst($1, 0), new AstSub($1, $2, new AstConst($1, 1))); } // // IEEE: associative_dimension //UNSUP '[' data_type ']' { UNSUP } //UNSUP yP_BRASTAR ']' { UNSUP } //UNSUP '[' '*' ']' { UNSUP } // // IEEE: queue_dimension // // '[' '$' ']' -- $ is part of expr // // '[' '$' ':' expr ']' -- anyrange:expr:$ ; random_qualifierE: // IEEE: random_qualifier + empty /*empty*/ { } | random_qualifier { } ; random_qualifier: // ==IEEE: random_qualifier yRAND { } // Ignored until we support randomize() | yRANDC { } // Ignored until we support randomize() ; taggedE: /*empty*/ { } //UNSUP yTAGGED { UNSUP } ; packedSigningE: // // AstNumeric::NOSIGN overloaded to indicate not packed /*empty*/ { $$ = signedst_NOSIGN; } | yPACKED signingE { $$ = $2; if ($$ == signedst_NOSIGN) $$ = signedst_UNSIGNED; } ; //************************************************ // enum // IEEE: part of data_type enumDecl: yENUM enum_base_typeE '{' enum_nameList '}' { $$ = new AstEnumDType($1,VFlagChildDType(),$2,$4); } ; enum_base_typeE: // IEEE: enum_base_type /* empty */ { $$ = new AstBasicDType(CRELINE(),AstBasicDTypeKwd::INT); } // // Not in spec, but obviously "enum [1:0]" should work // // implicit_type expanded, without empty // // Note enum base types are always packed data types | signingE rangeList { $$ = GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1),$2,true); } | signing { $$ = new AstBasicDType($1, LOGIC_IMPLICIT, $1); } // | integer_atom_type signingE { $1->setSignedState($2); $$ = $1; } | integer_vector_type signingE rangeListE { $1->setSignedState($2); $$ = GRAMMARP->addRange($1,$3,true); } // // below can be idAny or yaID__aTYPE // // IEEE requires a type, though no shift conflict if idAny | idAny rangeListE { $$ = GRAMMARP->createArray(new AstRefDType($1, *$1), $2, true); } ; enum_nameList: enum_name_declaration { $$ = $1; } | enum_nameList ',' enum_name_declaration { $$ = $1->addNextNull($3); } ; enum_name_declaration: // ==IEEE: enum_name_declaration idAny/*enum_identifier*/ enumNameRangeE enumNameStartE { $$ = new AstEnumItem($1, *$1, $2, $3); } ; enumNameRangeE: // IEEE: second part of enum_name_declaration /* empty */ { $$ = NULL; } | '[' intnumAsConst ']' { $$ = new AstRange($1,new AstConst($1,0), $2); } | '[' intnumAsConst ':' intnumAsConst ']' { $$ = new AstRange($1,$2,$4); } ; enumNameStartE: // IEEE: third part of enum_name_declaration /* empty */ { $$ = NULL; } | '=' constExpr { $$ = $2; } ; intnumAsConst: yaINTNUM { $$ = new AstConst($1,*$1); } ; //************************************************ // Typedef data_declaration: // ==IEEE: data_declaration // // VARRESET can't be called here - conflicts data_declarationVar { $$ = $1; } | type_declaration { $$ = $1; } | package_import_declaration { $$ = $1; } // // IEEE: virtual_interface_declaration // // "yVIRTUAL yID yID" looks just like a data_declaration // // Therefore the virtual_interface_declaration term isn't used ; data_declarationVar: // IEEE: part of data_declaration // // The first declaration has complications between assuming what's the type vs ID declaring data_declarationVarFront list_of_variable_decl_assignments ';' { $$ = $2; } ; data_declarationVarFront: // IEEE: part of data_declaration // // Expanded: "constE yVAR lifetimeE data_type" // // implicit_type expanded into /*empty*/ or "signingE rangeList" /**/ yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE($3); } | /**/ yVAR lifetimeE { VARRESET_NONLIST(VAR); VARDTYPE(new AstBasicDType($1, LOGIC_IMPLICIT)); } | /**/ yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDTYPE(GRAMMARP->addRange(new AstBasicDType($1, LOGIC_IMPLICIT, $3), $4,true)); } // // // implicit_type expanded into /*empty*/ or "signingE rangeList" | yCONST__ETC yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($1, VFlagChildDType(), $4)); } | yCONST__ETC yVAR lifetimeE { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($1, VFlagChildDType(), new AstBasicDType($2, LOGIC_IMPLICIT))); } | yCONST__ETC yVAR lifetimeE signingE rangeList { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($1, VFlagChildDType(), GRAMMARP->addRange(new AstBasicDType($2, LOGIC_IMPLICIT, $4), $5,true))); } // // // Expanded: "constE lifetimeE data_type" | /**/ data_type { VARRESET_NONLIST(VAR); VARDTYPE($1); } | /**/ lifetime data_type { VARRESET_NONLIST(VAR); VARDTYPE($2); } | yCONST__ETC lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($1, VFlagChildDType(), $3)); } // // = class_new is in variable_decl_assignment ; implicit_typeE: // IEEE: part of *data_type_or_implicit // // Also expanded in data_declaration /* empty */ { $$ = NULL; } | signingE rangeList { $$ = GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1),$2,true); } | signing { $$ = new AstBasicDType($1, LOGIC_IMPLICIT, $1); } ; type_declaration: // ==IEEE: type_declaration // // Use idAny, as we can redeclare a typedef on an existing typedef yTYPEDEF data_type idAny variable_dimensionListE dtypeAttrListE ';' /**/ { $$ = new AstTypedef($1, *$3, $5, VFlagChildDType(), GRAMMARP->createArray($2,$4,false)); SYMP->reinsert($$); } //UNSUP yTYPEDEF id/*interface*/ '.' idAny/*type*/ idAny/*type*/ ';' { $$ = NULL; $1->v3error("Unsupported: SystemVerilog 2005 typedef in this context"); } //UNSUP // // Combines into above "data_type id" rule // // Verilator: Not important what it is in the AST, just need to make sure the yaID__aTYPE gets returned | yTYPEDEF id ';' { $$ = NULL; $$ = new AstTypedefFwd($1, *$2); SYMP->reinsert($$); } | yTYPEDEF yENUM idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($1, *$3); SYMP->reinsert($$); } | yTYPEDEF ySTRUCT idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($1, *$3); SYMP->reinsert($$); } | yTYPEDEF yUNION idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($1, *$3); SYMP->reinsert($$); } //UNSUP yTYPEDEF yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($1, *$3); SYMP->reinsert($$); } ; dtypeAttrListE: /* empty */ { $$ = NULL; } | dtypeAttrList { $$ = $1; } ; dtypeAttrList: dtypeAttr { $$ = $1; } | dtypeAttrList dtypeAttr { $$ = $1->addNextNull($2); } ; dtypeAttr: yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::DT_PUBLIC); } ; //************************************************ // Module Items module_itemListE: // IEEE: Part of module_declaration /* empty */ { $$ = NULL; } | module_itemList { $$ = $1; } ; module_itemList: // IEEE: Part of module_declaration module_item { $$ = $1; } | module_itemList module_item { $$ = $1->addNextNull($2); } ; module_item: // ==IEEE: module_item port_declaration ';' { $$ = $1; } | non_port_module_item { $$ = $1; } ; non_port_module_item: // ==IEEE: non_port_module_item generate_region { $$ = $1; } | module_or_generate_item { $$ = $1; } | specify_block { $$ = $1; } | specparam_declaration { $$ = $1; } //UNSUP program_declaration { $$ = $1; } //UNSUP module_declaration { $$ = $1; } //UNSUP interface_declaration { $$ = $1; } | timeunits_declaration { $$ = $1; } // // Verilator specific | yaSCHDR { $$ = new AstScHdr($1,*$1); } | yaSCINT { $$ = new AstScInt($1,*$1); } | yaSCIMP { $$ = new AstScImp($1,*$1); } | yaSCIMPH { $$ = new AstScImpHdr($1,*$1); } | yaSCCTOR { $$ = new AstScCtor($1,*$1); } | yaSCDTOR { $$ = new AstScDtor($1,*$1); } | yVL_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::INLINE_MODULE); } | yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_MODULE); } | yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); v3Global.dpi(true); } ; module_or_generate_item: // ==IEEE: module_or_generate_item // // IEEE: parameter_override yDEFPARAM list_of_defparam_assignments ';' { $$ = $2; } // // IEEE: gate_instantiation + udp_instantiation + module_instantiation // // not here, see etcInst in module_common_item // // We joined udp & module definitions, so this goes here | combinational_body { $$ = $1; } // // This module_common_item shared with interface_or_generate_item:module_common_item | module_common_item { $$ = $1; } ; module_common_item: // ==IEEE: module_common_item module_or_generate_item_declaration { $$ = $1; } // // IEEE: interface_instantiation // // + IEEE: program_instantiation // // + module_instantiation from module_or_generate_item | etcInst { $$ = $1; } | concurrent_assertion_item { $$ = $1; } | bind_directive { $$ = $1; } | continuous_assign { $$ = $1; } // // IEEE: net_alias //UNSUP yALIAS variable_lvalue aliasEqList ';' { UNSUP } | initial_construct { $$ = $1; } | final_construct { $$ = $1; } // // IEEE: always_construct // // Verilator only - event_control attached to always | yALWAYS event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS, $2,$3); } | yALWAYS_FF event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_FF, $2,$3); } | yALWAYS_COMB event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_COMB, $2,$3); } | yALWAYS_LATCH event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_LATCH, $2,$3); } | loop_generate_construct { $$ = $1; } | conditional_generate_construct { $$ = $1; } // | error ';' { $$ = NULL; } ; continuous_assign: // IEEE: continuous_assign yASSIGN delayE assignList ';' { $$ = $3; } //UNSUP: strengthSpecE not in above assign ; initial_construct: // IEEE: initial_construct yINITIAL stmtBlock { $$ = new AstInitial($1,$2); } ; final_construct: // IEEE: final_construct yFINAL stmtBlock { $$ = new AstFinal($1,$2); } ; module_or_generate_item_declaration: // ==IEEE: module_or_generate_item_declaration package_or_generate_item_declaration { $$ = $1; } | genvar_declaration { $$ = $1; } | clocking_declaration { $$ = $1; } //UNSUP yDEFAULT yCLOCKING idAny/*new-clocking_identifier*/ ';' { $$ = $1; } ; bind_directive: // ==IEEE: bind_directive + bind_target_scope // // ';' - Note IEEE grammar is wrong, includes extra ';' - it's already in module_instantiation // // We merged the rules - id may be a bind_target_instance or module_identifier or interface_identifier yBIND bind_target_instance bind_instantiation { $$ = new AstBind($1,*$2,$3); } | yBIND bind_target_instance ':' bind_target_instance_list bind_instantiation { $$=NULL; $1->v3error("Unsupported: Bind with instance list"); } ; bind_target_instance_list: // ==IEEE: bind_target_instance_list bind_target_instance { } | bind_target_instance_list ',' bind_target_instance { } ; bind_target_instance: // ==IEEE: bind_target_instance //UNSUP hierarchical_identifierBit { } idAny { $$ = $1; } ; bind_instantiation: // ==IEEE: bind_instantiation // // IEEE: program_instantiation // // IEEE: + module_instantiation // // IEEE: + interface_instantiation // // Need to get an AstBind instead of AstCell, so have special rules instDecl { $$ = $1; } ; //************************************************ // Generates // // Way down in generate_item is speced a difference between module, // interface and checker generates. modules and interfaces are almost // identical (minus DEFPARAMs) so we overlap them. Checkers are too // different, so we copy all rules for checkers. generate_region: // ==IEEE: generate_region yGENERATE genItemList yENDGENERATE { $$ = new AstGenerate($1, $2); } | yGENERATE yENDGENERATE { $$ = NULL; } ; generate_block_or_null: // IEEE: generate_block_or_null // ';' // is included in // // IEEE: generate_block // // Must always return a BEGIN node, or NULL - see GenFor construction generate_item { $$ = $1 ? (new AstBegin($1->fileline(),"genblk",$1,true)) : NULL; } | genItemBegin { $$ = $1; } ; genItemBegin: // IEEE: part of generate_block yBEGIN genItemList yEND { $$ = new AstBegin($1,"genblk",$2,true); } | yBEGIN yEND { $$ = NULL; } | id ':' yBEGIN genItemList yEND endLabelE { $$ = new AstBegin($2,*$1,$4,true); GRAMMARP->endLabel($6,*$1,$6); } | id ':' yBEGIN yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($5,*$1,$5); } | yBEGIN ':' idAny genItemList yEND endLabelE { $$ = new AstBegin($2,*$3,$4,true); GRAMMARP->endLabel($6,*$3,$6); } | yBEGIN ':' idAny yEND endLabelE { $$ = NULL; GRAMMARP->endLabel($5,*$3,$5); } ; genItemOrBegin: // Not in IEEE, but our begin isn't under generate_item ~c~generate_item { $$ = $1; } | ~c~genItemBegin { $$ = $1; } ; genItemList: ~c~genItemOrBegin { $$ = $1; } | ~c~genItemList ~c~genItemOrBegin { $$ = $1->addNextNull($2); } ; generate_item: // IEEE: module_or_interface_or_generate_item // // Only legal when in a generate under a module (or interface under a module) module_or_generate_item { $$ = $1; } // // Only legal when in a generate under an interface //UNSUP interface_or_generate_item { $$ = $1; } // // IEEE: checker_or_generate_item // // Only legal when in a generate under a checker // // so below in c_generate_item ; conditional_generate_construct: // ==IEEE: conditional_generate_construct yCASE '(' expr ')' ~c~case_generate_itemListE yENDCASE { $$ = new AstGenCase($1,$3,$5); } | yIF '(' expr ')' generate_block_or_null %prec prLOWER_THAN_ELSE { $$ = new AstGenIf($1,$3,$5,NULL); } | yIF '(' expr ')' generate_block_or_null yELSE generate_block_or_null { $$ = new AstGenIf($1,$3,$5,$7); } ; loop_generate_construct: // ==IEEE: loop_generate_construct yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block_or_null { // Convert BEGIN(...) to BEGIN(GENFOR(...)), as we need the BEGIN to hide the local genvar AstBegin* lowerBegp = $9->castBegin(); if ($9 && !lowerBegp) $9->v3fatalSrc("Child of GENFOR should have been begin"); if (!lowerBegp) lowerBegp = new AstBegin($1,"genblk",NULL,true); // Empty body AstNode* lowerNoBegp = lowerBegp->stmtsp(); if (lowerNoBegp) lowerNoBegp->unlinkFrBackWithNext(); // AstBegin* blkp = new AstBegin($1,lowerBegp->name(),NULL,true); // V3LinkDot detects BEGIN(GENFOR(...)) as a special case AstNode* initp = $3; AstNode* varp = $3; if (varp->castVar()) { // Genvar initp = varp->nextp(); initp->unlinkFrBackWithNext(); // Detach 2nd from varp, make 1st init blkp->addStmtsp(varp); } // Statements are under 'genforp' as cells under this // for loop won't get an extra layer of hierarchy tacked on blkp->addGenforp(new AstGenFor($1,initp,$5,$7,lowerNoBegp)); $$ = blkp; lowerBegp->deleteTree(); lowerBegp=NULL; } ; genvar_initialization: // ==IEEE: genvar_initalization varRefBase '=' expr { $$ = new AstAssign($2,$1,$3); } | yGENVAR genvar_identifierDecl '=' constExpr { $$ = $2; $2->addNext(new AstAssign($3,new AstVarRef($3,$2,true), $4)); } ; genvar_iteration: // ==IEEE: genvar_iteration varRefBase '=' expr { $$ = new AstAssign($2,$1,$3); } | varRefBase yP_PLUSEQ expr { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),$3)); } | varRefBase yP_MINUSEQ expr { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),$3)); } | varRefBase yP_TIMESEQ expr { $$ = new AstAssign($2,$1,new AstMul ($2,$1->cloneTree(true),$3)); } | varRefBase yP_DIVEQ expr { $$ = new AstAssign($2,$1,new AstDiv ($2,$1->cloneTree(true),$3)); } | varRefBase yP_MODEQ expr { $$ = new AstAssign($2,$1,new AstModDiv ($2,$1->cloneTree(true),$3)); } | varRefBase yP_ANDEQ expr { $$ = new AstAssign($2,$1,new AstAnd ($2,$1->cloneTree(true),$3)); } | varRefBase yP_OREQ expr { $$ = new AstAssign($2,$1,new AstOr ($2,$1->cloneTree(true),$3)); } | varRefBase yP_XOREQ expr { $$ = new AstAssign($2,$1,new AstXor ($2,$1->cloneTree(true),$3)); } | varRefBase yP_SLEFTEQ expr { $$ = new AstAssign($2,$1,new AstShiftL ($2,$1->cloneTree(true),$3)); } | varRefBase yP_SRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftR ($2,$1->cloneTree(true),$3)); } | varRefBase yP_SSRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftRS($2,$1->cloneTree(true),$3)); } // // inc_or_dec_operator // When support ++ as a real AST type, maybe AstWhile::precondsp() becomes generic AstMathStmt? | yP_PLUSPLUS varRefBase { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } | yP_MINUSMINUS varRefBase { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } | varRefBase yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } | varRefBase yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } ; case_generate_itemListE: // IEEE: [{ case_generate_itemList }] /* empty */ { $$ = NULL; } | case_generate_itemList { $$ = $1; } ; case_generate_itemList: // IEEE: { case_generate_itemList } ~c~case_generate_item { $$=$1; } | ~c~case_generate_itemList ~c~case_generate_item { $$=$1; $1->addNext($2); } ; case_generate_item: // ==IEEE: case_generate_item caseCondList ':' generate_block_or_null { $$ = new AstCaseItem($2,$1,$3); } | yDEFAULT ':' generate_block_or_null { $$ = new AstCaseItem($2,NULL,$3); } | yDEFAULT generate_block_or_null { $$ = new AstCaseItem($1,NULL,$2); } ; //************************************************ // Assignments and register declarations assignList: assignOne { $$ = $1; } | assignList ',' assignOne { $$ = $1->addNext($3); } ; assignOne: variable_lvalue '=' expr { $$ = new AstAssignW($2,$1,$3); } ; delayE: /* empty */ { } | delay_control { $1->v3warn(ASSIGNDLY,"Unsupported: Ignoring delay on this assignment/primitive."); } /* ignored */ ; delay_control: //== IEEE: delay_control '#' delay_value { $$ = $1; } /* ignored */ | '#' '(' minTypMax ')' { $$ = $1; } /* ignored */ | '#' '(' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */ | '#' '(' minTypMax ',' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */ ; delay_value: // ==IEEE:delay_value // // IEEE: ps_identifier ps_id_etc { } | yaINTNUM { } | yaFLOATNUM { } | yaTIMENUM { } ; delayExpr: expr { DEL($1); } // // Verilator doesn't support yaTIMENUM, so not in expr | yaTIMENUM { } ; minTypMax: // IEEE: mintypmax_expression and constant_mintypmax_expression delayExpr { } | delayExpr ':' delayExpr ':' delayExpr { } ; netSigList: // IEEE: list_of_port_identifiers netSig { $$ = $1; } | netSigList ',' netSig { $$ = $1; $1->addNext($3); } ; netSig: // IEEE: net_decl_assignment - one element from list_of_port_identifiers netId sigAttrListE { $$ = VARDONEA($1,*$1, NULL, $2); } | netId sigAttrListE '=' expr { $$ = VARDONEA($1,*$1, NULL, $2); $$->addNext(new AstAssignW($3,new AstVarRef($3,$$->name(),true),$4)); } | netId variable_dimensionList sigAttrListE { $$ = VARDONEA($1,*$1, $2, $3); } ; netId: id/*new-net*/ { $$ = $1; $$=$1; } | idSVKwd { $$ = $1; $$=$1; } ; sigAttrListE: /* empty */ { $$ = NULL; } | sigAttrList { $$ = $1; } ; sigAttrList: sigAttr { $$ = $1; } | sigAttrList sigAttr { $$ = $1->addNextNull($2); } ; sigAttr: yVL_CLOCK { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK); } | yVL_CLOCKER { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCKER); } | yVL_NO_CLOCKER { $$ = new AstAttrOf($1,AstAttrType::VAR_NO_CLOCKER); } | yVL_CLOCK_ENABLE { $$ = new AstAttrOf($1,AstAttrType::VAR_CLOCK_ENABLE); } | yVL_PUBLIC { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC); v3Global.dpi(true); } | yVL_PUBLIC_FLAT { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT); v3Global.dpi(true); } | yVL_PUBLIC_FLAT_RD { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RD); v3Global.dpi(true); } | yVL_PUBLIC_FLAT_RW { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); v3Global.dpi(true); } | yVL_PUBLIC_FLAT_RW attr_event_control { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW); v3Global.dpi(true); $$ = $$->addNext(new AstAlwaysPublic($1,$2,NULL)); } | yVL_ISOLATE_ASSIGNMENTS { $$ = new AstAttrOf($1,AstAttrType::VAR_ISOLATE_ASSIGNMENTS); } | yVL_SC_BV { $$ = new AstAttrOf($1,AstAttrType::VAR_SC_BV); } | yVL_SFORMAT { $$ = new AstAttrOf($1,AstAttrType::VAR_SFORMAT); } ; rangeListE: // IEEE: [{packed_dimension}] /* empty */ { $$ = NULL; } | rangeList { $$ = $1; } ; rangeList: // IEEE: {packed_dimension} anyrange { $$ = $1; } | rangeList anyrange { $$ = $1; $1->addNext($2); } ; // IEEE: select // Merged into more general idArray anyrange: '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } ; packed_dimensionListE: // IEEE: [{ packed_dimension }] /* empty */ { $$ = NULL; } | packed_dimensionList { $$ = $1; } ; packed_dimensionList: // IEEE: { packed_dimension } packed_dimension { $$ = $1; } | packed_dimensionList packed_dimension { $$ = $1->addNext($2)->castRange(); } ; packed_dimension: // ==IEEE: packed_dimension anyrange { $$ = $1; } //UNSUP '[' ']' { UNSUP } ; //************************************************ // Parameters param_assignment: // ==IEEE: param_assignment // // IEEE: constant_param_expression // // constant_param_expression: '$' is in expr id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' expr /**/ { $$ = VARDONEA($1,*$1, $2, $3); $$->valuep($5); } //UNSUP: exprOrDataType instead of expr ; list_of_param_assignments: // ==IEEE: list_of_param_assignments param_assignment { $$ = $1; } | list_of_param_assignments ',' param_assignment { $$ = $1; $1->addNext($3); } ; list_of_defparam_assignments: //== IEEE: list_of_defparam_assignments defparam_assignment { $$ = $1; } | list_of_defparam_assignments ',' defparam_assignment { $$ = $1->addNext($3); } ; defparam_assignment: // ==IEEE: defparam_assignment id '.' id '=' expr { $$ = new AstDefParam($4,*$1,*$3,$5); } //UNSUP More general dotted identifiers ; //************************************************ // Instances // We don't know identifier types, so this matches all module,udp,etc instantiation // module_id [#(params)] name (pins) [, name ...] ; // module_instantiation // gate (strong0) [#(delay)] [name] (pins) [, (pins)...] ; // gate_instantiation // program_id [#(params}] name ; // program_instantiation // interface_id [#(params}] name ; // interface_instantiation // checker_id name (pins) ; // checker_instantiation etcInst: // IEEE: module_instantiation + gate_instantiation + udp_instantiation instDecl { $$ = $1; } | gateDecl { $$ = $1; } ; instDecl: id parameter_value_assignmentE {INSTPREP(*$1,$2);} instnameList ';' { $$ = $4; GRAMMARP->m_impliedDecl=false; if (GRAMMARP->m_instParamp) { GRAMMARP->m_instParamp->deleteTree(); GRAMMARP->m_instParamp = NULL; } } // // IEEE: interface_identifier' .' modport_identifier list_of_interface_identifiers | id/*interface*/ '.' id/*modport*/ { VARRESET_NONLIST(AstVarType::IFACEREF); VARDTYPE(new AstIfaceRefDType($1,"",*$1,*$3)); } mpInstnameList ';' { $$ = VARDONEP($5,NULL,NULL); } //UNSUP: strengthSpecE for udp_instantiations ; mpInstnameList: // Similar to instnameList, but for modport instantiations which have no parenthesis mpInstnameParen { $$ = $1; } | mpInstnameList ',' mpInstnameParen { $$ = $1->addNext($3); } ; mpInstnameParen: // Similar to instnameParen, but for modport instantiations which have no parenthesis id instRangeE sigAttrListE { $$ = VARDONEA($1,*$1,$2,$3); } ; instnameList: instnameParen { $$ = $1; } | instnameList ',' instnameParen { $$ = $1->addNext($3); } ; instnameParen: // // Must clone m_instParamp as may be comma'ed list of instances id instRangeE '(' cellpinList ')' { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,$4, GRAMMARP->m_instParamp->cloneTree(true),$2); $$->trace(GRAMMARP->allTracingOn($1)); } | id instRangeE { $$ = new AstCell($1,*$1,GRAMMARP->m_instModule,NULL,GRAMMARP->m_instParamp->cloneTree(true),$2); $$->trace(GRAMMARP->allTracingOn($1)); } //UNSUP instRangeE '(' cellpinList ')' { UNSUP } // UDP // // Adding above and switching to the Verilog-Perl syntax // // causes a shift conflict due to use of idClassSel inside exprScope. // // It also breaks allowing "id foo;" instantiation syntax. ; instRangeE: /* empty */ { $$ = NULL; } | '[' constExpr ']' { $$ = new AstRange($1,$2,$2->cloneTree(true)); } | '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } ; cellpinList: {VARRESET_LIST(UNKNOWN);} cellpinItList { $$ = $2; VARRESET_NONLIST(UNKNOWN); } ; cellpinItList: // IEEE: list_of_port_connections + list_of_parameter_assignmente cellpinItemE { $$ = $1; } | cellpinItList ',' cellpinItemE { $$ = $1->addNextNull($3)->castPin(); } ; cellpinItemE: // IEEE: named_port_connection + named_parameter_assignment + empty // Note empty can match either () or (,); V3LinkCells cleans up () /* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(),PINNUMINC(),"",NULL); } | yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); } | '.' idSVKwd { $$ = new AstPin($1,PINNUMINC(),*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);} | '.' idAny { $$ = new AstPin($1,PINNUMINC(),*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);} | '.' idAny '(' ')' { $$ = new AstPin($1,PINNUMINC(),*$2,NULL); } // // mintypmax is expanded here, as it might be a UDP or gate primitive | '.' idAny '(' expr ')' { $$ = new AstPin($1,PINNUMINC(),*$2,$4); } //UNSUP '.' idAny '(' expr ':' expr ')' { } //UNSUP '.' idAny '(' expr ':' expr ':' expr ')' { } // // For parameters //UNSUP '.' idAny '(' data_type ')' { PINDONE($1,$2,$4); GRAMMARP->pinNumInc(); } // // For parameters //UNSUP data_type { PINDONE($1->fileline(),"",$1); GRAMMARP->pinNumInc(); } // | expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); } //UNSUP expr ':' expr { } //UNSUP expr ':' expr ':' expr { } ; //************************************************ // EventControl lists attr_event_control: // ==IEEE: event_control '@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); } | '@' '(' '*' ')' { $$ = NULL; } | '@' '*' { $$ = NULL; } ; event_controlE: /* empty */ { $$ = NULL; } | event_control { $$ = $1; } ; event_control: // ==IEEE: event_control '@' '(' event_expression ')' { $$ = new AstSenTree($1,$3); } | '@' '(' '*' ')' { $$ = NULL; } | '@' '*' { $$ = NULL; } // // IEEE: hierarchical_event_identifier | '@' senitemVar { $$ = new AstSenTree($1,$2); } /* For events only */ // // IEEE: sequence_instance // // sequence_instance without parens matches idClassSel above. // // Ambiguity: "'@' sequence (-for-sequence" versus expr:delay_or_event_controlE "'@' id (-for-expr // // For now we avoid this, as it's very unlikely someone would mix // // 1995 delay with a sequence with parameters. // // Alternatively split this out of event_control, and delay_or_event_controlE // // and anywhere delay_or_event_controlE is called allow two expressions //| '@' idClassSel '(' list_of_argumentsE ')' { } ; event_expression: // IEEE: event_expression - split over several senitem { $$ = $1; } | event_expression yOR senitem { $$ = $1->addNextNull($3)->castNodeSenItem(); } | event_expression ',' senitem { $$ = $1->addNextNull($3)->castNodeSenItem(); } /* Verilog 2001 */ ; senitem: // IEEE: part of event_expression, non-'OR' ',' terms senitemEdge { $$ = $1; } | senitemVar { $$ = $1; } | '(' senitemVar ')' { $$ = $2; } //UNSUP expr { UNSUP } | '{' event_expression '}' { $$ = $2; } //UNSUP expr yIFF expr { UNSUP } // Since expr is unsupported we allow and ignore constants (removed in V3Const) | yaINTNUM { $$ = NULL; } | yaFLOATNUM { $$ = NULL; } | '(' yaINTNUM ')' { $$ = NULL; } | '(' yaFLOATNUM ')' { $$ = NULL; } ; senitemVar: idClassSel { $$ = new AstSenItem($1->fileline(),AstEdgeType::ET_ANYEDGE,$1); } ; senitemEdge: // IEEE: part of event_expression yPOSEDGE idClassSel { $$ = new AstSenItem($1,AstEdgeType::ET_POSEDGE,$2); } | yNEGEDGE idClassSel { $$ = new AstSenItem($1,AstEdgeType::ET_NEGEDGE,$2); } | yEDGE idClassSel { $$ = new AstSenItem($1,AstEdgeType::ET_BOTHEDGE,$2); } | yPOSEDGE '(' idClassSel ')' { $$ = new AstSenItem($1,AstEdgeType::ET_POSEDGE,$3); } | yNEGEDGE '(' idClassSel ')' { $$ = new AstSenItem($1,AstEdgeType::ET_NEGEDGE,$3); } | yEDGE '(' idClassSel ')' { $$ = new AstSenItem($1,AstEdgeType::ET_BOTHEDGE,$3); } //UNSUP yIFF... ; //************************************************ // Statements stmtBlock: // IEEE: statement + seq_block + par_block stmt { $$ = $1; } ; seq_block: // ==IEEE: seq_block // // IEEE doesn't allow declarations in unnamed blocks, but several simulators do. // // So need AstBegin's even if unnamed to scope variables down seq_blockFront blockDeclStmtList yEND endLabelE { $$=$1; $1->addStmtsp($2); SYMP->popScope($1); GRAMMARP->endLabel($4,$1,$4); } | seq_blockFront /**/ yEND endLabelE { $$=$1; SYMP->popScope($1); GRAMMARP->endLabel($3,$1,$3); } ; seq_blockFront: // IEEE: part of par_block yBEGIN { $$ = new AstBegin($1,"",NULL); SYMP->pushNew($$); } | yBEGIN ':' idAny/*new-block_identifier*/ { $$ = new AstBegin($1,*$3,NULL); SYMP->pushNew($$); } ; blockDeclStmtList: // IEEE: { block_item_declaration } { statement or null } // // The spec seems to suggest a empty declaration isn't ok, but most simulators take it block_item_declarationList { $$ = $1; } | block_item_declarationList stmtList { $$ = $1->addNextNull($2); } | stmtList { $$ = $1; } ; block_item_declarationList: // IEEE: [ block_item_declaration ] block_item_declaration { $$ = $1; } | block_item_declarationList block_item_declaration { $$ = $1->addNextNull($2); } ; block_item_declaration: // ==IEEE: block_item_declaration data_declaration { $$ = $1; } | local_parameter_declaration ';' { $$ = $1; } | parameter_declaration ';' { $$ = $1; } //UNSUP overload_declaration { $$ = $1; } //UNSUP let_declaration { $$ = $1; } ; stmtList: stmtBlock { $$ = $1; } | stmtList stmtBlock { $$ = ($2==NULL)?($1):($1->addNext($2)); } ; stmt: // IEEE: statement_or_null == function_statement_or_null statement_item { } //UNSUP: Labeling any statement | labeledStmt { $$ = $1; } | id ':' labeledStmt { $$ = new AstBegin($2, *$1, $3); } /*S05 block creation rule*/ // // from _or_null | ';' { $$ = NULL; } ; statement_item: // IEEE: statement_item // // IEEE: operator_assignment foperator_assignment ';' { $$ = $1; } // // // IEEE: blocking_assignment // // 1800-2009 restricts LHS of assignment to new to not have a range // // This is ignored to avoid conflicts //UNSUP fexprLvalue '=' class_new ';' { UNSUP } //UNSUP fexprLvalue '=' dynamic_array_new ';' { UNSUP } // // // IEEE: nonblocking_assignment | fexprLvalue yP_LTE delayE expr ';' { $$ = new AstAssignDly($2,$1,$4); } //UNSUP fexprLvalue yP_LTE delay_or_event_controlE expr ';' { UNSUP } // // // IEEE: procedural_continuous_assignment | yASSIGN idClassSel '=' delayE expr ';' { $$ = new AstAssign($1,$2,$5); } //UNSUP: delay_or_event_controlE above //UNSUP yDEASSIGN variable_lvalue ';' { UNSUP } //UNSUP yFORCE expr '=' expr ';' { UNSUP } //UNSUP yRELEASE variable_lvalue ';' { UNSUP } // // // IEEE: case_statement | unique_priorityE caseStart caseAttrE case_itemListE yENDCASE { $$ = $2; if ($4) $2->addItemsp($4); if ($1 == uniq_UNIQUE) $2->uniquePragma(true); if ($1 == uniq_UNIQUE0) $2->unique0Pragma(true); if ($1 == uniq_PRIORITY) $2->priorityPragma(true); } //UNSUP caseStart caseAttrE yMATCHES case_patternListE yENDCASE { } | unique_priorityE caseStart caseAttrE yINSIDE case_insideListE yENDCASE { $$ = $2; if ($5) $2->addItemsp($5); if (!$2->caseSimple()) $2->v3error("Illegal to have inside on a casex/casez"); $2->caseInsideSet(); if ($1 == uniq_UNIQUE) $2->uniquePragma(true); if ($1 == uniq_UNIQUE0) $2->unique0Pragma(true); if ($1 == uniq_PRIORITY) $2->priorityPragma(true); } // // // IEEE: conditional_statement | unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstIf($2,$4,$6,NULL); if ($1 == uniq_UNIQUE) $$->castIf()->uniquePragma(true); if ($1 == uniq_UNIQUE0) $$->castIf()->unique0Pragma(true); if ($1 == uniq_PRIORITY) $$->castIf()->priorityPragma(true); } | unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstIf($2,$4,$6,$8); if ($1 == uniq_UNIQUE) $$->castIf()->uniquePragma(true); if ($1 == uniq_UNIQUE0) $$->castIf()->unique0Pragma(true); if ($1 == uniq_PRIORITY) $$->castIf()->priorityPragma(true); } // | finc_or_dec_expression ';' { $$ = $1; } // // IEEE: inc_or_dec_expression // // Below under expr // // // IEEE: subroutine_call_statement //UNSUP yVOID yP_TICK '(' function_subroutine_callNoMethod ')' ';' { } //UNSUP yVOID yP_TICK '(' expr '.' function_subroutine_callNoMethod ')' ';' { } // // Expr included here to resolve our not knowing what is a method call // // Expr here must result in a subroutine_call | task_subroutine_callNoMethod ';' { $$ = $1; } //UNSUP fexpr '.' array_methodNoRoot ';' { UNSUP } | fexpr '.' task_subroutine_callNoMethod ';' { $$ = new AstDot($2,$1,$3); } //UNSUP fexprScope ';' { UNSUP } // // Not here in IEEE; from class_constructor_declaration // // Because we've joined class_constructor_declaration into generic functions // // Way over-permissive; // // IEEE: [ ySUPER '.' yNEW [ '(' list_of_arguments ')' ] ';' ] //UNSUP fexpr '.' class_new ';' { } // | statementVerilatorPragmas { $$ = $1; } // // // IEEE: disable_statement | yDISABLE idAny/*hierarchical_identifier-task_or_block*/ ';' { $$ = new AstDisable($1,*$2); } //UNSUP yDISABLE yFORK ';' { UNSUP } // // IEEE: event_trigger //UNSUP yP_MINUSGT hierarchical_identifier/*event*/ ';' { UNSUP } //UNSUP yP_MINUSGTGT delay_or_event_controlE hierarchical_identifier/*event*/ ';' { UNSUP } // // IEEE: loop_statement | yFOREVER stmtBlock { $$ = new AstWhile($1,new AstConst($1,AstConst::LogicTrue()),$2); } | yREPEAT '(' expr ')' stmtBlock { $$ = new AstRepeat($1,$3,$5);} | yWHILE '(' expr ')' stmtBlock { $$ = new AstWhile($1,$3,$5);} // // for's first ';' is in for_initalization | yFOR '(' for_initialization expr ';' for_stepE ')' stmtBlock { $$ = new AstBegin($1,"",$3); $3->addNext(new AstWhile($1, $4,$8,$6)); } | yDO stmtBlock yWHILE '(' expr ')' ';' { $$ = $2->cloneTree(true); $$->addNext(new AstWhile($1,$5,$2));} // // IEEE says array_identifier here, but dotted accepted in VMM and 1800-2009 //UNSUP yFOREACH '(' idClassForeach/*array_id[loop_variables]*/ ')' stmt { UNSUP } // // // IEEE: jump_statement | yRETURN ';' { $$ = new AstReturn($1); } | yRETURN expr ';' { $$ = new AstReturn($1,$2); } | yBREAK ';' { $$ = new AstBreak($1); } | yCONTINUE ';' { $$ = new AstContinue($1); } // //UNSUP par_block { $$ = $1; } // // IEEE: procedural_timing_control_statement + procedural_timing_control | delay_control stmtBlock { $$ = $2; $1->v3warn(STMTDLY,"Unsupported: Ignoring delay on this delayed statement."); } //UNSUP event_control stmtBlock { UNSUP } //UNSUP cycle_delay stmtBlock { UNSUP } // | seq_block { $$ = $1; } // // // IEEE: wait_statement //UNSUP yWAIT '(' expr ')' stmtBlock { UNSUP } //UNSUP yWAIT yFORK ';' { UNSUP } //UNSUP yWAIT_ORDER '(' hierarchical_identifierList ')' action_block { UNSUP } // // // IEEE: procedural_assertion_statement // // Verilator: Label included instead | concurrent_assertion_item { $$ = $1; } // // concurrent_assertion_statement { $$ = $1; } // // Verilator: Part of labeledStmt instead // // immediate_assert_statement { UNSUP } // // // IEEE: clocking_drive ';' // // Pattern w/o cycle_delay handled by nonblocking_assign above // // clockvar_expression made to fexprLvalue to prevent reduce conflict // // Note LTE in this context is highest precedence, so first on left wins //UNSUP cycle_delay fexprLvalue yP_LTE ';' { UNSUP } //UNSUP fexprLvalue yP_LTE cycle_delay expr ';' { UNSUP } // //UNSUP randsequence_statement { $$ = $1; } // // // IEEE: randcase_statement //UNSUP yRANDCASE case_itemList yENDCASE { UNSUP } // //UNSUP expect_property_statement { $$ = $1; } // | error ';' { $$ = NULL; } ; statementVerilatorPragmas: yVL_COVERAGE_BLOCK_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); } ; foperator_assignment: // IEEE: operator_assignment (for first part of expression) fexprLvalue '=' delayE expr { $$ = new AstAssign($2,$1,$4); } | fexprLvalue '=' yD_FOPEN '(' expr ')' { $$ = NULL; $3->v3error("Unsupported: $fopen with multichannel descriptor. Add ,\"w\" as second argument to open a file descriptor."); } | fexprLvalue '=' yD_FOPEN '(' expr ',' expr ')' { $$ = new AstFOpen($3,$1,$5,$7); } // //UNSUP ~f~exprLvalue '=' delay_or_event_controlE expr { UNSUP } //UNSUP ~f~exprLvalue yP_PLUS(etc) expr { UNSUP } | fexprLvalue yP_PLUSEQ expr { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_MINUSEQ expr { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_TIMESEQ expr { $$ = new AstAssign($2,$1,new AstMul ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_DIVEQ expr { $$ = new AstAssign($2,$1,new AstDiv ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_MODEQ expr { $$ = new AstAssign($2,$1,new AstModDiv ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_ANDEQ expr { $$ = new AstAssign($2,$1,new AstAnd ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_OREQ expr { $$ = new AstAssign($2,$1,new AstOr ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_XOREQ expr { $$ = new AstAssign($2,$1,new AstXor ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_SLEFTEQ expr { $$ = new AstAssign($2,$1,new AstShiftL ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_SRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftR ($2,$1->cloneTree(true),$3)); } | fexprLvalue yP_SSRIGHTEQ expr { $$ = new AstAssign($2,$1,new AstShiftRS($2,$1->cloneTree(true),$3)); } ; finc_or_dec_expression: // ==IEEE: inc_or_dec_expression //UNSUP: Generic scopes in incrementes fexprLvalue yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } | fexprLvalue yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2,V3Number($2,"'b1")))); } | yP_PLUSPLUS fexprLvalue { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } | yP_MINUSMINUS fexprLvalue { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1,V3Number($1,"'b1")))); } ; //************************************************ // Case/If unique_priorityE: // IEEE: unique_priority + empty /*empty*/ { $$ = uniq_NONE; } | yPRIORITY { $$ = uniq_PRIORITY; } | yUNIQUE { $$ = uniq_UNIQUE; } | yUNIQUE0 { $$ = uniq_UNIQUE0; } ; caseStart: // IEEE: part of case_statement yCASE '(' expr ')' { $$ = GRAMMARP->m_caseAttrp = new AstCase($1,VCaseType::CT_CASE,$3,NULL); } | yCASEX '(' expr ')' { $$ = GRAMMARP->m_caseAttrp = new AstCase($1,VCaseType::CT_CASEX,$3,NULL); } | yCASEZ '(' expr ')' { $$ = GRAMMARP->m_caseAttrp = new AstCase($1,VCaseType::CT_CASEZ,$3,NULL); } ; caseAttrE: /*empty*/ { } | caseAttrE yVL_FULL_CASE { GRAMMARP->m_caseAttrp->fullPragma(true); } | caseAttrE yVL_PARALLEL_CASE { GRAMMARP->m_caseAttrp->parallelPragma(true); } ; case_itemListE: // IEEE: [ { case_item } ] /* empty */ { $$ = NULL; } | case_itemList { $$ = $1; } ; case_insideListE: // IEEE: [ { case_inside_item } ] /* empty */ { $$ = NULL; } | case_inside_itemList { $$ = $1; } ; case_itemList: // IEEE: { case_item + ... } caseCondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); } | yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($2,NULL,$3); } | yDEFAULT stmtBlock { $$ = new AstCaseItem($1,NULL,$2); } | case_itemList caseCondList ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); } | case_itemList yDEFAULT stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$3)); } | case_itemList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); } ; case_inside_itemList: // IEEE: { case_inside_item + open_range_list ... } open_range_list ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); } | yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($2,NULL,$3); } | yDEFAULT stmtBlock { $$ = new AstCaseItem($1,NULL,$2); } | case_inside_itemList open_range_list ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); } | case_inside_itemList yDEFAULT stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$3)); } | case_inside_itemList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); } ; open_range_list: // ==IEEE: open_range_list + open_value_range open_value_range { $$ = $1; } | open_range_list ',' open_value_range { $$ = $1;$1->addNext($3); } ; open_value_range: // ==IEEE: open_value_range value_range { $$ = $1; } ; value_range: // ==IEEE: value_range expr { $$ = $1; } | '[' expr ':' expr ']' { $$ = new AstInsideRange($3,$2,$4); } ; caseCondList: // IEEE: part of case_item expr { $$ = $1; } | caseCondList ',' expr { $$ = $1;$1->addNext($3); } ; patternNoExpr: // IEEE: pattern **Excluding Expr* '.' id/*variable*/ { $1->v3error("Unsupported: '{} tagged patterns"); $$=NULL; } | yP_DOTSTAR { $1->v3error("Unsupported: '{} tagged patterns"); $$=NULL; } // // IEEE: "expr" excluded; expand in callers // // "yTAGGED id [expr]" Already part of expr //UNSUP yTAGGED id/*member_identifier*/ patternNoExpr { $1->v3error("Unsupported: '{} tagged patterns"); $$=NULL; } // // "yP_TICKBRA patternList '}'" part of expr under assignment_pattern ; patternList: // IEEE: part of pattern patternOne { $$ = $1; } | patternList ',' patternOne { $$ = $1->addNextNull($3); } ; patternOne: // IEEE: part of pattern expr { $$ = new AstPatMember($1->fileline(),$1,NULL,NULL); } | expr '{' argsExprList '}' { $$ = new AstPatMember($2,$3,NULL,$1); } | patternNoExpr { $$ = $1; } ; patternMemberList: // IEEE: part of pattern and assignment_pattern patternMemberOne { $$ = $1; } | patternMemberList ',' patternMemberOne { $$ = $1->addNextNull($3); } ; patternMemberOne: // IEEE: part of pattern and assignment_pattern patternKey ':' expr { $$ = new AstPatMember($2,$3,$1,NULL); } | patternKey ':' patternNoExpr { $2->v3error("Unsupported: '{} .* patterns"); $$=NULL; } // // From assignment_pattern_key | yDEFAULT ':' expr { $$ = new AstPatMember($2,$3,NULL,NULL); $$->isDefault(true); } | yDEFAULT ':' patternNoExpr { $2->v3error("Unsupported: '{} .* patterns"); $$=NULL; } ; patternKey: // IEEE: merge structure_pattern_key, array_pattern_key, assignment_pattern_key // // IEEE: structure_pattern_key // // id/*member*/ is part of constExpr below //UNSUP constExpr { $$ = $1; } // // IEEE: assignment_pattern_key //UNSUP simple_type { $1->v3error("Unsupported: '{} with data type as key"); $$=$1; } // // simple_type reference looks like constExpr // // Verilator: // // The above expressions cause problems because "foo" may be a constant identifier // // (if array) or a reference to the "foo"member (if structure) // // So for now we only allow a true constant number, or a identifier which we treat as a structure member name yaINTNUM { $$ = new AstConst($1,*$1); } | yaFLOATNUM { $$ = new AstConst($1,AstConst::RealDouble(),$1); } | yaID__ETC { $$ = new AstText($1,*$1); } ; assignment_pattern: // ==IEEE: assignment_pattern // This doesn't match the text of the spec. I think a : is missing, or example code needed // yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; } // // "'{ const_expression }" is same as patternList with one entry // // From patternNoExpr // // also IEEE: "''{' expression { ',' expression } '}'" // // matches since patternList includes expr yP_TICKBRA patternList '}' { $$ = new AstPattern($1,$2); } // // From patternNoExpr // // also IEEE "''{' structure_pattern_key ':' ... // // also IEEE "''{' array_pattern_key ':' ... | yP_TICKBRA patternMemberList '}' { $$ = new AstPattern($1,$2); } // // IEEE: Not in grammar, but in VMM | yP_TICKBRA '}' { $1->v3error("Unsupported: Empty '{}"); $$=NULL; } ; // "datatype id = x {, id = x }" | "yaId = x {, id=x}" is legal for_initialization: // ==IEEE: for_initialization + for_variable_declaration + extra terminating ";" // // IEEE: for_variable_declaration data_type idAny/*new*/ '=' expr ';' { VARRESET_NONLIST(VAR); VARDTYPE($1); $$ = VARDONEA($2,*$2,NULL,NULL); $$->addNext(new AstAssign($3,new AstVarRef($3,*$2,true),$4));} | varRefBase '=' expr ';' { $$ = new AstAssign($2,$1,$3); } //UNSUP: List of initializations ; for_stepE: // IEEE: for_step + empty /* empty */ { $$ = NULL; } | for_step { $$ = $1; } ; for_step: // IEEE: for_step //UNSUP: List of steps, instead we keep it simple genvar_iteration { $$ = $1; } ; //************************************************ // Functions/tasks taskRef: // IEEE: part of tf_call id { $$ = new AstTaskRef($1,*$1,NULL); } | id '(' list_of_argumentsE ')' { $$ = new AstTaskRef($1,*$1,$3); } | package_scopeIdFollows id '(' list_of_argumentsE ')' { $$ = AstDot::newIfPkg($2, $1, new AstTaskRef($2,*$2,$4)); } ; funcRef: // IEEE: part of tf_call // // package_scope/hierarchical_... is part of expr, so just need ID // // making-a id-is-a // // ----------------- ------------------ // // tf_call tf_identifier expr (list_of_arguments) // // method_call(post .) function_identifier expr (list_of_arguments) // // property_instance property_identifier property_actual_arg // // sequence_instance sequence_identifier sequence_actual_arg // // let_expression let_identifier let_actual_arg // id '(' list_of_argumentsE ')' { $$ = new AstFuncRef($2, *$1, $3); } | package_scopeIdFollows id '(' list_of_argumentsE ')' { $$ = AstDot::newIfPkg($2, $1, new AstFuncRef($2,*$2,$4)); } //UNSUP: idDotted is really just id to allow dotted method calls ; task_subroutine_callNoMethod: // function_subroutine_callNoMethod (as task) // // IEEE: tf_call taskRef { $$ = $1; } | system_t_call { $$ = $1; } // // IEEE: method_call requires a "." so is in expr //UNSUP randomize_call { $$ = $1; } ; function_subroutine_callNoMethod: // IEEE: function_subroutine_call (as function) // // IEEE: tf_call funcRef { $$ = $1; } | system_f_call { $$ = $1; } // // IEEE: method_call requires a "." so is in expr //UNSUP randomize_call { $$ = $1; } ; system_t_call: // IEEE: system_tf_call (as task) // yaD_IGNORE parenE { $$ = new AstSysIgnore($1,NULL); } | yaD_IGNORE '(' exprList ')' { $$ = new AstSysIgnore($1,$3); } // | yaD_DPI parenE { $$ = new AstTaskRef($1,*$1,NULL); } | yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($2,*$1,$3); GRAMMARP->argWrapList($$->castTaskRef()); } // | yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); } | yD_FCLOSE '(' idClassSel ')' { $$ = new AstFClose($1, $3); } | yD_FFLUSH parenE { $1->v3error("Unsupported: $fflush of all handles does not map to C++."); } | yD_FFLUSH '(' idClassSel ')' { $$ = new AstFFlush($1, $3); } | yD_FINISH parenE { $$ = new AstFinish($1); } | yD_FINISH '(' expr ')' { $$ = new AstFinish($1); DEL($3); } | yD_STOP parenE { $$ = new AstStop($1); } | yD_STOP '(' expr ')' { $$ = new AstStop($1); DEL($3); } // | yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); } | yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); } | yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1,$3); } // | yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"", NULL,NULL); } | yD_DISPLAY '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$3,NULL,$4); } | yD_WRITE parenE { $$ = NULL; } // NOP | yD_WRITE '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$3,NULL,$4); } | yD_FDISPLAY '(' idClassSel ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"",$3,NULL); } | yD_FDISPLAY '(' idClassSel ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$5,$3,$6); } | yD_FWRITE '(' idClassSel ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, *$5,$3,$6); } | yD_INFO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, "", NULL,NULL); } | yD_INFO '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, *$3,NULL,$4); } | yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING,"", NULL,NULL); } | yD_WARNING '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING,*$3,NULL,$4); } | yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); } | yD_ERROR '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); } | yD_FATAL parenE { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); } | yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); DEL($3); } | yD_FATAL '(' expr ',' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); DEL($3); } // | yD_READMEMB '(' expr ',' idClassSel ')' { $$ = new AstReadMem($1,false,$3,$5,NULL,NULL); } | yD_READMEMB '(' expr ',' idClassSel ',' expr ')' { $$ = new AstReadMem($1,false,$3,$5,$7,NULL); } | yD_READMEMB '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstReadMem($1,false,$3,$5,$7,$9); } | yD_READMEMH '(' expr ',' idClassSel ')' { $$ = new AstReadMem($1,true, $3,$5,NULL,NULL); } | yD_READMEMH '(' expr ',' idClassSel ',' expr ')' { $$ = new AstReadMem($1,true, $3,$5,$7,NULL); } | yD_READMEMH '(' expr ',' idClassSel ',' expr ',' expr ')' { $$ = new AstReadMem($1,true, $3,$5,$7,$9); } ; system_f_call: // IEEE: system_tf_call (as func) yaD_IGNORE parenE { $$ = new AstConst($1,V3Number($1,"'b0")); } // Unsized 0 | yaD_IGNORE '(' exprList ')' { $$ = new AstConst($2,V3Number($2,"'b0")); } // Unsized 0 // | yaD_DPI parenE { $$ = new AstFuncRef($1,*$1,NULL); } | yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); GRAMMARP->argWrapList($$->castFuncRef()); } // | yD_BITS '(' data_type ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); } | yD_BITS '(' data_type ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3,$5); } | yD_BITS '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3); } | yD_BITS '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_BITS,$3,$5); } | yD_BITSTOREAL '(' expr ')' { $$ = new AstBitsToRealD($1,$3); } | yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); } | yD_CEIL '(' expr ')' { $$ = new AstCeilD($1,$3); } | yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); } | yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes($1,$3); } | yD_DIMENSIONS '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_DIMENSIONS,$3); } | yD_EXP '(' expr ')' { $$ = new AstExpD($1,$3); } | yD_FEOF '(' expr ')' { $$ = new AstFEof($1,$3); } | yD_FGETC '(' expr ')' { $$ = new AstFGetC($1,$3); } | yD_FGETS '(' idClassSel ',' expr ')' { $$ = new AstFGetS($1,$3,$5); } | yD_FLOOR '(' expr ')' { $$ = new AstFloorD($1,$3); } | yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF($1,*$5,$3,$6); } | yD_HIGH '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,NULL); } | yD_HIGH '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_HIGH,$3,$5); } | yD_INCREMENT '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,NULL); } | yD_INCREMENT '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,$5); } | yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); } | yD_ITOR '(' expr ')' { $$ = new AstIToRD($1,$3); } | yD_LEFT '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LEFT,$3,NULL); } | yD_LEFT '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LEFT,$3,$5); } | yD_LN '(' expr ')' { $$ = new AstLogD($1,$3); } | yD_LOG10 '(' expr ')' { $$ = new AstLog10D($1,$3); } | yD_LOW '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LOW,$3,NULL); } | yD_LOW '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LOW,$3,$5); } | yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); } | yD_ONEHOT0 '(' expr ')' { $$ = new AstOneHot0($1,$3); } | yD_POW '(' expr ',' expr ')' { $$ = new AstPowD($1,$3,$5); } | yD_RANDOM '(' expr ')' { $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); } | yD_RANDOM parenE { $$ = new AstRand($1); } | yD_REALTIME parenE { $$ = new AstTimeD($1); } | yD_REALTOBITS '(' expr ')' { $$ = new AstRealToBits($1,$3); } | yD_RIGHT '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_RIGHT,$3,NULL); } | yD_RIGHT '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_RIGHT,$3,$5); } | yD_RTOI '(' expr ')' { $$ = new AstRToIS($1,$3); } //| yD_SFORMATF '(' str commaEListE ')' { $$ = new AstSFormatF($1,*$3,false,$4); } // Have AST, just need testing and debug | yD_SIGNED '(' expr ')' { $$ = new AstSigned($1,$3); } | yD_SIZE '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_SIZE,$3,NULL); } | yD_SIZE '(' expr ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_SIZE,$3,$5); } | yD_SQRT '(' expr ')' { $$ = new AstSqrtD($1,$3); } | yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF($1,*$5,$3,$6); } | yD_STIME parenE { $$ = new AstSel($1,new AstTime($1),0,32); } | yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); } | yD_TESTPLUSARGS '(' str ')' { $$ = new AstTestPlusArgs($1,*$3); } | yD_TIME parenE { $$ = new AstTime($1); } | yD_UNPACKED_DIMENSIONS '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_UNPK_DIMENSIONS,$3); } | yD_UNSIGNED '(' expr ')' { $$ = new AstUnsigned($1,$3); } | yD_VALUEPLUSARGS '(' str ',' expr ')' { $$ = new AstValuePlusArgs($1,*$3,$5); } ; list_of_argumentsE: // IEEE: [list_of_arguments] argsDottedList { $$ = $1; } | argsExprListE { if ($1->castArg() && $1->castArg()->emptyConnectNoNext()) { $1->deleteTree(); $$ = NULL; } // Mis-created when have 'func()' /*cont*/ else $$ = $1; } | argsExprListE ',' argsDottedList { $$ = $1->addNextNull($3); } ; task_declaration: // ==IEEE: task_declaration yTASK lifetimeE taskId tfGuts yENDTASK endLabelE { $$ = $3; $$->addStmtsp($4); SYMP->popScope($$); GRAMMARP->endLabel($6,$$,$6); } ; task_prototype: // ==IEEE: task_prototype yTASK taskId '(' tf_port_listE ')' { $$=$2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); } ; function_declaration: // IEEE: function_declaration + function_body_declaration yFUNCTION lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE { $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5); SYMP->popScope($$); GRAMMARP->endLabel($7,$$,$7); } ; function_prototype: // IEEE: function_prototype yFUNCTION funcId '(' tf_port_listE ')' { $$=$2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); } ; funcIsolateE: /* empty */ { $$ = 0; } | yVL_ISOLATE_ASSIGNMENTS { $$ = 1; } ; method_prototype: task_prototype { } | function_prototype { } ; lifetimeE: // IEEE: [lifetime] /* empty */ { } | lifetime { } ; lifetime: // ==IEEE: lifetime // // Note lifetime used by members is instead under memberQual ySTATIC { $1->v3error("Unsupported: Static in this context"); } | yAUTOMATIC { } ; taskId: tfIdScoped { $$ = new AstTask($1, *$1, NULL); SYMP->pushNewUnder($$, NULL); } ; funcId: // IEEE: function_data_type_or_implicit + part of function_body_declaration // // IEEE: function_data_type_or_implicit must be expanded here to prevent conflict // // function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID /**/ tfIdScoped { $$ = new AstFunc ($1,*$1,NULL, new AstBasicDType($1, LOGIC_IMPLICIT)); SYMP->pushNewUnder($$, NULL); } | signingE rangeList tfIdScoped { $$ = new AstFunc ($3,*$3,NULL, GRAMMARP->addRange(new AstBasicDType($3, LOGIC_IMPLICIT, $1), $2,true)); SYMP->pushNewUnder($$, NULL); } | signing tfIdScoped { $$ = new AstFunc ($2,*$2,NULL, new AstBasicDType($2, LOGIC_IMPLICIT, $1)); SYMP->pushNewUnder($$, NULL); } | data_type tfIdScoped { $$ = new AstFunc ($2,*$2,NULL,$1); SYMP->pushNewUnder($$, NULL); } // // To verilator tasks are the same as void functions (we separately detect time passing) | yVOID tfIdScoped { $$ = new AstTask ($2,*$2,NULL); SYMP->pushNewUnder($$, NULL); } ; tfIdScoped: // IEEE: part of function_body_declaration/task_body_declaration // // IEEE: [ interface_identifier '.' | class_scope ] function_identifier id { $$=$1; $$ = $1; } //UNSUP id/*interface_identifier*/ '.' id { UNSUP } //UNSUP class_scope_id { UNSUP } ; tfGuts: '(' tf_port_listE ')' ';' tfBodyE { $$ = $2->addNextNull($5); } | ';' tfBodyE { $$ = $2; } ; tfBodyE: // IEEE: part of function_body_declaration/task_body_declaration /* empty */ { $$ = NULL; } | tf_item_declarationList { $$ = $1; } | tf_item_declarationList stmtList { $$ = $1->addNextNull($2); } | stmtList { $$ = $1; } ; tf_item_declarationList: tf_item_declaration { $$ = $1; } | tf_item_declarationList tf_item_declaration { $$ = $1->addNextNull($2); } ; tf_item_declaration: // ==IEEE: tf_item_declaration block_item_declaration { $$ = $1; } | tf_port_declaration { $$ = $1; } | tf_item_declarationVerilator { $$ = $1; } ; tf_item_declarationVerilator: // Verilator extensions yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); v3Global.dpi(true); } | yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); } ; tf_port_listE: // IEEE: tf_port_list + empty // // Empty covered by tf_port_item {VARRESET_LIST(UNKNOWN); VARIO(INPUT); } tf_port_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); } ; tf_port_listList: // IEEE: part of tf_port_list tf_port_item { $$ = $1; } | tf_port_listList ',' tf_port_item { $$ = $1->addNextNull($3); } ; tf_port_item: // ==IEEE: tf_port_item // // We split tf_port_item into the type and assignment as don't know what follows a comma /* empty */ { $$ = NULL; PINNUMINC(); } // For example a ",," port | tf_port_itemFront tf_port_itemAssignment { $$ = $2; } | tf_port_itemAssignment { $$ = $1; } ; tf_port_itemFront: // IEEE: part of tf_port_item, which has the data type data_type { VARDTYPE($1); } | signingE rangeList { VARDTYPE(GRAMMARP->addRange(new AstBasicDType($2->fileline(), LOGIC_IMPLICIT, $1), $2, true)); } | signing { VARDTYPE(new AstBasicDType($1, LOGIC_IMPLICIT, $1)); } | yVAR data_type { VARDTYPE($2); } | yVAR implicit_typeE { VARDTYPE($2); } // | tf_port_itemDir /*implicit*/ { VARDTYPE(NULL); /*default_nettype-see spec*/ } | tf_port_itemDir data_type { VARDTYPE($2); } | tf_port_itemDir signingE rangeList { VARDTYPE(GRAMMARP->addRange(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $2),$3,true)); } | tf_port_itemDir signing { VARDTYPE(new AstBasicDType($2, LOGIC_IMPLICIT, $2)); } | tf_port_itemDir yVAR data_type { VARDTYPE($3); } | tf_port_itemDir yVAR implicit_typeE { VARDTYPE($3); } ; tf_port_itemDir: // IEEE: part of tf_port_item, direction port_direction { } // port_direction sets VARIO ; tf_port_itemAssignment: // IEEE: part of tf_port_item, which has assignment id variable_dimensionListE sigAttrListE { $$ = VARDONEA($1, *$1, $2, $3); } | id variable_dimensionListE sigAttrListE '=' expr { $$ = VARDONEA($1, *$1, $2, $3); $$->valuep($5); } ; parenE: /* empty */ { } | '(' ')' { } ; // method_call: // ==IEEE: method_call + method_call_body // // IEEE: method_call_root '.' method_identifier [ '(' list_of_arguments ')' ] // // "method_call_root '.' method_identifier" looks just like "expr '.' id" // // "method_call_root '.' method_identifier (...)" looks just like "expr '.' tf_call" // // IEEE: built_in_method_call // // method_call_root not needed, part of expr resolution // // What's left is below array_methodNoRoot dpi_import_export: // ==IEEE: dpi_import_export yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE function_prototype ';' { $$ = $5; if (*$4!="") $5->cname(*$4); $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE); $5->dpiImport(true); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); if ($$->prettyName()[0]=='$') SYMP->reinsert($$,NULL,$$->prettyName()); // For $SysTF overriding SYMP->reinsert($$); } | yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE task_prototype ';' { $$ = $5; if (*$4!="") $5->cname(*$4); $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE); $5->dpiImport(true); $5->dpiTask(true); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); if ($$->prettyName()[0]=='$') SYMP->reinsert($$,NULL,$$->prettyName()); // For $SysTF overriding SYMP->reinsert($$); } | yEXPORT yaSTRING dpi_importLabelE yFUNCTION idAny ';' { $$ = new AstDpiExport($1,*$5,*$3); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); } | yEXPORT yaSTRING dpi_importLabelE yTASK idAny ';' { $$ = new AstDpiExport($1,*$5,*$3); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); } ; dpi_importLabelE: // IEEE: part of dpi_import_export /* empty */ { static string s = ""; $$ = &s; } | idAny/*c_identifier*/ '=' { $$ = $1; $$=$1; } ; dpi_tf_import_propertyE: // IEEE: [ dpi_function_import_property + dpi_task_import_property ] /* empty */ { $$ = iprop_NONE; } | yCONTEXT { $$ = iprop_CONTEXT; } | yPURE { $$ = iprop_PURE; } ; //************************************************ // Expressions // // ~l~ means this is the (l)eft hand side of any operator // it will get replaced by "", "f" or "s"equence // ~r~ means this is a (r)ight hand later expansion in the same statement, // not under parenthesis for <= disambiguation // it will get replaced by "", or "f" // ~p~ means this is a (p)arenthetized expression // it will get replaced by "", or "s"equence constExpr: expr { $$ = $1; } ; expr: // IEEE: part of expression/constant_expression/primary // *SEE BELOW* // IEEE: primary/constant_primary // // // IEEE: unary_operator primary '+' ~r~expr %prec prUNARYARITH { $$ = $2; } | '-' ~r~expr %prec prUNARYARITH { $$ = new AstNegate ($1,$2); } | '!' ~r~expr %prec prNEGATION { $$ = new AstLogNot ($1,$2); } | '&' ~r~expr %prec prREDUCTION { $$ = new AstRedAnd ($1,$2); } | '~' ~r~expr %prec prNEGATION { $$ = new AstNot ($1,$2); } | '|' ~r~expr %prec prREDUCTION { $$ = new AstRedOr ($1,$2); } | '^' ~r~expr %prec prREDUCTION { $$ = new AstRedXor ($1,$2); } | yP_NAND ~r~expr %prec prREDUCTION { $$ = new AstLogNot($1,new AstRedAnd($1,$2)); } | yP_NOR ~r~expr %prec prREDUCTION { $$ = new AstLogNot($1,new AstRedOr ($1,$2)); } | yP_XNOR ~r~expr %prec prREDUCTION { $$ = new AstRedXnor ($1,$2); } // // // IEEE: inc_or_dec_expression //UNSUP ~l~inc_or_dec_expression { UNSUP } // // // IEEE: '(' operator_assignment ')' // // Need exprScope of variable_lvalue to prevent conflict //UNSUP '(' ~p~exprScope '=' expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_PLUSEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_MINUSEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_TIMESEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_DIVEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_MODEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_ANDEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_OREQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_XOREQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_SLEFTEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_SRIGHTEQ expr ')' { UNSUP } //UNSUP '(' ~p~exprScope yP_SSRIGHTEQ expr ')' { UNSUP } // // // IEEE: expression binary_operator expression | ~l~expr '+' ~r~expr { $$ = new AstAdd ($2,$1,$3); } | ~l~expr '-' ~r~expr { $$ = new AstSub ($2,$1,$3); } | ~l~expr '*' ~r~expr { $$ = new AstMul ($2,$1,$3); } | ~l~expr '/' ~r~expr { $$ = new AstDiv ($2,$1,$3); } | ~l~expr '%' ~r~expr { $$ = new AstModDiv ($2,$1,$3); } | ~l~expr yP_EQUAL ~r~expr { $$ = new AstEq ($2,$1,$3); } | ~l~expr yP_NOTEQUAL ~r~expr { $$ = new AstNeq ($2,$1,$3); } | ~l~expr yP_CASEEQUAL ~r~expr { $$ = new AstEqCase ($2,$1,$3); } | ~l~expr yP_CASENOTEQUAL ~r~expr { $$ = new AstNeqCase ($2,$1,$3); } | ~l~expr yP_WILDEQUAL ~r~expr { $$ = new AstEqWild ($2,$1,$3); } | ~l~expr yP_WILDNOTEQUAL ~r~expr { $$ = new AstNeqWild ($2,$1,$3); } | ~l~expr yP_ANDAND ~r~expr { $$ = new AstLogAnd ($2,$1,$3); } | ~l~expr yP_OROR ~r~expr { $$ = new AstLogOr ($2,$1,$3); } | ~l~expr yP_POW ~r~expr { $$ = new AstPow ($2,$1,$3); } | ~l~expr '<' ~r~expr { $$ = new AstLt ($2,$1,$3); } | ~l~expr '>' ~r~expr { $$ = new AstGt ($2,$1,$3); } | ~l~expr yP_GTE ~r~expr { $$ = new AstGte ($2,$1,$3); } | ~l~expr '&' ~r~expr { $$ = new AstAnd ($2,$1,$3); } | ~l~expr '|' ~r~expr { $$ = new AstOr ($2,$1,$3); } | ~l~expr '^' ~r~expr { $$ = new AstXor ($2,$1,$3); } | ~l~expr yP_XNOR ~r~expr { $$ = new AstXnor ($2,$1,$3); } | ~l~expr yP_NOR ~r~expr { $$ = new AstNot($2,new AstOr ($2,$1,$3)); } | ~l~expr yP_NAND ~r~expr { $$ = new AstNot($2,new AstAnd ($2,$1,$3)); } | ~l~expr yP_SLEFT ~r~expr { $$ = new AstShiftL ($2,$1,$3); } | ~l~expr yP_SRIGHT ~r~expr { $$ = new AstShiftR ($2,$1,$3); } | ~l~expr yP_SSRIGHT ~r~expr { $$ = new AstShiftRS ($2,$1,$3); } // // <= is special, as we need to disambiguate it with <= assignment // // We copy all of expr to fexpr and rename this token to a fake one. | ~l~expr yP_LTE~f__IGNORE~ ~r~expr { $$ = new AstLte ($2,$1,$3); } // // // IEEE: conditional_expression | ~l~expr '?' ~r~expr ':' ~r~expr { $$ = new AstCond($2,$1,$3,$5); } // // // IEEE: inside_expression | ~l~expr yINSIDE '{' open_range_list '}' { $$ = new AstInside($2,$1,$4); } // // // IEEE: tagged_union_expression //UNSUP yTAGGED id/*member*/ %prec prTAGGED { UNSUP } //UNSUP yTAGGED id/*member*/ %prec prTAGGED expr { UNSUP } // //======================// PSL expressions // | ~l~expr yP_MINUSGT ~r~expr { $$ = new AstLogIf ($2,$1,$3); } | ~l~expr yP_LOGIFF ~r~expr { $$ = new AstLogIff ($2,$1,$3); } // //======================// IEEE: primary/constant_primary // // // IEEE: primary_literal (minus string, which is handled specially) | yaINTNUM { $$ = new AstConst($1,*$1); } | yaFLOATNUM { $$ = new AstConst($1,AstConst::RealDouble(),$1); } //UNSUP yaTIMENUM { UNSUP } | strAsInt~noStr__IGNORE~ { $$ = $1; } // // // IEEE: "... hierarchical_identifier select" see below // // // IEEE: empty_queue //UNSUP '{' '}' // // // IEEE: concatenation/constant_concatenation // // Part of exprOkLvalue below // // // IEEE: multiple_concatenation/constant_multiple_concatenation | '{' constExpr '{' cateList '}' '}' { $$ = new AstReplicate($1,$4,$2); } // | function_subroutine_callNoMethod { $$ = $1; } // // method_call | ~l~expr '.' function_subroutine_callNoMethod { $$ = new AstDot($2,$1,$3); } // // method_call:array_method requires a '.' //UNSUP ~l~expr '.' array_methodNoRoot { UNSUP } // // // IEEE: let_expression // // see funcRef // // // IEEE: '(' mintypmax_expression ')' | ~noPar__IGNORE~'(' expr ')' { $$ = $2; } //UNSUP ~noPar__IGNORE~'(' expr ':' expr ':' expr ')' { $$ = $4; } // // PSL rule | '_' '(' expr ')' { $$ = $3; } // Arbitrary Verilog inside PSL // // // IEEE: cast/constant_cast | casting_type yP_TICK '(' expr ')' { $$ = new AstCast($2,$4,$1); } // // expanded from casting_type | ySIGNED yP_TICK '(' expr ')' { $$ = new AstSigned($1,$4); } | yUNSIGNED yP_TICK '(' expr ')' { $$ = new AstUnsigned($1,$4); } // // Spec only allows primary with addition of a type reference // // We'll be more general, and later assert LHS was a type. | ~l~expr yP_TICK '(' expr ')' { $$ = new AstCastParse($2,$4,$1); } // // // IEEE: assignment_pattern_expression // // IEEE: streaming_concatenation // // See exprOkLvalue // // // IEEE: sequence_method_call // // Indistinguishable from function_subroutine_call:method_call // //UNSUP '$' { UNSUP } //UNSUP yNULL { UNSUP } // // IEEE: yTHIS // // See exprScope // //---------------------- // // // Part of expr that may also be used as lvalue | ~l~exprOkLvalue { $$ = $1; } // //---------------------- // // // IEEE: cond_predicate - here to avoid reduce problems // // Note expr includes cond_pattern //UNSUP ~l~expr yP_ANDANDAND ~r~expr { UNSUP } // // // IEEE: cond_pattern - here to avoid reduce problems // // "expr yMATCHES pattern" // // IEEE: pattern - expanded here to avoid conflicts //UNSUP ~l~expr yMATCHES patternNoExpr { UNSUP } //UNSUP ~l~expr yMATCHES ~r~expr { UNSUP } // // // IEEE: expression_or_dist - here to avoid reduce problems // // "expr yDIST '{' dist_list '}'" //UNSUP ~l~expr yDIST '{' dist_list '}' { UNSUP } ; fexpr: // For use as first part of statement (disambiguates <=) BISONPRE_COPY(expr,{s/~l~/f/g; s/~r~/f/g; s/~f__IGNORE~/__IGNORE/g;}) // {copied} ; exprNoStr: // expression with string removed BISONPRE_COPY(expr,{s/~noStr__IGNORE~/Ignore/g;}) // {copied} ; exprOkLvalue: // expression that's also OK to use as a variable_lvalue ~l~exprScope { $$ = $1; } // // IEEE: concatenation/constant_concatenation // // Replicate(1) required as otherwise "{a}" would not be self-determined | '{' cateList '}' { $$ = new AstReplicate($1,$2,1); } // // IEEE: assignment_pattern_expression // // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type] // // We allow more here than the spec requires //UNSUP ~l~exprScope assignment_pattern { UNSUP } | data_type assignment_pattern { $$ = $2; $2->childDTypep($1); } | assignment_pattern { $$ = $1; } // | streaming_concatenation { $$ = $1; } ; fexprOkLvalue: // exprOkLValue, For use as first part of statement (disambiguates <=) BISONPRE_COPY(exprOkLvalue,{s/~l~/f/g}) // {copied} ; fexprLvalue: // For use as first part of statement (disambiguates <=) fexprOkLvalue { $$=$1; $$ = $1; } ; exprScope: // scope and variable for use to inside an expression // // Here we've split method_call_root | implicit_class_handle | class_scope | package_scope // // from the object being called and let expr's "." deal with resolving it. // // (note method_call_root was simplified to require a primary in 1800-2009) // // // IEEE: [ implicit_class_handle . | class_scope | package_scope ] hierarchical_identifier select // // Or method_call_body without parenthesis // // See also varRefClassBit, which is the non-expr version of most of this //UNSUP yTHIS { UNSUP } idArrayed { $$ = $1; } | package_scopeIdFollows idArrayed { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); } //UNSUP class_scopeIdFollows idArrayed { UNSUP } | ~l~expr '.' idArrayed { $$ = new AstDot($2,$1,$3); } // // expr below must be a "yTHIS" //UNSUP ~l~expr '.' ySUPER { UNSUP } // // Part of implicit_class_handle //UNSUP ySUPER { UNSUP } ; fexprScope: // exprScope, For use as first part of statement (disambiguates <=) BISONPRE_COPY(exprScope,{s/~l~/f/g}) // {copied} ; // PLI calls exclude "" as integers, they're strings // For $c("foo","bar") we want "bar" as a string, not a Verilog integer. exprStrText: exprNoStr { $$ = $1; } | strAsText { $$ = $1; } ; cStrList: exprStrText { $$ = $1; } | exprStrText ',' cStrList { $$ = $1;$1->addNext($3); } ; cateList: // // Not just 'expr' to prevent conflict via stream_concOrExprOrType stream_expression { $$ = $1; } | cateList ',' stream_expression { $$ = new AstConcat($2,$1,$3); } ; exprList: expr { $$ = $1; } | exprList ',' expr { $$ = $1;$1->addNext($3); } ; commaEListE: /* empty */ { $$ = NULL; } | ',' exprList { $$ = $2; } ; vrdList: idClassSel { $$ = $1; } | vrdList ',' idClassSel { $$ = $1;$1->addNext($3); } ; commaVRDListE: /* empty */ { $$ = NULL; } | ',' vrdList { $$ = $2; } ; argsExprList: // IEEE: part of list_of_arguments (used where ,, isn't legal) expr { $$ = $1; } | argsExprList ',' expr { $$ = $1->addNext($3); } ; argsExprListE: // IEEE: part of list_of_arguments argsExprOneE { $$ = $1; } | argsExprListE ',' argsExprOneE { $$ = $1->addNext($3); } ; argsExprOneE: // IEEE: part of list_of_arguments /*empty*/ { $$ = new AstArg(CRELINE(),"",NULL); } | expr { $$ = new AstArg(CRELINE(),"",$1); } ; argsDottedList: // IEEE: part of list_of_arguments argsDotted { $$ = $1; } | argsDottedList ',' argsDotted { $$ = $1->addNextNull($3); } ; argsDotted: // IEEE: part of list_of_arguments '.' idAny '(' ')' { $$ = new AstArg($1,*$2,NULL); } | '.' idAny '(' expr ')' { $$ = new AstArg($1,*$2,$4); } ; streaming_concatenation: // ==IEEE: streaming_concatenation // // Need to disambiguate {<< expr-{ ... expr-} stream_concat } // // From {<< stream-{ ... stream-} } // // Likewise simple_type's idScoped from constExpr's idScope // // Thus we allow always any two operations. Sorry // // IEEE: "'{' yP_SL/R stream_concatenation '}'" // // IEEE: "'{' yP_SL/R simple_type stream_concatenation '}'" // // IEEE: "'{' yP_SL/R constExpr stream_concatenation '}'" '{' yP_SLEFT stream_concOrExprOrType '}' { $$ = new AstStreamL($1, $3, new AstConst($1,1)); } | '{' yP_SRIGHT stream_concOrExprOrType '}' { $$ = new AstStreamR($1, $3, new AstConst($1,1)); } | '{' yP_SLEFT stream_concOrExprOrType stream_concatenation '}' { $$ = new AstStreamL($1, $4, $3); } | '{' yP_SRIGHT stream_concOrExprOrType stream_concatenation '}' { $$ = new AstStreamR($1, $4, $3); } ; stream_concOrExprOrType: // IEEE: stream_concatenation | slice_size:simple_type | slice_size:constExpr cateList { $$ = $1; } | simple_type { $$ = $1; } // // stream_concatenation found via cateList:stream_expr:'{-normal-concat' // // simple_typeRef found via cateList:stream_expr:expr:id // // constant_expression found via cateList:stream_expr:expr ; stream_concatenation: // ==IEEE: stream_concatenation '{' cateList '}' { $$ = $2; } ; stream_expression: // ==IEEE: stream_expression // // IEEE: array_range_expression expanded below expr { $$ = $1; } //UNSUP expr yWITH__BRA '[' expr ']' { UNSUP } //UNSUP expr yWITH__BRA '[' expr ':' expr ']' { UNSUP } //UNSUP expr yWITH__BRA '[' expr yP_PLUSCOLON expr ']' { UNSUP } //UNSUP expr yWITH__BRA '[' expr yP_MINUSCOLON expr ']' { UNSUP } ; //************************************************ // Gate declarations gateDecl: yBUF delayE gateBufList ';' { $$ = $3; } | yBUFIF0 delayE gateBufif0List ';' { $$ = $3; } | yBUFIF1 delayE gateBufif1List ';' { $$ = $3; } | yNOT delayE gateNotList ';' { $$ = $3; } | yNOTIF0 delayE gateNotif0List ';' { $$ = $3; } | yNOTIF1 delayE gateNotif1List ';' { $$ = $3; } | yAND delayE gateAndList ';' { $$ = $3; } | yNAND delayE gateNandList ';' { $$ = $3; } | yOR delayE gateOrList ';' { $$ = $3; } | yNOR delayE gateNorList ';' { $$ = $3; } | yXOR delayE gateXorList ';' { $$ = $3; } | yXNOR delayE gateXnorList ';' { $$ = $3; } | yPULLUP delayE gatePullupList ';' { $$ = $3; } | yPULLDOWN delayE gatePulldownList ';' { $$ = $3; } | yNMOS delayE gateBufif1List ';' { $$ = $3; } // ~=bufif1, as don't have strengths yet | yPMOS delayE gateBufif0List ';' { $$ = $3; } // ~=bufif0, as don't have strengths yet // | yTRAN delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tran"); } // Unsupported | yRCMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rcmos"); } // Unsupported | yCMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"cmos"); } // Unsupported | yRNMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rmos"); } // Unsupported | yRPMOS delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"pmos"); } // Unsupported | yRTRAN delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtran"); } // Unsupported | yRTRANIF0 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtranif0"); } // Unsupported | yRTRANIF1 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"rtranif1"); } // Unsupported | yTRANIF0 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tranif0"); } // Unsupported | yTRANIF1 delayE gateUnsupList ';' { $$ = $3; GATEUNSUP($3,"tranif1"); } // Unsupported ; gateBufList: gateBuf { $$ = $1; } | gateBufList ',' gateBuf { $$ = $1->addNext($3); } ; gateBufif0List: gateBufif0 { $$ = $1; } | gateBufif0List ',' gateBufif0 { $$ = $1->addNext($3); } ; gateBufif1List: gateBufif1 { $$ = $1; } | gateBufif1List ',' gateBufif1 { $$ = $1->addNext($3); } ; gateNotList: gateNot { $$ = $1; } | gateNotList ',' gateNot { $$ = $1->addNext($3); } ; gateNotif0List: gateNotif0 { $$ = $1; } | gateNotif0List ',' gateNotif0 { $$ = $1->addNext($3); } ; gateNotif1List: gateNotif1 { $$ = $1; } | gateNotif1List ',' gateNotif1 { $$ = $1->addNext($3); } ; gateAndList: gateAnd { $$ = $1; } | gateAndList ',' gateAnd { $$ = $1->addNext($3); } ; gateNandList: gateNand { $$ = $1; } | gateNandList ',' gateNand { $$ = $1->addNext($3); } ; gateOrList: gateOr { $$ = $1; } | gateOrList ',' gateOr { $$ = $1->addNext($3); } ; gateNorList: gateNor { $$ = $1; } | gateNorList ',' gateNor { $$ = $1->addNext($3); } ; gateXorList: gateXor { $$ = $1; } | gateXorList ',' gateXor { $$ = $1->addNext($3); } ; gateXnorList: gateXnor { $$ = $1; } | gateXnorList ',' gateXnor { $$ = $1->addNext($3); } ; gatePullupList: gatePullup { $$ = $1; } | gatePullupList ',' gatePullup { $$ = $1->addNext($3); } ; gatePulldownList: gatePulldown { $$ = $1; } | gatePulldownList ',' gatePulldown { $$ = $1->addNext($3); } ; gateUnsupList: gateUnsup { $$ = $1; } | gateUnsupList ',' gateUnsup { $$ = $1->addNext($3); } ; gateRangeE: instRangeE { $$ = $1; GATERANGE($1); } ; gateBuf: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateBufif0: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8),$6)); DEL($2); } ; gateBufif1: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8,$6)); DEL($2); } ; gateNot: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateNotif0: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,new AstNot($3,$8), new AstNot($3, $6))); DEL($2); } ; gateNotif1: gateIdE gateRangeE '(' variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW ($3,$4,new AstBufIf1($3,$8, new AstNot($3,$6))); DEL($2); } ; gateAnd: gateIdE gateRangeE '(' variable_lvalue ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateNand: gateIdE gateRangeE '(' variable_lvalue ',' gateAndPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateOr: gateIdE gateRangeE '(' variable_lvalue ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateNor: gateIdE gateRangeE '(' variable_lvalue ',' gateOrPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gateXor: gateIdE gateRangeE '(' variable_lvalue ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,$6); DEL($2); } ; gateXnor: gateIdE gateRangeE '(' variable_lvalue ',' gateXorPinList ')' { $$ = new AstAssignW ($3,$4,new AstNot($5,$6)); DEL($2); } ; gatePullup: gateIdE gateRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, true); DEL($2); } ; gatePulldown: gateIdE gateRangeE '(' variable_lvalue ')' { $$ = new AstPull ($3, $4, false); DEL($2); } ; gateUnsup: gateIdE gateRangeE '(' gateUnsupPinList ')' { $$ = new AstImplicit ($3,$4); DEL($2); } ; gateIdE: /*empty*/ {} | id {} ; gateAndPinList: gatePinExpr { $$ = $1; } | gateAndPinList ',' gatePinExpr { $$ = new AstAnd($2,$1,$3); } ; gateOrPinList: gatePinExpr { $$ = $1; } | gateOrPinList ',' gatePinExpr { $$ = new AstOr($2,$1,$3); } ; gateXorPinList: gatePinExpr { $$ = $1; } | gateXorPinList ',' gatePinExpr { $$ = new AstXor($2,$1,$3); } ; gateUnsupPinList: gatePinExpr { $$ = $1; } | gateUnsupPinList ',' gatePinExpr { $$ = $1->addNext($3); } ; gatePinExpr: expr { $$ = GRAMMARP ->createGatePin($1); } ; strengthSpecE: // IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty /* empty */ { } //UNSUP strengthSpec { } ; //************************************************ // Tables combinational_body: // IEEE: combinational_body + sequential_body yTABLE tableEntryList yENDTABLE { $$ = new AstUdpTable($1,$2); } ; tableEntryList: // IEEE: { combinational_entry | sequential_entry } tableEntry { $$ = $1; } | tableEntryList tableEntry { $$ = $1->addNext($2); } ; tableEntry: // IEEE: combinational_entry + sequential_entry yaTABLELINE { $$ = new AstUdpTableLine($1,*$1); } | error { $$ = NULL; } ; //************************************************ // Specify specify_block: // ==IEEE: specify_block ySPECIFY specifyJunkList yENDSPECIFY { $$ = NULL; } | ySPECIFY yENDSPECIFY { $$ = NULL; } ; specifyJunkList: specifyJunk { } /* ignored */ | specifyJunkList specifyJunk { } /* ignored */ ; specifyJunk: BISONPRE_NOT(ySPECIFY,yENDSPECIFY) { } | ySPECIFY specifyJunk yENDSPECIFY { } | error {} ; specparam_declaration: // ==IEEE: specparam_declaration ySPECPARAM junkToSemiList ';' { $$ = NULL; } ; junkToSemiList: junkToSemi { } /* ignored */ | junkToSemiList junkToSemi { } /* ignored */ ; junkToSemi: BISONPRE_NOT(';',yENDSPECIFY,yENDMODULE) { } | error {} ; //************************************************ // IDs id: yaID__ETC { $$ = $1; $$=$1; } ; idAny: // Any kind of identifier //UNSUP yaID__aCLASS { $$ = $1; $$=$1; } //UNSUP yaID__aCOVERGROUP { $$ = $1; $$=$1; } yaID__aPACKAGE { $$ = $1; $$=$1; } | yaID__aTYPE { $$ = $1; $$=$1; } | yaID__ETC { $$ = $1; $$=$1; } ; idSVKwd: // Warn about non-forward compatible Verilog 2001 code // // yBIT, yBYTE won't work here as causes conflicts yDO { static string s = "do" ; $$ = &s; ERRSVKWD($1,*$$); $$=$1; } | yFINAL { static string s = "final"; $$ = &s; ERRSVKWD($1,*$$); $$=$1; } ; variable_lvalue: // IEEE: variable_lvalue or net_lvalue // // Note many variable_lvalue's must use exprOkLvalue when arbitrary expressions may also exist idClassSel { $$ = $1; } | '{' variable_lvalueConcList '}' { $$ = $2; } // // IEEE: [ assignment_pattern_expression_type ] assignment_pattern_variable_lvalue // // We allow more assignment_pattern_expression_types then strictly required //UNSUP data_type yP_TICKBRA variable_lvalueList '}' { UNSUP } //UNSUP idClassSel yP_TICKBRA variable_lvalueList '}' { UNSUP } //UNSUP /**/ yP_TICKBRA variable_lvalueList '}' { UNSUP } //UNSUP streaming_concatenation { UNSUP } | streaming_concatenation { $$ = $1; } ; variable_lvalueConcList: // IEEE: part of variable_lvalue: '{' variable_lvalue { ',' variable_lvalue } '}' variable_lvalue { $$ = $1; } | variable_lvalueConcList ',' variable_lvalue { $$ = new AstConcat($2,$1,$3); } ; // VarRef to dotted, and/or arrayed, and/or bit-ranged variable idClassSel: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable idDotted { $$ = $1; } // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select //UNSUP yTHIS '.' idDotted { UNSUP } //UNSUP ySUPER '.' idDotted { UNSUP } //UNSUP yTHIS '.' ySUPER '.' idDotted { UNSUP } // // Expanded: package_scope idDotted //UNSUP class_scopeIdFollows idDotted { UNSUP } //UNSUP package_scopeIdFollows idDotted { UNSUP } ; idDotted: //UNSUP yD_ROOT '.' idDottedMore { UNSUP } idDottedMore { $$ = $1; } ; idDottedMore: idArrayed { $$ = $1; } | idDottedMore '.' idArrayed { $$ = new AstDot($2,$1,$3); } ; // Single component of dotted path, maybe [#]. // Due to lookahead constraints, we can't know if [:] or [+:] are valid (last dotted part), // we'll assume so and cleanup later. // id below includes: // enum_identifier idArrayed: // IEEE: id + select id { $$ = new AstParseRef($1,AstParseRefExp::PX_TEXT,*$1,NULL,NULL); } // // IEEE: id + part_select_range/constant_part_select_range | idArrayed '[' expr ']' { $$ = new AstSelBit($2,$1,$3); } // Or AstArraySel, don't know yet. | idArrayed '[' constExpr ':' constExpr ']' { $$ = new AstSelExtract($2,$1,$3,$5); } // // IEEE: id + indexed_range/constant_indexed_range | idArrayed '[' expr yP_PLUSCOLON constExpr ']' { $$ = new AstSelPlus($2,$1,$3,$5); } | idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2,$1,$3,$5); } ; // VarRef without any dots or vectorizaion varRefBase: id { $$ = new AstVarRef($1,*$1,false);} ; // yaSTRING shouldn't be used directly, instead via an abstraction below str: // yaSTRING but with \{escapes} need decoded yaSTRING { $$ = PARSEP->newString(GRAMMARP->deQuote($1,*$1)); } ; strAsInt: yaSTRING { $$ = new AstConst($1,V3Number(V3Number::VerilogStringLiteral(),$1,GRAMMARP->deQuote($1,*$1)));} ; strAsIntIgnore: // strAsInt, but never matches for when expr shouldn't parse strings yaSTRING__IGNORE { $$ = NULL; yyerror("Impossible token"); } ; strAsText: yaSTRING { $$ = GRAMMARP->createTextQuoted($1,*$1);} ; endLabelE: /* empty */ { $$ = NULL; $$=NULL; } | ':' idAny { $$ = $2; $$=$2; } //UNSUP ':' yNEW__ETC { $$ = $2; $$=$2; } ; //************************************************ // Clocking clocking_declaration: // IEEE: clocking_declaration (INCOMPLETE) yDEFAULT yCLOCKING '@' '(' senitemEdge ')' ';' yENDCLOCKING { $$ = new AstClocking($1, $5, NULL); } //UNSUP: Vastly simplified grammar ; //************************************************ // Asserts labeledStmt: immediate_assert_statement { $$ = $1; } ; concurrent_assertion_item: // IEEE: concurrent_assertion_item concurrent_assertion_statement { $$ = $1; } | id/*block_identifier*/ ':' concurrent_assertion_statement { $$ = new AstBegin($2,*$1,$3); } // // IEEE: checker_instantiation // // identical to module_instantiation; see etcInst ; concurrent_assertion_statement: // ==IEEE: concurrent_assertion_statement //UNSUP: assert/assume // // IEEE: cover_property_statement yCOVER yPROPERTY '(' property_spec ')' stmtBlock { $$ = new AstPslCover($1,$4,$6); } ; property_spec: // IEEE: property_spec //UNSUP: This rule has been super-specialized to what is supported now '@' '(' senitemEdge ')' yDISABLE yIFF '(' expr ')' expr { $$ = new AstPslClocked($1,$3,$8,$10); } | '@' '(' senitemEdge ')' expr { $$ = new AstPslClocked($1,$3,NULL,$5); } | yDISABLE yIFF '(' expr ')' expr { $$ = new AstPslClocked($4->fileline(),NULL,$4,$6); } | expr { $$ = new AstPslClocked($1->fileline(),NULL,NULL,$1); } ; immediate_assert_statement: // ==IEEE: immediate_assert_statement // // action_block expanded here, for compatibility with AstVAssert yASSERT '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstVAssert($1,$3,$5, GRAMMARP->createDisplayError($1)); } | yASSERT '(' expr ')' yELSE stmtBlock { $$ = new AstVAssert($1,$3,NULL,$6); } | yASSERT '(' expr ')' stmtBlock yELSE stmtBlock { $$ = new AstVAssert($1,$3,$5,$7); } ; //************************************************ // Covergroup //********************************************************************** // Randsequence //********************************************************************** // Class //========= // Package scoping - to traverse the symbol table properly, the final identifer // must be included in the rules below. // Each of these must end with {symsPackageDone | symsClassDone} ps_id_etc: // package_scope + general id package_scopeIdFollowsE id { } ; ps_type: // IEEE: ps_parameter_identifier | ps_type_identifier // Even though we looked up the type and have a AstNode* to it, // we can't fully resolve it because it may have been just a forward definition. package_scopeIdFollowsE yaID__aTYPE { $$ = new AstRefDType($2, *$2); $$->castRefDType()->packagep($1); } // // Simplify typing - from ps_covergroup_identifier //UNSUP package_scopeIdFollowsE yaID__aCOVERGROUP { $$=$1; $$=$1+$2; } ; //=== Below rules assume special scoping per above package_scopeIdFollowsE: // IEEE: [package_scope] // // IMPORTANT: The lexer will parse the following ID to be in the found package // // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ] /* empty */ { $$ = NULL; } | package_scopeIdFollows { $$ = $1; } ; package_scopeIdFollows: // IEEE: package_scope // // IMPORTANT: The lexer will parse the following ID to be in the found package // //vv mid rule action needed otherwise we might not have NextId in time to parse the id token yD_UNIT { SYMP->nextId(PARSEP->rootp()); } /*cont*/ yP_COLONCOLON { $$ = GRAMMARP->unitPackage($1); } | yaID__aPACKAGE { SYMP->nextId($1); } /*cont*/ yP_COLONCOLON { $$ = $1->castPackage(); } //UNSUP yLOCAL__COLONCOLON { PARSEP->symTableNextId($1); } //UNSUP /*cont*/ yP_COLONCOLON { UNSUP } ; //********************************************************************** // VLT Files vltItem: vltOffFront { V3Config::addIgnore($1,"*",0,0); } | vltOffFront yVLT_D_FILE yaSTRING { V3Config::addIgnore($1,*$3,0,0); } | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM { V3Config::addIgnore($1,*$3,$5->toUInt(),$5->toUInt()+1); } | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM { V3Config::addIgnore($1,*$3,$5->toUInt(),$7->toUInt()+1); } ; vltOffFront: yVLT_COVERAGE_OFF { $$ = V3ErrorCode::I_COVERAGE; } | yVLT_TRACING_OFF { $$ = V3ErrorCode::I_TRACING; } | yVLT_LINT_OFF { $$ = V3ErrorCode::I_LINT; } | yVLT_LINT_OFF yVLT_D_MSG yaID__ETC { $$ = V3ErrorCode((*$3).c_str()); if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<debugBison()>=9) yydebug = 1; return yyparse(); } const char* V3ParseImp::tokenName(int token) { #if YYDEBUG || YYERROR_VERBOSE if (token >= 255) return yytname[token-255]; else { static char ch[2]; ch[0]=token; ch[1]='\0'; return ch; } #else return ""; #endif } void V3ParseImp::parserClear() { // Clear up any dynamic memory V3Parser required VARDTYPE(NULL); } void V3ParseGrammar::argWrapList(AstNodeFTaskRef* nodep) { // Convert list of expressions to list of arguments AstNode* outp = NULL; while (nodep->pinsp()) { AstNode* exprp = nodep->pinsp()->unlinkFrBack(); // addNext can handle nulls: // cppcheck-suppress nullPointer outp = outp->addNext(new AstArg(exprp->fileline(), "", exprp)); } if (outp) nodep->addPinsp(outp); } AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int value) { FileLine* newfl = new FileLine (fileline); newfl->warnOff(V3ErrorCode::WIDTH, true); AstNode* nodep = new AstConst(newfl, V3Number(newfl)); // Adding a NOT is less work than figuring out how wide to make it if (value) nodep = new AstNot(newfl, nodep); nodep = new AstAssignW(newfl, new AstVarRef(fileline, name, true), nodep); return nodep; } AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, AstRange* rangep, bool isPacked) { // Split RANGE0-RANGE1-RANGE2 into ARRAYDTYPE0(ARRAYDTYPE1(ARRAYDTYPE2(BASICTYPE3),RANGE),RANGE) AstNodeDType* arrayp = basep; if (rangep) { // Maybe no range - return unmodified base type while (rangep->nextp()) rangep = rangep->nextp()->castRange(); while (rangep) { AstRange* prevp = rangep->backp()->castRange(); if (prevp) rangep->unlinkFrBack(); if (isPacked) { arrayp = new AstPackArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep); } else { arrayp = new AstUnpackArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep); } rangep = prevp; } } return arrayp; } AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp) { AstNodeDType* dtypep = GRAMMARP->m_varDTypep; UINFO(5," creVar "<m_varIO == AstVarType::UNKNOWN && GRAMMARP->m_varDecl == AstVarType::PORT) { // Just a port list with variable name (not v2k format); AstPort already created if (dtypep) fileline->v3error("Unsupported: Ranges ignored in port-lists"); return NULL; } AstVarType type = GRAMMARP->m_varIO; if (dtypep->castIfaceRefDType()) { if (arrayp) { fileline->v3error("Unsupported: Arrayed interfaces"); arrayp=NULL; } } if (!dtypep) { // Created implicitly dtypep = new AstBasicDType(fileline, LOGIC_IMPLICIT); } else { // May make new variables with same type, so clone dtypep = dtypep->cloneTree(false); } //UINFO(0,"CREVAR "<ascii()<<" decl="<m_varDecl.ascii()<<" io="<m_varIO.ascii()<m_varDecl != AstVarType::UNKNOWN)) type = GRAMMARP->m_varDecl; if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared"); if (type == AstVarType::GENVAR) { if (arrayp) fileline->v3error("Genvars may not be arrayed: "<addAttrsp(attrsp); if (GRAMMARP->m_varDecl != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varDecl); if (GRAMMARP->m_varIO != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varIO); if (GRAMMARP->m_varDecl == AstVarType::SUPPLY0) { nodep->addNext(V3ParseGrammar::createSupplyExpr(fileline, nodep->name(), 0)); } if (GRAMMARP->m_varDecl == AstVarType::SUPPLY1) { nodep->addNext(V3ParseGrammar::createSupplyExpr(fileline, nodep->name(), 1)); } // Don't set dtypep in the ranging; // We need to autosize parameters and integers separately // // Propagate from current module tracing state if (nodep->isGenVar()) nodep->trace(false); else if (nodep->isParam() && !v3Global.opt.traceParams()) nodep->trace(false); else nodep->trace(allTracingOn(nodep->fileline())); // Remember the last variable created, so we can attach attributes to it in later parsing GRAMMARP->m_varAttrp = nodep; return nodep; } string V3ParseGrammar::deQuote(FileLine* fileline, string text) { // Fix up the quoted strings the user put in, for example "\"" becomes " // Reverse is V3Number::quoteNameControls(...) bool quoted = false; string newtext; unsigned char octal_val = 0; int octal_digits = 0; for (const char* cp=text.c_str(); *cp; ++cp) { if (quoted) { if (isdigit(*cp)) { octal_val = octal_val*8 + (*cp-'0'); if (++octal_digits == 3) { octal_digits = 0; quoted = false; newtext += octal_val; } } else { if (octal_digits) { // Spec allows 1-3 digits octal_digits = 0; quoted = false; newtext += octal_val; --cp; // Backup to reprocess terminating character as non-escaped continue; } quoted = false; if (*cp == 'n') newtext += '\n'; else if (*cp == 'a') newtext += '\a'; // SystemVerilog 3.1 else if (*cp == 'f') newtext += '\f'; // SystemVerilog 3.1 else if (*cp == 'r') newtext += '\r'; else if (*cp == 't') newtext += '\t'; else if (*cp == 'v') newtext += '\v'; // SystemVerilog 3.1 else if (*cp == 'x' && isxdigit(cp[1]) && isxdigit(cp[2])) { // SystemVerilog 3.1 #define vl_decodexdigit(c) ((isdigit(c)?((c)-'0'):(tolower((c))-'a'+10))) newtext += (char)(16*vl_decodexdigit(cp[1]) + vl_decodexdigit(cp[2])); cp += 2; } else if (isalnum(*cp)) { fileline->v3error("Unknown escape sequence: \\"<<*cp); break; } else newtext += *cp; } } else if (*cp == '\\') { quoted = true; octal_digits = 0; } else if (*cp != '"') { newtext += *cp; } } return newtext; } //YACC = /kits/sources/bison-2.4.1/src/bison --report=lookahead // --report=lookahead // --report=itemset // --graph verilator-3.874/src/V3Task.cpp0000664000177100017500000014244512525171733016151 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add temporaries, such as for task nodes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Task's Transformations: // // Each module: // Look for TASKREF // Insert task's statements into the referrer // Look for TASKs // Remove them, they're inlined // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Task.h" #include "V3Inst.h" #include "V3Ast.h" #include "V3EmitCBase.h" #include "V3Graph.h" #include "V3LinkLValue.h" //###################################################################### // Graph subclasses class TaskBaseVertex : public V3GraphVertex { AstNode* m_impurep; // Node causing impure function w/ outside references bool m_noInline; // Marked with pragma public: TaskBaseVertex(V3Graph* graphp) : V3GraphVertex(graphp), m_impurep(NULL), m_noInline(false) {} virtual ~TaskBaseVertex() {} bool pure() const { return m_impurep==NULL; } AstNode* impureNode() const { return m_impurep; } void impure(AstNode* nodep) { m_impurep = nodep; } bool noInline() const { return m_noInline; } void noInline(bool flag) { m_noInline = flag; } }; class TaskFTaskVertex : public TaskBaseVertex { // Every task gets a vertex, and we link tasks together based on funcrefs. AstNodeFTask* m_nodep; AstCFunc* m_cFuncp; public: TaskFTaskVertex(V3Graph* graphp, AstNodeFTask* nodep) : TaskBaseVertex(graphp), m_nodep(nodep) { m_cFuncp=NULL; } virtual ~TaskFTaskVertex() {} AstNodeFTask* nodep() const { return m_nodep; } virtual string name() const { return nodep()->name(); } virtual string dotColor() const { return pure() ? "black" : "red"; } AstCFunc* cFuncp() const { return m_cFuncp; } void cFuncp(AstCFunc* nodep) { m_cFuncp=nodep; } }; class TaskCodeVertex : public TaskBaseVertex { // Top vertex for all calls not under another task public: TaskCodeVertex(V3Graph* graphp) : TaskBaseVertex(graphp) {} virtual ~TaskCodeVertex() {} virtual string name() const { return "*CODE*"; } virtual string dotColor() const { return "green"; } }; class TaskEdge : public V3GraphEdge { public: TaskEdge(V3Graph* graphp, TaskBaseVertex* fromp, TaskBaseVertex* top) : V3GraphEdge(graphp, fromp, top, 1, false) {} virtual ~TaskEdge() {} virtual string dotLabel() const { return "w"+cvtToStr(weight()); } }; //###################################################################### class TaskStateVisitor : public AstNVisitor { private: // NODE STATE // Output: // AstNodeFTask::user3p // AstScope* this FTask is under // AstNodeFTask::user4p // GraphFTaskVertex* this FTask is under // AstVar::user4p // GraphFTaskVertex* this variable is declared in AstUser3InUse m_inuser3; AstUser4InUse m_inuser4; // TYPES typedef std::map,AstVarScope*> VarToScopeMap; // MEMBERS VarToScopeMap m_varToScopeMap; // Map for Var -> VarScope mappings AstAssignW* m_assignwp; // Current assignment V3Graph m_callGraph; // Task call graph TaskBaseVertex* m_curVxp; // Current vertex we're adding to public: // METHODS AstScope* getScope(AstNodeFTask* nodep) { AstScope* scopep = nodep->user3p()->castNode()->castScope(); if (!scopep) nodep->v3fatalSrc("No scope for function"); return scopep; } AstVarScope* findVarScope(AstScope* scopep, AstVar* nodep) { VarToScopeMap::iterator iter = m_varToScopeMap.find(make_pair(scopep,nodep)); if (iter == m_varToScopeMap.end()) nodep->v3fatalSrc("No scope for var"); return iter->second; } bool ftaskNoInline(AstNodeFTask* nodep) { return (getFTaskVertex(nodep)->noInline()); } AstCFunc* ftaskCFuncp(AstNodeFTask* nodep) { return (getFTaskVertex(nodep)->cFuncp()); } void ftaskCFuncp(AstNodeFTask* nodep, AstCFunc* cfuncp) { getFTaskVertex(nodep)->cFuncp(cfuncp); } void checkPurity(AstNodeFTask* nodep) { checkPurity(nodep, getFTaskVertex(nodep)); } void checkPurity(AstNodeFTask* nodep, TaskBaseVertex* vxp) { if (!vxp->pure()) { nodep->v3warn(IMPURE,"Unsupported: External variable referenced by non-inlined function/task: "<prettyName()<impureNode()->warnMore()<<"... Location of the external reference: "<impureNode()->prettyName()); } // And, we need to check all tasks this task calls for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep=edgep->outNextp()) { checkPurity(nodep, static_cast(edgep->top())); } } private: TaskFTaskVertex* getFTaskVertex(AstNodeFTask* nodep) { if (!nodep->user4p()) { nodep->user4p(new TaskFTaskVertex(&m_callGraph, nodep)); } return static_cast(nodep->user4p()->castGraphVertex()); } // VISITORS virtual void visit(AstScope* nodep, AstNUser*) { // Each FTask is unique per-scope, so AstNodeFTaskRefs do not need // pointers to what scope the FTask is to be invoked under. // However, to create variables, we need to track the scopes involved. // Find all var->varscope mappings, for later cleanup for (AstNode* stmtp = nodep->varsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVarScope* vscp = stmtp->castVarScope()) { if (vscp->varp()->isFuncLocal()) { UINFO(9," funcvsc "<varp()), vscp)); } } } // Likewise, all FTask->scope mappings for (AstNode* stmtp = nodep->blocksp(); stmtp; stmtp=stmtp->nextp()) { if (AstNodeFTask* taskp = stmtp->castNodeFTask()) { taskp->user3p(nodep); } } nodep->iterateChildren(*this); } virtual void visit(AstAssignW* nodep, AstNUser*) { m_assignwp = nodep; nodep->iterateChildren(*this); nodep=NULL; // May delete nodep. m_assignwp = NULL; } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { if (m_assignwp) { // Wire assigns must become always statements to deal with insertion // of multiple statements. Perhaps someday make all wassigns into always's? UINFO(5," IM_WireRep "<convertToAlways(); pushDeletep(m_assignwp); m_assignwp=NULL; } // We make multiple edges if a task is called multiple times from another task. if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked task"); new TaskEdge (&m_callGraph, m_curVxp, getFTaskVertex(nodep->taskp())); } virtual void visit(AstNodeFTask* nodep, AstNUser*) { UINFO(9," TASK "<dpiImport()) m_curVxp->noInline(true); nodep->iterateChildren(*this); m_curVxp = lastVxp; } virtual void visit(AstPragma* nodep, AstNUser*) { if (nodep->pragType() == AstPragmaType::NO_INLINE_TASK) { // Just mark for the next steps, and we're done with it. m_curVxp->noInline(true); nodep->unlinkFrBack()->deleteTree(); } else { nodep->iterateChildren(*this); } } virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); nodep->user4p(m_curVxp); // Remember what task it's under } virtual void visit(AstVarRef* nodep, AstNUser*) { nodep->iterateChildren(*this); if (nodep->varp()->user4p() != m_curVxp) { if (m_curVxp->pure() && !nodep->varp()->isXTemp()) { m_curVxp->impure(nodep); } } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS TaskStateVisitor(AstNetlist* nodep) { m_assignwp = NULL; m_curVxp = new TaskCodeVertex(&m_callGraph); AstNode::user3ClearTree(); AstNode::user4ClearTree(); // nodep->accept(*this); // m_callGraph.removeRedundantEdgesSum(&TaskEdge::followAlwaysTrue); m_callGraph.dumpDotFilePrefixed("task_call"); } virtual ~TaskStateVisitor() {} }; //###################################################################### class TaskRelinkVisitor : public AstNVisitor { // Replace varrefs with new var pointer private: // NODE STATE // Input: // AstVar::user2p // AstVarScope* to replace varref with // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { // Similar code in V3Inline if (nodep->varp()->user2p()) { // It's being converted to a alias. UINFO(9, " relinkVar "<<(void*)nodep->varp()->user2p()<<" "<varp()->user2p()->castNode()->castVarScope(); if (!newvscp) nodep->v3fatalSrc("Null?\n"); nodep->varScopep(newvscp); nodep->varp(nodep->varScopep()->varp()); nodep->name(nodep->varp()->name()); } nodep->iterateChildren(*this); } //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS TaskRelinkVisitor(AstBegin* nodep) { // Passed temporary tree nodep->accept(*this); } virtual ~TaskRelinkVisitor() {} }; //###################################################################### // Task state, as a visitor of each AstNode class TaskVisitor : public AstNVisitor { private: // NODE STATE // Each module: // AstNodeFTask::user // True if its been expanded // Each funccall // to TaskRelinkVisitor: // AstVar::user2p // AstVarScope* to replace varref with AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // TYPES enum InsertMode { IM_BEFORE, // Pointing at statement ref is in, insert before this IM_AFTER, // Pointing at last inserted stmt, insert after IM_WHILE_PRECOND // Pointing to for loop, add to body end }; typedef map > DpiNames; // STATE TaskStateVisitor* m_statep; // Common state between visitors AstNodeModule* m_modp; // Current module AstTopScope* m_topScopep; // Current top scope AstScope* m_scopep; // Current scope InsertMode m_insMode; // How to insert AstNode* m_insStmtp; // Where to insert statement int m_modNCalls; // Incrementing func # for making symbols DpiNames m_dpiNames; // Map of all created DPI functions // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } AstVarScope* createFuncVar(AstCFunc* funcp, const string& name, AstVar* examplep) { AstVar* newvarp = new AstVar (funcp->fileline(), AstVarType::BLOCKTEMP, name, examplep); newvarp->funcLocal(true); funcp->addInitsp(newvarp); AstVarScope* newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp); m_scopep->addVarp(newvscp); return newvscp; } AstVarScope* createInputVar(AstCFunc* funcp, const string& name, AstBasicDTypeKwd kwd) { AstVar* newvarp = new AstVar (funcp->fileline(), AstVarType::BLOCKTEMP, name, funcp->findBasicDType(kwd)); newvarp->funcLocal(true); newvarp->combineType(AstVarType::INPUT); funcp->addArgsp(newvarp); AstVarScope* newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp); m_scopep->addVarp(newvscp); return newvscp; } AstVarScope* createVarScope(AstVar* invarp, const string& name) { // We could create under either the ref's scope or the ftask's scope. // It shouldn't matter, as they are only local variables. // We choose to do it under whichever called this function, which results // in more cache locality. AstVar* newvarp = new AstVar (invarp->fileline(), AstVarType::BLOCKTEMP, name, invarp); newvarp->funcLocal(false); newvarp->propagateAttrFrom(invarp); m_modp->addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope (newvarp->fileline(), m_scopep, newvarp); m_scopep->addVarp(newvscp); return newvscp; } AstNode* createInlinedFTask(AstNodeFTaskRef* refp, string namePrefix, AstVarScope* outvscp) { // outvscp is the variable for functions only, if NULL, it's a task if (!refp->taskp()) refp->v3fatalSrc("Unlinked?"); AstNode* newbodysp = refp->taskp()->stmtsp()->cloneTree(true); // Maybe NULL AstNode* beginp = new AstComment(refp->fileline(), (string)("Function: ")+refp->name()); if (newbodysp) beginp->addNext(newbodysp); if (debug()>=9) { beginp->dumpTreeAndNext(cout,"-newbegi:"); } // // Create input variables AstNode::user2ClearTree(); V3TaskConnects tconnects = V3Task::taskConnects(refp, beginp); for (V3TaskConnects::iterator it=tconnects.begin(); it!=tconnects.end(); ++it) { AstVar* portp = it->first; AstArg* argp = it->second; AstNode* pinp = argp->exprp(); portp->unlinkFrBack(); pushDeletep(portp); // Remove it from the clone (not original) if (pinp==NULL) { // Too few arguments in function call } else { UINFO(9, " Port "<unlinkFrBack(); // Relinked to assignment below argp->unlinkFrBack()->deleteTree(); // Args no longer needed // if ((portp->isInout()||portp->isOutput()) && pinp->castConst()) { pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName()); } else if (portp->isInout()) { if (AstVarRef* varrefp = pinp->castVarRef()) { // Connect to this exact variable AstVarScope* localVscp = varrefp->varScopep(); if (!localVscp) varrefp->v3fatalSrc("Null var scope"); portp->user2p(localVscp); pushDeletep(pinp); } else { pinp->v3warn(E_TASKNSVAR,"Unsupported: Function/task input argument is not simple variable"); } } else if (portp->isOutput()) { // Make output variables // Correct lvalue; we didn't know when we linked // This is slightly scary; are we sure no decisions were made // before here based on this not being a lvalue? // Doesn't seem so; V3Unknown uses it earlier, but works ok. V3LinkLValue::linkLValueSet(pinp); // Even if it's referencing a varref, we still make a temporary // Else task(x,x,x) might produce incorrect results AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName()); portp->user2p(outvscp); AstAssign* assp = new AstAssign (pinp->fileline(), pinp, new AstVarRef(outvscp->fileline(), outvscp, false)); assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block // Put assignment BEHIND of all other statements beginp->addNext(assp); } else if (portp->isInput()) { // Make input variable AstVarScope* inVscp = createVarScope (portp, namePrefix+"__"+portp->shortName()); portp->user2p(inVscp); AstAssign* assp = new AstAssign (pinp->fileline(), new AstVarRef(inVscp->fileline(), inVscp, true), pinp); assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block // Put assignment in FRONT of all other statements if (AstNode* afterp = beginp->nextp()) { afterp->unlinkFrBackWithNext(); assp->addNext(afterp); } beginp->addNext(assp); } } } if (refp->pinsp()) refp->v3fatalSrc("Pin wasn't removed by above loop"); { AstNode* nextstmtp; for (AstNode* stmtp = beginp; stmtp; stmtp=nextstmtp) { nextstmtp = stmtp->nextp(); if (AstVar* portp = stmtp->castVar()) { // Any I/O variables that fell out of above loop were already linked if (!portp->user2p()) { // Move it to a new localized variable portp->unlinkFrBack(); pushDeletep(portp); // Remove it from the clone (not original) AstVarScope* localVscp = createVarScope (portp, namePrefix+"__"+portp->shortName()); portp->user2p(localVscp); } } } } // Create function output variables if (outvscp) { //UINFO(0, "setflag on "<fvarp()<<" to "<taskp()->fvarp()->user2p(outvscp); } // Replace variable refs // Iteration requires a back, so put under temporary node { AstBegin* tempp = new AstBegin(beginp->fileline(),"[EditWrapper]",beginp); TaskRelinkVisitor visit (tempp); tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp=NULL; } // if (debug()>=9) { beginp->dumpTreeAndNext(cout,"-iotask: "); } return beginp; } AstNode* createNonInlinedFTask(AstNodeFTaskRef* refp, string namePrefix, AstVarScope* outvscp) { // outvscp is the variable for functions only, if NULL, it's a task if (!refp->taskp()) refp->v3fatalSrc("Unlinked?"); AstCFunc* cfuncp = m_statep->ftaskCFuncp(refp->taskp()); if (!cfuncp) refp->v3fatalSrc("No non-inline task associated with this task call?"); // AstNode* beginp = new AstComment(refp->fileline(), (string)("Function: ")+refp->name()); AstCCall* ccallp = new AstCCall(refp->fileline(), cfuncp, NULL); beginp->addNext(ccallp); // Convert complicated outputs to temp signals V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp()); for (V3TaskConnects::iterator it=tconnects.begin(); it!=tconnects.end(); ++it) { AstVar* portp = it->first; AstNode* pinp = it->second->exprp(); if (!pinp) { // Too few arguments in function call } else { UINFO(9, " Port "<isInout()||portp->isOutput()) && pinp->castConst()) { pinp->v3error("Function/task output connected to constant instead of variable: "+portp->prettyName()); } else if (portp->isInout()) { if (pinp->castVarRef()) { // Connect to this exact variable } else { pinp->v3warn(E_TASKNSVAR,"Unsupported: Function/task input argument is not simple variable"); } } else if (portp->isOutput()) { // Make output variables // Correct lvalue; we didn't know when we linked // This is slightly scary; are we sure no decisions were made // before here based on this not being a lvalue? // Doesn't seem so; V3Unknown uses it earlier, but works ok. V3LinkLValue::linkLValueSet(pinp); // Even if it's referencing a varref, we still make a temporary // Else task(x,x,x) might produce incorrect results AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName()); portp->user2p(outvscp); pinp->replaceWith(new AstVarRef(outvscp->fileline(), outvscp, true)); AstAssign* assp = new AstAssign (pinp->fileline(), pinp, new AstVarRef(outvscp->fileline(), outvscp, false)); assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block // Put assignment BEHIND of all other statements beginp->addNext(assp); } } } // First argument is symbol table, then output if a function bool needSyms = !refp->taskp()->dpiImport(); if (needSyms) ccallp->argTypes("vlSymsp"); if (refp->taskp()->dpiContext()) { // __Vscopep AstNode* snp = refp->scopeNamep()->unlinkFrBack(); if (!snp) refp->v3fatalSrc("Missing scoping context"); ccallp->addArgsp(snp); // __Vfilenamep ccallp->addArgsp(new AstCMath(refp->fileline(), "\""+refp->fileline()->filename()+"\"", 64, true)); // __Vlineno ccallp->addArgsp(new AstConst(refp->fileline(), refp->fileline()->lineno())); } // Create connections AstNode* nextpinp; for (AstNode* pinp = refp->pinsp(); pinp; pinp=nextpinp) { nextpinp = pinp->nextp(); // Move pin to the CCall, removing all Arg's AstNode* exprp = pinp->castArg()->exprp(); exprp->unlinkFrBack(); ccallp->addArgsp(exprp); } if (outvscp) { ccallp->addArgsp(new AstVarRef(refp->fileline(), outvscp, true)); } if (debug()>=9) { beginp->dumpTreeAndNext(cout,"-nitask: "); } return beginp; } string dpiprotoName(AstNodeFTask* nodep, AstVar* rtnvarp) const { // Return fancy export-ish name for DPI function // Variable names are NOT included so differences in only IO names won't matter string dpiproto; if (nodep->pure()) dpiproto += "pure "; if (nodep->dpiContext()) dpiproto += "context "; dpiproto += rtnvarp ? rtnvarp->dpiArgType(true,true):"void"; dpiproto += " "+nodep->cname()+" ("; string args; for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && !portp->isFuncReturn() && portp!=rtnvarp) { if (args != "") { args+= ", "; dpiproto+= ", "; } args += portp->name(); // Leftover so ,'s look nice if (nodep->dpiImport()) dpiproto += portp->dpiArgType(false,false); } } } dpiproto += ")"; return dpiproto; } AstNode* createDpiTemp(AstVar* portp, const string& suffix) { bool bitvec = (portp->basicp()->isBitLogic() && portp->width() > 32); string stmt; if (bitvec) { stmt += "svBitVecVal "+portp->name()+suffix; stmt += " ["+cvtToStr(portp->widthWords())+"]"; } else { stmt += portp->dpiArgType(true,true); stmt += " "+portp->name()+suffix; } stmt += ";\n"; return new AstCStmt(portp->fileline(), stmt); } AstNode* createAssignInternalToDpi(AstVar* portp, bool isPtr, const string& frSuffix, const string& toSuffix) { // Create assignment from internal format into DPI temporary bool bitvec = (portp->basicp()->isBitLogic() && portp->width() > 32); string stmt; string ket; // Someday we'll have better type support, and this can make variables and casts. // But for now, we'll just text-bash it. if (bitvec) { if (portp->isWide()) { stmt += ("VL_SET_SVBV_W("+cvtToStr(portp->width()) +", "+portp->name()+toSuffix+", "+portp->name()+frSuffix+")"); } else { stmt += "VL_SET_WQ("+portp->name()+toSuffix+", "+portp->name()+frSuffix+")"; } } else { if (isPtr) stmt += "*"; // DPI outputs are pointers stmt += portp->name()+toSuffix+" = "; if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::CHANDLE) { stmt += "VL_CVT_Q_VP("; ket += ")"; } stmt += portp->name()+frSuffix; if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::STRING) { stmt += ".c_str()"; } } stmt += ket + ";\n"; return new AstCStmt(portp->fileline(), stmt); } AstNode* createAssignDpiToInternal(AstVarScope* portvscp, const string& frName, bool cvt) { // Create assignment from DPI temporary into internal format AstVar* portp = portvscp->varp(); string stmt; string ket; if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::CHANDLE) { stmt += "VL_CVT_VP_Q("; ket += ")"; } else if (portp->basicp() && portp->basicp()->isBitLogic() && portp->width() != 1 && portp->isQuad()) { // SV is vector, Verilator isn't stmt += "VL_SET_QW("; ket += ")"; } if (!cvt && portp->basicp() && portp->basicp()->isBitLogic() && portp->width() != 1 && !portp->isWide() && !portp->isQuad()) stmt += "*"; // it's a svBitVecVal, which other code won't think is arrayed (as WData aren't), but really is stmt += frName; stmt += ket; // Use a AstCMath, as we want V3Clean to mask off bits that don't make sense. int cwidth = VL_WORDSIZE; if (portp->basicp()) cwidth = portp->basicp()->keyword().width(); if (portp->basicp() && portp->basicp()->isBitLogic()) cwidth = VL_WORDSIZE*portp->widthWords(); AstNode* newp = new AstAssign(portp->fileline(), new AstVarRef(portp->fileline(), portvscp, true), new AstSel(portp->fileline(), new AstCMath(portp->fileline(), stmt, cwidth, false), 0, portp->width())); return newp; } AstCFunc* makeDpiExportWrapper(AstNodeFTask* nodep, AstVar* rtnvarp) { AstCFunc* dpip = new AstCFunc(nodep->fileline(), nodep->cname(), m_scopep, (rtnvarp ? rtnvarp->dpiArgType(true,true) : "")); dpip->dontCombine(true); dpip->entryPoint(true); dpip->isStatic(true); dpip->dpiExportWrapper(true); dpip->cname(nodep->cname()); // Add DPI reference to top, since it's a global function m_topScopep->scopep()->addActivep(dpip); {// Create dispatch wrapper // Note this function may dispatch to myfunc on a different class. // Thus we need to be careful not to assume a particular function layout. // // Func numbers must be the same for each function, even when there are // completely different models with the same function name. // Thus we can't just use a constant computed at Verilation time. // We could use 64-bits of a MD5/SHA hash rather than a string here, // but the compare is only done on first call then memoized, so it's not worth optimizing. string stmt; stmt += "static int __Vfuncnum = -1;\n"; // Static doesn't need save-restore as if below will re-fill proper value // First time init (faster than what the compiler does if we did a singleton stmt += "if (VL_UNLIKELY(__Vfuncnum==-1)) { __Vfuncnum = Verilated::exportFuncNum(\""+nodep->cname()+"\"); }\n"; // If the find fails, it will throw an error stmt += "const VerilatedScope* __Vscopep = Verilated::dpiScope();\n"; // If dpiScope is fails and is null; the exportFind function throws and error string cbtype = v3Global.opt.prefix()+"__Vcb_"+nodep->cname()+"_t"; stmt += cbtype+" __Vcb = ("+cbtype+")__Vscopep->exportFind(__Vfuncnum);\n"; // If __Vcb is null the exportFind function throws and error dpip->addStmtsp(new AstCStmt(nodep->fileline(), stmt)); } // Convert input/inout DPI arguments to Internal types string args; args += "("+v3Global.opt.prefix()+"__Syms*)(__Vscopep->symsp())"; // Upcast w/o overhead AstNode* argnodesp = NULL; for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && !portp->isFuncReturn() && portp != rtnvarp) { // No createDpiTemp; we make a real internal variable instead // SAME CODE BELOW args+= ", "; if (args != "") { argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); args=""; } AstVarScope* outvscp = createFuncVar (dpip, portp->name()+"__Vcvt", portp); AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, portp->isOutput()); argnodesp = argnodesp->addNextNull(refp); if (portp->isInput()) { dpip->addStmtsp(createAssignDpiToInternal(outvscp, portp->name(), false)); } } } } if (rtnvarp) { AstVar* portp = rtnvarp; // SAME CODE ABOVE args+= ", "; if (args != "") { argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); args=""; } AstVarScope* outvscp = createFuncVar (dpip, portp->name()+"__Vcvt", portp); AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, portp->isOutput()); argnodesp = argnodesp->addNextNull(refp); } {// Call the user function // Add the variables referenced as VarRef's so that lifetime analysis // doesn't rip up the variables on us string stmt; stmt += "(*__Vcb)("; args += ");\n"; AstCStmt* newp = new AstCStmt(nodep->fileline(), stmt); newp->addBodysp(argnodesp); argnodesp=NULL; newp->addBodysp(new AstText(nodep->fileline(), args, true)); dpip->addStmtsp(newp); } // Convert output/inout arguments back to internal type for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && portp->isOutput() && !portp->isFuncReturn()) { dpip->addStmtsp(createAssignInternalToDpi(portp,true,"__Vcvt","")); } } } if (rtnvarp) { dpip->addStmtsp(createDpiTemp(rtnvarp,"")); dpip->addStmtsp(createAssignInternalToDpi(rtnvarp,false,"__Vcvt","")); string stmt = "return "+rtnvarp->name()+";\n"; dpip->addStmtsp(new AstCStmt(nodep->fileline(), stmt)); } return dpip; } AstCFunc* makeDpiImportWrapper(AstNodeFTask* nodep, AstVar* rtnvarp) { if (nodep->cname() != AstNode::prettyName(nodep->cname())) { nodep->v3error("DPI function has illegal characters in C identifier name: "<cname())); } AstCFunc* dpip = new AstCFunc(nodep->fileline(), nodep->cname(), m_scopep, (rtnvarp ? rtnvarp->dpiArgType(true,true) // Tasks (but not void functions) return bool indicating disabled : nodep->dpiTask() ? "int" : "")); dpip->dontCombine(true); dpip->entryPoint (false); dpip->funcPublic (true); dpip->isStatic (false); dpip->pure (nodep->pure()); dpip->dpiImport (true); // Add DPI reference to top, since it's a global function m_topScopep->scopep()->addActivep(dpip); return dpip; } void bodyDpiImportFunc(AstNodeFTask* nodep, AstVarScope* rtnvscp, AstCFunc* cfuncp) { // Convert input/inout arguments to DPI types string args; for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { AstVarScope* portvscp = portp->user2p()->castNode()->castVarScope(); // Remembered when we created it earlier if (portp->isIO() && !portp->isFuncReturn() && portvscp != rtnvscp && portp->name() != "__Vscopep" // Passed to dpiContext, not callee && portp->name() != "__Vfilenamep" && portp->name() != "__Vlineno") { bool bitvec = (portp->basicp()->isBitLogic() && portp->width() > 32); if (args != "") { args+= ", "; } if (bitvec) {} else if (portp->isOutput()) args += "&"; else if (portp->basicp() && portp->basicp()->isBitLogic() && portp->width() != 1) args += "&"; // it's a svBitVecVal args += portp->name()+"__Vcvt"; cfuncp->addStmtsp(createDpiTemp(portp,"__Vcvt")); if (portp->isInput()) { cfuncp->addStmtsp(createAssignInternalToDpi(portp,false,"","__Vcvt")); } } } } // Store context, if needed if (nodep->dpiContext()) { string stmt = "Verilated::dpiContext(__Vscopep, __Vfilenamep, __Vlineno);\n"; cfuncp->addStmtsp(new AstCStmt(nodep->fileline(), stmt)); } {// Call the user function string stmt; if (rtnvscp) { // isFunction will no longer work as we unlinked the return var stmt += rtnvscp->varp()->dpiArgType(true,true) + " "+rtnvscp->varp()->name()+"__Vcvt = "; } stmt += nodep->cname()+"("+args+");\n"; cfuncp->addStmtsp(new AstCStmt(nodep->fileline(), stmt)); } // Convert output/inout arguments back to internal type for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && (portp->isOutput() || portp->isFuncReturn())) { AstVarScope* portvscp = portp->user2p()->castNode()->castVarScope(); // Remembered when we created it earlier cfuncp->addStmtsp(createAssignDpiToInternal(portvscp,portp->name()+"__Vcvt",true)); } } } } AstCFunc* makeUserFunc(AstNodeFTask* nodep, bool ftaskNoInline) { // Given a already cloned node, make a public C function, or a non-inline C function // Probably some of this work should be done later, but... // should the type of the function be bool/uint32/64 etc (based on lookup) or IData? AstNode::user2ClearTree(); AstVar* rtnvarp = NULL; AstVarScope* rtnvscp = NULL; if (nodep->isFunction()) { AstVar* portp = NULL; if (NULL!=(portp = nodep->fvarp()->castVar())) { if (!portp->isFuncReturn()) nodep->v3error("Not marked as function return var"); if (portp->isWide()) nodep->v3error("Unsupported: Public functions with return > 64 bits wide. (Make it a output instead.)"); if (ftaskNoInline || nodep->dpiExport()) portp->funcReturn(false); // Converting return to 'outputs' portp->unlinkFrBack(); rtnvarp = portp; rtnvarp->funcLocal(true); rtnvarp->name(rtnvarp->name()+"__Vfuncrtn"); // Avoid conflict with DPI function name rtnvscp = new AstVarScope (rtnvarp->fileline(), m_scopep, rtnvarp); m_scopep->addVarp(rtnvscp); rtnvarp->user2p(rtnvscp); } else { nodep->v3fatalSrc("function without function output variable"); } } string prefix = ""; if (nodep->dpiImport()) prefix = "__Vdpiimwrap_"; else if (nodep->dpiExport()) prefix = "__Vdpiexp_"; else if (ftaskNoInline) prefix = "__VnoInFunc_"; // Unless public, v3Descope will not uniquify function names even if duplicate per-scope, // so make it unique now. string suffix = ""; // So, make them unique if (!nodep->taskPublic()) suffix = "_"+m_scopep->nameDotless(); AstCFunc* cfuncp = new AstCFunc(nodep->fileline(), prefix + nodep->name() + suffix, m_scopep, ((nodep->taskPublic() && rtnvarp) ? rtnvarp->cPubArgType(true,true) : "")); // It's ok to combine imports because this is just a wrapper; duplicate wrappers can get merged. cfuncp->dontCombine(!nodep->dpiImport()); cfuncp->entryPoint (!nodep->dpiImport()); cfuncp->funcPublic (nodep->taskPublic()); cfuncp->dpiExport (nodep->dpiExport()); cfuncp->isStatic (!(nodep->dpiImport()||nodep->taskPublic())); cfuncp->pure (nodep->pure()); //cfuncp->dpiImport // Not set in the wrapper - the called function has it set if (cfuncp->dpiExport()) cfuncp->cname (nodep->cname()); bool needSyms = !nodep->dpiImport(); if (needSyms) { if (nodep->taskPublic()) { // We need to get a pointer to all of our variables (may have eval'ed something else earlier) cfuncp->addInitsp( new AstCStmt(nodep->fileline(), EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n")); } else { // Need symbol table cfuncp->argTypes(EmitCBaseVisitor::symClassVar()); } } if (nodep->dpiContext()) { // First three args go to dpiContext call createInputVar (cfuncp, "__Vscopep", AstBasicDTypeKwd::SCOPEPTR); createInputVar (cfuncp, "__Vfilenamep", AstBasicDTypeKwd::CHARPTR); createInputVar (cfuncp, "__Vlineno", AstBasicDTypeKwd::INT); } if (!nodep->dpiImport()) { cfuncp->addInitsp(new AstCStmt(nodep->fileline(), EmitCBaseVisitor::symTopAssign()+"\n")); } if (nodep->dpiExport()) { AstScopeName* snp = nodep->scopeNamep(); if (!snp) nodep->v3fatalSrc("Missing scoping context"); snp->dpiExport(true); // The AstScopeName is really a statement(ish) for tracking, not a function snp->unlinkFrBack(); cfuncp->addInitsp(snp); } AstCFunc* dpip = NULL; string dpiproto; if (nodep->dpiImport() || nodep->dpiExport()) { dpiproto = dpiprotoName(nodep, rtnvarp); // Only create one DPI extern for each specified cname, // as it's legal for the user to attach multiple tasks to one dpi cname DpiNames::iterator iter = m_dpiNames.find(nodep->cname()); if (iter == m_dpiNames.end()) { // m_dpiNames insert below if (nodep->dpiImport()) { dpip = makeDpiImportWrapper(nodep, rtnvarp); } else if (nodep->dpiExport()) { dpip = makeDpiExportWrapper(nodep, rtnvarp); cfuncp->addInitsp(new AstComment(dpip->fileline(), (string)("Function called from: ")+dpip->cname())); } m_dpiNames.insert(make_pair(nodep->cname(), make_pair(dpip, dpiproto))); } else if (iter->second.second != dpiproto) { nodep->v3error("Duplicate declaration of DPI function with different formal arguments: "<prettyName()<warnMore()<<"... New prototype: "<second.first->warnMore()<<"... Original prototype: "<second.second); } } // Create list of arguments and move to function for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp=nextp) { nextp = stmtp->nextp(); if (AstVar* portp = stmtp->castVar()) { if (portp->isIO()) { // Move it to new function portp->unlinkFrBack(); portp->funcLocal(true); cfuncp->addArgsp(portp); if (dpip) { dpip->addArgsp(portp->cloneTree(false)); if (!portp->basicp() || portp->basicp()->keyword().isDpiUnsupported()) { portp->v3error("Unsupported: DPI argument of type "<basicp()->prettyTypeName()<warnMore()<<"... For best portability, use bit, byte, int, or longint"); } } } else { // "Normal" variable, mark inside function portp->funcLocal(true); } AstVarScope* newvscp = new AstVarScope (portp->fileline(), m_scopep, portp); m_scopep->addVarp(newvscp); portp->user2p(newvscp); } } // Fake output variable if was a function. It's more efficient to // have it last, rather than first, as the C compiler can sometimes // avoid copying variables when calling shells if argument 1 // remains argument 1 (which it wouldn't if a return got added). if (rtnvarp) cfuncp->addArgsp(rtnvarp); // Move body AstNode* bodysp = nodep->stmtsp(); if (bodysp) { bodysp->unlinkFrBackWithNext(); cfuncp->addStmtsp(bodysp); } if (nodep->dpiImport()) { bodyDpiImportFunc(nodep, rtnvscp, cfuncp); } // Return statement if (rtnvscp && nodep->taskPublic()) { cfuncp->addFinalsp(new AstCReturn(rtnvscp->fileline(), new AstVarRef(rtnvscp->fileline(), rtnvscp, false))); } // Replace variable refs // Iteration requires a back, so put under temporary node { AstBegin* tempp = new AstBegin(cfuncp->fileline(),"[EditWrapper]",cfuncp); TaskRelinkVisitor visit (tempp); tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp=NULL; } // Delete rest of cloned task and return new func pushDeletep(nodep); nodep=NULL; if (debug()>=9) { cfuncp->dumpTree(cout,"-userFunc: "); } return cfuncp; } void iterateIntoFTask(AstNodeFTask* nodep) { // Iterate into the FTask we are calling. Note it may be under a different // scope then the caller, so we need to restore state. AstScope* oldscopep = m_scopep; InsertMode prevInsMode = m_insMode; AstNode* prevInsStmtp = m_insStmtp; m_scopep = m_statep->getScope(nodep); nodep->accept(*this); m_scopep = oldscopep; m_insMode = prevInsMode; m_insStmtp = prevInsStmtp; } void insertBeforeStmt(AstNode* nodep, AstNode* newp) { // See also AstNode::addBeforeStmt; this predates that function if (debug()>=9) { nodep->dumpTree(cout,"-newstmt:"); } if (!m_insStmtp) nodep->v3fatalSrc("Function not underneath a statement"); if (m_insMode == IM_BEFORE) { // Add the whole thing before insertAt UINFO(5," IM_Before "<=9) { newp->dumpTree(cout,"-newfunc:"); } m_insStmtp->addHereThisAsNext(newp); } else if (m_insMode == IM_AFTER) { UINFO(5," IM_After "<addNextHere(newp); } else if (m_insMode == IM_WHILE_PRECOND) { UINFO(5," IM_While_Precond "<castWhile(); if (!whilep) nodep->v3fatalSrc("Insert should be under WHILE"); whilep->addPrecondsp(newp); } else { nodep->v3fatalSrc("Unknown InsertMode"); } m_insMode = IM_AFTER; m_insStmtp = newp; } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; m_insStmtp = NULL; m_modNCalls = 0; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstTopScope* nodep, AstNUser*) { m_topScopep = nodep; nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep, AstNUser*) { m_scopep = nodep; m_insStmtp = NULL; nodep->iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked?"); iterateIntoFTask(nodep->taskp()); // First, do hierarchical funcs UINFO(4," FTask REF "<=9) { nodep->dumpTree(cout,"-inlfunc:"); } if (!m_scopep) nodep->v3fatalSrc("func ref not under scope"); string namePrefix = ((nodep->castFuncRef()?"__Vfunc_":"__Vtask_") +nodep->taskp()->shortName()+"__"+cvtToStr(m_modNCalls++)); // Create output variable AstVarScope* outvscp = NULL; if (nodep->taskp()->isFunction()) { // Not that it's a FUNCREF, but that we're calling a function (perhaps as a task) outvscp = createVarScope (nodep->taskp()->fvarp()->castVar(), namePrefix+"__Vfuncout"); } // Create cloned statements AstNode* beginp; if (m_statep->ftaskNoInline(nodep->taskp())) { // This may share VarScope's with a public task, if any. Yuk. beginp = createNonInlinedFTask(nodep, namePrefix, outvscp); } else { beginp = createInlinedFTask(nodep, namePrefix, outvscp); } // Replace the ref if (nodep->castFuncRef()) { if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function"); AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false); nodep->replaceWith(outrefp); // Insert new statements insertBeforeStmt(nodep, beginp); } else { // outvscp maybe non-NULL if calling a function in a taskref, // but if so we want to simply ignore the function result nodep->replaceWith(beginp); } // Cleanup nodep->deleteTree(); nodep=NULL; UINFO(4," FTask REF Done.\n"); } virtual void visit(AstNodeFTask* nodep, AstNUser*) { UINFO(4," Inline "<stmtsp(); // Might be null if no statements, but we won't use it if (!nodep->user1SetOnce()) { // Just one creation needed per function // Expand functions in it int modes = 0; if (nodep->dpiImport()) modes++; if (nodep->dpiExport()) modes++; if (nodep->taskPublic()) modes++; if (modes > 1) nodep->v3error("Cannot mix DPI import, DPI export and/or public on same function: "<prettyName()); if (nodep->dpiImport() || nodep->dpiExport() || nodep->taskPublic() || m_statep->ftaskNoInline(nodep)) { // Clone it first, because we may have later FTaskRef's that still need // the original version. if (m_statep->ftaskNoInline(nodep)) m_statep->checkPurity(nodep); AstNodeFTask* clonedFuncp = nodep->cloneTree(false); AstCFunc* cfuncp = makeUserFunc(clonedFuncp, m_statep->ftaskNoInline(nodep)); nodep->addNextHere(cfuncp); if (nodep->dpiImport() || m_statep->ftaskNoInline(nodep)) { m_statep->ftaskCFuncp(nodep, cfuncp); } iterateIntoFTask(clonedFuncp); // Do the clone too } // Any variables inside the function still have varscopes pointing to them. // We're going to delete the vars, so delete the varscopes. if (nodep->isFunction()) { if (AstVar* portp = nodep->fvarp()->castVar()) { AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp); UINFO(9," funcremovevsc "<unlinkFrBack()); vscp=NULL; } } for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp=nextp) { nextp = stmtp->nextp(); if (AstVar* portp = stmtp->castVar()) { AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp); UINFO(9," funcremovevsc "<unlinkFrBack()); vscp=NULL; } } // Just push for deletion, as other references to func may // remain until visitor exits nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } m_insMode = prevInsMode; m_insStmtp = prevInsStmtp; } virtual void visit(AstWhile* nodep, AstNUser*) { // Special, as statements need to be put in different places // Preconditions insert first just before themselves (the normal rule for other statement types) m_insStmtp = NULL; // First thing should be new statement nodep->precondsp()->iterateAndNext(*this); // Conditions insert first at end of precondsp. m_insMode = IM_WHILE_PRECOND; m_insStmtp = nodep; nodep->condp()->iterateAndNext(*this); // Body insert just before themselves m_insStmtp = NULL; // First thing should be new statement nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); // Done the loop m_insStmtp = NULL; // Next thing should be new statement } virtual void visit(AstNodeFor* nodep, AstNUser*) { nodep->v3fatalSrc("For statements should have been converted to while statements in V3Begin.cpp\n"); } virtual void visit(AstNodeStmt* nodep, AstNUser*) { m_insMode = IM_BEFORE; m_insStmtp = nodep; nodep->iterateChildren(*this); m_insStmtp = NULL; // Next thing should be new statement } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS TaskVisitor(AstNetlist* nodep, TaskStateVisitor* statep) : m_statep(statep) { m_modp = NULL; m_topScopep = NULL; m_scopep = NULL; m_insStmtp = NULL; AstNode::user1ClearTree(); nodep->accept(*this); } virtual ~TaskVisitor() {} }; //###################################################################### // Task class functions V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) { // Output list will be in order of the port declaration variables (so func calls are made right in C) // Missing pin/expr? We return (pinvar, NULL) // Extra pin/expr? We clean it up typedef map NameToIndex; NameToIndex nameToIndex; V3TaskConnects tconnects; if (!nodep->taskp()) nodep->v3fatalSrc("unlinked"); // Find ports //map name_to_pinnum; int tpinnum = 0; AstVar* sformatp = NULL; for (AstNode* stmtp = taskStmtsp; stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO()) { tconnects.push_back(make_pair(portp, (AstArg*)NULL)); nameToIndex.insert(make_pair(portp->name(), tpinnum)); // For name based connections tpinnum++; if (portp->attrSFormat()) { sformatp = portp; } else if (sformatp) { nodep->v3error("/*verilator sformat*/ can only be applied to last argument of a function"); } } } } // Find pins int ppinnum = 0; bool reorganize = false; for (AstNode* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) { nextp = pinp->nextp(); AstArg* argp = pinp->castArg(); if (!argp) pinp->v3fatalSrc("Non-arg under ftask reference"); if (argp->name() != "") { // By name NameToIndex::iterator it = nameToIndex.find(argp->name()); if (it == nameToIndex.end()) { pinp->v3error("No such argument '"<prettyName() <<"' in function call to "<taskp()->prettyTypeName()); // We'll just delete it; seems less error prone than making a false argument pinp->unlinkFrBack()->deleteTree(); pinp=NULL; } else { if (tconnects[it->second].second) { pinp->v3error("Duplicate argument '"<prettyName() <<"' in function call to "<taskp()->prettyTypeName()); } argp->name(""); // Can forget name as will add back in pin order tconnects[it->second].second = argp; reorganize = true; } } else { // By pin number if (ppinnum >= tpinnum) { if (sformatp) { tconnects.push_back(make_pair(sformatp, (AstArg*)NULL)); tconnects[ppinnum].second = argp; tpinnum++; } else { pinp->v3error("Too many arguments in function call to "<taskp()->prettyTypeName()); // We'll just delete it; seems less error prone than making a false argument pinp->unlinkFrBack()->deleteTree(); pinp=NULL; } } else { tconnects[ppinnum].second = argp; } } ppinnum++; } // Connect missing ones for (int i=0; iexprp()) { AstNode* newvaluep = NULL; if (!portp->valuep()) { nodep->v3error("Missing argument on non-defaulted argument '"<prettyName() <<"' in function call to "<taskp()->prettyTypeName()); newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0); } else if (!portp->valuep()->castConst()) { // Problem otherwise is we might have a varref, task call, or something else that only // makes sense in the domain of the function, not the callee. nodep->v3error("Unsupported: Non-constant default value in missing argument '"<prettyName() <<"' in function call to "<taskp()->prettyTypeName()); newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0); } else { newvaluep = portp->valuep()->cloneTree(true); } // To avoid problems with callee needing to know to deleteTree or not, we make this into a pin UINFO(9,"Default pin for "<fileline(), portp->name(), newvaluep); if (tconnects[i].second) { // Have a "NULL" pin already defined for it tconnects[i].second->unlinkFrBack()->deleteTree(); tconnects[i].second=NULL; } tconnects[i].second = newp; reorganize = true; } if (tconnects[i].second) { UINFO(9,"Connect "< "< NONE"<pinsp()) nodep->pinsp()->unlinkFrBack(); // Must unlink each pin, not all pins linked together as one list for (int i=0; iv3fatalSrc("Lost argument in func conversion"); nodep->addPinsp(argp); } } if (debug()>=9) { nodep->dumpTree(cout,"-ftref-out: "); for (int i=0; i= 3); } verilator-3.874/src/V3Dead.cpp0000664000177100017500000002421612525171733016077 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Dead code elimination // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // DEAD TRANSFORMATIONS: // Remove any unreferenced modules // Remove any unreferenced variables // // TODO: A graph would make the process of circular and interlinked // dependencies easier to resolve. // NOTE: If redo this, consider using maybePointedTo()/broken() ish scheme // instead of needing as many visitors. //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Dead.h" #include "V3Ast.h" //###################################################################### class DeadModVisitor : public AstNVisitor { // In a module that is dead, cleanup the in-use counts of the modules private: // NODE STATE // ** Shared with DeadVisitor ** // VISITORS virtual void visit(AstCell* nodep, AstNUser*) { nodep->iterateChildren(*this); nodep->modp()->user1(nodep->modp()->user1() - 1); } //----- virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS DeadModVisitor(AstNodeModule* nodep) { nodep->accept(*this); } virtual ~DeadModVisitor() {} }; //###################################################################### // Dead state, as a visitor of each AstNode class DeadVisitor : public AstNVisitor { private: // NODE STATE // Entire Netlist: // AstNodeModule::user1() -> int. Count of number of cells referencing this module. // AstVar::user1() -> int. Count of number of references // AstVarScope::user1() -> int. Count of number of references // AstNodeDType::user1() -> int. Count of number of references AstUser1InUse m_inuser1; // TYPES typedef multimap AssignMap; // STATE AstNodeModule* m_modp; // Current module vector m_varEtcsp; // List of all encountered to avoid another loop through tree vector m_vscsp; // List of all encountered to avoid another loop through tree AssignMap m_assignMap; // List of all simple assignments for each variable bool m_elimUserVars; // Allow removal of user's vars bool m_elimDTypes; // Allow removal of DTypes bool m_sideEffect; // Side effects discovered in assign RHS // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void checkAll(AstNode* nodep) { if (nodep != nodep->dtypep()) { // NodeDTypes reference themselves if (AstNode* subnodep = nodep->dtypep()) subnodep->user1Inc(); } if (AstNode* subnodep = nodep->getChildDTypep()) subnodep->user1Inc(); } void checkDType(AstNodeDType* nodep) { if (!nodep->generic() // Don't remove generic types && m_elimDTypes // dtypes stick around until post-widthing && !nodep->castMemberDType() // Keep member names iff upper type exists ) { m_varEtcsp.push_back(nodep); } if (AstNode* subnodep = nodep->virtRefDTypep()) subnodep->user1Inc(); } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; nodep->iterateChildren(*this); checkAll(nodep); m_modp = NULL; } virtual void visit(AstCell* nodep, AstNUser*) { nodep->iterateChildren(*this); checkAll(nodep); nodep->modp()->user1Inc(); } virtual void visit(AstNodeVarRef* nodep, AstNUser*) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->varScopep()) { nodep->varScopep()->user1Inc(); nodep->varScopep()->varp()->user1Inc(); } if (nodep->varp()) { nodep->varp()->user1Inc(); } if (nodep->packagep()) { nodep->packagep()->user1Inc(); } } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->packagep()) { nodep->packagep()->user1Inc(); } } virtual void visit(AstRefDType* nodep, AstNUser*) { nodep->iterateChildren(*this); checkDType(nodep); checkAll(nodep); if (nodep->packagep()) { nodep->packagep()->user1Inc(); } } virtual void visit(AstNodeDType* nodep, AstNUser*) { nodep->iterateChildren(*this); checkDType(nodep); checkAll(nodep); } virtual void visit(AstEnumItemRef* nodep, AstNUser*) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->packagep()) { nodep->packagep()->user1Inc(); } } virtual void visit(AstTypedef* nodep, AstNUser*) { nodep->iterateChildren(*this); checkAll(nodep); // Don't let packages with only public variables disappear // Normal modules may disappear, e.g. if they are parameterized then removed if (nodep->attrPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc(); } virtual void visit(AstVarScope* nodep, AstNUser*) { nodep->iterateChildren(*this); checkAll(nodep); if (mightElim(nodep->varp())) { m_vscsp.push_back(nodep); } } virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); checkAll(nodep); if (nodep->isSigPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc(); if (mightElim(nodep)) { m_varEtcsp.push_back(nodep); } } virtual void visit(AstNodeAssign* nodep, AstNUser*) { // See if simple assignments to variables may be eliminated because that variable is never used. // Similar code in V3Life m_sideEffect = false; nodep->rhsp()->iterateAndNext(*this); checkAll(nodep); // Has to be direct assignment without any EXTRACTing. AstVarRef* varrefp = nodep->lhsp()->castVarRef(); if (varrefp && !m_sideEffect && varrefp->varScopep()) { // For simplicity, we only remove post-scoping m_assignMap.insert(make_pair(varrefp->varScopep(), nodep)); checkAll(varrefp); // Must track reference to dtype() } else { // Track like any other statement nodep->lhsp()->iterateAndNext(*this); } checkAll(nodep); } //----- virtual void visit(AstNode* nodep, AstNUser*) { if (nodep->isOutputter()) m_sideEffect=true; nodep->iterateChildren(*this); checkAll(nodep); } // METHODS void deadCheckMod() { // Kill any unused modules // V3LinkCells has a graph that is capable of this too, but we need to do it // after we've done all the generate blocks for (bool retry=true; retry; ) { retry=false; AstNodeModule* nextmodp; for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) { nextmodp = modp->nextp()->castNodeModule(); if (modp->level()>2 && modp->user1()==0 && !modp->internal()) { // > 2 because L1 is the wrapper, L2 is the top user module UINFO(4," Dead module "<unlinkFrBack()->deleteTree(); modp=NULL; retry = true; } } } } bool mightElim(AstVar* nodep) { return (!nodep->isSigPublic() // Can't elim publics! && !nodep->isIO() && (nodep->isTemp() || (nodep->isParam() && !nodep->isTrace()) || m_elimUserVars)); // Post-Trace can kill most anything } void deadCheckVar() { // Delete any unused varscopes for (vector::iterator it = m_vscsp.begin(); it!=m_vscsp.end(); ++it) { AstVarScope* vscp = *it; if (vscp->user1() == 0) { UINFO(4," Dead "< eqrange = m_assignMap.equal_range(vscp); for (AssignMap::iterator it = eqrange.first; it != eqrange.second; ++it) { AstNodeAssign* assp = it->second; UINFO(4," Dead assign "<unlinkFrBack()->deleteTree(); assp=NULL; } vscp->unlinkFrBack()->deleteTree(); vscp=NULL; } } for (vector::iterator it = m_varEtcsp.begin(); it!=m_varEtcsp.end(); ++it) { if ((*it)->user1() == 0) { UINFO(4," Dead "<<(*it)<unlinkFrBack()->deleteTree(); (*it)=NULL; } } } public: // CONSTRUCTORS DeadVisitor(AstNetlist* nodep, bool elimUserVars, bool elimDTypes) { m_modp = NULL; m_elimUserVars = elimUserVars; m_elimDTypes = elimDTypes; m_sideEffect = false; // Prepare to remove some datatypes nodep->typeTablep()->clearCache(); // Operate on whole netlist nodep->accept(*this); deadCheckVar(); // Modules after vars, because might be vars we delete inside a mod we delete deadCheckMod(); // We may have removed some datatypes, cleanup nodep->typeTablep()->repairCache(); } virtual ~DeadVisitor() {} }; //###################################################################### // Dead class functions void V3Dead::deadifyModules(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } void V3Dead::deadifyDTypes(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Dead::deadifyAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3EmitV.h0000664000177100017500000000255612525171733015736 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit Verilog code for module tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3EMITV_H_ #define _V3EMITV_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3EmitV { public: static void emitv(); static void verilogForTree(AstNode* nodep, ostream& os=cout); static void verilogPrefixedTree(AstNode* nodep, ostream& os, const string& prefix, int flWidth, AstSenTree* domainp, bool user3percent); }; #endif // Guard verilator-3.874/src/V3LifePost.h0000664000177100017500000000226012525171733016427 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Lifepost variable analysis // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LIFEPOST_H_ #define _V3LIFEPOST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3LifePost { public: static void lifepostAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Coverage.h0000664000177100017500000000230412525171733016434 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Coverage modules/signals together // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3COVERAGE_H_ #define _V3COVERAGE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Coverage { public: // CREATORS static void coverage(AstNetlist* rootp); }; #endif // Guard verilator-3.874/src/VlcBucket.h0000664000177100017500000000757412525171734016371 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Bucket container // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCBUCKET_H_ #define _VLCBUCKET_H_ 1 #include "config_build.h" #include "verilatedos.h" //******************************************************************** // VlcBuckets - Container of all coverage point hits for a given test // This is a bitmap array - we store a single bit to indicate a test // has hit that point with sufficient coverage. class VlcBuckets { private: // MEMBERS vluint64_t* m_datap; ///< Pointer to first bucket (dynamically allocated) vluint64_t m_dataSize; ///< Current entries in m_datap vluint64_t m_bucketsCovered; ///< Num buckets with sufficient coverage private: static inline vluint64_t covBit(vluint64_t point) { return 1ULL<<(point & 63); } inline vluint64_t allocSize() const { return sizeof(vluint64_t) * m_dataSize / 64; } void allocate(vluint64_t point) { vluint64_t oldsize = m_dataSize; if (m_dataSize= sufficient()) { //UINFO(9," addData "< #include #include #include #include #include #include #include "V3Global.h" #include "V3GraphAlg.h" //###################################################################### //###################################################################### // Algorithms - delete void V3Graph::deleteCutableOnlyEdges() { // Any vertices with only cutable edges will get deleted // Vertex::m_user begin: indicates can be deleted // Pass 1, mark those. Don't delete now, as we don't want to rip out whole trees for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertexp->user(true); for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { if (!edgep->cutable()) { vertexp->user(false); // Can't delete it break; } } for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (!edgep->cutable()) { vertexp->user(false); // Can't delete it break; } } } // Pass 2, delete those marked // Rather than doing a delete() we set the weight to 0 which disconnects the edge. for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (vertexp->user()) { //UINFO(7,"Disconnect "<name()<outBeginp(); edgep; edgep=edgep->outNextp()) { edgep->cut(); } } } // Vertex::m_user end, now unused } //###################################################################### //###################################################################### // Algorithms - weakly connected components class GraphRemoveRedundant : GraphAlg { bool m_sumWeights; ///< Sum, rather then maximize weights private: void main() { for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertexIterate(vertexp); } } void vertexIterate(V3GraphVertex* vertexp) { // Clear marks for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { edgep->top()->userp(NULL); } // Mark edges and detect duplications for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); if (followEdge(edgep)) { V3GraphVertex* outVertexp = edgep->top(); V3GraphEdge* prevEdgep = (V3GraphEdge*)outVertexp->userp(); if (!prevEdgep) { // No previous assignment outVertexp->userp(edgep); } else { // Duplicate bool saveOld = true; if (prevEdgep->cutable() && !edgep->cutable()) { saveOld = false; // new !cutable more important than old } else if (!prevEdgep->cutable() && edgep->cutable()) { saveOld = true; // old !cutable more important than new } else { saveOld = true; if (!m_sumWeights && (prevEdgep->weight() < edgep->weight())) { // Keep max weight prevEdgep->weight(edgep->weight()); } } if (saveOld) { if (m_sumWeights) prevEdgep->weight(prevEdgep->weight() + edgep->weight()); edgep->unlinkDelete(); edgep = NULL; } else { if (m_sumWeights) edgep->weight(prevEdgep->weight() + edgep->weight()); prevEdgep->unlinkDelete(); prevEdgep = NULL; outVertexp->userp(edgep); } } } } } public: GraphRemoveRedundant(V3Graph* graphp, V3EdgeFuncP edgeFuncp, bool sumWeights) : GraphAlg(graphp, edgeFuncp), m_sumWeights(sumWeights) { main(); } ~GraphRemoveRedundant() {} }; void V3Graph::removeRedundantEdges(V3EdgeFuncP edgeFuncp) { GraphRemoveRedundant (this, edgeFuncp, false); } void V3Graph::removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp) { GraphRemoveRedundant (this, edgeFuncp, true); } //###################################################################### //###################################################################### // Algorithms - weakly connected components class GraphAlgWeakly : GraphAlg { private: void main() { // Initialize state m_graphp->clearColors(); // Color graph uint32_t currentColor = 0; for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { currentColor ++; vertexIterate(vertexp, currentColor); } } void vertexIterate(V3GraphVertex* vertexp, uint32_t currentColor) { // Assign new color to each unvisited node // then visit each of its edges, giving them the same color if (vertexp->color()) return; // Already colored it vertexp->color(currentColor); for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (followEdge(edgep)) { vertexIterate(edgep->top(), currentColor); } } for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) { if (followEdge(edgep)) { vertexIterate(edgep->fromp(), currentColor); } } } public: GraphAlgWeakly(V3Graph* graphp, V3EdgeFuncP edgeFuncp) : GraphAlg(graphp, edgeFuncp) { main(); } ~GraphAlgWeakly() {} }; void V3Graph::weaklyConnected(V3EdgeFuncP edgeFuncp) { GraphAlgWeakly (this, edgeFuncp); } //###################################################################### //###################################################################### // Algorithms - strongly connected components class GraphAlgStrongly : GraphAlg { private: uint32_t m_currentDfs; // DFS count vector m_callTrace; // List of everything we hit processing so far void main() { // Use Tarjan's algorithm to find the strongly connected subgraphs. // Node State: // Vertex::user // DFS number indicating possible root of subtree, 0=not iterated // Vertex::color // Output subtree number (fully processed) // Clear info for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertexp->color(0); vertexp->user(0); } // Color graph for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (!vertexp->user()) { m_currentDfs++; vertexIterate(vertexp); } } // If there's a single vertex of a color, it doesn't need a subgraph // This simplifies the consumer's code, and reduces graph debugging clutter for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { bool onecolor = true; for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (followEdge(edgep)) { if (vertexp->color() == edgep->top()->color()) { onecolor = false; break; } } } if (onecolor) vertexp->color(0); } } void vertexIterate(V3GraphVertex* vertexp) { uint32_t thisDfsNum = m_currentDfs++; vertexp->user(thisDfsNum); vertexp->color(0); for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (followEdge(edgep)) { V3GraphVertex* top = edgep->top(); if (!top->user()) { // Dest not computed yet vertexIterate(top); } if (!top->color()) { // Dest not in a component if (vertexp->user() > top->user()) vertexp->user(top->user()); } } } if (vertexp->user() == thisDfsNum) { // New head of subtree vertexp->color(thisDfsNum); // Mark as component while (!m_callTrace.empty()) { V3GraphVertex* popVertexp = m_callTrace.back(); if (popVertexp->user() >= thisDfsNum) { // Lower node is part of this subtree m_callTrace.pop_back(); popVertexp->color(thisDfsNum); } else { break; } } } else { // In another subtree (maybe...) m_callTrace.push_back(vertexp); } } public: GraphAlgStrongly(V3Graph* graphp, V3EdgeFuncP edgeFuncp) : GraphAlg(graphp, edgeFuncp) { m_currentDfs = 0; main(); } ~GraphAlgStrongly() {} }; void V3Graph::stronglyConnected(V3EdgeFuncP edgeFuncp) { GraphAlgStrongly (this, edgeFuncp); } //###################################################################### //###################################################################### // Algorithms - ranking class GraphAlgRank : GraphAlg { private: void main() { // Rank each vertex, ignoring cutable edges // Vertex::m_user begin: 1 indicates processing, 2 indicates completed // Clear existing ranks for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertexp->rank(0); vertexp->user(0); } for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (!vertexp->user()) { vertexIterate(vertexp,1); } } } void vertexIterate(V3GraphVertex* vertexp, uint32_t currentRank) { // Assign rank to each unvisited node // If larger rank is found, assign it and loop back through // If we hit a back node make a list of all loops if (vertexp->user() == 1) { m_graphp->reportLoops(m_edgeFuncp, vertexp); m_graphp->loopsMessageCb(vertexp); return; } if (vertexp->rank() >= currentRank) return; // Already processed it vertexp->user(1); vertexp->rank(currentRank); for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (followEdge(edgep)) { vertexIterate(edgep->top(),currentRank+1); } } vertexp->user(2); } public: GraphAlgRank(V3Graph* graphp, V3EdgeFuncP edgeFuncp) : GraphAlg(graphp, edgeFuncp) { main(); } ~GraphAlgRank() {} }; void V3Graph::rank() { GraphAlgRank (this, &V3GraphEdge::followAlwaysTrue); } void V3Graph::rank(V3EdgeFuncP edgeFuncp) { GraphAlgRank (this, edgeFuncp); } //###################################################################### //###################################################################### // Algorithms - ranking class GraphAlgRLoops : GraphAlg { private: vector m_callTrace; // List of everything we hit processing so far bool m_done; // Exit algorithm void main(V3GraphVertex* vertexp) { // Vertex::m_user begin: 1 indicates processing, 2 indicates completed // Clear existing ranks m_graphp->userClearVertices(); m_callTrace.reserve(100); vertexIterate(vertexp, 0); } void vertexIterate(V3GraphVertex* vertexp, uint32_t currentRank) { // Assign rank to each unvisited node // When we hit ourself again, return the list of all loops if (m_done) return; // Can't just reserve(), unless we modify size() before setting array directly while (m_callTrace.size() <= currentRank) m_callTrace.push_back(vertexp); m_callTrace[currentRank++] = vertexp; if (vertexp->user() == 1) { for (unsigned i=0; iloopsVertexCb(m_callTrace[i]); } m_done = true; return; } if (vertexp->user() == 2) return; // Already processed it vertexp->user(1); for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (followEdge(edgep)) { vertexIterate(edgep->top(),currentRank); } } vertexp->user(2); } public: GraphAlgRLoops(V3Graph* graphp, V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) : GraphAlg(graphp, edgeFuncp) { m_done = false; main(vertexp); } ~GraphAlgRLoops() {} }; void V3Graph::reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) { GraphAlgRLoops (this, edgeFuncp, vertexp); } //###################################################################### //###################################################################### // Algorithms - subtrees class GraphAlgSubtrees : GraphAlg { private: V3Graph* m_loopGraphp; //! Iterate through all connected nodes of a graph with a loop or loops. V3GraphVertex* vertexIterateAll(V3GraphVertex* vertexp) { if (V3GraphVertex* newVertexp = (V3GraphVertex*)vertexp->userp()) { return newVertexp; } else { newVertexp = vertexp->clone(m_loopGraphp); vertexp->userp(newVertexp); for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { if (followEdge(edgep)) { V3GraphEdge* newEdgep = (V3GraphEdge*)edgep->userp(); if (!newEdgep) { V3GraphVertex* newTop = vertexIterateAll(edgep->top()); newEdgep = edgep->clone(m_loopGraphp, newVertexp, newTop); edgep->userp(newEdgep); } } } return newVertexp; } } public: GraphAlgSubtrees(V3Graph* graphp, V3Graph* loopGraphp, V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) : GraphAlg(graphp, edgeFuncp), m_loopGraphp (loopGraphp) { // Vertex::m_userp - New vertex if we have seen this vertex already // Edge::m_userp - New edge if we have seen this edge already m_graphp->userClearVertices(); m_graphp->userClearEdges(); (void) vertexIterateAll(vertexp); } ~GraphAlgSubtrees() {} }; //! Report the entire connected graph with a loop or loops void V3Graph::subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp, V3Graph* loopGraphp) { GraphAlgSubtrees (this, loopGraphp, edgeFuncp, vertexp); } //###################################################################### //###################################################################### // Algorithms - make non cutable void V3Graph::makeEdgesNonCutable(V3EdgeFuncP edgeFuncp) { for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { // Only need one direction, we'll always see the other at some point... for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { if (edgep->cutable() && edgep->weight() && (edgeFuncp)(edgep)) { edgep->cutable(false); } } } } //###################################################################### //###################################################################### // Algorithms - sorting struct GraphSortVertexCmp { inline bool operator () (const V3GraphVertex* lhsp, const V3GraphVertex* rhsp) const { return lhsp->sortCmp(rhsp) < 0; } }; struct GraphSortEdgeCmp { inline bool operator () (const V3GraphEdge* lhsp, const V3GraphEdge* rhsp) const { return lhsp->sortCmp(rhsp) < 0; } }; void V3Graph::sortVertices() { // Sort list of vertices by rank, then fanout vector vertices; for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { vertices.push_back(vertexp); } std::stable_sort(vertices.begin(), vertices.end(), GraphSortVertexCmp()); this->verticesUnlink(); for (vector::iterator it = vertices.begin(); it!=vertices.end(); ++it) { (*it)->verticesPushBack(this); } } void V3Graph::sortEdges() { // Sort edges by rank then fanout of node they point to vector edges; for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { // Make a vector for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { edges.push_back(edgep); } // Sort std::stable_sort(edges.begin(), edges.end(), GraphSortEdgeCmp()); // Relink edges in specified order // We know the vector contains all of the edges that were // there originally (didn't delete or add) vertexp->outUnlink(); for (vector::const_iterator it = edges.begin(); it!=edges.end(); ++it) { (*it)->outPushBack(); } // Prep for next edges.clear(); } } //###################################################################### //###################################################################### // Algorithms - ordering // Compute near optimal ordering of the nodes, where: // If a required edge is A->B, rank(A)verticesNextp()) { if (!vertexp->user()) { orderDFSIterate(vertexp); } } // Sort list of vertices by rank, then fanout. Fanout is a bit of a // misnomer. It is the sum of all the fanouts of nodes reached from a node // *plus* the count of edges in to that node. sortVertices(); // Sort edges by rank then fanout of node they point to sortEdges(); } double V3Graph::orderDFSIterate(V3GraphVertex* vertexp) { // Compute fanouts of each node // If forward edge, don't double count that fanout if (vertexp->user() == 2) return vertexp->fanout(); // Already processed it if (vertexp->user() == 1) v3fatalSrc("Loop found, backward edges should be dead\n"); vertexp->user(1); double fanout = 0; for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { if (edgep->weight()) fanout += orderDFSIterate(edgep->m_top); } // Just count inbound edges for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { if (edgep->weight()) fanout ++; } vertexp->fanout(fanout); vertexp->user(2); return vertexp->fanout(); } verilator-3.874/src/V3LangCode.h0000664000177100017500000000437212525171733016364 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Language code class // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LANGCODE_H_ #define _V3LANGCODE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include //###################################################################### //! Class for the different languages supported. //! A separate file, since used both in V3Options (globally) and FileLine 9per //! file). class V3LangCode { public: enum en { L_ERROR, // Must be first. L1364_1995, L1364_2001, L1364_2005, L1800_2005, L1800_2009, L1800_2012, // ***Add new elements below also*** _ENUM_END }; const char* ascii() const { const char* names[] = { // These must match the `begin_keywords values. " ERROR", "1364-1995", "1364-2001", "1364-2005", "1800-2005", "1800-2009", "1800-2012" }; return names[m_e]; }; static V3LangCode mostRecent() { return V3LangCode(L1800_2012); } bool systemVerilog() const { return m_e == L1800_2005 || m_e == L1800_2009 || m_e == L1800_2012; } bool legal() const { return m_e != L_ERROR; } // enum en m_e; inline V3LangCode () : m_e(L_ERROR) {} inline V3LangCode (en _e) : m_e(_e) {} V3LangCode (const char* textp); explicit inline V3LangCode (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; //###################################################################### #endif // guard verilator-3.874/src/V3Order.h0000664000177100017500000000223512525171733015757 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Block code ordering // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3ORDER_H_ #define _V3ORDER_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Order { public: static void orderAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Undriven.h0000664000177100017500000000226712525171733016503 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Check for unused/undriven signals // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3UNDRIVEN_H_ #define _V3UNDRIVEN_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Undriven { public: static void undrivenAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/VlcPoint.h0000664000177100017500000001125712525171734016236 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Coverage points // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCPOINT_H_ #define _VLCPOINT_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "verilated_cov_key.h" #include #include #include //******************************************************************** // VlcPoint - A coverage point (across all tests) class VlcPoint { private: // MEMBERS string m_name; //< Name of the point vluint64_t m_pointNum; //< Point number vluint64_t m_testsCovering;//< Number tests with non-zero coverage of this point vluint64_t m_count; //< Count of hits across all tests public: // CONSTRUCTORS VlcPoint(const string& name, int pointNum) { m_name = name; m_pointNum = pointNum; m_testsCovering = 0; m_count = 0; } ~VlcPoint() {} // ACCESSORS const string& name() const { return m_name; } vluint64_t pointNum() const { return m_pointNum; } vluint64_t testsCovering() const { return m_testsCovering; } void countInc(vluint64_t inc) { m_count += inc; } vluint64_t count() const { return m_count; } void testsCoveringInc() { m_testsCovering++; } // KEY ACCESSORS string filename() const { return keyExtract(VL_CIK_FILENAME); } string comment() const { return keyExtract(VL_CIK_COMMENT); } string type() const { return keyExtract(VL_CIK_TYPE); } string thresh() const { return keyExtract(VL_CIK_THRESH); } // string as maybe "" int lineno() const { return atoi(keyExtract(VL_CIK_LINENO).c_str()); } int column() const { return atoi(keyExtract(VL_CIK_COLUMN).c_str()); } // METHODS string keyExtract(const char* shortKey) const { // Hot function size_t shortLen = strlen(shortKey); const string namestr = name(); for (const char* cp = namestr.c_str(); *cp; ++cp) { if (*cp == '\001') { if (0==strncmp(cp+1, shortKey, shortLen) && cp[shortLen+1] == '\002') { cp += shortLen+2; // Skip \001+short+\002 const char* ep = cp; while (*ep && *ep != '\001') ++ep; return string(cp, ep-cp); } } } return ""; } static void dumpHeader() { cout<<"Points:\n"; cout<<" Num, TestsCover, Count, Name"< NameMap; NameMap m_nameMap; //< Name to point-number vector m_points; //< List of all points vluint64_t m_numPoints; //< Total unique points public: // ITERATORS typedef NameMap ByName; typedef ByName::iterator iterator; ByName::iterator begin() { return m_nameMap.begin(); } ByName::iterator end() { return m_nameMap.end(); } public: // CONSTRUCTORS VlcPoints() { m_numPoints = 0; } ~VlcPoints() {} // METHODS void dump() { UINFO(2,"dumpPoints...\n"); VlcPoint::dumpHeader(); for (VlcPoints::ByName::iterator it=begin(); it!=end(); ++it) { const VlcPoint& point = pointNumber(it->second); point.dump(); } } VlcPoint& pointNumber(vluint64_t num) { return m_points[num]; } vluint64_t findAddPoint(const string& name, vluint64_t count) { vluint64_t pointnum; NameMap::iterator iter = m_nameMap.find(name); if (iter != m_nameMap.end()) { pointnum = iter->second; m_points[pointnum].countInc(count); } else { pointnum = m_numPoints++; VlcPoint point (name, pointnum); point.countInc(count); m_points.push_back(point); m_nameMap.insert(make_pair(point.name(), point.pointNum())); } return pointnum; } }; //###################################################################### #endif // guard verilator-3.874/src/V3OrderGraph.h0000664000177100017500000005575712525171733016762 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Block code ordering // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // OrderGraph Class Hierarchy: // // V3GraphVertex // OrderMoveVertex // OrderEitherVertex // OrderInputsVertex // OrderSettleVertex // OrderLogicVertex // OrderLoopBeginVertex // OrderLoopEndVertex // OrderVarVertex // OrderVarStdVertex // OrderVarPreVertex // OrderVarPostVertex // OrderVarPordVertex // OrderVarSettleVertex // // V3GraphEdge // OrderEdge // OrderChangeDetEdge // OrderComboCutEdge // OrderPostCutEdge // OrderPreCutEdge //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include "V3Ast.h" #include "V3Graph.h" class OrderVisitor; class OrderMoveVertex; class OrderMoveDomScope; //###################################################################### enum OrderWeights { WEIGHT_INPUT = 1, // Low weight just so dot graph looks nice WEIGHT_COMBO = 1, // Breakable combo logic WEIGHT_LOOPBE = 1, // Connection to loop begin/end WEIGHT_POST = 2, // Post-delayed used var WEIGHT_PRE = 3, // Breakable pre-delayed used var WEIGHT_MEDIUM = 8, // Medium weight just so dot graph looks nice WEIGHT_NORMAL = 32 }; // High weight just so dot graph looks nice enum OrderLoopId { LOOPID_UNKNOWN = 0, // Not assigned yet LOOPID_NOTLOOPED=1, // Not looped LOOPID_FIRST = 2, // First assigned id (numbers increment from here) LOOPID_MAX = (1<<30) }; struct OrderVEdgeType { enum en { VERTEX_UNKNOWN = 0, VERTEX_INPUTS, VERTEX_SETTLE, VERTEX_LOGIC, VERTEX_VARSTD, VERTEX_VARPRE, VERTEX_VARPOST, VERTEX_VARPORD, VERTEX_VARSETTLE, VERTEX_LOOPBEGIN, VERTEX_LOOPEND, VERTEX_MOVE, EDGE_STD, EDGE_CHANGEDET, EDGE_COMBOCUT, EDGE_PRECUT, EDGE_POSTCUT, _ENUM_END }; const char* ascii() const { static const char* names[] = { "%E-vedge", "VERTEX_INPUTS", "VERTEX_SETTLE", "VERTEX_LOGIC", "VERTEX_VARSTD", "VERTEX_VARPRE", "VERTEX_VARPOST", "VERTEX_VARPORD", "VERTEX_VARSETTLE", "VERTEX_LOOPBEGIN", "VERTEX_LOOPEND", "VERTEX_MOVE", "EDGE_STD", "EDGE_CHANGEDET", "EDGE_COMBOCUT", "EDGE_PRECUT", "EDGE_POSTCUT", "_ENUM_END" }; return names[m_e]; } enum en m_e; inline OrderVEdgeType () : m_e(VERTEX_UNKNOWN) {} inline OrderVEdgeType (en _e) : m_e(_e) {} explicit inline OrderVEdgeType (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } }; inline bool operator== (OrderVEdgeType lhs, OrderVEdgeType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (OrderVEdgeType lhs, OrderVEdgeType::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (OrderVEdgeType::en lhs, OrderVEdgeType rhs) { return (lhs == rhs.m_e); } //###################################################################### // Graph types class OrderGraph : public V3Graph { public: OrderGraph() {} virtual ~OrderGraph() {} // Methods virtual void loopsVertexCb(V3GraphVertex* vertexp); }; //! Graph for UNOPTFLAT loops class UnoptflatGraph : public OrderGraph { public: UnoptflatGraph() {} virtual ~UnoptflatGraph() {} // Methods virtual void loopsVertexCb(V3GraphVertex* vertexp); }; //###################################################################### // Vertex types class OrderEitherVertex : public V3GraphVertex { AstScope* m_scopep; // Scope the vertex is in AstSenTree* m_domainp; // Clock domain (NULL = to be computed as we iterate) OrderLoopId m_inLoop; // Loop number vertex is in bool m_isFromInput; // From input, or derrived therefrom (conservatively false) protected: OrderEitherVertex(V3Graph* graphp, const OrderEitherVertex& old) : V3GraphVertex(graphp, old), m_scopep(old.m_scopep), m_domainp(old.m_domainp) , m_inLoop(old.m_inLoop), m_isFromInput(old.m_isFromInput) {} public: OrderEitherVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp) : V3GraphVertex(graphp), m_scopep(scopep), m_domainp(domainp) , m_inLoop(LOOPID_UNKNOWN), m_isFromInput(false) {} virtual ~OrderEitherVertex() {} virtual OrderEitherVertex* clone(V3Graph* graphp) const = 0; // Methods virtual OrderVEdgeType type() const = 0; virtual bool domainMatters() = 0; // Must be in same domain when cross edge to this vertex virtual string dotName() const { return cvtToStr((void*)m_scopep)+"_"; } // Accessors void domainp(AstSenTree* domainp) { m_domainp = domainp; } AstScope* scopep() const { return m_scopep; } AstSenTree* domainp() const { return m_domainp; } OrderLoopId inLoop() const { return m_inLoop; } void inLoop(OrderLoopId inloop) { m_inLoop = inloop; } void isFromInput(bool flag) { m_isFromInput=flag; } bool isFromInput() const { return m_isFromInput; } }; class OrderInputsVertex : public OrderEitherVertex { OrderInputsVertex(V3Graph* graphp, const OrderInputsVertex& old) : OrderEitherVertex(graphp, old) {} public: OrderInputsVertex(V3Graph* graphp, AstSenTree* domainp) : OrderEitherVertex(graphp, NULL, domainp) { isFromInput(true); // By definition } virtual ~OrderInputsVertex() {} virtual OrderInputsVertex* clone(V3Graph* graphp) const { return new OrderInputsVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_INPUTS; } virtual string name() const { return "*INPUTS*"; } virtual string dotColor() const { return "green"; } virtual string dotName() const { return ""; } virtual bool domainMatters() { return false; } }; class OrderSettleVertex : public OrderEitherVertex { OrderSettleVertex(V3Graph* graphp, const OrderSettleVertex& old) : OrderEitherVertex(graphp, old) {} public: OrderSettleVertex(V3Graph* graphp, AstSenTree* domainp) : OrderEitherVertex(graphp, NULL, domainp) {} virtual ~OrderSettleVertex() {} virtual OrderSettleVertex* clone(V3Graph* graphp) const { return new OrderSettleVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_SETTLE; } virtual string name() const { return "*SETTLE*"; } virtual string dotColor() const { return "green"; } virtual string dotName() const { return ""; } virtual bool domainMatters() { return true; } }; class OrderLogicVertex : public OrderEitherVertex { AstNode* m_nodep; OrderMoveVertex* m_moveVxp; protected: OrderLogicVertex(V3Graph* graphp, const OrderLogicVertex& old) : OrderEitherVertex(graphp, old), m_nodep(old.m_nodep), m_moveVxp(old.m_moveVxp) {} public: OrderLogicVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp, AstNode* nodep) : OrderEitherVertex(graphp, scopep, domainp), m_nodep(nodep), m_moveVxp(NULL) {} virtual ~OrderLogicVertex() {} virtual OrderLogicVertex* clone(V3Graph* graphp) const { return new OrderLogicVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOGIC; } virtual bool domainMatters() { return true; } // Accessors virtual string name() const { return (cvtToStr((void*)m_nodep)+"\\n "+cvtToStr(nodep()->typeName())); } AstNode* nodep() const { return m_nodep; } virtual string dotColor() const { return "yellow"; } OrderMoveVertex* moveVxp() const { return m_moveVxp; } void moveVxp(OrderMoveVertex* moveVxp) { m_moveVxp = moveVxp; } }; class OrderVarVertex : public OrderEitherVertex { AstVarScope* m_varScp; OrderVarVertex* m_pilNewVertexp; // for processInsLoopNewVar bool m_isClock; // Used as clock bool m_isDelayed; // Set in a delayed assignment protected: OrderVarVertex(V3Graph* graphp, const OrderVarVertex& old) : OrderEitherVertex(graphp, old) , m_varScp(old.m_varScp), m_pilNewVertexp(old.m_pilNewVertexp), m_isClock(old.m_isClock) , m_isDelayed(old.m_isDelayed) {} public: OrderVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp) , m_pilNewVertexp(NULL), m_isClock(false), m_isDelayed(false) {} virtual ~OrderVarVertex() {} virtual OrderVarVertex* clone (V3Graph* graphp) const = 0; virtual OrderVEdgeType type() const = 0; // Accessors AstVarScope* varScp() const { return m_varScp; } void isClock(bool flag) { m_isClock=flag; } bool isClock() const { return m_isClock; } void isDelayed(bool flag) { m_isDelayed=flag; } bool isDelayed() const { return m_isDelayed; } OrderVarVertex* pilNewVertexp() const { return m_pilNewVertexp; } void pilNewVertexp (OrderVarVertex* vertexp) { m_pilNewVertexp = vertexp; } }; class OrderVarStdVertex : public OrderVarVertex { OrderVarStdVertex(V3Graph* graphp, const OrderVarStdVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarStdVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep, varScp) {} virtual ~OrderVarStdVertex() {} virtual OrderVarStdVertex* clone(V3Graph* graphp) const { return new OrderVarStdVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSTD; } virtual string name() const { return (cvtToStr((void*)varScp())+"\\n "+varScp()->name());} virtual string dotColor() const { return "skyblue"; } virtual bool domainMatters() { return true; } }; class OrderVarPreVertex : public OrderVarVertex { OrderVarPreVertex(V3Graph* graphp, const OrderVarPreVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarPreVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual ~OrderVarPreVertex() {} virtual OrderVarPreVertex* clone(V3Graph* graphp) const { return new OrderVarPreVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPRE; } virtual string name() const { return (cvtToStr((void*)varScp())+" PRE\\n "+varScp()->name());} virtual string dotColor() const { return "lightblue"; } virtual bool domainMatters() { return false; } }; class OrderVarPostVertex : public OrderVarVertex { OrderVarPostVertex(V3Graph* graphp, const OrderVarPostVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarPostVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual OrderVarPostVertex* clone(V3Graph* graphp) const { return new OrderVarPostVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPOST; } virtual ~OrderVarPostVertex() {} virtual string name() const { return (cvtToStr((void*)varScp())+" POST\\n "+varScp()->name());} virtual string dotColor() const { return "CadetBlue"; } virtual bool domainMatters() { return false; } }; class OrderVarPordVertex : public OrderVarVertex { OrderVarPordVertex(V3Graph* graphp, const OrderVarPordVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarPordVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual ~OrderVarPordVertex() {} virtual OrderVarPordVertex* clone(V3Graph* graphp) const { return new OrderVarPordVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPORD; } virtual string name() const { return (cvtToStr((void*)varScp())+" PORD\\n "+varScp()->name());} virtual string dotColor() const { return "NavyBlue"; } virtual bool domainMatters() { return false; } }; class OrderVarSettleVertex : public OrderVarVertex { OrderVarSettleVertex(V3Graph* graphp, const OrderVarSettleVertex& old) : OrderVarVertex(graphp, old) {} public: OrderVarSettleVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual ~OrderVarSettleVertex() {} virtual OrderVarSettleVertex* clone(V3Graph* graphp) const { return new OrderVarSettleVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSETTLE; } virtual string name() const { return (cvtToStr((void*)varScp())+" STL\\n "+varScp()->name());} virtual string dotColor() const { return "PowderBlue"; } virtual bool domainMatters() { return false; } }; //###################################################################### //--- Looping constructs class OrderLoopBeginVertex : public OrderLogicVertex { // A vertex can never be under two loops... // However, a LoopBeginVertex is not "under" the loop per se, and it may be under another loop. OrderLoopId m_loopId; // Arbitrary # to ID this loop uint32_t m_loopColor; // Color # of loop (for debug) OrderLoopBeginVertex(V3Graph* graphp, const OrderLoopBeginVertex& old) : OrderLogicVertex(graphp, *this) , m_loopId(old.m_loopId), m_loopColor(old.m_loopColor) {} public: OrderLoopBeginVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp, AstUntilStable* nodep, OrderLoopId loopId, uint32_t loopColor) : OrderLogicVertex(graphp, scopep, domainp, nodep) , m_loopId(loopId), m_loopColor(loopColor) {} virtual ~OrderLoopBeginVertex() {} virtual OrderLoopBeginVertex* clone(V3Graph* graphp) const { return new OrderLoopBeginVertex(graphp, *this); } // Methods virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOOPBEGIN; } virtual string name() const { return "LoopBegin_"+cvtToStr(loopId())+"_c"+cvtToStr(loopColor()); } virtual bool domainMatters() { return true; } virtual string dotColor() const { return "blue"; } AstUntilStable* untilp() const { return nodep()->castUntilStable(); } OrderLoopId loopId() const { return m_loopId; } uint32_t loopColor() const { return m_loopColor; } }; class OrderLoopEndVertex : public OrderLogicVertex { // A end vertex points to the *same nodep* as the Begin, as we need it to // be a logic vertex for moving, but don't need a permanent node. We // won't add to the output graph though, so it shouldn't matter. OrderLoopBeginVertex* m_beginVertexp; // Corresponding loop begin OrderLoopEndVertex(V3Graph* graphp, const OrderLoopEndVertex& old) : OrderLogicVertex(graphp, old), m_beginVertexp(old.m_beginVertexp) {} public: OrderLoopEndVertex(V3Graph* graphp, OrderLoopBeginVertex* beginVertexp) : OrderLogicVertex(graphp, beginVertexp->scopep(), beginVertexp->domainp(), beginVertexp->nodep()) , m_beginVertexp(beginVertexp) { inLoop(beginVertexp->loopId()); } virtual ~OrderLoopEndVertex() {} virtual OrderLoopEndVertex* clone(V3Graph* graphp) const { return new OrderLoopEndVertex(graphp, *this); } // Methods virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOOPEND; } virtual string name() const { return "LoopEnd_"+cvtToStr(inLoop())+"_c"+cvtToStr(loopColor()); } virtual bool domainMatters() { return false; } virtual string dotColor() const { return "blue"; } OrderLoopBeginVertex* beginVertexp() const { return m_beginVertexp; } uint32_t loopColor() const { return beginVertexp()->loopColor(); } }; //###################################################################### //--- Following only under the move graph, not the main graph class OrderMoveVertex : public V3GraphVertex { typedef enum {POM_WAIT, POM_READY, POM_MOVED} OrderMState; OrderLogicVertex* m_logicp; OrderMState m_state; // Movement state OrderMoveDomScope* m_domScopep; // Domain/scope list information protected: friend class OrderVisitor; // These only contain the "next" item, // for the head of the list, see the same var name under OrderVisitor V3ListEnt m_pomWaitingE; // List of nodes needing inputs to become ready V3ListEnt m_readyVerticesE;// List of ready under domain/scope // CONSTRUCTORS OrderMoveVertex(V3Graph* graphp, const OrderMoveVertex& old) : V3GraphVertex(graphp, old), m_logicp(old.m_logicp), m_state(old.m_state) , m_domScopep(old.m_domScopep) {} public: OrderMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp) : V3GraphVertex(graphp), m_logicp(logicp), m_state(POM_WAIT), m_domScopep(NULL) {} virtual ~OrderMoveVertex() {} virtual OrderMoveVertex* clone(V3Graph* graphp) const { return new OrderMoveVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_MOVE; } virtual string dotColor() const { return logicp()->dotColor(); } virtual string name() const { string nm = logicp()->name(); nm += (string("\\nMV:") +" lp="+cvtToStr(logicp()->inLoop()) +" d="+cvtToStr((void*)logicp()->domainp()) +" s="+cvtToStr((void*)logicp()->scopep())); return nm; } // ACCESSORS OrderLogicVertex* logicp() const { return m_logicp; } bool isWait() const { return m_state==POM_WAIT; } void setReady() { UASSERT(m_state==POM_WAIT, "Wait->Ready on node not in proper state\n"); m_state = POM_READY; } void setMoved() { UASSERT(m_state==POM_READY, "Ready->Moved on node not in proper state\n"); m_state = POM_MOVED; } OrderMoveDomScope* domScopep() const { return m_domScopep; } OrderMoveVertex* pomWaitingNextp() const { return m_pomWaitingE.nextp(); } void domScopep(OrderMoveDomScope* ds) { m_domScopep=ds; } }; //###################################################################### // Edge types class OrderEdge : public V3GraphEdge { protected: OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, const OrderEdge& old) : V3GraphEdge(graphp, fromp, top, old) {} public: OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false) : V3GraphEdge(graphp, fromp, top, weight, cutable) {} virtual ~OrderEdge() {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_STD; } virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { return new OrderEdge(graphp, fromp, top, *this); } // When ordering combo blocks with stronglyConnected, follow edges not involving pre/pos variables virtual bool followComboConnected() const { return true; } virtual bool followSequentConnected() const { return true; } static bool followComboConnected(const V3GraphEdge* edgep) { const OrderEdge* oedgep = dynamic_cast(edgep); if (!oedgep) v3fatalSrc("Following edge of non-OrderEdge type"); return (oedgep->followComboConnected()); } static bool followSequentConnected(const V3GraphEdge* edgep) { const OrderEdge* oedgep = dynamic_cast(edgep); if (!oedgep) v3fatalSrc("Following edge of non-OrderEdge type"); return (oedgep->followSequentConnected()); } }; class OrderChangeDetEdge : public OrderEdge { // Edge created from variable to OrderLoopEndVertex // Indicates a change detect will be required for this loop construct OrderChangeDetEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, const OrderChangeDetEdge& old) : OrderEdge(graphp, fromp, top, old) {} public: OrderChangeDetEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : OrderEdge(graphp, fromp, top, WEIGHT_MEDIUM, false) {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_CHANGEDET; } virtual ~OrderChangeDetEdge() {} virtual OrderChangeDetEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { return new OrderChangeDetEdge(graphp, fromp, top, *this); } virtual string dotColor() const { return "blue"; } }; class OrderComboCutEdge : public OrderEdge { // Edge created from output of combo logic // Breakable if the output var is also a input, // in which case we'll need a change detect loop around this var. OrderComboCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, const OrderComboCutEdge& old) : OrderEdge(graphp, fromp, top, old) {} public: OrderComboCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : OrderEdge(graphp, fromp, top, WEIGHT_COMBO, CUTABLE) {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_COMBOCUT; } virtual ~OrderComboCutEdge() {} virtual OrderComboCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { return new OrderComboCutEdge(graphp, fromp, top, *this); } virtual string dotColor() const { return "yellowGreen"; } virtual bool followComboConnected() const { return true; } virtual bool followSequentConnected() const { return true; } }; class OrderPostCutEdge : public OrderEdge { // Edge created from output of post assignment // Breakable if the output var feeds back to input combo logic or another clock pin // in which case we'll need a change detect loop around this var. OrderPostCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, const OrderPostCutEdge& old) : OrderEdge(graphp, fromp, top, old) {} public: OrderPostCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : OrderEdge(graphp, fromp, top, WEIGHT_COMBO, CUTABLE) {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_POSTCUT; } virtual ~OrderPostCutEdge() {} virtual OrderPostCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { return new OrderPostCutEdge(graphp, fromp, top, *this); } virtual string dotColor() const { return "PaleGreen"; } virtual bool followComboConnected() const { return false; } virtual bool followSequentConnected() const { return true; } }; class OrderPreCutEdge : public OrderEdge { // Edge created from var_PREVAR->consuming logic vertex // Always breakable, just results in performance loss // in which case we can't optimize away the pre/post delayed assignments OrderPreCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, const OrderPreCutEdge& old) : OrderEdge(graphp, fromp, top, old) {} public: OrderPreCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : OrderEdge(graphp, fromp, top, WEIGHT_PRE, CUTABLE) {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_PRECUT; } virtual OrderPreCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { return new OrderPreCutEdge(graphp, fromp, top, *this); } virtual ~OrderPreCutEdge() {} virtual string dotColor() const { return "khaki"; } virtual bool followComboConnected() const { return false; } virtual bool followSequentConnected() const { return false; } }; verilator-3.874/src/V3File.h0000664000177100017500000002103312525172036015555 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: File stream wrapper that understands indentation // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3FILE_H_ #define _V3FILE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include #include #include #include #include //============================================================================ // V3File: Create streams, recording dependency information class V3File { public: static ifstream* new_ifstream(const string& filename) { addSrcDepend(filename); return new_ifstream_nodepend (filename); } static ifstream* new_ifstream_nodepend(const string& filename) { return new ifstream(filename.c_str()); } static ofstream* new_ofstream(const string& filename, bool append=false) { addTgtDepend(filename); return new_ofstream_nodepend (filename, append); } static ofstream* new_ofstream_nodepend(const string& filename, bool append=false) { if (filename != VL_DEV_NULL) createMakeDir(); if (append) { return new ofstream(filename.c_str(), ios::app); } else { return new ofstream(filename.c_str()); } } static FILE* new_fopen_w(const string& filename) { if (filename != VL_DEV_NULL) createMakeDir(); addTgtDepend(filename); return fopen(filename.c_str(),"w"); } // Dependencies static void addSrcDepend(const string& filename); static void addTgtDepend(const string& filename); static void writeDepend(const string& filename); static void writeTimes(const string& filename, const string& cmdline); static bool checkTimes(const string& filename, const string& cmdline); // Directory utilities static void createMakeDir(); }; //============================================================================ // V3InFilter: Read a input file, possibly filtering it, and caching contents class V3InFilterImp; class V3InFilter { V3InFilterImp* m_impp; public: // TYPES typedef list StrList; // METHODS // Read file contents and return it. Return true on success. bool readWholefile(const string& filename, StrList& outl); // CONSTRUCTORS V3InFilter(const string& command); ~V3InFilter(); }; //============================================================================ // V3OutFormatter: A class for automatic indentation of C++ or Verilog code. class V3OutFormatter { // TYPES enum MiscConsts { INDBLK = 4, // Indentation per block level WIDTH = 50, // Width after which to break at ,'s MAXSPACE = 80}; // After this indent, stop indenting more public: enum AlignClass { AL_AUTO = 0, AL_STATIC = 1}; enum Language { LA_C = 0, LA_VERILOG = 1, LA_MK = 2, LA_XML = 3, }; private: // MEMBERS string m_filename; Language m_lang; // Indenting Verilog code int m_lineno; int m_column; int m_nobreak; // Basic operator or begin paren, don't break next bool m_prependIndent; int m_indentLevel; // Current {} indentation int m_declSAlign; // Byte alignment of next declaration, statics int m_declNSAlign; // Byte alignment of next declaration, nonstatics int m_declPadNum; // Pad variable number stack m_parenVec; // Stack of columns where last ( was int endLevels(const char* strg); const char* indentStr(int levels); void putcNoTracking(char chr); public: V3OutFormatter(const string& filename, Language lang); virtual ~V3OutFormatter() {} // ACCESSORS int column() const { return m_column; } // METHODS void printf(const char* fmt...) VL_ATTR_PRINTF(2); void puts(const char* strg); void puts(const string& strg) { puts(strg.c_str()); } void putsNoTracking(const char* strg); void putsNoTracking(const string& strg) { putsNoTracking(strg.c_str()); } void putsQuoted(const char* strg); void putsQuoted(const string& strg) { putsQuoted(strg.c_str()); } void putBreak(); // Print linebreak if line is too wide void putBreakExpr(); // Print linebreak in expression if line is too wide void putAlign(bool isstatic/*AlignClass*/, int align, int size=0/*=align*/, const char* prefix=""); // Declare a variable, with natural alignment void putbs(const char* strg) { putBreakExpr(); puts(strg); } void putbs(const string& strg) { putBreakExpr(); puts(strg); } bool exceededWidth() const { return m_column > WIDTH; } bool tokenStart(const char* cp, const char* cmp); bool tokenEnd(const char* cp); void indentInc() { m_indentLevel += INDBLK; } void indentDec() { m_indentLevel -= INDBLK; UASSERT(m_indentLevel>=0, ": "<printf("%-19s\t%s;\n", classStar.c_str(), cellname.c_str()); } virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); } virtual void putsIntTopInclude() { } // Print out public/privates void resetPrivate() { m_private = 0; } void putsPrivate(bool setPrivate) { if (setPrivate && m_private!=1) { puts("private:\n"); m_private = 1; } else if (!setPrivate && m_private!=2) { puts("public:\n"); m_private = 2; } } }; class V3OutScFile : public V3OutCFile { public: V3OutScFile(const string& filename) : V3OutCFile(filename) {} virtual ~V3OutScFile() {} virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); } virtual void putsIntTopInclude() { puts("#include \"systemc.h\"\n"); puts("#include \"verilated_sc.h\"\n"); } }; class V3OutSpFile : public V3OutCFile { public: V3OutSpFile(const string& filename) : V3OutCFile(filename) {} virtual ~V3OutSpFile() {} virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); } virtual void putsIntTopInclude() { puts("#include \"systemperl.h\"\n"); puts("#include \"verilated_sc.h\"\n"); } }; class V3OutVFile : public V3OutFile { public: V3OutVFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_VERILOG) {} virtual ~V3OutVFile() {} virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); } }; class V3OutXmlFile : public V3OutFile { public: V3OutXmlFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_XML) {} virtual ~V3OutXmlFile() {} virtual void putsHeader() { puts("\n"); } }; class V3OutMkFile : public V3OutFile { public: V3OutMkFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_MK) {} virtual ~V3OutMkFile() {} virtual void putsHeader() { puts("# Verilated -*- Makefile -*-\n"); } // No automatic indentation yet. void puts(const char* strg) { putsNoTracking(strg); } void puts(const string& strg) { putsNoTracking(strg); } }; #endif // Guard verilator-3.874/src/V3Graph.h0000664000177100017500000002660012525171733015747 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph optimizations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3GRAPH_H_ #define _V3GRAPH_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3List.h" #include "V3Ast.h" #include #include class V3Graph; class V3GraphVertex; class V3GraphEdge; class GraphAcycEdge; class OrderEitherVertex; class OrderLogicVertex; //============================================================================= // Most graph algorithms accept an arbitrary function that returns // True for those edges we should honor. typedef bool (*V3EdgeFuncP)(const V3GraphEdge* edgep); //============================================================================ class V3Graph { private: // STATE V3List m_vertices; // All vertices static int s_debug; protected: friend class V3GraphVertex; friend class V3GraphEdge; friend class GraphAcyc; // METHODS void acyclicDFS(); void acyclicDFSIterate(V3GraphVertex *vertexp, int depth, uint32_t currentRank); void acyclicCut(); void acyclicLoop(V3GraphVertex* vertexp, int depth); double orderDFSIterate(V3GraphVertex* vertexp); void dumpEdge(ostream& os, V3GraphVertex* vertexp, V3GraphEdge* edgep); void verticesUnlink() { m_vertices.reset(); } // ACCESSORS static int debug(); public: V3Graph(); virtual ~V3Graph(); static void debug(int level) { s_debug = level; } virtual string dotRankDir() { return "TB"; } // rankdir for dot plotting // METHODS void clear(); // Empty it of all vertices/edges, as if making a new object void clearColors(); V3GraphVertex* verticesBeginp() const { return m_vertices.begin(); } // METHODS - ALGORITHMS /// Assign same color to all vertices in the same weakly connected component /// Thus different color if there's no edges between the two subgraphs void weaklyConnected(V3EdgeFuncP edgeFuncp); /// Assign same color to all vertices that are strongly connected /// Thus different color if there's no directional circuit within the subgraphs. /// (I.E. all loops will occur within each color, not between them.) void stronglyConnected(V3EdgeFuncP edgeFuncp); /// Assign same color to all destination vertices that have same /// subgraph feeding into them /// (I.E. all "from" nodes are common within each color) /// See V3ClkGater if this is needed again; it got specialized /// Assign a ordering number to all vertexes in a tree. /// All nodes with no inputs will get rank 1 void rank(V3EdgeFuncP edgeFuncp); void rank(); /// Sort all vertices and edges using the V3GraphVertex::sortCmp() function void sortVertices(); /// Sort all edges and edges using the V3GraphEdge::sortCmp() function void sortEdges(); /// Order all vertices by rank and fanout, lowest first /// Sort all vertices by rank and fanout, lowest first /// Sort all edges by weight, lowest first void order(); /// Make acyclical (into a tree) by breaking a minimal subset of cutable edges. void acyclic(V3EdgeFuncP edgeFuncp); /// Delete any nodes with only outputs void deleteCutableOnlyEdges(); /// Any cutable edged become non-cutable void makeEdgesNonCutable(V3EdgeFuncP edgeFuncp); /// Remove any redundant edges, weights become MAX of any other weight void removeRedundantEdges(V3EdgeFuncP edgeFuncp); /// Remove any redundant edges, weights become SUM of any other weight void removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp); /// Call loopsVertexCb on any one loop starting where specified void reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp); /// Build a subgraph of all loops starting where specified void subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp, V3Graph* loopGraphp); /// Debugging void dump(ostream& os=cout); void dumpDotFile(const string& filename, bool colorAsSubgraph); void dumpDotFilePrefixed(const string& nameComment, bool colorAsSubgraph=false); void dumpDotFilePrefixedAlways(const string& nameComment, bool colorAsSubgraph=false); void userClearVertices(); void userClearEdges(); static void test(); // CALLBACKS virtual void loopsMessageCb(V3GraphVertex* vertexp) { v3fatalSrc("Loops detected in graph: "< m_vertices;// All vertices, linked list V3List m_outs; // Outbound edges,linked list V3List m_ins; // Inbound edges, linked list double m_fanout; // Order fanout uint32_t m_color; // Color of the node uint32_t m_rank; // Rank of edge union { void* m_userp; // Marker for some algorithms uint32_t m_user; // Marker for some algorithms }; // METHODS void verticesPushBack(V3Graph* graphp); // ACCESSORS void fanout(double fanout) { m_fanout = fanout; } void rank(uint32_t rank) { m_rank = rank; } void inUnlink() { m_ins.reset(); } // Low level; normally unlinkDelete is what you want void outUnlink() { m_outs.reset(); } // Low level; normally unlinkDelete is what you want protected: // CONSTRUCTORS V3GraphVertex(V3Graph* graphp, const V3GraphVertex& old); public: V3GraphVertex(V3Graph* graphp); //! Clone copy constructor. Doesn't copy edges or user/userp. virtual V3GraphVertex* clone(V3Graph* graphp) const { return new V3GraphVertex(graphp, *this); } virtual ~V3GraphVertex() {} void unlinkEdges(V3Graph* graphp); void unlinkDelete(V3Graph* graphp); // ACCESSORS virtual string name() const { return ""; } virtual string dotColor() const { return "black"; } virtual string dotShape() const { return ""; } virtual string dotStyle() const { return ""; } virtual string dotName() const { return ""; } virtual int sortCmp(const V3GraphVertex* rhsp) const { // LHS goes first if of lower rank, or lower fanout if (m_rank < rhsp->m_rank) return -1; if (m_rank > rhsp->m_rank) return 1; if (m_fanout < rhsp->m_fanout) return -1; if (m_fanout > rhsp->m_fanout) return 1; return 0; } uint32_t color() const { return m_color; } void color(uint32_t color) { m_color = color; } uint32_t rank() const { return m_rank; } double fanout() const { return m_fanout; } void user(uint32_t user) { m_user = user; } uint32_t user() const { return m_user; } void userp(void* userp) { m_userp = userp; } void* userp() const { return m_userp; } // ITERATORS V3GraphVertex* verticesNextp() const { return m_vertices.nextp(); } V3GraphEdge* inBeginp() const { return m_ins.begin(); } bool inEmpty() const { return inBeginp()==NULL; } bool inSize1() const; uint32_t inHash() const; V3GraphEdge* outBeginp() const { return m_outs.begin(); } bool outEmpty() const { return outBeginp()==NULL; } bool outSize1() const; uint32_t outHash() const; // METHODS void rerouteEdges(V3Graph* graphp); ///< Edges are routed around this vertex to point from "from" directly to "to" }; ostream& operator<<(ostream& os, V3GraphVertex* vertexp); //============================================================================ class V3GraphEdge { // Wires/variables aren't edges. Edges have only a single to/from vertex public: // ENUMS enum Cuttable { NOT_CUTABLE = false, CUTABLE = true }; // For passing to V3GraphEdge protected: friend class V3Graph; friend class V3GraphVertex; friend class GraphAcyc; friend class GraphAcycEdge; V3ListEnt m_outs; // Next Outbound edge for same vertex (linked list) V3ListEnt m_ins; // Next Inbound edge for same vertex (linked list) // V3GraphVertex* m_fromp; // Vertices pointing to this edge V3GraphVertex* m_top; // Vertices this edge points to int m_weight; // Weight of the connection bool m_cutable; // Interconnect may be broken in order sorting union { void* m_userp; // Marker for some algorithms uint32_t m_user; // Marker for some algorithms }; // METHODS void init(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false); void cut() { m_weight = 0; } // 0 weight is same as disconnected void outPushBack(); void inPushBack(); // CONSTRUCTORS protected: V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, const V3GraphEdge& old) { init(graphp, fromp, top, old.m_weight, old.m_cutable); } public: //! Add DAG from one node to the specified node V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false) { init(graphp, fromp, top, weight, cutable); } //! Clone copy constructor. Doesn't copy existing vertices or user/userp. virtual V3GraphEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { return new V3GraphEdge(graphp, fromp, top, *this); } virtual ~V3GraphEdge() {} // METHODS virtual string name() const { return m_fromp->name()+"->"+m_top->name(); } virtual string dotLabel() const { return ""; } virtual string dotColor() const { return cutable()?"yellowGreen":"red"; } virtual string dotStyle() const { return cutable()?"dashed":""; } virtual int sortCmp(const V3GraphEdge* rhsp) const { if (!m_weight || !rhsp->m_weight) return 0; return top()->sortCmp(rhsp->top()); } void unlinkDelete(); V3GraphEdge* relinkFromp(V3GraphVertex* newFromp); // ACCESSORS int weight() const { return m_weight; } void weight(int weight) { m_weight=weight; } bool cutable() const { return m_cutable; } void cutable(bool cutable) { m_cutable=cutable; } void userp(void* user) { m_userp = user; } void* userp() const { return m_userp; } void user(uint32_t user) { m_user = user; } uint32_t user() const { return m_user; } V3GraphVertex* fromp() const { return m_fromp; } V3GraphVertex* top() const { return m_top; } // STATIC ACCESSORS static bool followNotCutable(const V3GraphEdge* edgep) { return !edgep->m_cutable; } static bool followAlwaysTrue(const V3GraphEdge*) { return true; } // ITERATORS V3GraphEdge* outNextp() const { return m_outs.nextp(); } V3GraphEdge* inNextp() const { return m_ins.nextp(); } }; //============================================================================ #endif // Guard verilator-3.874/src/V3Number.cpp0000664000177100017500000015630712525461132016474 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Large 4-state numbers // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Number.h" #define MAX_SPRINTF_DOUBLE_SIZE 100 // Maximum characters with a sprintf %e/%f/%g (probably < 30) //###################################################################### // Read class functions // CREATION V3Number::V3Number(VerilogStringLiteral, FileLine* fileline, const string& str) { // Create a number using a verilog string as the value, thus 8 bits per character. // cppcheck bug - doesn't see init() resets these // cppcheck: Member variable 'm_sized/m_width' is not initialized in the constructor init(fileline, str.length()*8); m_fromString = true; for (unsigned pos=0; posopAdd(product,addend); if (product.bitsValue(width(), 4)) { // Overflowed m_fileline->v3error("Too many digits for "<v3error("Unsized X/Z/? not legal in decimal constant: "<<*cp); setAllBitsZ(); got_z = 1; break; } case 'x': { if (!m_sized) m_fileline->v3error("Unsized X/Z/? not legal in decimal constant: "<<*cp); got_x = 1; setAllBitsX(); break; } case '_': break; default: { m_fileline->v3error("Illegal character in decimal constant: "<<*cp); break; } } } obit = width(); if ((got_01+got_x+got_z)>1) m_fileline->v3error("Mixing X/Z/? with digits not legal in decimal constant: "<=value_startp && obit<=width()); cp--) { if (*cp!='_' && *cp!='0' && obit>=width()) { m_fileline->v3error("Too many digits for "<v3error("Illegal character in binary constant: "<<*cp); } break; } case 'o': case 'c': { switch(tolower(*cp)) { case '0': setBit(obit++, 0); setBit(obit++, 0); setBit(obit++, 0); break; case '1': setBit(obit++, 1); setBit(obit++, 0); setBit(obit++, 0); break; case '2': setBit(obit++, 0); setBit(obit++, 1); setBit(obit++, 0); break; case '3': setBit(obit++, 1); setBit(obit++, 1); setBit(obit++, 0); break; case '4': setBit(obit++, 0); setBit(obit++, 0); setBit(obit++, 1); break; case '5': setBit(obit++, 1); setBit(obit++, 0); setBit(obit++, 1); break; case '6': setBit(obit++, 0); setBit(obit++, 1); setBit(obit++, 1); break; case '7': setBit(obit++, 1); setBit(obit++, 1); setBit(obit++, 1); break; case 'z': case '?': setBit(obit++, 'z'); setBit(obit++, 'z'); setBit(obit++, 'z'); break; case 'x': setBit(obit++, 'x'); setBit(obit++, 'x'); setBit(obit++, 'x'); break; case '_': break; default: m_fileline->v3error("Illegal character in octal constant"); } break; } case 'h': { switch(tolower(*cp)) { case '0': setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); break; case '1': setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); break; case '2': setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); break; case '3': setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); break; case '4': setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); break; case '5': setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); break; case '6': setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); break; case '7': setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); break; case '8': setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); break; case '9': setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); break; case 'a': setBit(obit++,0); setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); break; case 'b': setBit(obit++,1); setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); break; case 'c': setBit(obit++,0); setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); break; case 'd': setBit(obit++,1); setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); break; case 'e': setBit(obit++,0); setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); break; case 'f': setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); setBit(obit++,1); break; case 'z': case '?': setBit(obit++,'z'); setBit(obit++,'z'); setBit(obit++,'z'); setBit(obit++,'z'); break; case 'x': setBit(obit++,'x'); setBit(obit++,'x'); setBit(obit++,'x'); setBit(obit++,'x'); break; case '_': break; default: m_fileline->v3error("Illegal character in hex constant: "<<*cp); } break; } default: m_fileline->v3error("Illegal base character: "<0; bit--) if (num & (VL_ULL(1)<>VL_ULL(32)) & VL_ULL(0xffffffff); opCleanThis(); return *this; } V3Number& V3Number::setLong(uint32_t value) { for (int i=0; iv3fatalSrc("Real operation on wrong sized number"); } m_double = true; union { double d; uint32_t u[2]; } u; u.d = value; for (int i=2; i=0; bit--) { if (bitIs0(bit)) str+='0'; else if (bitIs1(bit)) str+='1'; else if (bitIsZ(bit)) str+='z'; else str+='x'; } return str; } case 'o': { int bit = width()-1; if (fmtsize == "0") while (bit && bitIs0(bit)) bit--; while ((bit%3)!=2) bit++; for (; bit>0; bit -= 3) { int v = bitsValue(bit-2, 3); str += (char)('0'+v); } return str; } case 'h': case 'x': { int bit = width()-1; if (fmtsize == "0") while (bit && bitIs0(bit)) bit--; while ((bit%4)!=3) bit++; for (; bit>0; bit -= 4) { int v = bitsValue(bit-3, 4); if (v>=10) str += (char)('a'+v-10); else str += (char)('0'+v); } return str; } case 'c': { if (this->width()>8) m_fileline->v3error("$display-like format of char of > 8 bit value"); int v = bitsValue(0, 8); str += (char)(v); return str; } case '@': { // Packed string return toString(); } case 's': { // Spec says always drop leading zeros, this isn't quite right, we space pad. int bit=this->width()-1; bool start=true; while ((bit%8)!=7) bit++; for (; bit>=0; bit -= 8) { int v = bitsValue(bit-7, 8); if (!start || v) { str += (char)((v==0)?' ':v); start = false; // Drop leading 0s } else { if (fmtsize != "0") str += ' '; } } return str; } case '~': // Signed decimal case 't': // Time case 'd': { // Unsigned decimal bool issigned = (code == '~'); if (fmtsize == "") { double mantissabits = this->width() - (issigned?1:0); double maxval = pow(2.0, mantissabits); double dchars = log10(maxval)+1.0; if (issigned) dchars++; // space for sign fmtsize = cvtToStr(int(dchars)); } if (width() > 64) { m_fileline->v3error("Unsupported: $display-like format of decimal of > 64 bit results (use hex format instead)"); return "ERR"; } if (issigned) { str = cvtToStr(toSQuad()); } else { str = cvtToStr(toUQuad()); } int intfmtsize = atoi(fmtsize.c_str()); bool zeropad = fmtsize.length()>0 && fmtsize[0]=='0'; while ((int)(str.length()) < intfmtsize) { if (zeropad) str = "0"+str; else str = " "+str; } return str; } case 'e': case 'f': case 'g': { char tmp[MAX_SPRINTF_DOUBLE_SIZE]; sprintf(tmp, vformat.c_str(), toDouble()); return tmp; } default: m_fileline->v3fatalSrc("Unknown $display-like format code for number: %"<v3fatalSrc("Real conversion on non-real number"); } if (VL_UNLIKELY(width()!=64)) { m_fileline->v3fatalSrc("Real operation on wrong sized number"); } union { double d; uint32_t u[2]; } u; u.u[0] = m_value[0]; u.u[1] = m_value[1]; return u.d; } vlsint32_t V3Number::toSInt() const { if (isSigned()) { uint32_t v = toUInt(); uint32_t signExtend = (-(v & (1UL<<(width()-1)))); uint32_t extended = v | signExtend; return (vlsint32_t)(extended); } else { // Where we use this (widths, etc) and care about signedness, // we can reasonably assume the MSB isn't set on unsigned numbers. return (vlsint32_t)toUInt(); } } vluint64_t V3Number::toUQuad() const { UASSERT(!isFourState(),"toUQuad with 4-state "<<*this); UASSERT(width()<65, "Value too wide "<<*this); if (width()<=32) return ((vluint64_t)(toUInt())); return ((vluint64_t)m_value[1]<width()-1; bool start=true; while ((bit%8)!=7) bit++; string str; for (; bit>=0; bit -= 8) { int v = bitsValue(bit-7, 8); if (!start || v) { str += (char)((v==0)?' ':v); start = false; // Drop leading 0s } } return str; } uint32_t V3Number::toHash() const { return m_value[0]; } uint32_t V3Number::dataWord(int word) const { UASSERT(!isFourState(),"dataWord with 4-state "<<*this); return m_value[word]; } bool V3Number::isEqZero() const { for (int i=0; iwidth(),rhs.width()); bit++) { if (this->bitIs1(bit) && rhs.bitIs0(bit)) { return 1; } if (rhs.bitIs1(bit) && this->bitIs0(bit)) { return 0; } if (this->bitIsXZ(bit)) { return 0; } if (rhs.bitIsXZ(bit)) { return 0; } } return 0; } bool V3Number::isLtXZ(const V3Number& rhs) const { // Include X/Z in comparisons for sort ordering for (int bit=0; bitwidth(),rhs.width()); bit++) { if (this->bitIs1(bit) && rhs.bitIs0(bit)) { return 1; } if (rhs.bitIs1(bit) && this->bitIs0(bit)) { return 0; } if (this->bitIsXZ(bit)) { return 1; } if (rhs.bitIsXZ(bit)) { return 0; } } return 0; } int V3Number::widthMin() const { for(int bit=width()-1; bit>0; bit--) { if (!bitIs0(bit)) return bit+1; } return 1; // one bit even if number is == 0 } uint32_t V3Number::countOnes() const { int n=0; for(int bit=0; bitwidth(); bit++) { if (bitIs1(bit)) n++; } return n; } uint32_t V3Number::mostSetBitP1() const { for (int bit=this->width()-1; bit>=0; bit--) { if (bitIs1(bit)) return bit+1; } return 0; } //====================================================================== V3Number& V3Number::opBitsNonX (const V3Number& lhs) { // 0/1->1, X/Z->0 // op i, L(lhs) bit return setZero(); for(int bit=0; bitwidth(); bit++) { if (lhs.bitIs0(bit) || lhs.bitIs1(bit)) { setBit(bit,1); } } return *this; } V3Number& V3Number::opBitsOne (const V3Number& lhs) { // 1->1, 0/X/Z->0 // op i, L(lhs) bit return setZero(); for(int bit=0; bitwidth(); bit++) { if (lhs.bitIs1(bit)) { setBit(bit,1); } } return *this; } V3Number& V3Number::opBitsXZ (const V3Number& lhs) { // 0/1->1, X/Z->0 // op i, L(lhs) bit return setZero(); for(int bit=0; bitwidth(); bit++) { if (lhs.bitIsXZ(bit)) { setBit(bit,1); } } return *this; } V3Number& V3Number::opBitsZ (const V3Number& lhs) { // 0/1->1, X/Z->0 // op i, L(lhs) bit return setZero(); for(int bit=0; bitwidth(); bit++) { if (lhs.bitIsZ(bit)) { setBit(bit,1); } } return *this; } V3Number& V3Number::opBitsNonZ (const V3Number& lhs) { // 0/1->1, X/Z->0 // op i, L(lhs) bit return setZero(); for(int bit=0; bitwidth(); bit++) { if (!lhs.bitIsZ(bit)) { setBit(bit,1); } } return *this; } //====================================================================== // Operators - Simple per-bit logical ops V3Number& V3Number::opRedOr (const V3Number& lhs) { // op i, 1 bit return char outc = 0; for(int bit=0; bit=0; bit--) { if (lhs.bitIs1(bit)) { setLong(bit+adjust); return *this; } } setZero(); return *this; } V3Number& V3Number::opLogNot (const V3Number& lhs) { // op i, 1 bit return char outc = 1; for(int bit=0; bitwidth(); bit++) { if (lhs.bitIs0(bit)) { setBit(bit,1); } else if (lhs.bitIsXZ(bit)) { setBit(bit,'x'); } } return *this; } V3Number& V3Number::opAnd (const V3Number& lhs, const V3Number& rhs) { // i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend. setZero(); for(int bit=0; bitwidth(); bit++) { if (lhs.bitIs1(bit) && rhs.bitIs1(bit)) { setBit(bit,1); } else if (lhs.bitIs0(bit) || rhs.bitIs0(bit)) ; // 0 else { setBit(bit,'x'); } } return *this; } V3Number& V3Number::opOr (const V3Number& lhs, const V3Number& rhs) { // i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend. setZero(); for(int bit=0; bitwidth(); bit++) { if (lhs.bitIs1(bit) || rhs.bitIs1(bit)) { setBit(bit,1); } else if (lhs.bitIs0(bit) && rhs.bitIs0(bit)) ; // 0 else { setBit(bit,'x'); } } return *this; } V3Number& V3Number::opChangeXor (const V3Number& lhs, const V3Number& rhs) { // 32 bit result opEq(lhs,rhs); return *this; } V3Number& V3Number::opXor (const V3Number& lhs, const V3Number& rhs) { // i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend. setZero(); for(int bit=0; bitwidth(); bit++) { if (lhs.bitIs1(bit) && rhs.bitIs0(bit)) { setBit(bit,1); } else if (lhs.bitIs0(bit) && rhs.bitIs1(bit)) { setBit(bit,1); } else if (lhs.bitIsXZ(bit) && rhs.bitIsXZ(bit)) { setBit(bit,'x'); } // else zero } return *this; } V3Number& V3Number::opXnor (const V3Number& lhs, const V3Number& rhs) { // i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend. setZero(); for(int bit=0; bitwidth(); bit++) { if (lhs.bitIs1(bit) && rhs.bitIs1(bit)) { setBit(bit,1); } else if (lhs.bitIs0(bit) && rhs.bitIs0(bit)) { setBit(bit,1); } else if (lhs.bitIsXZ(bit) && rhs.bitIsXZ(bit)) { setBit(bit,'x'); } // else zero } return *this; } V3Number& V3Number::opConcat (const V3Number& lhs, const V3Number& rhs) { setZero(); // See also error in V3Width if (!lhs.sized() || !rhs.sized()) { m_fileline->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations."); } int obit = 0; for(int bit=0; bitv3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications."); return opRepl(lhs, rhs.toUInt()); } V3Number& V3Number::opRepl (const V3Number& lhs, uint32_t rhsval) { // rhs is # of times to replicate // i op repl, L(i)*value(rhs) bit return setZero(); if (rhsval>8192) m_fileline->v3fatal("More than a 8k bit replication is probably wrong: "<v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in streams."); } // Slice size should never exceed the lhs width int ssize=min(rhs.toUInt(), (unsigned)lhs.width()); for (int istart=0; istartwidth() != rhs.width()) return false; for (int bit=0; bitwidth(),rhs.width()); bit++) { if (this->bitIs(bit) != rhs.bitIs(bit)) { return false; } } return true; } V3Number& V3Number::opCaseEq (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.isCaseEq(rhs) ? 1:0); } V3Number& V3Number::opCaseNeq (const V3Number& lhs, const V3Number& rhs) { // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend. char outc = 0; for (int bit=0; bit - else if (lhs.bitIs1Extend(mbit) && rhs.bitIs0(mbit)) { outc=0; } // - !> + else { // both positive or negative, normal > for (int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIs((bit + rhsval) % this->width())); } return *this; } V3Number& V3Number::opRotL (const V3Number& lhs, const V3Number& rhs) { // L(lhs) bit return if (rhs.isFourState()) return setAllBitsX(); setZero(); uint32_t rhsval = rhs.toUInt(); for (int bit=0; bitwidth(); bit++) { if (bit >= (int)rhsval) { setBit(bit,lhs.bitIs((bit - rhsval) % this->width())); } } return *this; } V3Number& V3Number::opShiftR (const V3Number& lhs, const V3Number& rhs) { // L(lhs) bit return if (rhs.isFourState()) return setAllBitsX(); setZero(); uint32_t rhsval = rhs.toUInt(); if (rhsval < (uint32_t)lhs.width()) { for (int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIs(bit + rhsval)); } } return *this; } V3Number& V3Number::opShiftRS (const V3Number& lhs, const V3Number& rhs, uint32_t lbits) { // L(lhs) bit return // The spec says a unsigned >>> still acts as a normal >>. // We presume it is signed; as that's V3Width's job to convert to opShiftR if (rhs.isFourState()) return setAllBitsX(); setZero(); uint32_t rhsval = rhs.toUInt(); if (rhsval < (uint32_t)lhs.width()) { for (int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIsExtend(bit + rhsval, lbits)); } } else { for (int bit=0; bitwidth(); bit++) { setBit(bit,lhs.bitIs(lbits-1)); } } return *this; } V3Number& V3Number::opShiftL (const V3Number& lhs, const V3Number& rhs) { // L(lhs) bit return if (rhs.isFourState()) return setAllBitsX(); setZero(); uint32_t rhsval = rhs.toUInt(); for (int bit=0; bitwidth(); bit++) { if (bit >= (int)rhsval) { setBit(bit,lhs.bitIs(bit - rhsval)); } } return *this; } //====================================================================== // Ops - Arithmetic V3Number& V3Number::opAbsS (const V3Number& lhs) { // op i, L(lhs) bit return if (lhs.isFourState()) return setAllBitsX(); if (lhs.isNegative()) { return opNegate(lhs); } else { return opAssign(lhs); } } V3Number& V3Number::opNegate (const V3Number& lhs) { // op i, L(lhs) bit return if (lhs.isFourState()) return setAllBitsX(); V3Number notlhs (lhs.m_fileline, width()); notlhs.opNot(lhs); V3Number one (lhs.m_fileline, width(), 1); opAdd(notlhs,one); return *this; } V3Number& V3Number::opAdd (const V3Number& lhs, const V3Number& rhs) { // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX(); setZero(); // Addem int carry=0; for (int bit=0; bitwidth(); bit++) { int sum = ((lhs.bitIs1(bit)?1:0) + (rhs.bitIs1(bit)?1:0) + carry); if (sum & 1) { setBit(bit,1); } carry = (sum >= 2); } return *this; } V3Number& V3Number::opSub (const V3Number& lhs, const V3Number& rhs) { // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX(); V3Number negrhs (rhs.m_fileline, rhs.width()); negrhs.opNegate(rhs); return opAdd(lhs, negrhs); } V3Number& V3Number::opMul (const V3Number& lhs, const V3Number& rhs) { // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX(); setZero(); if (width() <= 64) { setQuad(lhs.toUQuad() * rhs.toUQuad()); opCleanThis(); // Mult produces extra bits in result } else { for (int lword=0; lwordwords(); qword++) { mul += (vluint64_t)(m_value[qword]); m_value[qword] = (mul & VL_ULL(0xffffffff)); mul = (mul >> VL_ULL(32)) & VL_ULL(0xffffffff); } } } opCleanThis(); // Mult produces extra bits in result } return *this; } V3Number& V3Number::opMulS (const V3Number& lhs, const V3Number& rhs) { // Signed multiply if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX(); V3Number lhsNoSign = lhs; if (lhs.isNegative()) lhsNoSign.opNegate(lhs); V3Number rhsNoSign = rhs; if (rhs.isNegative()) rhsNoSign.opNegate(rhs); V3Number qNoSign = opMul(lhsNoSign,rhsNoSign); if ((lhs.isNegative() && !rhs.isNegative()) || (!lhs.isNegative() && rhs.isNegative())) { opNegate(qNoSign); } else { opAssign(qNoSign); } return *this; } V3Number& V3Number::opDiv (const V3Number& lhs, const V3Number& rhs) { UINFO(9, "opdiv "<>divs-start "<divs-mid "<= 0; j--) { vluint64_t unw64 = ((k<> 32 won't mask the value for (int i = vw-1; i>0; i--) { vn[i] = (rhs.m_value[i] << s) | (shift_mask & (rhs.m_value[i-1] >> (32-s))); } vn[0] = rhs.m_value[0] << s; // Copy and shift dividend by same amount; may set new upper word if (s) un[uw] = lhs.m_value[uw-1] >> (32-s); else un[uw] = 0; for (int i=uw-1; i>0; i--) { un[i] = (lhs.m_value[i] << s) | (shift_mask & (lhs.m_value[i-1] >> (32-s))); } un[0] = lhs.m_value[0] << s; //printf(" un="); for(int i=5; i>=0; i--) printf(" %08x",un[i]); printf("\n"); //printf(" vn="); for(int i=5; i>=0; i--) printf(" %08x",vn[i]); printf("\n"); //printf(" mv="); for(int i=5; i>=0; i--) printf(" %08x",m_value[i]); printf("\n"); // Main loop for (int j = uw - vw; j >= 0; j--) { // Estimate vluint64_t unw64 = ((vluint64_t)(un[j+vw])<= VL_ULL(0x100000000) || ((qhat*vn[vw-2]) > ((rhat<> VL_ULL(32)) - (t >> VL_ULL(32)); } t = un[j+vw] - k; un[j+vw] = t; this->m_value[j] = qhat; // Save quotient digit if (t < 0) { // Over subtracted; correct by adding back this->m_value[j]--; k = 0; for (int i=0; i> VL_ULL(32); } un[j+vw] = un[j+vw] + k; } } //printf(" un="); for(int i=5; i>=0; i--) printf(" %08x",un[i]); printf("\n"); //printf(" vn="); for(int i=5; i>=0; i--) printf(" %08x",vn[i]); printf("\n"); //printf(" mv="); for(int i=5; i>=0; i--) printf(" %08x",m_value[i]); printf("\n"); if (is_modulus) { // modulus // Need to reverse normalization on copy to output for (int i=0; i> s) | (shift_mask & (un[i+1] << (32-s))); } for (int i=vw; i64bit ** power operator not implemented yet: "<<*this); if (rhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large >64bit ** power operator not implemented yet: "<<*this); if (rsign && rhs.isNegative()) { if (lhs.isEqZero()) return setAllBitsXRemoved(); else if (lhs.isEqOne()) return setQuad(1); else if (lsign && lhs.isEqAllOnes()) { if (rhs.bitIs1(0)) return setAllBits1(); // -1^odd=-1 else return setQuad(1); // -1^even=1 } return setZero(); } if (lhs.isEqZero()) return setZero(); setZero(); m_value[0] = 1; V3Number power (lhs.m_fileline, width()); power.opAssign(lhs); for (int bit=0; bit0) { // power = power*power V3Number lastPower (lhs.m_fileline, width()); lastPower.opAssign(power); power.opMul(lastPower, lastPower); } if (rhs.bitIs1(bit)) { // out *= power V3Number lastOut (lhs.m_fileline, width()); lastOut.opAssign(*this); this->opMul(lastOut, power); //UINFO(0, "pow "<width(); bit++) { if (if0s.bitIs1(bit) && if1s.bitIs1(bit)) { setBit(bit,1); } else if (if0s.bitIs0(bit) && if1s.bitIs0(bit)) { setBit(bit,0); } else setBit(bit,'x'); } } return *this; } //====================================================================== // Ops - Floating point V3Number& V3Number::opIToRD (const V3Number& lhs) { return setDouble(lhs.toSInt()); } V3Number& V3Number::opRToIS (const V3Number& lhs) { double v = VL_TRUNC(lhs.toDouble()); vlsint32_t i = (vlsint32_t)v; // C converts from double to vlsint32 return setLongS(i); } V3Number& V3Number::opRToIRoundS (const V3Number& lhs) { double v = VL_ROUND(lhs.toDouble()); vlsint32_t i = (vlsint32_t)v; // C converts from double to vlsint32 return setLongS(i); } V3Number& V3Number::opRealToBits (const V3Number& lhs) { // Conveniently our internal format is identical so we can copy bits... if (lhs.width()!=64 || this->width()!=64) { m_fileline->v3fatalSrc("Real operation on wrong sized number"); } return opAssign(lhs); } V3Number& V3Number::opBitsToRealD (const V3Number& lhs) { // Conveniently our internal format is identical so we can copy bits... if (lhs.width()!=64 || this->width()!=64) { m_fileline->v3fatalSrc("Real operation on wrong sized number"); } return opAssign(lhs); } V3Number& V3Number::opNegateD (const V3Number& lhs) { return setDouble(- lhs.toDouble()); } V3Number& V3Number::opAddD (const V3Number& lhs, const V3Number& rhs) { return setDouble(lhs.toDouble() + rhs.toDouble()); } V3Number& V3Number::opSubD (const V3Number& lhs, const V3Number& rhs) { return setDouble(lhs.toDouble() - rhs.toDouble()); } V3Number& V3Number::opMulD (const V3Number& lhs, const V3Number& rhs) { return setDouble(lhs.toDouble() * rhs.toDouble()); } V3Number& V3Number::opDivD (const V3Number& lhs, const V3Number& rhs) { // On exceptions, we just generate 'inf' through floating point // IEEE says it's implementation defined what happens return setDouble(lhs.toDouble() / rhs.toDouble()); } V3Number& V3Number::opPowD (const V3Number& lhs, const V3Number& rhs) { // On exceptions, we just generate 'inf' through floating point // IEEE says it's implementation defined what happens return setDouble(pow(lhs.toDouble(), rhs.toDouble())); } V3Number& V3Number::opEqD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() == rhs.toDouble()); } V3Number& V3Number::opNeqD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() != rhs.toDouble()); } V3Number& V3Number::opGtD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() > rhs.toDouble()); } V3Number& V3Number::opGteD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() >= rhs.toDouble()); } V3Number& V3Number::opLtD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() < rhs.toDouble()); } V3Number& V3Number::opLteD (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toDouble() <= rhs.toDouble()); } //====================================================================== // Ops - String V3Number& V3Number::opConcatN (const V3Number& lhs, const V3Number& rhs) { return setString(lhs.toString() + rhs.toString()); } V3Number& V3Number::opReplN (const V3Number& lhs, const V3Number& rhs) { return opReplN(lhs, rhs.toUInt()); } V3Number& V3Number::opReplN (const V3Number& lhs, uint32_t rhsval) { string out; out.reserve(lhs.toString().length() * rhsval); for (unsigned times=0; times rhs.toString()); } V3Number& V3Number::opGteN (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toString() >= rhs.toString()); } V3Number& V3Number::opLtN (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toString() < rhs.toString()); } V3Number& V3Number::opLteN (const V3Number& lhs, const V3Number& rhs) { return setSingleBits(lhs.toString() <= rhs.toString()); } verilator-3.874/src/V3SymTable.h0000664000177100017500000002510112525171733016421 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Symbol table // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LINKSYMTABLE_H_ #define _V3LINKSYMTABLE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Ast.h" #include "V3File.h" class VSymGraph; class VSymEnt; //###################################################################### // Symbol table typedef set VSymMap; class VSymEnt { // Symbol table that can have a "superior" table for resolving upper references private: // MEMBERS typedef std::multimap IdNameMap; IdNameMap m_idNameMap; // Hash of variables by name AstNode* m_nodep; // Node that entry belongs to VSymEnt* m_fallbackp; // Table "above" this one in name scope, for fallback resolution VSymEnt* m_parentp; // Table that created this table, dot notation needed to resolve into it AstPackage* m_packagep; // Package node is in (for V3LinkDot, unused here) string m_symPrefix; // String to prefix symbols with (for V3LinkDot, unused here) bool m_exported; // Allow importing bool m_imported; // Was imported #ifdef VL_DEBUG static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel("V3LinkDot.cpp"); return level; } #else static inline int debug() { return 0; } // NOT runtime, too hot of a function #endif public: void dumpIterate(ostream& os, VSymMap& doneSymsr, const string& indent, int numLevels, const string& searchName) { os<= 1) { it->second->dumpIterate(os, doneSymsr, indent+"| ", numLevels-1, it->first); } } } } void dump(ostream& os, const string& indent="", int numLevels=1) { VSymMap doneSyms; dumpIterate(os, doneSyms, indent, numLevels, "TOP"); } // METHODS VSymEnt(VSymGraph* graphp, const VSymEnt* symp); // Below VSymEnt(VSymGraph* graphp, AstNode* nodep); // Below ~VSymEnt() { // Change links so we coredump if used #ifdef VL_DEBUG m_nodep = (AstNode*)1; m_fallbackp = (VSymEnt*)1; m_parentp = (VSymEnt*)1; m_packagep = (AstPackage*)1; #endif } #if defined(VL_DEBUG) && !defined(VL_LEAK_CHECKS) void operator delete(void* objp, size_t size) {} // For testing, leak so above destructor 1 assignments work #endif void fallbackp(VSymEnt* entp) { m_fallbackp = entp; } void parentp(VSymEnt* entp) { m_parentp = entp; } VSymEnt* parentp() const { return m_parentp; } void packagep(AstPackage* entp) { m_packagep = entp; } AstPackage* packagep() const { return m_packagep; } AstNode* nodep() const { if (!this) return NULL; else return m_nodep; } // null check so can call .findId(...)->nodep() string symPrefix() const { return m_symPrefix; } void symPrefix(const string& name) { m_symPrefix = name; } bool exported() const { return m_exported; } void exported(bool flag) { m_exported = flag; } bool imported() const { return m_imported; } void imported(bool flag) { m_imported = flag; } void insert(const string& name, VSymEnt* entp) { UINFO(9, " SymInsert se"<<(void*)this<<" '"<nodep()<=9 || V3Error::debugDefault()) dump(cout,"- err-dump: ", 1); entp->nodep()->v3fatalSrc("Inserting two symbols with same name: "<nodep()<second = entp; // Replace } else { insert(name,entp); } } VSymEnt* findIdFlat(const string& name) const { // Find identifier without looking upward through symbol hierarchy // First, scan this begin/end block or module for the name IdNameMap::const_iterator it = m_idNameMap.find(name); UINFO(9, " SymFind se"<<(void*)this<<" '"< "<<(it == m_idNameMap.end() ? "NONE" : "se"+cvtToStr((void*)(it->second))+" n="+cvtToStr((void*)(it->second->nodep())))<second); return NULL; } VSymEnt* findIdFallback(const string& name) const { // Find identifier looking upward through symbol hierarchy // First, scan this begin/end block or module for the name if (VSymEnt* entp = findIdFlat(name)) return entp; // Then scan the upper begin/end block or module for the name if (m_fallbackp) return m_fallbackp->findIdFallback(name); return NULL; } private: bool importOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) { if (srcp->exported() && !findIdFlat(name)) { // Don't insert over existing entry VSymEnt* symp = new VSymEnt(graphp, srcp); symp->exported(false); // Can't reimport an import without an export symp->imported(true); reinsert(name, symp); return true; } else { return false; } } public: bool importFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) { // Import tokens from source symbol table into this symbol table // Returns true if successful bool any = false; if (id_or_star != "*") { IdNameMap::const_iterator it = srcp->m_idNameMap.find(id_or_star); if (it != m_idNameMap.end()) { importOneSymbol(graphp, it->first, it->second); } any = true; // Legal, though perhaps lint questionable to import nothing } else { for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) { if (importOneSymbol(graphp, it->first, it->second)) any = true; } } return any; } void importFromIface(VSymGraph* graphp, const VSymEnt* srcp) { // Import interface tokens from source symbol table into this symbol table, recursively UINFO(9, " importIf se"<<(void*)this<<" from se"<<(void*)srcp<m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) { const string& name = it->first; VSymEnt* subSrcp = it->second; VSymEnt* subSymp = new VSymEnt(graphp, subSrcp); reinsert(name, subSymp); // And recurse to create children subSymp->importFromIface(graphp, subSrcp); } } void cellErrorScopes(AstNode* lookp, string prettyName="") { if (prettyName=="") prettyName = lookp->prettyName(); string scopes; for (IdNameMap::iterator it = m_idNameMap.begin(); it!=m_idNameMap.end(); ++it) { AstNode* nodep = it->second->nodep(); if (nodep->castCell() || (nodep->castModule() && nodep->castModule()->isTop())) { if (scopes != "") scopes += ", "; scopes += AstNode::prettyName(it->first); } } if (scopes=="") scopes=""; cerr< SymStack; private: // MEMBERS VSymEnt* m_symRootp; // Root symbol table SymStack m_symsp; // All symbol tables, to cleanup protected: friend class VSymEnt; void pushNewEnt(VSymEnt* entp) { m_symsp.push_back(entp); } public: VSymEnt* rootp() const { return m_symRootp; } // Debug void dump(ostream& os, const string& indent="") { VSymMap doneSyms; os<<"SymEnt Dump:\n"; m_symRootp->dumpIterate(os, doneSyms, indent, 9999, "$root"); bool first = true; for (SymStack::iterator it = m_symsp.begin(); it != m_symsp.end(); ++it) { if (doneSyms.find(*it) == doneSyms.end()) { if (first) { first=false; os<<"%%Warning: SymEnt Orphans:\n"; } (*it)->dumpIterate(os, doneSyms, indent, 9999, "Orphan"); } } } void dumpFilePrefixed(const string& nameComment) { if (v3Global.opt.dumpTree()) { string filename = v3Global.debugFilename(nameComment)+".txt"; UINFO(2,"Dumping "< logp (V3File::new_ofstream(filename)); if (logp->fail()) v3fatalSrc("Can't write "<pushNewEnt(this); } inline VSymEnt::VSymEnt(VSymGraph* graphp, const VSymEnt* symp) : m_nodep(symp->nodep()) { m_fallbackp = symp->m_fallbackp; m_parentp = symp->m_parentp; m_packagep = symp->m_packagep; m_exported = symp->m_exported; m_imported = symp->m_imported; graphp->pushNewEnt(this); } #endif // guard verilator-3.874/src/config_build.h.in0000664000177100017500000000457712525172076017540 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Configure source; system configuration // // This file is part of Verilator. // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* //********************************************************************** //**** Version and host name // Autoconf substitutes this with the strings from AC_INIT. #define PACKAGE_STRING "" #define DTVERSION PACKAGE_STRING //********************************************************************** //**** Functions //********************************************************************** //**** Headers //********************************************************************** //**** Default environment // Set defines to defaults for environment variables // If set to "", this default is ignored and the user is expected // to set them at Verilator runtime. #ifndef DEFENV_SYSTEMC # define DEFENV_SYSTEMC "" #endif #ifndef DEFENV_SYSTEMC_ARCH # define DEFENV_SYSTEMC_ARCH "" #endif #ifndef DEFENV_SYSTEMC_INCLUDE # define DEFENV_SYSTEMC_INCLUDE "" #endif #ifndef DEFENV_SYSTEMC_LIBDIR # define DEFENV_SYSTEMC_LIBDIR "" #endif #ifndef DEFENV_SYSTEMPERL # define DEFENV_SYSTEMPERL "" #endif #ifndef DEFENV_SYSTEMPERL_INCLUDE # define DEFENV_SYSTEMPERL_INCLUDE "" #endif #ifndef DEFENV_VERILATOR_ROOT # define DEFENV_VERILATOR_ROOT "" #endif //********************************************************************** //**** Compile options #include #include #include #include #include using namespace std; //********************************************************************** //**** OS and compiler specifics #include "verilatedos.h" verilator-3.874/src/V3ParseLex.cpp0000664000177100017500000000510412525171733016760 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Netlist (top level) functions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Error.h" #include "V3Global.h" #include "V3File.h" #include "V3ParseImp.h" //====================================================================== // Build in LEX script #define yyFlexLexer V3LexerBase #include "V3Lexer.yy.cpp" #undef yyFlexLexer //###################################################################### // Lex-derived class /// Override the base lexer class so we can add some access functions class V3Lexer : public V3LexerBase { public: // CONSTRUCTORS V3Lexer() : V3LexerBase(NULL) {} ~V3Lexer() {} // METHODS void statePop() { yy_pop_state(); } void unputString(const char* textp, size_t length) { // Add characters to input stream in back-to-front order const char* cp = textp; for (cp += length - 1; length--; cp--) { unput(*cp); } } }; void V3ParseImp::statePop() { parsep()->m_lexerp->statePop(); } void V3ParseImp::unputString(const char* textp, size_t length) { parsep()->m_lexerp->unputString(textp, length); } int V3ParseImp::yylexReadTok() { // Call yylex() remembering last non-whitespace token int token = parsep()->m_lexerp->yylex(); m_prevLexToken = token; // Save so can find '#' to parse following number return token; } //###################################################################### // Read class functions void V3ParseImp::lexNew(int debug) { if (m_lexerp) delete m_lexerp; // Restart from clean slate. m_lexerp = new V3Lexer(); if (debugFlex()>=9) { m_lexerp->set_debug(~0); } } void V3ParseImp::lexDestroy() { if (m_lexerp) { delete m_lexerp; m_lexerp = NULL; } } verilator-3.874/src/V3ClkGater.cpp0000664000177100017500000010241412525171733016733 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity active domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2008-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3ClkGater's Transformations: // // Look for clock gaters // Note there's overlap between this process and V3Split's // ALWAYS: Build graph // IF: Form vertex pointing to any IFs or ALWAYS above // VARREF: Form vertex pointing to IFs it is under // ASSIGN: If under normal assignment, disable optimization // FUTURE OPTIMIZE: If signal is set to itself, consider that OK for gating. // !splitable: Mark all VARREFs in this statement as comming from it // Optimize graph so if signal is referenced under multiple IF branches it moves up // Make ALWAYS for each new gating term, and move statements there //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Ast.h" #include "V3Stats.h" #include "V3Graph.h" #include "V3ClkGater.h" //###################################################################### // Base for debug class GaterBaseVisitor : public AstNVisitor { protected: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //###################################################################### // Support classes class GaterVarVertex; class GaterVertex : public V3GraphVertex { static uint32_t s_rankNum; public: GaterVertex(V3Graph* graphp) : V3GraphVertex(graphp) { s_rankNum++; rank(s_rankNum); } virtual ~GaterVertex() {} virtual int typeNum() const = 0; static void clearRank() { s_rankNum=0; } virtual int sortCmp(const V3GraphVertex* rhsp) const; }; uint32_t GaterVertex::s_rankNum = 0; class GaterHeadVertex : public GaterVertex { public: GaterHeadVertex(V3Graph* graphp) : GaterVertex(graphp) {} virtual ~GaterHeadVertex() {} virtual int typeNum() const { return __LINE__; } // C++ typeof() equivelent virtual string name() const { return "*HEAD*"; } virtual string dotColor() const { return "green"; } }; class GaterPliVertex : public GaterVertex { public: GaterPliVertex(V3Graph* graphp) : GaterVertex(graphp) {} virtual ~GaterPliVertex() {} virtual int typeNum() const { return __LINE__; } // C++ typeof() equivelent virtual string name() const { return "*PLI*"; } virtual string dotColor() const { return "red"; } }; class GaterIfVertex : public GaterVertex { AstNodeIf* m_nodep; public: AstNodeIf* nodep() const { return m_nodep; } GaterIfVertex(V3Graph* graphp, AstNodeIf* nodep) : GaterVertex(graphp), m_nodep(nodep) { } virtual ~GaterIfVertex() {} virtual int typeNum() const { return __LINE__; } // C++ typeof() equivelent virtual string name() const { return cvtToStr((void*)m_nodep)+" {"+cvtToStr(m_nodep->fileline()->lineno())+"}"; } }; class GaterVarVertex : public GaterVertex { AstVarScope* m_nodep; public: AstVarScope* nodep() const { return m_nodep; } GaterVarVertex(V3Graph* graphp, AstVarScope* nodep) : GaterVertex(graphp), m_nodep(nodep) { } virtual ~GaterVarVertex() {} virtual int typeNum() const { return __LINE__; } // C++ typeof() equivelent virtual string name() const { return nodep()->name(); } virtual string dotColor() const { return "skyblue"; } }; //###################################################################### // Edge types class GaterEdge : public V3GraphEdge { uint32_t m_ifelse; // True branch of if public: // These are used as shift amounts into node's user() #define VU_DEFINE enum VarUsage { VU_NONE=0, VU_IF=1, VU_ELSE=2, VU_PLI=4, VU_MADE=8} VU_DEFINE; uint32_t ifelse() const { return m_ifelse; } bool ifelseTrue() const { return m_ifelse & VU_IF; } bool ifelseFalse() const { return m_ifelse & VU_ELSE; } bool ifelseBoth() const { return ifelseTrue() && ifelseFalse(); } GaterEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, uint32_t ifelse) : V3GraphEdge(graphp, fromp, top, 10, false), m_ifelse(ifelse) {} virtual ~GaterEdge() {} virtual string dotColor() const { return ((ifelse() & VU_PLI) ? "red" : (ifelseBoth() ? "blue" : (ifelseTrue() ? "green" : "darkgreen"))); } virtual int sortCmp(const V3GraphEdge* rEdgep) const { // Our master sort sorts by edges first, so we don't want to // consider the upstream vertex::sortCmp when sorting by edges. // We do want to order by something though; rank works if (fromp()->rank() < rEdgep->fromp()->rank()) return -1; if (fromp()->rank() > rEdgep->fromp()->rank()) return 1; // If same, resolve by ifelse const GaterEdge* crEdgep = static_cast(rEdgep); if (m_ifelse < crEdgep->m_ifelse) return -1; if (m_ifelse > crEdgep->m_ifelse) return 1; return 0; } }; int GaterVertex::sortCmp(const V3GraphVertex* rhsp) const { const GaterVertex* crhsp = static_cast(rhsp); // We really only care about ordering Var's together, but... // First put same type together if (typeNum() < crhsp->typeNum()) return -1; if (typeNum() > crhsp->typeNum()) return 1; // If variable, group by same input fanin // (know they're the same type based on above compare) if (dynamic_cast(this)) { // We've already sorted by edges, so just see if same tree // If this gets too slow, we could compute a hash up front V3GraphEdge* lEdgep = this->inBeginp(); V3GraphEdge* rEdgep = rhsp->inBeginp(); while (lEdgep && rEdgep) { const GaterEdge* clEdgep = static_cast(lEdgep); const GaterEdge* crEdgep = static_cast(rEdgep); if (lEdgep->fromp()->rank() < rEdgep->fromp()->rank()) return -1; if (lEdgep->fromp()->rank() > rEdgep->fromp()->rank()) return 1; if (clEdgep->ifelse() < crEdgep->ifelse()) return -1; if (clEdgep->ifelse() > crEdgep->ifelse()) return 1; lEdgep = lEdgep->inNextp(); rEdgep = rEdgep->inNextp(); } if (!lEdgep && !rEdgep) return 0; return lEdgep ? -1 : 1; } // Finally by rank of this vertex if (rank() < rhsp->rank()) return -1; if (rank() > rhsp->rank()) return 1; return 0; } //###################################################################### // Check for non-simple gating equations class GaterCondVisitor : public GaterBaseVisitor { private: // RETURN STATE bool m_isSimple; // Set false when we know it isn't simple // METHODS inline void okIterate(AstNode* nodep) { if (m_isSimple) nodep->iterateChildren(*this); } // VISITORS virtual void visit(AstOr* nodep, AstNUser*) { okIterate(nodep); } virtual void visit(AstAnd* nodep, AstNUser*) { okIterate(nodep); } virtual void visit(AstNot* nodep, AstNUser*) { okIterate(nodep); } virtual void visit(AstLogOr* nodep, AstNUser*) { okIterate(nodep); } virtual void visit(AstLogAnd* nodep, AstNUser*) { okIterate(nodep); } virtual void visit(AstLogNot* nodep, AstNUser*) { okIterate(nodep); } virtual void visit(AstVarRef* nodep, AstNUser*) { okIterate(nodep); } // Other possibilities are equals, etc // But, we don't want to get too complicated or it will take too much // effort to calculate the gater virtual void visit(AstNode* nodep, AstNUser*) { m_isSimple = false; //nodep->iterateChildren(*this); } public: // CONSTUCTORS GaterCondVisitor(AstNode* nodep) { m_isSimple = true; nodep->accept(*this); } virtual ~GaterCondVisitor() {} // PUBLIC METHODS bool isSimple() const { return m_isSimple; } }; //###################################################################### // Check for non-simple gating equations class GaterBodyVisitor : public GaterBaseVisitor { // NODE STATE // Input state // AstVarScope::user2p() -> AstAlways* moving this variable to enum State { // This is used as a bitmask STATE_UNKNOWN=0, STATE_KEEP=1, // Seen a variable we need, keep this statement STATE_DELETE=2 // Seen a variable we need, delete this statement // 3=keep & delete }; bool m_original; // Deleting original statements, vs deleting new var statements AstNode* m_exprp; // New gater expression we are building bool m_cloning; // Clone this object 0=not sure yet, 1=do uint32_t m_state; // Parsing state // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->lvalue()) { AstVarScope* vscp = nodep->varScopep(); if (vscp->user2p()->castNode() == m_exprp) { // This variable's block needs to move to the new always if (m_original) { UINFO(9," VARREF delete in old: "<iterateChildren(*this); childstate = m_state; } m_state = oldstate; UINFO(9," Did state="<unlinkFrBack()->deleteTree(); nodep=NULL; // Pass upwards we did delete m_state |= STATE_DELETE; } else { // Pass upwards we must keep m_state |= STATE_KEEP; } } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS GaterBodyVisitor(AstAlways* nodep, AstNode* exprp, bool original) { m_exprp = exprp; m_original = original; m_state = STATE_UNKNOWN; m_cloning = false; if (debug()>=9) nodep->dumpTree(cout," GateBodyIn: "); nodep->bodysp()->iterateAndNext(*this); if (debug()>=9) nodep->dumpTree(cout," GateBodyOut: "); // If there's no statements we shouldn't have had a resulting graph // vertex asking for this creation } virtual ~GaterBodyVisitor() {} }; //###################################################################### // Create clock gaters class GaterVisitor : public GaterBaseVisitor { // NODE STATE // Cleared on Always // AstVarScope::user1p() -> GaterVarVertex* // AstAlways::user4() -> bool. True indicates processed // Cleared on each new Always // AstVarScope::user2p() -> AstAlways* moving this variable to AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser4InUse m_inuser4; // GRAPH STATE // Cleared on simplify // Vertex::user() -> VarUsage: Mark of which if/else edges are hit // TYPES VU_DEFINE; enum MiscConsts { IF_DEPTH_MAX = 4, // IFs deep we bother to analyze DOMAINS_MAX = 32 // Clock domains before avoiding O(N^2) blowup }; // MEMBERS string m_nonopt; // Reason block is not optimizable V3Double0 m_statGaters; // Statistic tracking V3Double0 m_statBits; // Statistic tracking bool m_directlyUnderAlw; // Immediately under Always or If int m_ifDepth; // Depth of IF statements int m_numIfs; // Number of IF statements V3Graph m_graph; // Scoreboard of var usages/dependencies GaterPliVertex* m_pliVertexp; // Element specifying PLI ordering GaterHeadVertex* m_headVertexp; // Top vertex V3GraphVertex* m_aboveVertexp; // Vertex above this point in tree uint32_t m_aboveTrue; // Vertex above this point is true branch AstVarScope* m_stmtVscp; // Current statement had variable assigned bool m_stmtInPli; // Current statement has PLI // METHODS void nonOptimizable(AstNode* nodep, const char* reasonp) { if (m_nonopt=="") { UINFO(9," Nonopt: "<user1p()); new GaterEdge(&m_graph, m_pliVertexp, varVtxp, VU_PLI); } m_stmtInPli = true; // Mark all followon variables too } // METHODS -- GRAPH stuff void simplifyGraph() { if (debug()>=9) m_graph.dumpDotFilePrefixed("gater_init", false); // We now have all PLI variables with edges FROM the pli vertex simplifyPli(); if (debug()>=9) m_graph.dumpDotFilePrefixed("gater_pli", false); // Any vertex that points along both true & false path to variable // can be simplfied so parent points to that vertex. Any vertex // that points to a (great...) grandparent of a variable can just // point to the edge. m_graph.userClearVertices(); // user() will contain VarUsage simplifyIfElseRecurse(m_headVertexp); if (debug()>=9) m_graph.dumpDotFilePrefixed("gater_ifelse", false); m_graph.userClearVertices(); // user() will contain VarUsage simplifyGrandRecurse(m_headVertexp, 1); if (debug()>=9) m_graph.dumpDotFilePrefixed("gater_grand", false); simplifyRemoveUngated(m_headVertexp); // Give all signals with same gating term same color graphColorSameFeeder(); if (debug()>=9) m_graph.dumpDotFilePrefixed("gater_done", false); } void simplifyPli() { // For now, we'll not gate any logic with PLI lvariables in it. In // the future we may move PLI statements. One way to do so is to // all below pli VARs to go IfVertex -> PliVertex -> VarVertex then // they all must get colored the same. There may be a lot of // duplicated edges to the PLI; they'll need cleanup. All of the // later optimizations need to deal, and the GaterBodyVisitor needs // to know how to move them. if (m_pliVertexp) { // Follow PLI out edges to find all relevant variables for (V3GraphEdge* nextp,* edgep = m_pliVertexp->outBeginp(); edgep; edgep = nextp) { nextp = edgep->outNextp(); // We may edit the list if (GaterVarVertex* vVxp = dynamic_cast(edgep->top())) { vVxp->unlinkDelete(&m_graph); vVxp=NULL; edgep=NULL; } else { m_graph.dump(); v3fatalSrc("PLI vertex points to non-signal"); } } m_pliVertexp->unlinkDelete(&m_graph); m_pliVertexp = NULL; } } void simplifyIfElseRecurse(V3GraphVertex* vertexp) { // From bottom-up, propagate duplicate IF/ELSE branches to grandparent for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { simplifyIfElseRecurse(edgep->top()); } //UINFO(9,"IERecurse "<(vertexp)) { // Clear indications for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { edgep->top()->user(VU_NONE); } // Mark nodes on to/from side for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { V3GraphVertex* toVxp = edgep->top(); GaterEdge* cedgep = static_cast(edgep); // We may mark this twice in one pass - if so it's duplicated; no worries if (cedgep->ifelseTrue()) toVxp->user(toVxp->user() | VU_IF); if (cedgep->ifelseFalse()) toVxp->user(toVxp->user() | VU_ELSE); //UINFO(9," mark "<outBeginp(); edgep; edgep = nextp) { nextp = edgep->outNextp(); // We may edit the list V3GraphVertex* toVxp = edgep->top(); //UINFO(9," to "<user()<<" "<user() & VU_IF) && (toVxp->user() & VU_ELSE)) { edgep->unlinkDelete(); edgep = NULL; if (!(toVxp->user() & VU_MADE)) { // Make an edge only once toVxp->user(toVxp->user() | VU_MADE); GaterEdge* inedgep = static_cast(vertexp->inBeginp()); V3GraphVertex* grandparent = inedgep->fromp(); new GaterEdge(&m_graph, grandparent, toVxp, inedgep->ifelse()); } } } } } void simplifyGrandRecurse(V3GraphVertex* vertexp, uint32_t depth) { // From top-down delete any vars that grandparents source // IE A -> B -> C -> VAR // \----------^ //UINFO(9,"GRecurse "<outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); // We may edit the list if (GaterVarVertex* toVxp = dynamic_cast(edgep->top())) { if (toVxp->user() && toVxp->user() < depth) { // A recursion "above" us marked it, // Remove this edge, it's redundant with the upper edge edgep->unlinkDelete(); edgep=NULL; } else { GaterEdge* cedgep = static_cast(edgep); if (cedgep->ifelseBoth()) { toVxp->user(depth); } } } } // Recurse for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { simplifyGrandRecurse(edgep->top(), depth+1); } // Clean our marks for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { V3GraphVertex* toVxp = edgep->top(); if (toVxp->user() && toVxp->user() < depth) { // A recursion "above" us marked it; don't mess with it } else { toVxp->user(0); // We marked it originally, so unmark now } } // Delete any If nodes with no children // Last, as want bottom-up cleanup for (V3GraphEdge *nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); // We may edit the list if (GaterIfVertex* toVxp = dynamic_cast(edgep->top())) { if (!toVxp->outBeginp()) { if (!nextp || nextp->top() != edgep->top()) { // Else next would disappear; we'll do it next loop toVxp->unlinkDelete(&m_graph); toVxp=NULL; edgep=NULL; } } } } } void simplifyRemoveUngated(V3GraphVertex* vertexp) { // Remove variables that are ungated // At this point, any variable under the head is ungated for (V3GraphEdge *nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) { nextp = edgep->outNextp(); // We may edit the list if (GaterVarVertex* toVxp = dynamic_cast(edgep->top())) { if (!nextp || nextp->top() != edgep->top()) { // Else next would disappear; we'll do it next loop toVxp->unlinkDelete(&m_graph); toVxp=NULL; edgep=NULL; } } } } void graphColorSameFeeder() { // Assign same color to all destination vertices that have same // subgraph feeding into them // (I.E. all "from" nodes are common within each color) // We could hash, but instead it's faster to sort edges, so we know // the same edge list is always adjacent. The result is a // O(vertices*edges) loop, but we'd need that to hash too. if (debug()>9) { cout<<"PreColor:\n"; m_graph.dump(); } m_graph.sortEdges(); // Now sort vertices, so same inbound edge set ends up adjacent m_graph.sortVertices(); // Now walk and assign colors; same color is adjacent m_graph.clearColors(); m_graph.userClearEdges(); // Used by newExprFromGraph uint32_t color = 1; GaterVarVertex* lastVxp = NULL; for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { if (GaterVarVertex* vVxp = dynamic_cast(vertexp)) { if (!vVxp->inBeginp()) { // At this point, any variable not linked is an error // (It should have at least landed under the Head node) vVxp->nodep()->v3fatalSrc("Variable became stranded in clk gate detection\n"); } if (!lastVxp || vVxp->sortCmp(lastVxp)) { // Different sources for this new node color++; } vVxp->color(color); lastVxp = vVxp; } } if (debug()>9) { cout<<"PostColor:\n"; m_graph.dump(); } } AstNode* newExprFromGraph(GaterVarVertex* vertexp) { // Recurse backwards, then form equation on return path // We could use user()!=0, but zeroing it is slow, so instead we'll mark with a generation // We get equations like "a | (!a & b)" which obviously could be reduced here, // instead out of generality, there's a V3Const::matchOrAndNot that'll clean it up static uint32_t s_generation = 0; ++s_generation; nafgMarkRecurse(vertexp, s_generation); AstNode* nodep = nafgCreateRecurse(m_headVertexp, s_generation); if (debug()>=9) nodep->dumpTree(cout," GateExpr: "); return nodep; } void nafgMarkRecurse(V3GraphVertex* vertexp, uint32_t generation) { // Backwards mark user() on the path we recurse //UINFO(9," nafgMark: v "<<(void*)(vertexp)<<" "<name()<inBeginp(); edgep; edgep = edgep->inNextp()) { //UINFO(9," nafgMark: "<<(void*)(edgep)<<" "<name()<user(generation); nafgMarkRecurse(edgep->fromp(), generation); } } AstNode* nafgCreateRecurse(V3GraphVertex* vertexp, uint32_t generation) { // Forewards follow user() marked previously and build tree AstNode* nodep = NULL; // OR across all edges found at this level //UINFO(9," nafgEnter: v "<<(void*)(vertexp)<<" "<name()<outBeginp(); edgep; edgep = edgep->outNextp()) { if (edgep->user() == generation) { GaterEdge* cedgep = static_cast(edgep); AstNode* eqnp = NULL; //UINFO(9," nafgFollow: "<<(void*)(edgep)<<" "<name()<(edgep->fromp())) { // Just OR in all lower terms eqnp = nafgCreateRecurse(edgep->top(), generation); } else if (GaterIfVertex* cVxp = dynamic_cast(edgep->fromp())) { // Edges from IFs represent a real IF branch in the equation tree //UINFO(9," ifver "<<(void*)(edgep)<<" cc"<dotColor()<nodep()->condp()->cloneTree(true); if (eqnp && cedgep->ifelseFalse()) { eqnp = new AstNot(eqnp->fileline(),eqnp); } // We need to AND this term onto whatever was found below it AstNode* belowp = nafgCreateRecurse(edgep->top(), generation); if (belowp) eqnp = new AstAnd(eqnp->fileline(),eqnp,belowp); } // Top level we could choose to make multiple gaters, or ORs under the gater // Right now we'll put OR lower down and let other optimizations deal if (nodep) nodep = new AstOr(eqnp->fileline(),nodep,eqnp); else nodep = eqnp; //if (debug()>=9) nodep->dumpTree(cout," followExpr: "); } } //UINFO(9," nafgExit: "<<(void*)(vertexp)<<" "<name()<verticesNextp()) { if (GaterVarVertex* vVxp = dynamic_cast(vertexp)) { if (!lastExprp || lastColor != vVxp->color()) { lastColor = vVxp->color(); // Create the block we've just finished if (lastExprp) newAlwaysTree(nodep, lastExprp); // Duplicate below // New expression for this color lastExprp = newExprFromGraph(vVxp); } // Mark variable to move if (vVxp->nodep()->user2p()) vVxp->nodep()->v3fatalSrc("One variable got marked under two gaters"); vVxp->nodep()->user2p(lastExprp); m_statBits += vVxp->nodep()->width(); // Moving a wide bus counts more! // There shouldn't be two possibilities we want to // move to, IE {A,B} <= Z because we marked such // things as unoptimizable } } // Create the final block we've just finished if (lastExprp) newAlwaysTree(nodep, lastExprp); // Duplicate above } void newAlwaysTree(AstAlways* nodep, AstNode* exprp) { // Create new always with specified gating expression // Relevant vars are already marked with user2p // Should we put the gater under the always itself, // or make a new signal? // New signal: May cause replicated logic until we can combine // Need way to toggle signal on complicated pos/negedge // Under Always: More complicated, may not propagate logic with gateer // Untill we get better gate optimization, we'll go this route. //#define GATER_NOP #ifdef GATER_NOP // For testing only, don't clock gate but still make new always AstSenTree* sensesp = nodep->sensesp()->cloneTree(true); #else // Make a SenGate AstSenItem* oldsenitemsp = nodep->sensesp()->sensesp()->castSenItem(); if (!oldsenitemsp) nodep->v3fatalSrc("SenTree doesn't have any SenItem under it"); AstSenTree* sensesp = new AstSenTree(nodep->fileline(), new AstSenGate(nodep->fileline(), oldsenitemsp->cloneTree(true), exprp)); #endif // Make new body; note clone will preserve user2p() indicating moving vars AstNode* bodyp = nodep->bodysp()->cloneTree(true); AstAlways* alwp = new AstAlways(nodep->fileline(), nodep->keyword(), sensesp, bodyp); alwp->user4(1); // No need to process the new always again! nodep->addNextHere(alwp); // Blow moved statements from old body GaterBodyVisitor(nodep,exprp,true); // Blow old statements from new body GaterBodyVisitor(alwp,exprp,false); ++m_statGaters; if (debug()>=9) alwp->dumpTree(cout," new: "); } // VISITORS virtual void visit(AstAlways* nodep, AstNUser*) { if (debug()>=9) cout<user4SetOnce()) return; clear(); if (debug()>=9) nodep->dumpTree(cout," Alwin: "); // Look for constructs we can't optimize // Form graph with Vertices at each IF, and each Variable m_aboveTrue = VU_IF | VU_ELSE; iterateChildrenAlw(nodep, true); // Other reasons to not optimize if (!m_numIfs) nonOptimizable(nodep, "No if statements"); // Something to optimize, oh my! if (m_nonopt!="") { UINFO(5, " Gater non-opt: "<verticesNextp()) { if (GaterVarVertex* vVxp = dynamic_cast(vertexp)) { if (lastColor < vVxp->color()) { lastColor = vVxp->color(); } } } if (lastColor == 0) { // Nothing we moved! nonOptimizable(nodep, "Nothing moved"); } else if (lastColor > DOMAINS_MAX) { // Our move algorithm is fairly slow and if we're splitting // up too much it'll get really nasty. It's probably a bad // move for performance to split too much, anyhow, as the // number of gaters will result in calling many small c functions. nonOptimizable(nodep, "Too much moved"); } if (m_nonopt=="") { newAlwaysTrees(nodep); if (debug()>=9) nodep->dumpTree(cout," Gaterout: "); } } UINFO(5, " Gater done"<lvalue()) { AstVarScope* vscp = nodep->varScopep(); if (nodep->varp()->isSigPublic()) { // Public signals shouldn't be changed, pli code might be messing with them scoreboardPli(nodep); } // If another lvalue in this node, give up optimizing. // We could just not optimize this variable, but we've already marked the // other variable as optimizable, so we can instead pretend it's a PLI node. if (m_stmtVscp) { UINFO(5, " Multiple lvalues in one statement: "<user1p()); if (!vertexp) { vertexp = new GaterVarVertex(&m_graph, vscp); vscp->user1p(vertexp); } new GaterEdge(&m_graph, m_aboveVertexp, vertexp, m_aboveTrue); if (m_stmtInPli) { new GaterEdge(&m_graph, m_pliVertexp, vertexp, VU_PLI); } } } virtual void visit(AstNodeIf* nodep, AstNUser*) { m_ifDepth++; bool allowGater = m_directlyUnderAlw && m_ifDepth <= IF_DEPTH_MAX; if (allowGater) { GaterCondVisitor condVisitor(nodep->condp()); if (!condVisitor.isSimple()) { // Don't clear optimization, simply drop this IF as part of the gating UINFO(5," IFnon-simple-condition: "<condp()->iterateAndNext(*this); // directlyUnder stays as-is } { m_aboveVertexp = vertexp; // Vars will point at this edge m_aboveTrue = VU_IF; nodep->ifsp()->iterateAndNext(*this); // directlyUnder stays as-is (true) } { m_aboveVertexp = vertexp; // Vars will point at this edge m_aboveTrue = VU_ELSE; nodep->elsesp()->iterateAndNext(*this); // directlyUnder stays as-is (true) } m_aboveVertexp = lastabovep; m_aboveTrue = lasttrue; } m_ifDepth--; } virtual void visit(AstAssignDly* nodep, AstNUser*) { // iterateChildrenAlw will detect this is a statement for us iterateChildrenAlw(nodep, false); } virtual void visit(AstNodeAssign* nodep, AstNUser*) { // Note NOT AssignDly; handled above, We'll just mark this block as // not optimizable. // // A future alternative is to look for any lvalues that are also // variables in the sensitivity list, or rvalues in this block. If // any hit, disable optimization. Unlikely to be useful (For loops // being an exception, but they're already unrolled.) nonOptimizable(nodep, "Non-delayed assignment"); // No reason to iterate. } virtual void visit(AstSenItem* nodep, AstNUser*) { if (!nodep->isClocked()) { nonOptimizable(nodep, "Non-clocked sensitivity"); } iterateChildrenAlw(nodep, false); } //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { if (m_nonopt=="") { // Else accelerate iterateChildrenAlw(nodep, false); } } inline void iterateChildrenAlw(AstNode* nodep, bool under) { // **** USE THIS INSTEAD OF iterateChildren! // Note If visitor doesn't call here; does it its own way bool lastdua = m_directlyUnderAlw; AstVarScope* lastvscp = m_stmtVscp; bool lastpli = m_stmtInPli; m_directlyUnderAlw = under; if (nodep->castNodeStmt()) { // Restored below UINFO(9," Stmt: "<isPure() || nodep->isBrancher()) { // May also be a new statement (above if); if so we mark it immediately UINFO(9," NotPure "<iterateChildren(*this); } m_directlyUnderAlw = lastdua; if (nodep->castNodeStmt()) { // Reset what set above; else propagate up to above statement m_stmtVscp = lastvscp; m_stmtInPli = lastpli; } } public: // CONSTUCTORS GaterVisitor(AstNode* nodep) { // AstAlways visitor does the real work, so most zeroing needs to be in clear() clear(); nodep->accept(*this); } void clear() { m_nonopt = ""; m_directlyUnderAlw = false; m_ifDepth = 0; m_numIfs = 0; AstNode::user1ClearTree(); AstNode::user2ClearTree(); // Prepare graph m_graph.clear(); GaterVertex::clearRank(); m_pliVertexp = NULL; m_headVertexp = new GaterHeadVertex(&m_graph); m_aboveVertexp = m_headVertexp; m_aboveTrue = false; m_stmtVscp = NULL; m_stmtInPli = false; } virtual ~GaterVisitor() { V3Stats::addStat("Optimizations, Gaters inserted", m_statGaters); V3Stats::addStat("Optimizations, Gaters impacted bits", m_statBits); } }; //###################################################################### // Active class functions void V3ClkGater::clkGaterAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Width.cpp0000664000177100017500000046664412534630412016332 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Expression width calculations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Width's Transformations: // Top down traversal: // Determine width of sub-expressions // width() = # bits upper expression wants, 0 for anything-goes // widthUnsized() = # bits for unsized constant, or 0 if it's sized // widthMin() = Alternative acceptable width for linting, or width() if sized // Determine this subop's width, can be either: // Fixed width X // Unsized, min width X ('d5 is unsized, min 3 bits.) // Pass up: // width() = # bits this expression generates // widthSized() = true if all constants sized, else false // Compute size of this expression // Lint warn about mismatches // If expr size != subop fixed, bad // If expr size < subop unsized minimum, bad // If expr size != subop, edit netlist // For == and similar ops, if multibit underneath, add a REDOR // If subop larger, add a EXTRACT // If subop smaller, add a EXTEND // Pass size to sub-expressions if required (+/-* etc) // FINAL = true. // Subexpressions lint and extend as needed // //************************************************************************* // Signedness depends on: // Decimal numbers are signed // Based numbers are unsigned unless 's' prefix // Comparison results are unsigned // Bit&Part selects are unsigned, even if whole // Concatenates are unsigned // Ignore signedness of self-determined: // shift rhs, ** rhs, x?: lhs, concat and replicate members // Else, if any operand unsigned, output unsigned // // Real number rules: // Real numbers are real (duh) // Reals convert to integers by rounding // Reals init to 0.0 // Logicals convert compared to zero // If any operand is real, result is real //************************************************************************* // V3Width is the only visitor that uses vup. We could switch to using userp, // though note some iterators operate on next() and so would need to pass the // same value on each nextp(). //************************************************************************* // See notes in internal.txt about misuse of iterateAndNext and use of // acceptSubtreeReturnEdits. //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3Width.h" #include "V3Number.h" #include "V3Const.h" #include "V3String.h" #include "V3Task.h" // More code; this file was getting too large; see actions there #define _V3WIDTH_CPP_ #include "V3WidthCommit.h" //###################################################################### enum Stage { PRELIM=1,FINAL=2,BOTH=3 }; // Numbers are a bitmask <0>=prelim, <1>=final ostream& operator<<(ostream& str, const Stage& rhs) { return str<<("-PFB"[(int)rhs]); } enum Determ { SELF, // Self-determined CONTEXT, // Context-determined ASSIGN // Assignment-like where sign comes from RHS only }; ostream& operator<<(ostream& str, const Determ& rhs) { static const char* s_det[] = {"SELF","CNTX","ASSN"}; return str<width(); } int widthMin() const { if (!m_dtypep) v3fatalSrc("Width request on self-determined or preliminary VUP"); return m_dtypep->widthMin(); } bool prelim() const { return m_stage & PRELIM; } bool final() const { return m_stage & FINAL; } void dump(ostream& str) const { if (!this) { str<<" VUP(NULL)"; } else if (!m_dtypep) { str<<" VUP(s="<dump(str); return str; } //###################################################################### class WidthVisitor : public AstNVisitor { private: // TYPES typedef map, AstVar*> TableMap; typedef map PatVecMap; // STATE bool m_paramsOnly; // Computing parameter value; limit operation AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations AstFunc* m_funcp; // Current function AstInitial* m_initialp; // Current initial block AstAttrOf* m_attrp; // Current attribute bool m_doGenerate; // Do errors later inside generate statement int m_dtTables; // Number of created data type tables TableMap m_tableMap; // Created tables so can remove duplicates // ENUMS enum ExtendRule { EXTEND_EXP, // Extend if expect sign and node signed, e.g. node=y in ADD(x,y), "x + y" EXTEND_ZERO, // Extend with zeros. e.g. node=y in EQ(x,y), "x == y" EXTEND_LHS, // Extend with sign if node signed. e.g. node=y in ASSIGN(y,x), "x = y" EXTEND_OFF // No extension }; // METHODS static int debug() { return V3Width::debug(); } // VISITORS // Naming: width_O{outputtype}_L{lhstype}_R{rhstype}_W{widthing}_S{signing} // Where type: // _O1=boolean (width 1 unsigned) // _Ou=unsigned // _Os=signed // _Ous=unsigned or signed // _Or=real // _Ox=anything // Widths: 1 bit out, lhs 1 bit; Real: converts via compare with 0 virtual void visit(AstLogNot* nodep, AstNUser* vup) { visit_log_not(nodep,vup); } // Widths: 1 bit out, lhs 1 bit, rhs 1 bit; Real: converts via compare with 0 virtual void visit(AstLogAnd* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); } virtual void visit(AstLogOr* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); } virtual void visit(AstLogIf* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); } // Conversion from real not in IEEE, but a fallout virtual void visit(AstLogIff* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); } // Conversion from real not in IEEE, but a fallout // Widths: 1 bit out, Any width lhs virtual void visit(AstRedAnd* nodep, AstNUser* vup) { visit_red_and_or(nodep,vup); } virtual void visit(AstRedOr* nodep, AstNUser* vup) { visit_red_and_or(nodep,vup); } virtual void visit(AstRedXnor* nodep, AstNUser* vup){ visit_red_and_or(nodep,vup); } virtual void visit(AstRedXor* nodep,AstNUser* vup) { visit_red_and_or(nodep,vup); } virtual void visit(AstOneHot* nodep,AstNUser* vup) { visit_red_and_or(nodep,vup); } virtual void visit(AstOneHot0* nodep,AstNUser* vup) { visit_red_and_or(nodep,vup); } virtual void visit(AstIsUnknown* nodep,AstNUser* vup) { visit_red_unknown(nodep,vup); } // Allow real // These have different node types, as they operate differently // Must add to case statement below, // Widths: 1 bit out, lhs width == rhs width. real if lhs|rhs real virtual void visit(AstEq* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstNeq* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstGt* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstGte* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstLt* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstLte* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstGtS* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstGteS* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstLtS* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstLteS* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstEqCase* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } virtual void visit(AstNeqCase* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,true); } // ... These comparisons don't allow reals virtual void visit(AstEqWild* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,false); } virtual void visit(AstNeqWild* nodep, AstNUser* vup) { visit_cmp_eq_gt(nodep,vup,false); } // ... Real compares virtual void visit(AstEqD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } virtual void visit(AstNeqD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } virtual void visit(AstLtD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } virtual void visit(AstLteD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } virtual void visit(AstGtD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } virtual void visit(AstGteD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); } // ... String compares virtual void visit(AstEqN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } virtual void visit(AstNeqN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } virtual void visit(AstLtN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } virtual void visit(AstLteN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } virtual void visit(AstGtN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } virtual void visit(AstGteN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); } // Widths: out width = lhs width = rhs width // Signed: Output signed iff LHS & RHS signed. // Real: Not allowed virtual void visit(AstAnd* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } virtual void visit(AstOr* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } virtual void visit(AstXnor* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } virtual void visit(AstXor* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } virtual void visit(AstBufIf1* nodep, AstNUser* vup) { visit_boolmath_and_or(nodep,vup); } // Signed behavior changing in 3.814 // Width: Max(Lhs,Rhs) sort of. // Real: If either side real // Signed: If both sides real virtual void visit(AstAdd* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,true); } virtual void visit(AstSub* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,true); } virtual void visit(AstDiv* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,true); } virtual void visit(AstMul* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,true); } // These can't promote to real virtual void visit(AstModDiv* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,false); } virtual void visit(AstModDivS* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,false); } virtual void visit(AstMulS* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,false); } virtual void visit(AstDivS* nodep, AstNUser* vup) { visit_add_sub_replace(nodep,vup,false); } // Widths: out width = lhs width, but upper matters // Signed: Output signed iff LHS signed; unary operator // Unary promote to real virtual void visit(AstNegate* nodep, AstNUser* vup) { visit_negate_not(nodep,vup,true); } // Unary never real virtual void visit(AstNot* nodep, AstNUser* vup) { visit_negate_not(nodep,vup,false); } // Real: inputs and output real virtual void visit(AstAddD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } virtual void visit(AstSubD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } virtual void visit(AstDivD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } virtual void visit(AstMulD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } virtual void visit(AstPowD* nodep, AstNUser* vup) { visit_real_add_sub(nodep,vup); } // Real: Output real virtual void visit(AstNegateD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } virtual void visit(AstCeilD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } virtual void visit(AstExpD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } virtual void visit(AstFloorD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } virtual void visit(AstLogD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } virtual void visit(AstLog10D* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } virtual void visit(AstSqrtD* nodep, AstNUser* vup) { visit_real_neg_ceil(nodep,vup); } // Widths: out signed/unsigned width = lhs width, input un|signed virtual void visit(AstSigned* nodep, AstNUser* vup) { visit_signed_unsigned(nodep,vup,AstNumeric::SIGNED); } virtual void visit(AstUnsigned* nodep, AstNUser* vup) { visit_signed_unsigned(nodep,vup,AstNumeric::UNSIGNED); } // Widths: Output width from lhs, rhs<33 bits // Signed: If lhs signed virtual void visit(AstShiftL* nodep, AstNUser* vup) { visit_shift(nodep,vup); } virtual void visit(AstShiftR* nodep, AstNUser* vup) { visit_shift(nodep,vup); } // ShiftRS converts to ShiftR, but not vice-versa virtual void visit(AstShiftRS* nodep, AstNUser* vup) { visit_shift(nodep,vup); } //======== // Widths: Output real, input integer signed virtual void visit(AstBitsToRealD* nodep, AstNUser* vup) { visit_Or_Lu64(nodep,vup); } virtual void visit(AstIToRD* nodep, AstNUser* vup) { visit_Or_Ls32(nodep,vup); } // Widths: Output integer signed, input real virtual void visit(AstRToIS* nodep, AstNUser* vup) { visit_Os32_Lr(nodep,vup); } virtual void visit(AstRToIRoundS* nodep, AstNUser* vup) { visit_Os32_Lr(nodep,vup); } // Widths: Output integer unsigned, input real virtual void visit(AstRealToBits* nodep, AstNUser* vup) { visit_Ou64_Lr(nodep,vup); } // Widths: Constant, terminal virtual void visit(AstTime* nodep, AstNUser*) { nodep->dtypeSetUInt64(); } virtual void visit(AstTimeD* nodep, AstNUser*) { nodep->dtypeSetDouble(); } virtual void visit(AstTestPlusArgs* nodep, AstNUser*) { nodep->dtypeSetSigned32(); } virtual void visit(AstScopeName* nodep, AstNUser*) { nodep->dtypeSetUInt64(); } // A pointer, but not that it matters // Special cases. So many.... virtual void visit(AstNodeCond* nodep, AstNUser* vup) { // op=cond?expr1:expr2 // Signed: Output signed iff RHS & THS signed (presumed, not in IEEE) // See IEEE-2012 11.4.11 and Table 11-21. // LHS is self-determined // Width: max(RHS,THS) // Real: Output real if either expression is real, non-real argument gets converted if (vup->c()->prelim()) { // First stage evaluation // Just once, do the conditional, expect one bit out. iterateCheckBool(nodep,"Conditional Test",nodep->condp(),BOTH); // Determine sub expression widths only relying on what's in the subops // CONTEXT determined, but need data type for pattern assignments nodep->expr1p()->iterateAndNext(*this,WidthVP(vup->c()->dtypeNullp(),PRELIM).p()); nodep->expr2p()->iterateAndNext(*this,WidthVP(vup->c()->dtypeNullp(),PRELIM).p()); // Calculate width of this expression. // First call (prelim()) vup->c()->width() is probably zero, so we'll return // the size of this subexpression only. // Second call (final()) vup->c()->width() is probably the expression size, so // the expression includes the size of the output too. if (nodep->expr1p()->isDouble() || nodep->expr2p()->isDouble()) { nodep->dtypeSetDouble(); } else { int width = max(nodep->expr1p()->width(), nodep->expr2p()->width()); int mwidth = max(nodep->expr1p()->widthMin(), nodep->expr2p()->widthMin()); bool issigned = nodep->expr1p()->isSigned() && nodep->expr2p()->isSigned(); nodep->dtypeSetLogicSized(width,mwidth,AstNumeric::fromBool(issigned)); } } if (vup->c()->final()) { AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // Error report and change sizes for suboperands of this node. iterateCheck(nodep,"Conditional True", nodep->expr1p(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); iterateCheck(nodep,"Conditional False",nodep->expr2p(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); } } virtual void visit(AstConcat* nodep, AstNUser* vup) { // Real: Not allowed (assumed) // Signed: unsigned output, input either (assumed) // IEEE-2012 Table 11-21, and 11.8.1: // LHS, RHS is self-determined // signed: Unsigned (11.8.1) // width: LHS + RHS if (vup->c()->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); nodep->dtypeSetLogicSized(nodep->lhsp()->width() + nodep->rhsp()->width(), nodep->lhsp()->widthMin() + nodep->rhsp()->widthMin(), AstNumeric::UNSIGNED); // Cleanup zero width Verilog2001 {x,{0{foo}}} now, // otherwise having width(0) will cause later assertions to fire if (AstReplicate* repp=nodep->lhsp()->castReplicate()) { if (repp->width()==0) { // Keep rhs nodep->replaceWith(nodep->rhsp()->unlinkFrBack()); pushDeletep(nodep); nodep=NULL; return; } } if (AstReplicate* repp=nodep->rhsp()->castReplicate()) { if (repp->width()==0) { // Keep lhs nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); pushDeletep(nodep); nodep=NULL; return; } } if (nodep->lhsp()->isString() || nodep->rhsp()->isString()) { AstNode* newp = new AstConcatN (nodep->fileline(),nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; return; } } if (vup->c()->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations."); } } } virtual void visit(AstConcatN* nodep, AstNUser* vup) { // String concatenate. // Already did AstConcat simplifications if (vup->c()->prelim()) { iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckString(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetString(); } if (vup->c()->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations."); } } } virtual void visit(AstReplicate* nodep, AstNUser* vup) { // IEEE-2012 Table 11-21: // LHS, RHS is self-determined // width: value(LHS) * width(RHS) if (vup->c()->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change AstConst* constp = nodep->rhsp()->castConst(); if (!constp) { nodep->v3error("Replication value isn't a constant."); return; } uint32_t times = constp->toUInt(); if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up. nodep->v3error("Replication value of 0 is only legal under a concatenation."); times=1; } if (nodep->lhsp()->isString()) { AstNode* newp = new AstReplicateN(nodep->fileline(),nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; return; } else { nodep->dtypeSetLogicSized((nodep->lhsp()->width() * times), (nodep->lhsp()->widthMin() * times), AstNumeric::UNSIGNED); } } if (vup->c()->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications."); } } } virtual void visit(AstReplicateN* nodep, AstNUser* vup) { // Replicate with string if (vup->c()->prelim()) { iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change AstConst* constp = nodep->rhsp()->castConst(); if (!constp) { nodep->v3error("Replication value isn't a constant."); return; } uint32_t times = constp->toUInt(); if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up. nodep->v3error("Replication value of 0 is only legal under a concatenation."); times=1; } nodep->dtypeSetString(); } if (vup->c()->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications."); } } } virtual void visit(AstNodeStream* nodep, AstNUser* vup) { if (vup->c()->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change AstConst* constp = nodep->rhsp()->castConst(); AstBasicDType* basicp = nodep->rhsp()->castBasicDType(); if (!constp && !basicp) { nodep->v3error("Slice size isn't a constant or basic data type."); return; } if (basicp) { // Convert data type to a constant size AstConst* newp = new AstConst(basicp->fileline(), basicp->width()); nodep->rhsp()->replaceWith(newp); pushDeletep(basicp); } else { uint32_t sliceSize = constp->toUInt(); if (!sliceSize) { nodep->v3error("Slice size cannot be zero."); return; } } nodep->dtypeSetLogicSized((nodep->lhsp()->width()), (nodep->lhsp()->widthMin()), AstNumeric::UNSIGNED); } if (vup->c()->final()) { if (!nodep->dtypep()->widthSized()) { // See also error in V3Number nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in streams."); } } } virtual void visit(AstRange* nodep, AstNUser* vup) { // Real: Not allowed // Signed: unsigned output, input either // Convert all range values to constants UINFO(6,"RANGE "<msbp()); // May relink pointed to node V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node checkConstantOrReplace(nodep->msbp(), "MSB of bit range isn't a constant"); checkConstantOrReplace(nodep->lsbp(), "LSB of bit range isn't a constant"); int msb = nodep->msbConst(); int lsb = nodep->lsbConst(); if (msblittleEndian(!nodep->littleEndian()); // Internally we'll always have msb() be the greater number // We only need to correct when doing [] AstSel extraction, // and when tracing the vector. nodep->msbp()->swapWith(nodep->lsbp()); } if (vup->c()->prelim()) { // Don't need to iterate because V3Const already constified int width = nodep->elementsConst(); if (width > (1<<28)) nodep->v3error("Width of bit range is huge; vector of over 1billion bits: 0x"<littleEndian() && !nodep->backp()->castUnpackArrayDType()) { nodep->v3warn(LITENDIAN,"Little bit endian vector: MSB < LSB of bit range: "<lsbConst()<<":"<msbConst()); } } } virtual void visit(AstSel* nodep, AstNUser* vup) { // Signed: always unsigned; Real: Not allowed // LSB is self-determined (IEEE 2012 11.5.1) // We also use SELs to shorten a signed constant etc, in this case they are signed. if (nodep->didWidth()) return; if (vup->c()->prelim()) { if (debug()>=9) nodep->dumpTree(cout,"-selWidth: "); nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); nodep->lsbp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); checkCvtUS(nodep->fromp()); iterateCheckSizedSelf(nodep,"Select Width",nodep->widthp(),SELF,BOTH); iterateCheckSizedSelf(nodep,"Select LHS",nodep->lhsp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->widthp()); // widthp may change AstConst* widthConstp = nodep->widthp()->castConst(); if (!widthConstp) { nodep->v3error("Width of bit extract isn't a constant"); nodep->dtypeSetLogicBool(); return; } int width = nodep->widthConst(); if (!nodep->dtypep()) nodep->v3fatalSrc("dtype wasn't set") // by V3WidthSel if (nodep->lsbp()->castConst() && nodep->msbConst() < nodep->lsbConst()) { nodep->v3error("Unsupported: MSB < LSB of bit extract: " <msbConst()<<"<"<lsbConst()); width = (nodep->lsbConst() - nodep->msbConst() + 1); nodep->dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); nodep->widthp()->replaceWith(new AstConst(nodep->widthp()->fileline(), width)); nodep->lsbp()->replaceWith(new AstConst(nodep->lsbp()->fileline(), 0)); } // We're extracting, so just make sure the expression is at least wide enough. if (nodep->fromp()->width() < width) { nodep->v3error("Extracting "<fromp()->width()<<" bit number"); // Extend it. AstNodeDType* subDTypep = nodep->findLogicDType(width,width,nodep->fromp()->dtypep()->numeric()); widthCheckSized(nodep,"errorless...",nodep->fromp(),subDTypep,EXTEND_EXP,false/*noerror*/); } // Check bit indexes. // What is the MSB? We want the true MSB, not one starting at 0, // because a 4 bit index is required to look at a one-bit variable[15:15] and 5 bits for [15:-2] int frommsb = nodep->fromp()->width() - 1; int fromlsb = 0; int elw = nodep->declElWidth(); // Must adjust to tell user bit ranges if (nodep->declRange().ranged()) { frommsb = nodep->declRange().hiMaxSelect()*elw + (elw-1); // Corrected for negative lsb fromlsb = nodep->declRange().lo()*elw; } else { //nodep->v3fatalSrc("Should have been declRanged in V3WidthSel"); } int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit AstNodeDType* selwidthDTypep = nodep->findLogicDType(selwidth,selwidth,nodep->lsbp()->dtypep()->numeric()); nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,FINAL).p()); nodep->lsbp()->iterateAndNext(*this,WidthVP(SELF,FINAL).p()); if (widthBad(nodep->lsbp(),selwidthDTypep) && nodep->lsbp()->width()!=32) { if (!nodep->fileline()->warnIsOff(V3ErrorCode::WIDTH)) { nodep->v3warn(WIDTH,"Bit extraction of var["<<(frommsb/elw)<<":"<<(fromlsb/elw)<<"] requires " <<(selwidth/elw)<<" bit index, not " <<(nodep->lsbp()->width()/elw) <<(nodep->lsbp()->width()!=nodep->lsbp()->widthMin() ?" or "+cvtToStr(nodep->lsbp()->widthMin()/elw):"") <<" bits."); UINFO(1," Related node: "<lsbp()->castConst() && nodep->msbConst() > frommsb) { // See also warning in V3Const // We need to check here, because the widthCheckSized may silently // add another SEL which will lose the out-of-range check // // We don't want to trigger an error here if we are just // evaluating type sizes for a generate block condition. We // should only trigger the error if the out-of-range access is // actually generated. if (m_doGenerate) { UINFO(5, "Selection index out of range inside generate."<v3warn(SELRANGE,"Selection index out of range: " <msbConst()<<":"<lsbConst() <<" outside "<lsbp(),selwidthDTypep,EXTEND_EXP,false/*NOWARN*/); } } } virtual void visit(AstArraySel* nodep, AstNUser* vup) { // Signed/Real: Output signed iff LHS signed/real; binary operator // Note by contrast, bit extract selects are unsigned // LSB is self-determined (IEEE 2012 11.5.1) if (vup->c()->prelim()) { iterateCheckSizedSelf(nodep,"Bit select",nodep->bitp(),SELF,BOTH); nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); // int frommsb; int fromlsb; AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp(); if (AstUnpackArrayDType* adtypep = fromDtp->castUnpackArrayDType()) { frommsb = adtypep->msb(); fromlsb = adtypep->lsb(); if (fromlsb>frommsb) {int t=frommsb; frommsb=fromlsb; fromlsb=t; } // However, if the lsb<0 we may go negative, so need more bits! if (fromlsb < 0) frommsb += -fromlsb; nodep->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference } else { // Note PackArrayDType doesn't use an ArraySel but a normal Sel. UINFO(1," Related dtype: "<v3fatalSrc("Array reference exceeds dimension of array"); frommsb = fromlsb = 0; } int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit AstNodeDType* selwidthDTypep = nodep->findLogicDType(selwidth,selwidth,nodep->bitp()->dtypep()->numeric()); if (widthBad(nodep->bitp(),selwidthDTypep) && nodep->bitp()->width()!=32) { nodep->v3warn(WIDTH,"Bit extraction of array["<bitp()->width() <<(nodep->bitp()->width()!=nodep->bitp()->widthMin() ?" or "+cvtToStr(nodep->bitp()->widthMin()):"") <<" bits."); if (!nodep->fileline()->warnIsOff(V3ErrorCode::WIDTH)) { UINFO(1," Related node: "<dtypep()<bitp()->castConst() && (nodep->bitp()->castConst()->toSInt() > (frommsb-fromlsb) || nodep->bitp()->castConst()->toSInt() < 0)) { nodep->v3warn(SELRANGE,"Selection index out of range: " <<(nodep->bitp()->castConst()->toSInt()+fromlsb) <<" outside "<bitp(),selwidthDTypep,EXTEND_EXP,false/*NOWARN*/); } } } virtual void visit(AstSelBit* nodep, AstNUser* vup) { // Just a quick check as after V3Param these nodes instead are AstSel's nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->thsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } nodep->v3fatalSrc("AstSelBit should disappear after widthSel"); } virtual void visit(AstSelExtract* nodep, AstNUser* vup) { // Just a quick check as after V3Param these nodes instead are AstSel's nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->thsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } nodep->v3fatalSrc("AstSelExtract should disappear after widthSel"); } virtual void visit(AstSelPlus* nodep, AstNUser* vup) { nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->thsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } nodep->v3fatalSrc("AstSelPlus should disappear after widthSel"); } virtual void visit(AstSelMinus* nodep, AstNUser* vup) { nodep->fromp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->thsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); //FINAL in AstSel nodep->attrp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } nodep->v3fatalSrc("AstSelMinus should disappear after widthSel"); } virtual void visit(AstExtend* nodep, AstNUser* vup) { // Only created by this process, so we know width from here down is correct. } virtual void visit(AstExtendS* nodep, AstNUser* vup) { // Only created by this process, so we know width from here down is correct. } virtual void visit(AstConst* nodep, AstNUser* vup) { // The node got setup with the signed/real state of the node. // However a later operation may have changed the node->signed w/o changing // the number's sign. So we don't: nodep->dtypeChgSigned(nodep->num().isSigned()); if (vup && vup->c()->prelim()) { if (nodep->num().isString()) { nodep->dtypeSetString(); } else if (nodep->num().sized()) { nodep->dtypeChgWidth(nodep->num().width(), nodep->num().width()); } else { nodep->dtypeChgWidth(nodep->num().width(), nodep->num().widthMin()); } } // We don't size the constant until we commit the widths, as need parameters // to remain unsized, and numbers to remain unsized to avoid backp() warnings } virtual void visit(AstRand* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->dtypeSetSigned32(); // Says the spec } } virtual void visit(AstUCFunc* nodep, AstNUser* vup) { // Give it the size the user wants. if (vup && vup->c()->prelim()) { nodep->dtypeSetLogicSized(32,1,AstNumeric::UNSIGNED); // We don't care // All arguments seek their natural sizes nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); } if (vup->c()->final()) { AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); nodep->dtypeFrom(expDTypep); // Assume user knows the rules; go with the flow if (nodep->width()>64) nodep->v3error("Unsupported: $c can't generate wider than 64 bits"); } } virtual void visit(AstCLog2* nodep, AstNUser* vup) { if (vup->c()->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); nodep->dtypeSetSigned32(); } } virtual void visit(AstPow* nodep, AstNUser* vup) { // Pow is special, output sign only depends on LHS sign, but function result depends on both signs // RHS is self-determined (IEEE) // Real if either side is real (as with AstAdd) if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); spliceCvtD(nodep->rhsp()); replaceWithDVersion(nodep); nodep=NULL; return; } checkCvtUS(nodep->lhsp()); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); nodep->dtypeFrom(nodep->lhsp()); } if (vup->c()->final()) { AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); nodep->dtypeFrom(expDTypep); // rhs already finalized in iterate_shift_prelim iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,nodep->dtypep(),EXTEND_EXP); if (nodep->width()>64) nodep->v3error("Unsupported: Large >64bit ** power operator not implemented."); AstNode* newp = NULL; // No change if (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()) { newp = new AstPowSS (nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); } else if (nodep->lhsp()->isSigned() && !nodep->rhsp()->isSigned()) { newp = new AstPowSU (nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); } else if (!nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()) { newp = new AstPowUS (nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); } if (newp) { newp->dtypeFrom(nodep); UINFO(9,"powOld "<replaceWith(newp); nodep=NULL; } } } virtual void visit(AstPowSU* nodep, AstNUser* vup) { // POWSU/SS/US only created here, dtype already determined, so nothing to do in this function nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } virtual void visit(AstPowSS* nodep, AstNUser* vup) { // POWSU/SS/US only created here, dtype already determined, so nothing to do in this function nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } virtual void visit(AstPowUS* nodep, AstNUser* vup) { // POWSU/SS/US only created here, dtype already determined, so nothing to do in this function nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } virtual void visit(AstCountOnes* nodep, AstNUser* vup) { if (vup->c()->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); // If it's a 32 bit number, we need a 6 bit number as we need to return '32'. int selwidth = V3Number::log2b(nodep->lhsp()->width())+1; nodep->dtypeSetLogicSized(selwidth,selwidth,AstNumeric::UNSIGNED); // Spec doesn't indicate if an integer } } virtual void visit(AstCvtPackString* nodep, AstNUser* vup) { // Opaque returns, so arbitrary nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); // Type set in constructor } virtual void visit(AstAttrOf* nodep, AstNUser*) { AstAttrOf* oldAttr = m_attrp; m_attrp = nodep; nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); // Don't iterate children, don't want to lose VarRef. switch (nodep->attrType()) { case AstAttrType::VAR_BASE: // Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf break; case AstAttrType::MEMBER_BASE: // Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf break; case AstAttrType::DIM_DIMENSIONS: case AstAttrType::DIM_UNPK_DIMENSIONS: { if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); pair dim = nodep->fromp()->dtypep()->dimensions(true); int val = (nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS ? dim.second : (dim.first+dim.second)); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32(), val)); nodep->deleteTree(); nodep=NULL; break; } case AstAttrType::DIM_BITS: case AstAttrType::DIM_HIGH: case AstAttrType::DIM_INCREMENT: case AstAttrType::DIM_LEFT: case AstAttrType::DIM_LOW: case AstAttrType::DIM_RIGHT: case AstAttrType::DIM_SIZE: { if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); pair dim = nodep->fromp()->dtypep()->skipRefp()->dimensions(true); uint32_t msbdim = dim.first+dim.second; if (!nodep->dimp() || nodep->dimp()->castConst() || msbdim<1) { int dim = !nodep->dimp() ? 1 : nodep->dimp()->castConst()->toSInt(); AstConst* newp = dimensionValue(nodep->fromp()->dtypep(), nodep->attrType(), dim); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } else { // Need a runtime lookup table. Yuk. if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); AstVar* varp = dimensionVarp(nodep->fromp()->dtypep(), nodep->attrType(), msbdim); AstNode* dimp = nodep->dimp()->unlinkFrBack(); AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false); varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp()); AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, dimp); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } break; } default: { // Everything else resolved earlier nodep->dtypeSetLogicSized(32,1,AstNumeric::UNSIGNED); // Approximation, unsized 32 UINFO(1,"Missing ATTR type case node: "<v3fatalSrc("Missing ATTR type case"); break; } } m_attrp = oldAttr; } virtual void visit(AstText* nodep, AstNUser* vup) { // Only used in CStmts which don't care.... } // DTYPES virtual void visit(AstNodeArrayDType* nodep, AstNUser*) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep)); // Iterate into subDTypep() to resolve that type and update pointer. nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); // Cleanup array size nodep->rangep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->dtypep(nodep); // The array itself, not subDtype if (nodep->castUnpackArrayDType()) { // Historically array elements have width of the ref type not the full array nodep->widthFromSub(nodep->subDTypep()); } else { int width = nodep->subDTypep()->width() * nodep->rangep()->elementsConst(); nodep->widthForce(width,width); } UINFO(4,"dtWidthed "<didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->generic()) return; // Already perfect if (nodep->rangep()) { nodep->rangep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); // Because this DType has a unique child range, we know it's not pointed at by // other nodes unless they are referencing this type. Furthermore the width() // calculation would return identical values. Therefore we can directly replace the width nodep->widthForce(nodep->rangep()->elementsConst(), nodep->rangep()->elementsConst()); } else if (nodep->implicit()) { // Parameters may notice implicitness and change to different dtype nodep->widthForce(1,1); } // else width in node is correct; it was set based on keyword().width() // at construction time. Ditto signed, so "unsigned byte" etc works right. nodep->cvtRangeConst(); // TODO: If BasicDType now looks like a generic type, we can convert to a real generic dtype // Instead for now doing this in V3WidthCommit UINFO(4,"dtWidthed "<didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed // Move any childDTypep to instead be in global AstTypeTable. // This way if this node gets deleted and some other dtype points to it // it won't become a dead pointer. This doesn't change the object pointed to. if (nodep->childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep)); // Iterate into subDTypep() to resolve that type and update pointer. nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); nodep->iterateChildren(*this); nodep->dtypep(nodep); // Should already be set, but be clear it's not the subDType nodep->widthFromSub(nodep->subDTypep()); UINFO(4,"dtWidthed "<didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed nodep->iterateChildren(*this); if (nodep->subDTypep()) nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); nodep->dtypeFrom(nodep->dtypeSkipRefp()); nodep->widthFromSub(nodep->subDTypep()); UINFO(4,"dtWidthed "<didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); nodep->iterateChildren(*this); nodep->dtypep(iterateEditDTypep(nodep, nodep->subDTypep())); } virtual void visit(AstCastParse* nodep, AstNUser* vup) { // nodep->dtp could be data type, or a primary_constant // Don't iterate lhsp, will deal with that once convert the type V3Const::constifyParamsEdit(nodep->dtp()); // itemp may change if (AstConst* constp = nodep->dtp()->castConst()) { constp->unlinkFrBack(); AstNode* newp = new AstCastSize(nodep->fileline(), nodep->lhsp()->unlinkFrBack(), constp); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; newp->accept(*this,vup); } else { nodep->v3error("Unsupported: Cast to "<dtp()->prettyTypeName()); nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); } } virtual void visit(AstCast* nodep, AstNUser* vup) { if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep())); //if (debug()) nodep->dumpTree(cout," CastPre: "); nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); // When more general casts are supported, the cast elimination will be done later. // For now, replace it ASAP, so widthing can propagate easily // The cast may change signing, but we don't know the sign yet. Make it so. // Note we don't sign lhsp() that would make the algorithm O(n^2) if lots of casting. AstBasicDType* basicp = nodep->dtypep()->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Casting non-simple data type"); // When implement more complicated types need to convert childDTypep to dtypep() not as a child if (!basicp->isDouble() && !nodep->lhsp()->isDouble()) { // Note widthCheckSized might modify nodep->lhsp() AstNodeDType* subDTypep = nodep->findLogicDType(nodep->width(),nodep->width(), nodep->lhsp()->dtypep()->numeric()); widthCheckSized(nodep,"Cast",nodep->lhsp(),subDTypep,EXTEND_EXP,false); } AstNode* newp = nodep->lhsp()->unlinkFrBack(); if (basicp->isDouble() && !newp->isDouble()) { newp = new AstIToRD(nodep->fileline(), newp); } else if (!basicp->isDouble() && newp->isDouble()) { if (basicp->isSigned()) { newp = new AstRToIRoundS(nodep->fileline(), newp); } else { newp = new AstUnsigned(nodep->fileline(), new AstRToIS(nodep->fileline(), newp)); } } else if (basicp->isSigned() && !newp->isSigned()) { newp = new AstSigned(nodep->fileline(), newp); } else if (!basicp->isSigned() && newp->isSigned()) { newp = new AstUnsigned(nodep->fileline(), newp); } else { //newp = newp; // Can just remove cast } nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; //if (debug()) newp->dumpTree(cout," CastOut: "); } virtual void visit(AstCastSize* nodep, AstNUser* vup) { // IEEE: Signedness of result is same as self-determined signedness // However, the result is same as BITSEL, so we do not sign extend the LHS if (!nodep->rhsp()->castConst()) nodep->v3fatalSrc("Unsupported: Non-const cast of size"); //if (debug()) nodep->dumpTree(cout," CastSizePre: "); if (vup->c()->prelim()) { int width = nodep->rhsp()->castConst()->toSInt(); if (width < 1) { nodep->v3error("Size-changing cast to zero or negative size"); width=1; } nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); AstBasicDType* underDtp = nodep->lhsp()->dtypep()->castBasicDType(); if (!underDtp) { nodep->v3error("Unsupported: Size-changing cast on non-basic data type"); underDtp = nodep->findLogicBoolDType()->castBasicDType(); } // A cast propagates its size to the lower expression and is included in the maximum // width, so 23'(1'b1 + 1'b1) uses 23-bit math, but 1'(2'h2 * 2'h1) uses two-bit math. // However the output width is exactly that requested. // So two steps, first do the calculation's width (max of the two widths) { int calcWidth = max(width, underDtp->width()); AstNodeDType* calcDtp = (underDtp->keyword().isFourstate() ? nodep->findLogicDType(calcWidth, calcWidth, underDtp->numeric()) : nodep->findBitDType(calcWidth, calcWidth, underDtp->numeric())); nodep->dtypep(calcDtp); // We ignore warnings as that is sort of the point of a cast iterateCheck(nodep,"Cast expr",nodep->lhsp(),CONTEXT,FINAL,calcDtp,EXTEND_EXP,false); } if (debug()) nodep->dumpTree(cout," CastSizeClc: "); // Next step, make the proper output width { AstNodeDType* outDtp = (underDtp->keyword().isFourstate() ? nodep->findLogicDType(width, width, underDtp->numeric()) : nodep->findBitDType(width, width, underDtp->numeric())); nodep->dtypep(outDtp); // We ignore warnings as that is sort of the point of a cast widthCheckSized(nodep,"Cast expr",nodep->lhsp(),outDtp,EXTEND_EXP,false); } } if (vup->c()->final()) { // CastSize not needed once sizes determined AstNode* underp = nodep->lhsp()->unlinkFrBack(); nodep->replaceWith(underp); pushDeletep(nodep); nodep=NULL; } //if (debug()) nodep->dumpTree(cout," CastSizeOut: "); } virtual void visit(AstVar* nodep, AstNUser* vup) { //if (debug()) nodep->dumpTree(cout," InitPre: "); // Must have deterministic constant width // We can't skip this step when width()!=0, as creating a AstVar // with non-constant range gets size 1, not size 0. So use didWidth(). if (nodep->didWidth()) return; if (nodep->doingWidth()) { // Early exit if have circular parameter definition if (!nodep->valuep()) nodep->v3fatalSrc("circular, but without value"); nodep->v3error("Variable's initial value is circular: "<prettyName()); pushDeletep(nodep->valuep()->unlinkFrBack()); nodep->valuep(new AstConst(nodep->fileline(), AstConst::LogicTrue())); nodep->dtypeFrom(nodep->valuep()); nodep->didWidth(true); return; } nodep->doingWidth(true); // Make sure dtype is sized if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep())); if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype determined for var"); if (nodep->isIO() && !(nodep->dtypeSkipRefp()->castBasicDType() || nodep->dtypeSkipRefp()->castNodeArrayDType() || nodep->dtypeSkipRefp()->castNodeClassDType())) { nodep->v3error("Unsupported: Inputs and outputs must be simple data types"); } if (nodep->dtypep()->skipRefToConstp()->castConstDType()) { nodep->isConst(true); } // Parameters if implicit untyped inherit from what they are assigned to AstBasicDType* bdtypep = nodep->dtypep()->castBasicDType(); bool didchk = false; bool implicitParam = nodep->isParam() && bdtypep && bdtypep->implicit(); if (implicitParam) { if (nodep->valuep()) { nodep->valuep()->iterateAndNext(*this,WidthVP(nodep->dtypep(),PRELIM).p()); UINFO(9,"implicitParamPRELIMIV "<valuep()<valuep()->isDouble()) { nodep->dtypeSetDouble(); bdtypep=NULL; } else { int width=0; AstBasicDType* valueBdtypep = nodep->valuep()->dtypep()->basicp(); bool issigned = false; if (bdtypep->isNosign()) { if (valueBdtypep && valueBdtypep->isSigned()) issigned=true; } else issigned = bdtypep->isSigned(); if (nodep->valuep()->dtypep()->widthSized()) { width = nodep->valuep()->width(); } else { if (nodep->valuep()->width()>32) nodep->valuep()->v3warn(WIDTH,"Assigning >32 bit to unranged parameter (defaults to 32 bits)"); width = 32; } // Can't just inherit valuep()->dtypep() as mwidth might not equal width if (width==1) { // one bit parameter is same as "parameter [0] foo", not "parameter logic foo" // as you can extract "foo[0]" from a parameter but not a wire nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(), AstNumeric::fromBool(issigned)); nodep->dtypep(nodep->findLogicRangeDType (VNumRange(0,0,false), nodep->valuep()->widthMin(), AstNumeric::fromBool(issigned))); } else { nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(), AstNumeric::fromBool(issigned)); } didchk = true; } iterateCheckAssign(nodep,"Initial value",nodep->valuep(),FINAL,nodep->dtypep()); UINFO(9,"implicitParamFromIV "<valuep()<dtypeSetSigned32(); bdtypep=NULL; } } else if (bdtypep && bdtypep->implicit()) { // Implicits get converted to size 1 nodep->dtypeSetLogicSized(1,1,bdtypep->numeric()); bdtypep=NULL; } if (nodep->valuep() && !didchk) { //if (debug()) nodep->dumpTree(cout," final: "); // AstPattern requires assignments to pass datatype on PRELIM nodep->valuep()->iterateAndNext(*this,WidthVP(nodep->dtypep(),PRELIM).p()); iterateCheckAssign(nodep,"Initial value",nodep->valuep(),FINAL,nodep->dtypep()); } UINFO(4,"varWidthed "<dumpTree(cout," InitOut: "); nodep->didWidth(true); nodep->doingWidth(false); } virtual void visit(AstNodeVarRef* nodep, AstNUser* vup) { if (nodep->didWidth()) return; if (!nodep->varp()) nodep->v3fatalSrc("Unlinked varref"); if (!nodep->varp()->didWidth()) { // Var hasn't been widthed, so make it so. nodep->varp()->iterate(*this); } //if (debug()>=9) { nodep->dumpTree(cout," VRin "); nodep->varp()->dumpTree(cout," forvar "); } // Note genvar's are also entered as integers nodep->dtypeFrom(nodep->varp()); if (nodep->backp()->castNodeAssign() && nodep->lvalue()) { // On LHS if (!nodep->widthMin()) v3fatalSrc("LHS var should be size complete"); } //if (debug()>=9) nodep->dumpTree(cout," VRout "); if (nodep->lvalue() && nodep->varp()->isConst() && !m_paramsOnly && !m_initialp) { // Too loose, but need to allow our generated first assignment // // Move this to a property of the AstInitial block nodep->v3error("Assigning to const variable: "<prettyName()); } nodep->didWidth(true); } virtual void visit(AstEnumDType* nodep, AstNUser* vup) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed UINFO(5," ENUMDTYPE "<childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep)); nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); nodep->dtypep(nodep); nodep->widthFromSub(nodep->subDTypep()); // Assign widths nodep->itemsp()->iterateAndNext(*this,WidthVP(nodep->dtypep(),BOTH).p()); // Assign missing values V3Number num (nodep->fileline(), nodep->width(), 0); V3Number one (nodep->fileline(), nodep->width(), 1); map inits; for (AstEnumItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) { if (itemp->valuep()) { if (debug()>=9) { UINFO(0,"EnumInit "<valuep()->dumpTree(cout,"-EnumInit: "); } V3Const::constifyParamsEdit(itemp->valuep()); // itemp may change if (!itemp->valuep()->castConst()) { itemp->valuep()->v3error("Enum value isn't a constant"); itemp->valuep()->unlinkFrBack()->deleteTree(); continue; } // TODO IEEE says assigning sized number that is not same size as enum is illegal } if (!itemp->valuep()) { if (num.isEqZero() && itemp != nodep->itemsp()) itemp->v3error("Enum value wrapped around"); // IEEE says illegal if (!nodep->dtypep()->basicp() && !nodep->dtypep()->basicp()->keyword().isIntNumeric()) { itemp->v3error("Enum names without values only allowed on numeric types"); // as can't +1 to resolve them. } itemp->valuep(new AstConst(itemp->fileline(), num)); } num.opAssign(itemp->valuep()->castConst()->num()); // Look for duplicates if (inits.find(num) != inits.end()) { // IEEE says illegal itemp->v3error("Overlapping enumeration value: "<prettyName()<second->warnMore() <<"... Location of original declaration"); } else { inits.insert(make_pair(num,itemp)); } num.opAdd(one, itemp->valuep()->castConst()->num()); } } virtual void visit(AstEnumItem* nodep, AstNUser* vup) { UINFO(5," ENUMITEM "<c()->dtypep(); if (!vdtypep) nodep->v3fatalSrc("ENUMITEM not under ENUM"); nodep->dtypep(vdtypep); if (nodep->valuep()) { // else the value will be assigned sequentially // Default type is int, but common to assign narrower values, so minwidth from value nodep->valuep()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); int mwidth = nodep->valuep()->widthMin(); // Value determines minwidth nodep->dtypeChgWidth(nodep->width(), mwidth); iterateCheck(nodep,"Enum value",nodep->valuep(),CONTEXT,FINAL,nodep->dtypep(),EXTEND_EXP); } } virtual void visit(AstEnumItemRef* nodep, AstNUser* vup) { if (!nodep->itemp()->didWidth()) { // We need to do the whole enum en-mass AstNode* enump = nodep->itemp(); if (!enump) nodep->v3fatalSrc("EnumItemRef not linked"); for (; enump; enump=enump->backp()) { if (enump->castEnumDType()) break; } if (!enump) nodep->v3fatalSrc("EnumItemRef can't deref back to an Enum"); enump->iterate(*this,vup); enump=NULL; // parent's connection to enump may be relinked } nodep->dtypeFrom(nodep->itemp()); } virtual void visit(AstInitArray* nodep, AstNUser* vup) { // InitArray has type of the array; children are array values if (vup->c()->prelim()) { // First stage evaluation AstNodeDType* vdtypep = vup->c()->dtypep(); if (!vdtypep) nodep->v3fatalSrc("InitArray type not assigned by AstPattern/Var visitor"); nodep->dtypep(vdtypep); if (AstNodeArrayDType* arrayp = vdtypep->castNodeArrayDType()) { nodep->iterateChildren(*this,WidthVP(arrayp->subDTypep(),BOTH).p()); } else { nodep->v3fatalSrc("InitArray on non-array"); } } } virtual void visit(AstInside* nodep, AstNUser* vup) { nodep->exprp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); for (AstNode* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp(); // Prelim may cause the node to get replaced itemp->iterate(*this,WidthVP(CONTEXT,PRELIM).p()); itemp=NULL; } // Take width as maximum across all items int width = nodep->exprp()->width(); int mwidth = nodep->exprp()->widthMin(); for (AstNode* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()) { width = max(width,itemp->width()); mwidth = max(mwidth,itemp->widthMin()); } // Apply width AstNodeDType* subDTypep = nodep->findLogicDType(width,mwidth,nodep->exprp()->dtypep()->numeric()); iterateCheck(nodep,"Inside expression",nodep->exprp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); for (AstNode* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()) { iterateCheck(nodep,"Inside Item",itemp,CONTEXT,FINAL,subDTypep,EXTEND_EXP); } nodep->dtypeSetLogicBool(); if (debug()>=9) nodep->dumpTree(cout,"-inside-in: "); // Now rip out the inside and replace with simple math AstNode* newp = NULL; for (AstNode* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp(); // Will be unlinking AstNode* inewp; if (AstInsideRange* irangep = itemp->castInsideRange()) { // Similar logic in V3Case inewp = new AstAnd(itemp->fileline(), new AstGte(itemp->fileline(), nodep->exprp()->cloneTree(true), irangep->lhsp()->unlinkFrBack()), new AstLte(itemp->fileline(), nodep->exprp()->cloneTree(true), irangep->rhsp()->unlinkFrBack())); } else { inewp = new AstEqWild(itemp->fileline(), nodep->exprp()->cloneTree(true), itemp->unlinkFrBack()); } if (newp) newp = new AstOr(nodep->fileline(), newp, inewp); else newp = inewp; } if (!newp) newp = new AstConst(nodep->fileline(), AstConst::LogicFalse()); if (debug()>=9) newp->dumpTree(cout,"-inside-out: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } virtual void visit(AstInsideRange* nodep, AstNUser* vup) { // Just do each side; AstInside will rip these nodes out later nodep->lhsp()->iterateAndNext(*this,vup); nodep->rhsp()->iterateAndNext(*this,vup); nodep->dtypeFrom(nodep->lhsp()); } virtual void visit(AstIfaceRefDType* nodep, AstNUser* vup) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed UINFO(5," IFACEREF "<iterateChildren(*this, vup); nodep->dtypep(nodep); nodep->widthForce(1, 1); // Not really relevant UINFO(4,"dtWidthed "<didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed UINFO(5," NODECLASS "<=9) nodep->dumpTree("-class-in--"); if (!nodep->packed()) { nodep->v3warn(UNPACKED, "Unsupported: Unpacked struct/union"); } nodep->iterateChildren(*this); // First size all members nodep->repairMemberCache(); // Determine bit assignments and width nodep->dtypep(nodep); int lsb = 0; int width = 0; // MSB is first, so go backwards AstMemberDType* itemp; for (itemp = nodep->membersp(); itemp && itemp->nextp(); itemp=itemp->nextp()->castMemberDType()) ; for (AstMemberDType* backip; itemp; itemp=backip) { backip = itemp->backp()->castMemberDType(); itemp->lsb(lsb); if (nodep->castUnionDType()) { width = max(width, itemp->width()); } else { lsb += itemp->width(); width += itemp->width(); } } nodep->widthForce(width,width); // Signing stays as-is, as parsed from declaration //if (debug()>=9) nodep->dumpTree("-class-out-"); } virtual void visit(AstMemberDType* nodep, AstNUser* vup) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep)); // Iterate into subDTypep() to resolve that type and update pointer. nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); nodep->dtypep(nodep); // The member itself, not subDtype nodep->widthFromSub(nodep->subDTypep()); } virtual void visit(AstMemberSel* nodep, AstNUser* vup) { UINFO(5," MEMBERSEL "<=9) nodep->dumpTree("-mbs-in: "); nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); if (debug()>=9) nodep->dumpTree("-mbs-ic: "); // Find the fromp dtype - should be a class AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump(); UINFO(9," from dt "<castNodeClassDType()) { // No need to width-resolve the class, as it was done when we did the child memberp = adtypep->findMember(nodep->name()); if (!memberp) { nodep->v3error("Member '"<prettyName()<<"' not found in structure"); } } else if (fromDtp->castEnumDType()) { // Method call on enum without following parenthesis, e.g. "ENUM.next" // Convert this into a method call, and let that visitor figure out what to do next AstNode* newp = new AstMethodSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), NULL); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; newp->accept(*this,vup); return; } else { nodep->v3error("Member selection of non-struct/union object '" <fromp()->prettyTypeName()<<"' which is a '"<fromp()->dtypep()->prettyTypeName()<<"'"); } if (memberp) { if (m_attrp) { // Looking for the base of the attribute nodep->dtypep(memberp); UINFO(9," MEMBERSEL(attr) -> "< "<dtypep()<fileline(), nodep->fromp()->unlinkFrBack(), memberp->lsb(), memberp->width()); newp->dtypep(memberp->skipRefp()); // Must skip over the member to find the union; as the member may disappear later newp->didWidth(true); // Don't replace dtype with basic type UINFO(9," MEMBERSEL -> "< "<dtypep()<replaceWith(newp); pushDeletep(nodep); nodep=NULL; // Should be able to treat it as a normal-ish nodesel - maybe. The lhsp() will be strange until this stage; create the number here? } } if (!memberp) { // Very bogus, but avoids core dump nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::LogicFalse())); pushDeletep(nodep); nodep=NULL; } } virtual void visit(AstMethodSel* nodep, AstNUser* vup) { UINFO(5," METHODSEL "<=9) nodep->dumpTree("-mts-in: "); // Should check types the method requires, but at present we don't do much nodep->fromp()->accept(*this,WidthVP(SELF,BOTH).p()); for (AstArg* argp = nodep->pinsp()->castArg(); argp; argp = argp->nextp()->castArg()) { if (argp->exprp()) argp->exprp()->accept(*this,WidthVP(SELF,BOTH).p()); } // Find the fromp dtype - should be a class if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression"); AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump(); UINFO(9," from dt "<castEnumDType()) { // Method call on enum without following parenthesis, e.g. "ENUM.next" // Convert this into a method call, and let that visitor figure out what to do next if (adtypep) {} if (nodep->name() == "num" || nodep->name() == "first" || nodep->name() == "last") { // Constant value AstConst* newp = NULL; if (nodep->pinsp()) nodep->v3error("Arguments passed to enum.num method, but it does not take arguments"); if (nodep->name() == "num") { int items = 0; for (AstNode* itemp = adtypep->itemsp(); itemp; itemp = itemp->nextp()) ++items; newp = new AstConst(nodep->fileline(), AstConst::Signed32(), items); } else if (nodep->name() == "first") { AstEnumItem* itemp = adtypep->itemsp(); if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const } else if (nodep->name() == "last") { AstEnumItem* itemp = adtypep->itemsp(); while (itemp && itemp->nextp()) itemp = itemp->nextp()->castEnumItem(); if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const } if (!newp) nodep->v3fatalSrc("Enum method (perhaps enum item) not const"); newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer; may have warning disables nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else if (nodep->name() == "name" || nodep->name() == "next" || nodep->name() == "prev") { AstAttrType attrType; if (nodep->name() == "name") attrType = AstAttrType::ENUM_NAME; else if (nodep->name() == "next") attrType = AstAttrType::ENUM_NEXT; else if (nodep->name() == "prev") attrType = AstAttrType::ENUM_PREV; else nodep->v3fatalSrc("Bad case"); if (nodep->pinsp() && nodep->name() == "name") { nodep->v3error("Arguments passed to enum.name method, but it does not take arguments"); } else if (nodep->pinsp() && !(nodep->pinsp()->castArg()->exprp()->castConst() && nodep->pinsp()->castArg()->exprp()->castConst()->toUInt()==1 && !nodep->pinsp()->nextp())) { nodep->v3error("Unsupported: Arguments passed to enum.next method"); } // Need a runtime lookup table. Yuk. // Ideally we would have a fast algorithm when a number is // of small width and complete and so can use an array, and // a map for when the value is many bits and sparse. uint64_t msbdim = 0; { for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp = itemp->nextp()->castEnumItem()) { AstConst* vconstp = itemp->valuep()->castConst(); if (!vconstp) nodep->v3fatalSrc("Enum item without constified value"); if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad(); } if (adtypep->itemsp()->width() > 64 || msbdim >= 1024) { nodep->v3error("Unsupported; enum next/prev method on enum with > 10 bits"); return; } } AstVar* varp = enumVarp(adtypep, attrType, msbdim); AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false); varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp()); AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, nodep->fromp()->unlinkFrBack()); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } else { nodep->v3error("Unknown built-in enum method '"<fromp()->prettyTypeName()<<"'"); } } else { nodep->v3error("Unsupported: Member call on non-enum object '" <fromp()->prettyTypeName()<<"' which is a '"<fromp()->dtypep()->prettyTypeName()<<"'"); } } virtual void visit(AstPattern* nodep, AstNUser* vup) { if (nodep->didWidthAndSet()) return; UINFO(9,"PATTERN "<childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); // data_type '{ pattern } if (!nodep->dtypep() && vup->c()->dtypeNullp()) { // Get it from parent assignment/pin/etc nodep->dtypep(vup->c()->dtypep()); } AstNodeDType* vdtypep = nodep->dtypep(); if (!vdtypep) nodep->v3error("Unsupported/Illegal: Assignment pattern member not underneath a supported construct: "<backp()->prettyTypeName()); { vdtypep = vdtypep->skipRefp(); nodep->dtypep(vdtypep); UINFO(9," adtypep "<dtypep(vdtypep); // Determine replication count, and replicate initial value as widths need to be individually determined for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) { int times = visitPatMemberRep(patp); for (int i=1; icloneTree(false); patp->addNextHere(newp); // This loop will see the new elements as part of nextp() } } // Convert any PatMember with multiple items to multiple PatMembers for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) { if (patp->lhssp()->nextp()) { // Can't just addNext, as would add to end of all members. So detach, add next and reattach AstNRelinker relinkHandle; patp->unlinkFrBack(&relinkHandle); while (AstNode* movep = patp->lhssp()->nextp()) { movep->unlinkFrBack(); // Not unlinkFrBackWithNext, just one AstPatMember* newp = new AstPatMember(patp->fileline(), movep, patp->keyp()->cloneTree(true), NULL); patp->addNext(newp); } relinkHandle.relink(patp); } } AstPatMember* defaultp = NULL; for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) { if (patp->isDefault()) { if (defaultp) nodep->v3error("Multiple '{ default: } clauses"); defaultp = patp; patp->unlinkFrBack(); } } while (AstConstDType* classp = vdtypep->castConstDType()) { vdtypep = classp->subDTypep()->skipRefp(); } if (AstNodeClassDType* classp = vdtypep->castNodeClassDType()) { // Due to "default" and tagged patterns, we need to determine // which member each AstPatMember corresponds to before we can // determine the dtypep for that PatMember's value, and then // width the initial value appropriately. typedef map PatMap; PatMap patmap; { AstMemberDType* memp = classp->membersp(); AstPatMember* patp = nodep->itemsp()->castPatMember(); for (; memp || patp; ) { if (patp) { if (patp->keyp()) { if (AstText* textp = patp->keyp()->castText()) { memp = classp->findMember(textp->text()); if (!memp) { patp->keyp()->v3error("Assignment pattern key '"<text()<<"' not found as member"); continue; } } else { patp->keyp()->v3error("Assignment pattern key not supported/understood: "<keyp()->prettyTypeName()); } } } if (memp && !patp) { // Missing init elements, warn below memp=NULL; patp=NULL; break; } else if (!memp && patp) { patp->v3error("Assignment pattern contains too many elements"); memp=NULL; patp=NULL; break; } else { patmap.insert(make_pair(memp, patp)); } // Next if (memp) memp = memp->nextp()->castMemberDType(); if (patp) patp = patp->nextp()->castPatMember(); } } AstNode* newp = NULL; for (AstMemberDType* memp = classp->membersp(); memp; memp=memp->nextp()->castMemberDType()) { PatMap::iterator it = patmap.find(memp); AstPatMember* newpatp = NULL; AstPatMember* patp = NULL; if (it == patmap.end()) { if (defaultp) { newpatp = defaultp->cloneTree(false); patp = newpatp; } else { if (!classp->castUnionDType()) { patp->v3error("Assignment pattern missed initializing elements: "<prettyTypeName()); } } } else { patp = it->second; } if (patp) { // Determine initial values vdtypep = memp; patp->dtypep(memp); patp->accept(*this,WidthVP(memp,BOTH).p()); // Convert to concat for now AstNode* valuep = patp->lhssp()->unlinkFrBack(); if (valuep->castConst()) { // Forming a AstConcat will cause problems with unsized (uncommitted sized) constants if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) { pushDeletep(valuep); valuep=NULL; valuep = newp; } } if (!newp) newp = valuep; else { AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep); newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), concatp->lhsp()->width()+concatp->rhsp()->width(), nodep->dtypep()->numeric()); } } if (newpatp) { pushDeletep(newpatp); newpatp=NULL; } } if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); pushDeletep(nodep); nodep = NULL; // Deletes defaultp also, if present } else if (vdtypep->castNodeArrayDType()) { AstNodeArrayDType* arrayp = vdtypep->castNodeArrayDType(); VNumRange range = arrayp->declRange(); PatVecMap patmap = patVectorMap(nodep, range); UINFO(9,"ent "<=range.lo(); --ent) { AstPatMember* newpatp = NULL; AstPatMember* patp = NULL; PatVecMap::iterator it=patmap.find(ent); if (it == patmap.end()) { if (defaultp) { newpatp = defaultp->cloneTree(false); patp = newpatp; } else { nodep->v3error("Assignment pattern missed initializing elements: "<second; patmap.erase(it); } if (patp) { // Determine initial values vdtypep = arrayp->subDTypep(); // Don't want the RHS an array patp->dtypep(vdtypep); // Determine values - might be another InitArray patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p()); // Convert to InitArray or constify immediately AstNode* valuep = patp->lhssp()->unlinkFrBack(); if (valuep->castConst()) { // Forming a AstConcat will cause problems with unsized (uncommitted sized) constants if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) { pushDeletep(valuep); valuep=NULL; valuep = newp; } } if (arrayp->castUnpackArrayDType()) { if (!newp) { newp = new AstInitArray(nodep->fileline(), arrayp, valuep); } else { // We iterate hi()..lo() as that is what packed needs, // but INITARRAY needs lo() first newp->castInitArray()->initsp()->addHereThisAsNext(valuep); } } else { // Packed. Convert to concat for now. if (!newp) newp = valuep; else { AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep); newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), concatp->lhsp()->width()+concatp->rhsp()->width(), nodep->dtypep()->numeric()); } } } if (newpatp) { pushDeletep(newpatp); newpatp=NULL; } } if (!patmap.empty()) nodep->v3error("Assignment pattern with too many elements"); if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); //if (debug()>=9) newp->dumpTree("-apat-out: "); pushDeletep(nodep); nodep = NULL; // Deletes defaultp also, if present } else if (vdtypep->castBasicDType() && vdtypep->castBasicDType()->isRanged()) { AstBasicDType* bdtypep = vdtypep->castBasicDType(); VNumRange range = bdtypep->declRange(); PatVecMap patmap = patVectorMap(nodep, range); UINFO(9,"ent "<=range.lo(); --ent) { AstPatMember* newpatp = NULL; AstPatMember* patp = NULL; PatVecMap::iterator it=patmap.find(ent); if (it == patmap.end()) { if (defaultp) { newpatp = defaultp->cloneTree(false); patp = newpatp; } else { nodep->v3error("Assignment pattern missed initializing elements: "<second; patmap.erase(it); } if (patp) { // Determine initial values vdtypep = nodep->findLogicBoolDType(); // Don't want the RHS an array patp->dtypep(vdtypep); // Determine values - might be another InitArray patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p()); // Convert to InitArray or constify immediately AstNode* valuep = patp->lhssp()->unlinkFrBack(); if (valuep->castConst()) { // Forming a AstConcat will cause problems with unsized (uncommitted sized) constants if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) { pushDeletep(valuep); valuep=NULL; valuep = newp; } } { // Packed. Convert to concat for now. if (!newp) newp = valuep; else { AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep); newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), concatp->lhsp()->width()+concatp->rhsp()->width(), nodep->dtypep()->numeric()); } } } if (newpatp) { pushDeletep(newpatp); newpatp=NULL; } } if (!patmap.empty()) nodep->v3error("Assignment pattern with too many elements"); if (newp) nodep->replaceWith(newp); else nodep->v3error("Assignment pattern with no members"); //if (debug()>=9) newp->dumpTree("-apat-out: "); pushDeletep(nodep); nodep = NULL; // Deletes defaultp also, if present } else { nodep->v3error("Unsupported: Assignment pattern applies against non struct/union: "<prettyTypeName()); } } } virtual void visit(AstPatMember* nodep, AstNUser* vup) { AstNodeDType* vdtypep = vup->c()->dtypeNullp(); if (!vdtypep) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor"); nodep->dtypep(vdtypep); UINFO(9," PATMEMBER "<lhssp()->nextp()) nodep->v3fatalSrc("PatMember value should be singular w/replicates removed"); // Need to propagate assignment type downwards, even on prelim nodep->iterateChildren(*this,WidthVP(nodep->dtypep(),BOTH).p()); iterateCheck(nodep,"Pattern value",nodep->lhssp(),CONTEXT,FINAL,vdtypep,EXTEND_LHS); } int visitPatMemberRep(AstPatMember* nodep) { uint32_t times = 1; if (nodep->repp()) { // else repp()==NULL shorthand for rep count 1 iterateCheckSizedSelf(nodep,"LHS",nodep->repp(),SELF,BOTH); V3Const::constifyParamsEdit(nodep->repp()); // repp may change AstConst* constp = nodep->repp()->castConst(); if (!constp) { nodep->v3error("Replication value isn't a constant."); times=0; } else times = constp->toUInt(); if (times==0) { nodep->v3error("Pattern replication value of 0 is not legal."); times=1; } nodep->repp()->unlinkFrBackWithNext()->deleteTree(); // Done with replicate before cloning } return times; } virtual void visit(AstPslClocked* nodep, AstNUser* vup) { if (vup->c()->prelim()) { // First stage evaluation iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); nodep->sensesp()->iterateAndNext(*this); if (nodep->disablep()) { iterateCheckBool(nodep,"Disable",nodep->disablep(),BOTH); // it's like an if() condition. } nodep->dtypeSetLogicBool(); } } //-------------------- // Top levels virtual void visit(AstNodeCase* nodep, AstNUser* vup) { // IEEE-2012 12.5: // Width: MAX(expr, all items) // Signed: Only if expr, and all items signed assertAtStatement(nodep,vup); nodep->exprp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); for (AstCaseItem* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp()->castCaseItem(); // Prelim may cause the node to get replaced if (!nodep->castGenCase()) itemp->bodysp()->iterateAndNext(*this); for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) { nextcp = condp->nextp(); // Prelim may cause the node to get replaced condp->iterate(*this,WidthVP(CONTEXT,PRELIM).p()); condp=NULL; } } // Take width as maximum across all items, if any is real whole thing is real AstNodeDType* subDTypep = nodep->exprp()->dtypep(); for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* condp = itemp->condsp(); condp; condp=condp->nextp()) { if (condp->dtypep() != subDTypep) { if (condp->dtypep()->isDouble()) { subDTypep = nodep->findDoubleDType(); } else { int width = max(subDTypep->width(),condp->width()); int mwidth = max(subDTypep->widthMin(),condp->widthMin()); bool issigned = subDTypep->isSigned() && condp->isSigned(); subDTypep = nodep->findLogicDType(width,mwidth,AstNumeric::fromBool(issigned)); } } } } // Apply width iterateCheck(nodep,"Case expression",nodep->exprp(),CONTEXT,FINAL,subDTypep,EXTEND_LHS); for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstNode* condp = itemp->condsp(); condp; condp=condp->nextp()) { iterateCheck(nodep,"Case Item",condp,CONTEXT,FINAL,subDTypep,EXTEND_LHS); } } } virtual void visit(AstNodeFor* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); nodep->initsp()->iterateAndNext(*this); iterateCheckBool(nodep,"For Test Condition",nodep->condp(),BOTH); // it's like an if() condition. if (!nodep->castGenFor()) nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); } virtual void visit(AstRepeat* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); nodep->countp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstWhile* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); nodep->precondsp()->iterateAndNext(*this); iterateCheckBool(nodep,"For Test Condition",nodep->condp(),BOTH); // it's like an if() condition. nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); } virtual void visit(AstNodeIf* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); //if (debug()) nodep->dumpTree(cout," IfPre: "); if (!nodep->castGenIf()) { // for m_paramsOnly nodep->ifsp()->iterateAndNext(*this); nodep->elsesp()->iterateAndNext(*this); } iterateCheckBool(nodep,"If",nodep->condp(),BOTH); // it's like an if() condition. //if (debug()) nodep->dumpTree(cout," IfOut: "); } virtual void visit(AstNodeAssign* nodep, AstNUser* vup) { // IEEE-2012 10.7, 11.8.2, 11.8.3, 11.5: (Careful of 11.8.1 which is // only one step; final dtype depends on assign LHS.) // Determine RHS type width and signing // Propagate type down to *non-self-determined* operators // Real propagates only across one operator if one side is real - handled in each visitor. // Then LHS sign-extends only if *RHS* is signed assertAtStatement(nodep,vup); //if (debug()) nodep->dumpTree(cout," AssignPre: "); { //if (debug()) nodep->dumpTree(cout,"- assin: "); nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); if (!nodep->lhsp()->dtypep()) nodep->v3fatalSrc("How can LHS be untyped?"); if (!nodep->lhsp()->dtypep()->widthSized()) nodep->v3fatalSrc("How can LHS be unsized?"); nodep->dtypeFrom(nodep->lhsp()); // // AstPattern needs to know the proposed data type of the lhs, so pass on the prelim nodep->rhsp()->iterateAndNext(*this,WidthVP(nodep->dtypep(),PRELIM).p()); // //if (debug()) nodep->dumpTree(cout,"- assign: "); AstNodeDType* lhsDTypep = nodep->lhsp()->dtypep(); // Note we use rhsp for context determined iterateCheckAssign(nodep,"Assign RHS",nodep->rhsp(),FINAL,lhsDTypep); //if (debug()) nodep->dumpTree(cout," AssignOut: "); } } virtual void visit(AstSFormatF* nodep, AstNUser* vup) { // Excludes NodeDisplay, see below if (vup && !vup->c()->prelim()) return; // Can be called as statement or function // Just let all arguments seek their natural sizes nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); // UINFO(9," Display in "<text()<exprsp(); string txt = nodep->text(); for (string::const_iterator it = txt.begin(); it!=txt.end(); ++it) { char ch = *it; if (!inPct && ch=='%') { inPct = true; } else if (inPct && isdigit(ch)) { } else if (tolower(inPct)) { inPct = false; switch (tolower(ch)) { case '%': break; // %% - just output a % case 'm': break; // %m - auto insert "name" case 'd': { // Convert decimal to either 'd' or 'u' if (argp && argp->isSigned()) { // Convert it ch = '~'; } if (argp) argp=argp->nextp(); break; } case 's': { // Convert string to pack string if (argp && argp->dtypep()->basicp()->isString()) { // Convert it ch = '@'; } if (argp) argp=argp->nextp(); break; } default: { // Most operators, just move to next argument if (argp) argp=argp->nextp(); break; } } // switch } dispout += ch; } nodep->text(dispout); UINFO(9," Display out "<text()<filep()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); } // Just let all arguments seek their natural sizes nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); } virtual void visit(AstFOpen* nodep, AstNUser* vup) { // Although a system function in IEEE, here a statement which sets the file pointer (MCD) assertAtStatement(nodep,vup); iterateCheckFileDesc(nodep,nodep->filep(),BOTH); nodep->filenamep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->modep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } virtual void visit(AstFClose* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); iterateCheckFileDesc(nodep,nodep->filep(),BOTH); } virtual void visit(AstFEof* nodep, AstNUser* vup) { if (vup->c()->prelim()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); nodep->dtypeSetLogicSized(32,1,AstNumeric::SIGNED); // Spec says integer return } } virtual void visit(AstFFlush* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); if (nodep->filep()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); } } virtual void visit(AstFGetC* nodep, AstNUser* vup) { if (vup->c()->prelim()) { iterateCheckFileDesc(nodep,nodep->filep(),BOTH); nodep->dtypeSetLogicSized(32,8,AstNumeric::SIGNED); // Spec says integer return } } virtual void visit(AstFGetS* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return iterateCheckFileDesc(nodep,nodep->filep(),BOTH); nodep->strgp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } } virtual void visit(AstFScanF* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return iterateCheckFileDesc(nodep,nodep->filep(),BOTH); nodep->exprsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } } virtual void visit(AstSScanF* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->dtypeSetSigned32(); // Spec says integer return nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->exprsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } } virtual void visit(AstSysIgnore* nodep, AstNUser* vup) { nodep->exprsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } virtual void visit(AstSystemF* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->dtypeSetSigned32(); // Spec says integer return } } virtual void visit(AstSystemT* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } virtual void visit(AstReadMem* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); nodep->filenamep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->memp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); if (!nodep->memp()->dtypep()->skipRefp()->castUnpackArrayDType()) { nodep->memp()->v3error("Unsupported: $readmem into other than unpacked array"); } nodep->lsbp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->msbp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } virtual void visit(AstValuePlusArgs* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->exprsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->dtypeSetSigned32(); // Spec says integer return } } virtual void visit(AstUCStmt* nodep, AstNUser* vup) { // Just let all arguments seek their natural sizes assertAtStatement(nodep,vup); nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); } virtual void visit(AstPslCover* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); // it's like an if() condition. nodep->stmtsp()->iterateAndNext(*this); } virtual void visit(AstVAssert* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); // it's like an if() condition. nodep->passsp()->iterateAndNext(*this); nodep->failsp()->iterateAndNext(*this); } virtual void visit(AstPin* nodep, AstNUser*) { //if (debug()) nodep->dumpTree(cout,"- PinPre: "); // TOP LEVEL NODE if (nodep->modVarp() && nodep->modVarp()->isGParam()) { // Widthing handled as special init() case nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); } else if (!m_paramsOnly) { if (!nodep->modVarp()->didWidth()) { // Var hasn't been widthed, so make it so. nodep->modVarp()->iterate(*this); } if (!nodep->exprp()) { // No-connect return; } // Very much like like an assignment, but which side is LH/RHS // depends on pin being a in/output/inout. nodep->exprp()->iterateAndNext(*this,WidthVP(nodep->modVarp()->dtypep(),PRELIM).p()); AstNodeDType* pinDTypep = nodep->modVarp()->dtypep(); AstNodeDType* conDTypep = nodep->exprp()->dtypep(); AstNodeDType* subDTypep = pinDTypep; int pinwidth = pinDTypep->width(); int conwidth = conDTypep->width(); if (conDTypep == pinDTypep) { // If match, we're golden nodep->exprp()->iterateAndNext(*this,WidthVP(subDTypep,FINAL).p()); } else if (m_cellRangep) { int numInsts = m_cellRangep->elementsConst(); if (conwidth == pinwidth) { // Arrayed instants: widths match so connect to each instance subDTypep = conDTypep; // = same expr dtype } else if (conwidth == numInsts*pinwidth) { // Arrayed instants: one bit for each of the instants (each assign is 1 pinwidth wide) subDTypep = conDTypep; // = same expr dtype (but numInst*pin_dtype) } else { // Must be a error according to spec // (Because we need to know if to connect to one or all instants) nodep->v3error(ucfirst(nodep->prettyOperatorName())<<" as part of a module instance array" <<" requires "<exprp()->prettyTypeName() <<" generates "<exprp()->iterateAndNext(*this,WidthVP(subDTypep,FINAL).p()); } else { if (nodep->modVarp()->isTristate()) { if (pinwidth != conwidth) { nodep->v3error("Unsupported: "<prettyOperatorName()) <<" to inout signal requires "<exprp()->prettyTypeName() <<" generates "<exprp()->dtypep()->skipRefp()->castUnpackArrayDType(); bool loArray = nodep->modVarp()->dtypep()->skipRefp()->castUnpackArrayDType(); if (loArray != hiArray && pinwidth != conwidth) { nodep->v3error("Illegal "<prettyOperatorName()<<"," <<" mismatch between port which is"<<(hiArray?"":" not")<<" an array," <<" and expression which is"<<(loArray?"":" not")<<" an array."); UINFO(1," Related lo: "<exprp()->dtypep()->skipRefp()<modVarp()->dtypep()->skipRefp()<exprp(),FINAL,subDTypep); } } //if (debug()) nodep->dumpTree(cout,"- PinOut: "); } virtual void visit(AstCell* nodep, AstNUser*) { if (!m_paramsOnly) { if (nodep->modp()->castNotFoundModule()) { // We've resolved parameters and hit a module that we couldn't resolve. It's // finally time to report it. // Note only here in V3Width as this is first visitor after V3Dead. nodep->v3error("Cannot find file containing module: "<modName()); v3Global.opt.filePathLookedMsg(nodep->fileline(), nodep->modName()); } if (nodep->rangep()) { m_cellRangep = nodep->rangep(); nodep->rangep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); } nodep->pinsp()->iterateAndNext(*this); } nodep->paramsp()->iterateAndNext(*this); m_cellRangep = NULL; } virtual void visit(AstGatePin* nodep, AstNUser* vup) { if (vup->c()->prelim()) { nodep->rangep()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->exprp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); nodep->dtypeFrom(nodep->rangep()); // Very much like like an pin AstNodeDType* conDTypep = nodep->exprp()->dtypep(); int numInsts = nodep->rangep()->elementsConst(); int pinwidth = numInsts; int conwidth = conDTypep->width(); if (conwidth == 1 && pinwidth > 1) { // Multiple connections AstNodeDType* subDTypep = nodep->findLogicDType(1,1, conDTypep->numeric()); nodep->exprp()->iterateAndNext(*this,WidthVP(subDTypep,FINAL).p()); AstNode* newp = new AstReplicate(nodep->fileline(), nodep->exprp()->unlinkFrBack(), numInsts); nodep->replaceWith(newp); } else { // Eliminating so pass down all of vup nodep->exprp()->iterateAndNext(*this,vup); nodep->replaceWith(nodep->exprp()->unlinkFrBack()); } pushDeletep(nodep); nodep=NULL; } } virtual void visit(AstNodeFTask* nodep, AstNUser* vup) { // Grab width from the output variable (if it's a function) if (nodep->didWidth()) return; UINFO(5," FTASK "<doingWidth()) { nodep->v3error("Unsupported: Recursive function or task call"); nodep->dtypeSetLogicBool(); nodep->didWidth(true); return; } // Function hasn't been widthed, so make it so. nodep->doingWidth(true); // Would use user1 etc, but V3Width called from too many places to spend a user nodep->iterateChildren(*this); if (nodep->fvarp()) { m_funcp = nodep->castFunc(); if (!m_funcp) nodep->v3fatalSrc("FTask with function variable, but isn't a function"); nodep->dtypeFrom(nodep->fvarp()); // Which will get it from fvarp()->dtypep() } nodep->didWidth(true); nodep->doingWidth(false); m_funcp = NULL; } virtual void visit(AstReturn* nodep, AstNUser* vup) { // IEEE: Assignment-like context assertAtStatement(nodep,vup); if (!m_funcp) { if (nodep->lhsp()) { // Return w/o value ok other places nodep->v3error("Return with return value isn't underneath a function"); } } else { if (nodep->lhsp()) { // Function hasn't been widthed, so make it so. nodep->dtypeFrom(m_funcp->fvarp()); // AstPattern requires assignments to pass datatype on PRELIM nodep->lhsp()->iterateAndNext(*this,WidthVP(nodep->dtypep(),PRELIM).p()); iterateCheckAssign(nodep,"Return value",nodep->lhsp(),FINAL,nodep->dtypep()); } } } virtual void visit(AstFuncRef* nodep, AstNUser* vup) { visit(nodep->castNodeFTaskRef(), vup); nodep->dtypeFrom(nodep->taskp()); //if (debug()) nodep->dumpTree(cout," FuncOut: "); } virtual void visit(AstNodeFTaskRef* nodep, AstNUser* vup) { // For arguments, is assignment-like context; see IEEE rules in AstNodeAssign // Function hasn't been widthed, so make it so. UINFO(5, " FTASKREF "<taskp()) nodep->v3fatalSrc("Unlinked"); if (nodep->didWidth()) return; nodep->taskp()->iterate(*this); // // And do the arguments to the task/function too for (int accept_mode=0; accept_mode<3; accept_mode++) { // Avoid duplicate code; just do inner stuff several times reloop: V3TaskConnects tconnects = V3Task::taskConnects(nodep, nodep->taskp()->stmtsp()); for (V3TaskConnects::iterator it=tconnects.begin(); it!=tconnects.end(); ++it) { AstVar* portp = it->first; AstArg* argp = it->second; AstNode* pinp = argp->exprp(); if (pinp!=NULL) { // Else argument error we'll find later if (accept_mode==0) { // Prelim may cause the node to get replaced; we've lost our // pointer, so need to iterate separately later if (portp->attrSFormat() && (!pinp->castSFormatF() || pinp->nextp())) { // Not already done UINFO(4," sformat via metacomment: "<unlinkFrBackWithNext(&handle); // Format + additional args, if any AstNode* argsp = NULL; while (AstArg* nextargp = argp->nextp()->castArg()) { // cppcheck-suppress nullPointer argsp = argsp->addNext(nextargp->exprp()->unlinkFrBackWithNext()); // Expression goes to SFormatF nextargp->unlinkFrBack()->deleteTree(); // Remove the call's Arg wrapper } string format; if (pinp->castConst()) format = pinp->castConst()->num().toString(); else pinp->v3error("Format to $display-like function must have constant format string"); pushDeletep(argp); argp=NULL; AstSFormatF* newp = new AstSFormatF(nodep->fileline(), format, false, argsp); if (!newp->scopeNamep() && newp->formatScopeTracking()) { newp->scopeNamep(new AstScopeName(newp->fileline())); } handle.relink(new AstArg(newp->fileline(), "", newp)); // Connection list is now incorrect (has extra args in it). goto reloop; // so exit early; next loop will correct it } else if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::STRING && !pinp->castCvtPackString() && !pinp->castSFormatF() // Already generates a string && !(pinp->castVarRef() && pinp->castVarRef()->varp()->basicp()->keyword()==AstBasicDTypeKwd::STRING)) { UINFO(4," Add CvtPackString: "<unlinkFrBack(&handle); // No next, that's the next pin AstNode* newp = new AstCvtPackString(pinp->fileline(), pinp); handle.relink(newp); pinp = newp; } // AstPattern requires assignments to pass datatype on PRELIM pinp->accept(*this,WidthVP(portp->dtypep(),PRELIM).p()); pinp=NULL; } else if (accept_mode==1) { // Change data types based on above accept completion if (portp->isDouble()) { spliceCvtD(pinp); pinp=NULL; } } else if (accept_mode==2) { // Do PRELIM again, because above accept may have exited early due to node replacement pinp->accept(*this,WidthVP(portp->dtypep(),PRELIM).p()); if ((portp->isOutput() || portp->isInout()) && pinp->width() != portp->width()) { pinp->v3error("Unsupported: Function output argument '"<prettyName()<<"'" <<" requires "<width() <<" bits, but connection's "<prettyTypeName() <<" generates "<width()<<" bits."); // otherwise would need some mess to force both sides to proper size // (get an ASSIGN with EXTEND on the lhs instead of rhs) } if (!portp->basicp() || portp->basicp()->isOpaque()) { pinp->accept(*this,WidthVP(portp->dtypep(),FINAL).p()); } else { iterateCheckAssign(nodep,"Function Argument",pinp,FINAL,portp->dtypep()); } } } } } nodep->didWidth(true); } virtual void visit(AstInitial* nodep, AstNUser* vup) { assertAtStatement(nodep,vup); m_initialp = nodep; nodep->iterateChildren(*this); m_initialp = NULL; } virtual void visit(AstNetlist* nodep, AstNUser*) { // Iterate modules backwards, in bottom-up order. That's faster nodep->iterateChildrenBackwards(*this); } //-------------------- // Default virtual void visit(AstNodeMath* nodep, AstNUser*) { nodep->v3fatalSrc("Visit function missing? Widthed function missing for math node: "<iterateChildren(*this); } virtual void visit(AstNode* nodep, AstNUser* vup) { // Default: Just iterate if (vup) nodep->v3fatalSrc("Visit function missing? Widthed expectation for this node: "<iterateChildren(*this); } //---------------------------------------------------------------------- // WIDTH METHODs -- all iterate void visit_Or_Lu64(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: AstBitsToRealD // Real: Output real // LHS presumed self-determined, then coerced to real if (vup->c()->prelim()) { // First stage evaluation nodep->dtypeSetDouble(); AstNodeDType* subDTypep = nodep->findLogicDType(64,64, AstNumeric::UNSIGNED); // Self-determined operand nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,subDTypep,EXTEND_EXP); } } void visit_Or_Ls32(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: AstIToRD // Real: Output real // LHS presumed self-determined, then coerced to real if (vup->c()->prelim()) { // First stage evaluation nodep->dtypeSetDouble(); AstNodeDType* subDTypep = nodep->findLogicDType(32,32, AstNumeric::SIGNED); // Self-determined operand nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,subDTypep,EXTEND_EXP); } } void visit_Os32_Lr(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: RToI // Real: LHS real // LHS presumed self-determined, then coerced to real if (vup->c()->prelim()) { // First stage evaluation iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetSigned32(); } } void visit_Ou64_Lr(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: RealToBits // Real: LHS real // LHS presumed self-determined, then coerced to real if (vup->c()->prelim()) { // First stage evaluation iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetUInt64(); } } void visit_log_not(AstNode* nodep, AstNUser* vup) { // CALLER: LogNot // Width-check: lhs 1 bit // Real: Allowed; implicitly compares with zero // We calculate the width of the UNDER expression. // We then check its width to see if it's legal, and edit if not // We finally set the width of our output // IEEE-2012: Table 11-21 and 11.8.1 (same as RedAnd): // LHS is self-determined // Width: 1 bit out // Sign: unsigned out (11.8.1) if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); if (vup->c()->prelim()) { iterateCheckBool(nodep,"LHS",nodep->op1p(),BOTH); nodep->dtypeSetLogicBool(); } } void visit_log_and_or(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: LogAnd, LogOr, LogIf, LogIff // Widths: 1 bit out, lhs 1 bit, rhs 1 bit // IEEE-2012 Table 11-21: // LHS is self-determined // RHS is self-determined if (vup->c()->prelim()) { iterateCheckBool(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckBool(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetLogicBool(); } } void visit_red_and_or(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: RedAnd, RedOr, ... // Signed: Output unsigned, Lhs/Rhs/etc non-real (presumed, not in IEEE) // IEEE-2012: Table 11-21 and 11.8.1: // LHS is self-determined // Width: 1 bit out // Sign: unsigned out (11.8.1) if (vup->c()->prelim()) { iterateCheckSizedSelf(nodep,"LHS",nodep->lhsp(),SELF,BOTH); nodep->dtypeSetLogicBool(); } } void visit_red_unknown(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: IsUnknown // Signed: Output unsigned, Lhs/Rhs/etc non-real (presumed, not in IEEE) // IEEE-2012: Table 11-21 and 11.8.1: // LHS is self-determined // Width: 1 bit out // Sign: unsigned out (11.8.1) if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p()); nodep->dtypeSetLogicBool(); } } void visit_cmp_eq_gt(AstNodeBiop* nodep, AstNUser* vup, bool realok) { // CALLER: AstEq, AstGt, ..., AstLtS // Real allowed if and only if real_lhs set // See IEEE-2012 11.4.4, and 11.8.1: // Widths: 1 bit out, width is max of LHS or RHS // Sign: signed compare (not output) if both signed, compare is signed, width mismatches sign extend // else, compare is unsigned, **zero-extends** // Real: If either real, other side becomes real and real compare // TODO: chandle/class handle/iface handle: WildEq/WildNeq same as Eq/Neq // TODO: chandle/class handle/iface handle only allowed to self-compare or against null // TODO: chandle/class handle/iface handle no relational compares if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { if (!realok) nodep->v3error("Real not allowed as operand to in ?== operator"); if (AstNodeBiop* newp=replaceWithDVersion(nodep)) { nodep=NULL; nodep = newp; // Process new node instead iterateCheckReal(nodep,"LHS",nodep->lhsp(),FINAL); iterateCheckReal(nodep,"RHS",nodep->rhsp(),FINAL); } } else if (nodep->lhsp()->isString() || nodep->rhsp()->isString()) { if (AstNodeBiop* newp=replaceWithNVersion(nodep)) { nodep=NULL; nodep = newp; // Process new node instead iterateCheckString(nodep,"LHS",nodep->lhsp(),FINAL); iterateCheckString(nodep,"RHS",nodep->rhsp(),FINAL); } } else { bool signedFl = nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned(); if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, signedFl)) { nodep=NULL; nodep = newp; // Process new node instead } int width = max(nodep->lhsp()->width(), nodep->rhsp()->width()); int ewidth = max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin()); AstNodeDType* subDTypep = nodep->findLogicDType(width, ewidth, AstNumeric::fromBool(signedFl)); iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,signedFl?EXTEND_LHS:EXTEND_ZERO); iterateCheck(nodep,"RHS",nodep->rhsp(),CONTEXT,FINAL,subDTypep,signedFl?EXTEND_LHS:EXTEND_ZERO); } nodep->dtypeSetLogicBool(); } } void visit_cmp_real(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: EqD, LtD // Widths: 1 bit out, lhs width == rhs width // Signed compare (not output) if both sides signed // Real if and only if real_allow set // IEEE, 11.4.4: relational compares (<,>,<=,>=,==,===,!=,!==) use "zero padding" on unsigned if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); if (vup->c()->prelim()) { // See similar handling in visit_cmp_eq_gt where created iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckReal(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetLogicBool(); } } void visit_cmp_string(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: EqN, LtN // Widths: 1 bit out, lhs width == rhs width // String compare (not output) // Real if and only if real_allow set if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); if (vup->c()->prelim()) { // See similar handling in visit_cmp_eq_gt where created iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckString(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetLogicBool(); } } void visit_negate_not(AstNodeUniop* nodep, AstNUser* vup, bool real_ok) { // CALLER: (real_ok=false) Not // CALLER: (real_ok=true) Negate // Signed: From lhs // IEEE-2012 Table 11-21: // Widths: out width = lhs width if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); if (!real_ok) checkCvtUS(nodep->lhsp()); } if (real_ok && nodep->lhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); if (AstNodeUniop* newp=replaceWithDVersion(nodep)) { nodep=NULL; nodep = newp; // Process new node instead iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetDouble(); return; } } else { // Note there aren't yet uniops that need version changes // So no need to call replaceWithUOrSVersion(nodep, nodep->isSigned()) } if (vup->c()->prelim()) { nodep->dtypeFrom(nodep->lhsp()); } if (vup->c()->final()) { AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); nodep->dtypep(expDTypep); // Propagate expression type to negation AstNodeDType* subDTypep = expDTypep; iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); } } void visit_signed_unsigned(AstNodeUniop* nodep, AstNUser* vup, AstNumeric rs_out) { // CALLER: Signed, Unsigned // Width: lhs is self determined width // See IEEE-2012 6.24.1: // Width: Returns packed array, of size $bits(expression). // Sign: Output sign is as specified by operation // TODO: Type: Two-state if input is two-state, else four-state if (nodep->op2p()) nodep->v3fatalSrc("For unary ops only!"); if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); checkCvtUS(nodep->lhsp()); int width = nodep->lhsp()->width(); AstNodeDType* expDTypep = nodep->findLogicDType(width,width,rs_out); nodep->dtypep(expDTypep); AstNodeDType* subDTypep = expDTypep; // The child's width is self determined iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,subDTypep,EXTEND_EXP); } } void visit_shift(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: ShiftL, ShiftR, ShiftRS // Widths: Output width from lhs, rhs<33 bits // Signed: Output signed iff LHS signed; unary operator // See IEEE 2012 11.4.10: // RHS is self-determined. RHS is always treated as unsigned, has no effect on result. iterate_shift_prelim(nodep,vup); nodep->dtypeChgSigned(nodep->lhsp()->isSigned()); AstNodeBiop* newp = iterate_shift_final(nodep,vup); nodep=NULL; if (newp) {} // Ununused } void iterate_shift_prelim(AstNodeBiop* nodep, AstNUser* vup) { // Shifts // See IEEE-2012 11.4.10 and Table 11-21. // RHS is self-determined. RHS is always treated as unsigned, has no effect on result. if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(SELF,PRELIM).p()); checkCvtUS(nodep->lhsp()); iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH); nodep->dtypeFrom(nodep->lhsp()); } } AstNodeBiop* iterate_shift_final(AstNodeBiop* nodep, AstNUser* vup) { // Nodep maybe edited if (vup->c()->final()) { AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // ShiftRS converts to ShiftR, but not vice-versa if (nodep->castShiftRS()) { if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, nodep->isSigned())) { nodep=NULL; nodep = newp; // Process new node instead } } bool warnOn = true; // No warning if "X = 1'b1<lhsp()->isOne() && nodep->backp()->castNodeAssign()) warnOn = false; iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP,warnOn); if (nodep->rhsp()->width()>32) { AstConst* shiftp = nodep->rhsp()->castConst(); if (shiftp && shiftp->num().mostSetBitP1() <= 32) { // If (number)<<96'h1, then make it into (number)<<32'h1 V3Number num (shiftp->fileline(), 32, 0); num.opAssign(shiftp->num()); AstNode* shiftp = nodep->rhsp(); nodep->rhsp()->replaceWith(new AstConst(shiftp->fileline(), num)); shiftp->deleteTree(); shiftp=NULL; } else { nodep->rhsp()->v3error("Unsupported: Shifting of by over 32-bit number isn't supported." <<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n"); } } } return nodep; // May edit } void visit_boolmath_and_or(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: And, Or, Xor, ... // Lint widths: out width = lhs width = rhs width // Signed: if lhs & rhs signed // IEEE-2012 Table 11-21: // Width: max(LHS, RHS) if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!"); // If errors are off, we need to follow the spec; thus we really need to do the max() // because the rhs could be larger, and we need to have proper editing to get the widths // to be the same for our operations. if (vup->c()->prelim()) { // First stage evaluation // Determine expression widths only relying on what's in the subops nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); int width = max(nodep->lhsp()->width(), nodep->rhsp()->width()); int mwidth = max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin()); bool expSigned = (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); nodep->dtypeChgWidthSigned(width,mwidth,AstNumeric::fromBool(expSigned)); } if (vup->c()->final()) { AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); // Error report and change sizes for suboperands of this node. iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); iterateCheck(nodep,"RHS",nodep->rhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP); } } void visit_add_sub_replace(AstNodeBiop* nodep, AstNUser* vup, bool real_ok) { // CALLER: (real_ok=false) AddS, SubS, ... // CALLER: (real_ok=true) Add, Sub, ... // Widths: out width = lhs width = rhs width // Signed: Replace operator with signed operator, or signed to unsigned // Real: Replace operator with real operator // IEEE-2012 Table 11-21: // Width: max(LHS, RHS) // If errors are off, we need to follow the spec; thus we really need to do the max() // because the rhs could be larger, and we need to have proper editing to get the widths // to be the same for our operations. // //if (debug()>=9) { UINFO(0,"-rus "<c()<dumpTree(cout,"-rusin-"); } if (vup->c()->prelim()) { // First stage evaluation // Determine expression widths only relying on what's in the subops nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); if (!real_ok) { checkCvtUS(nodep->lhsp()); checkCvtUS(nodep->rhsp()); } if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) { spliceCvtD(nodep->lhsp()); spliceCvtD(nodep->rhsp()); if (AstNodeBiop* newp=replaceWithDVersion(nodep)) { nodep=NULL; nodep = newp; // Process new node instead } nodep->dtypeSetDouble(); iterateCheckReal(nodep,"LHS",nodep->lhsp(),FINAL); iterateCheckReal(nodep,"RHS",nodep->rhsp(),FINAL); return; } else { int width = max(nodep->lhsp()->width(), nodep->rhsp()->width()); int mwidth = max(nodep->lhsp()->widthMin(), nodep->rhsp()->widthMin()); bool expSigned = (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()); nodep->dtypeChgWidthSigned(width,mwidth,AstNumeric::fromBool(expSigned)); } } if (vup->c()->final()) { // Parent's data type was computed using the max(upper, nodep->dtype) AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep()); AstNodeDType* subDTypep = expDTypep; nodep->dtypeFrom(expDTypep); if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, expDTypep->isSigned())) { nodep=NULL; nodep = newp; // Process new node instead } // Some warning suppressions bool lhsWarn=true; bool rhsWarn = true; if (nodep->castAdd() || nodep->castSub()) { if (subDTypep->widthMin() == (nodep->lhsp()->widthMin()+1)) lhsWarn=false; // Warn if user wants extra bit from carry if (subDTypep->widthMin() == (nodep->rhsp()->widthMin()+1)) rhsWarn=false; // Warn if user wants extra bit from carry } else if (nodep->castMul() || nodep->castMulS()) { if (subDTypep->widthMin() >= (nodep->lhsp()->widthMin())) lhsWarn=false; if (subDTypep->widthMin() >= (nodep->rhsp()->widthMin())) rhsWarn=false; } // Final call, so make sure children check their sizes // Error report and change sizes for suboperands of this node. iterateCheck(nodep,"LHS",nodep->lhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP,lhsWarn); iterateCheck(nodep,"RHS",nodep->rhsp(),CONTEXT,FINAL,subDTypep,EXTEND_EXP,rhsWarn); } //if (debug()>=9) nodep->dumpTree(cout,"-rusou-"); } void visit_real_add_sub(AstNodeBiop* nodep, AstNUser* vup) { // CALLER: AddD, MulD, ... if (vup->c()->prelim()) { // First stage evaluation // Note similar steps in visit_add_sub_replace promotion to double iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); iterateCheckReal(nodep,"RHS",nodep->rhsp(),BOTH); nodep->dtypeSetDouble(); } } void visit_real_neg_ceil(AstNodeUniop* nodep, AstNUser* vup) { // CALLER: Negate, Ceil, Log, ... if (vup->c()->prelim()) { // First stage evaluation // See alsl visit_negate_not conversion iterateCheckReal(nodep,"LHS",nodep->lhsp(),BOTH); nodep->dtypeSetDouble(); } } //---------------------------------------------------------------------- // LOWER LEVEL WIDTH METHODS (none iterate) bool widthBad (AstNode* nodep, AstNodeDType* expDTypep) { int expWidth = expDTypep->width(); int expWidthMin = expDTypep->widthMin(); if (!nodep->dtypep()) nodep->v3fatalSrc("Under node "<prettyTypeName()<<" has no dtype?? Missing Visitor func?"); if (nodep->width()==0) nodep->v3fatalSrc("Under node "<prettyTypeName()<<" has no expected width?? Missing Visitor func?"); if (expWidth==0) nodep->v3fatalSrc("Node "<prettyTypeName()<<" has no expected width?? Missing Visitor func?"); if (expWidthMin==0) expWidthMin = expWidth; if (nodep->dtypep()->widthSized() && nodep->width() != expWidthMin) return true; if (!nodep->dtypep()->widthSized() && nodep->widthMin() > expWidthMin) return true; return false; } void fixWidthExtend (AstNode* nodep, AstNodeDType* expDTypep, ExtendRule extendRule) { // Fix the width mismatch by extending or truncating bits // *ONLY* call this from checkWidth() // Truncation is rarer, but can occur: parameter [3:0] FOO = 64'h12312; // A(CONSTwide)+B becomes A(CONSTwidened)+B // A(somewide)+B becomes A(TRUNC(somewide,width))+B // or A(EXTRACT(somewide,width,0))+B // Sign extension depends on the type of the *present* // node, while the output dtype is the *expected* sign. // It is reasonable to have sign extension with unsigned output, // for example $unsigned(a)+$signed(b), the SIGNED(B) will be unsigned dtype out UINFO(4," widthExtend_(r="<castConst(); int expWidth = expDTypep->width(); if (constp && !nodep->isSigned()) { // Save later constant propagation work, just right-size it. V3Number num (nodep->fileline(), expWidth); num.opAssign(constp->num()); num.isSigned(expDTypep->isSigned()); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); pushDeletep(constp); constp=NULL; nodep=NULL; nodep=newp; } else if (expWidthwidth()) { // Trunc - Extract AstNRelinker linker; nodep->unlinkFrBack(&linker); AstNode* newp = new AstSel(nodep->fileline(), nodep, 0, expWidth); newp->didWidth(true); // Don't replace dtype with unsigned linker.relink(newp); nodep=newp; } else { // Extend AstNRelinker linker; nodep->unlinkFrBack(&linker); bool doSigned = false; switch (extendRule) { case EXTEND_ZERO: doSigned = false; break; case EXTEND_EXP: doSigned = nodep->isSigned() && expDTypep->isSigned(); break; case EXTEND_LHS: doSigned = nodep->isSigned(); break; default: nodep->v3fatalSrc("bad case"); } AstNode* newp = (doSigned ? (new AstExtendS(nodep->fileline(), nodep))->castNode() : (new AstExtend (nodep->fileline(), nodep))->castNode()); linker.relink(newp); nodep=newp; } if (expDTypep->isDouble() && !nodep->isDouble()) { // For AstVar init() among others // TODO do all to-real and to-integer conversions in this function rather than in callers AstNode* newp = spliceCvtD(nodep); nodep = newp; } nodep->dtypeFrom(expDTypep); UINFO(4," _new: "<castConst(); if (constp) { V3Number num (nodep->fileline(), expWidth); num.opRedOr(constp->num()); num.isSigned(expSigned); AstNode* newp = new AstConst(nodep->fileline(), num); constp->replaceWith(newp); constp->deleteTree(); constp=NULL; nodep=NULL; nodep=newp; } else { AstNRelinker linker; nodep->unlinkFrBack(&linker); AstNode* newp = new AstRedOr(nodep->fileline(), nodep); linker.relink(newp); nodep=newp; } nodep->dtypeChgWidthSigned(expWidth,expWidth,AstNumeric::fromBool(expSigned)); UINFO(4," _new: "<castConst()) { if (constp->num().autoExtend() && !constp->num().sized() && constp->width()==1) { // Make it the proper size. Careful of proper extension of 0's/1's V3Number num (constp->fileline(), expWidth); num.opRepl(constp->num(), expWidth); // {width{'1}} AstNode* newp = new AstConst(constp->fileline(), num); // Spec says always unsigned with proper width if (debug()>4) constp->dumpTree(cout," fixAutoExtend_old: "); if (debug()>4) newp->dumpTree(cout," _new: "); constp->replaceWith(newp); constp->deleteTree(); constp=NULL; // Tell caller the new constp, and that we changed it. nodepr = newp; return true; } } return false; // No change } void iterateCheckFileDesc (AstNode* nodep, AstNode* underp, Stage stage) { if (stage != BOTH) nodep->v3fatalSrc("Bad call"); // underp may change as a result of replacement underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p()); AstNodeDType* expDTypep = underp->findUInt32DType(); underp = iterateCheck(nodep,"file_descriptor",underp,SELF,FINAL,expDTypep,EXTEND_EXP); } void iterateCheckReal (AstNode* nodep, const char* side, AstNode* underp, Stage stage) { // Coerce child to real if not already. Child is self-determined // e.g. nodep=ADDD, underp=ADD in ADDD(ADD(a,b), real-CONST) // Don't need separate PRELIM and FINAL(double) calls; // as if resolves to double, the BOTH correctly resolved double, // otherwise self-determined was correct // underp may change as a result of replacement if (stage & PRELIM) { underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p()); } if (stage & FINAL) { AstNodeDType* expDTypep = nodep->findDoubleDType(); underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP); } } void iterateCheckString (AstNode* nodep, const char* side, AstNode* underp, Stage stage) { if (stage & PRELIM) { underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p()); } if (stage & FINAL) { AstNodeDType* expDTypep = nodep->findStringDType(); underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP); } } void iterateCheckSizedSelf (AstNode* nodep, const char* side, AstNode* underp, Determ determ, Stage stage) { // Coerce child to any sized-number data type; child is self-determined i.e. isolated from expected type. // e.g. nodep=CONCAT, underp=lhs in CONCAT(lhs,rhs) if (determ != SELF) nodep->v3fatalSrc("Bad call"); if (stage != FINAL && stage != BOTH) nodep->v3fatalSrc("Bad call"); // underp may change as a result of replacement if (stage & PRELIM) underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p()); underp = checkCvtUS(underp); AstNodeDType* expDTypep = underp->dtypep(); underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP); } void iterateCheckAssign(AstNode* nodep, const char* side, AstNode* rhsp, Stage stage, AstNodeDType* lhsDTypep) { // Check using assignment-like context rules //if (debug()) nodep->dumpTree(cout,"-checkass: "); if (stage != FINAL) nodep->v3fatalSrc("Bad width call"); // We iterate and size the RHS based on the result of RHS evaluation bool lhsStream = (nodep->castNodeAssign() && nodep->castNodeAssign()->lhsp()->castNodeStream()); rhsp = iterateCheck(nodep,side,rhsp,ASSIGN,FINAL,lhsDTypep,lhsStream?EXTEND_OFF:EXTEND_LHS); //if (debug()) nodep->dumpTree(cout,"-checkout: "); } void iterateCheckBool (AstNode* nodep, const char* side, AstNode* underp, Stage stage) { if (stage != BOTH) nodep->v3fatalSrc("Bad call"); // Booleans always self-determined so do BOTH at once // Underp is used in a self-determined but boolean context, reduce a multibit number to one bit // stage is always BOTH so not passed as argument // underp may change as a result of replacement if (!underp) underp->v3fatalSrc("Node has no type"); underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,BOTH).p()); if (!underp || !underp->dtypep()) underp->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it? // // For DOUBLE under a logical op, add implied test against zero, never a warning if (underp && underp->isDouble()) { UINFO(6," spliceCvtCmpD0: "<unlinkFrBack(&linker); AstNode* newp = new AstNeqD(nodep->fileline(), underp, new AstConst(nodep->fileline(), AstConst::RealDouble(), 0.0)); linker.relink(newp); } else if (!underp->dtypep()->basicp()) { nodep->v3error("Logical Operator "<prettyTypeName() <<" expects a non-complex data type on the "<replaceWith(new AstConst(nodep->fileline(), AstConst::LogicFalse())); pushDeletep(underp); underp=NULL; } else { bool bad = widthBad(underp,nodep->findLogicBoolDType()); if (bad) { bool warnOn = true; // Not used if (warnOn) { if (debug()>4) nodep->backp()->dumpTree(cout," back: "); nodep->v3warn(WIDTH,"Logical Operator "<prettyTypeName() <<" expects 1 bit on the "<prettyTypeName()<<" generates "<width() <<(underp->width()!=underp->widthMin() ?" or "+cvtToStr(underp->widthMin()):"") <<" bits."); } fixWidthReduce(underp); underp=NULL;//Changed } } } AstNode* iterateCheck (AstNode* nodep, const char* side, AstNode* underp, Determ determ, Stage stage, AstNodeDType* expDTypep, ExtendRule extendRule, bool warnOn=true) { // Perform data type check on underp, which is underneath nodep used for error reporting // Returns the new underp // Conversion to/from doubles and integers are before iterating. if (stage != FINAL) nodep->v3fatalSrc("Bad state to iterateCheck"); if (!underp || !underp->dtypep()) underp->v3fatalSrc("Node has no type"); // Perhaps forgot to do a prelim visit on it? if (expDTypep == underp->dtypep()) { // Perfect underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); } else if (expDTypep->isDouble() && underp->isDouble()) { // Also good underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); } else if (expDTypep->isDouble() && !underp->isDouble()) { underp = spliceCvtD(underp); underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); } else if (!expDTypep->isDouble() && underp->isDouble()) { underp = spliceCvtS(underp, true); // Round RHS underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); } else if (expDTypep->isString() && !underp->dtypep()->isString()) { underp = spliceCvtString(underp); underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); } else { AstBasicDType* expBasicp = expDTypep->basicp(); AstBasicDType* underBasicp = underp->dtypep()->basicp(); if (expBasicp && underBasicp) { AstNodeDType* subDTypep = expDTypep; // We then iterate FINAL before width fixes, as if the under-operation // is e.g. an ADD, the ADD will auto-adjust to the proper data type // or if another operation e.g. ATOI will not. if (determ == SELF) { underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p()); } else if (determ == ASSIGN) { // IEEE: Signedness is solely determined by the RHS (underp), not by the LHS (expDTypep) if (underp->isSigned() != subDTypep->isSigned() || underp->width() != subDTypep->width()) { subDTypep = nodep->findLogicDType(max(subDTypep->width(), underp->width()), max(subDTypep->widthMin(), underp->widthMin()), AstNumeric::fromBool(underp->isSigned())); UINFO(9,"Assignment of opposite-signed RHS to LHS: "<acceptSubtreeReturnEdits(*this,WidthVP(subDTypep,FINAL).p()); } else { underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(subDTypep,FINAL).p()); } // Note the check uses the expected size, not the child's subDTypep as we want the // child node's width to end up correct for the assignment (etc) widthCheckSized(nodep,side,underp,expDTypep,extendRule,warnOn); } else { // Hope it just works out } } return underp; } void widthCheckSized (AstNode* nodep, const char* side, AstNode* underp, // Node to be checked or have typecast added in front of AstNodeDType* expDTypep, ExtendRule extendRule, bool warnOn=true) { // Issue warnings on sized number width mismatches, then do appropriate size extension // Generally iterateCheck is what is wanted instead of this //UINFO(9,"wchk "<basicp(); AstBasicDType* underBasicp = underp->dtypep()->basicp(); if (expDTypep == underp->dtypep()) { return; // Same type must match } else if (!expBasicp || expBasicp->isDouble() || !underBasicp || underBasicp->isDouble()) { // This is perhaps a v3fatalSrc as we should have checked the types before calling widthCheck, // but we may have missed a non-sized check in earlier code, so might as well assume it is the users' fault. nodep->v3error(ucfirst(nodep->prettyOperatorName())<<" expected non-complex non-double "<v3fatalSrc("widthCheckSized should not be called on doubles/complex types"); #endif return; } else { int expWidth = expDTypep->width(); int expWidthMin = expDTypep->widthMin(); if (expWidthMin==0) expWidthMin = expWidth; bool bad = widthBad(underp,expDTypep); if ((bad || underp->width() != expWidth) && fixAutoExtend(underp/*ref*/,expWidth)) { underp=NULL; // Changes underp return; } if (underp->castConst() && underp->castConst()->num().isFromString() && expWidth > underp->width() && (((expWidth - underp->width()) % 8) == 0)) { // At least it's character sized // reg [31:0] == "foo" we'll consider probably fine. // Maybe this should be a special warning? Not for now. warnOn = false; } if ((nodep->castAdd() && underp->width()==1 && underp->isOne()) || (nodep->castSub() && underp->width()==1 && underp->isOne() && 0==strcmp(side,"RHS"))) { // "foo + 1'b1", or "foo - 1'b1" are very common, people assume they extend correctly warnOn = false; } if (bad && warnOn) { if (debug()>4) nodep->backp()->dumpTree(cout," back: "); nodep->v3warn(WIDTH,ucfirst(nodep->prettyOperatorName()) <<" expects "<prettyTypeName()<<" generates "<width() <<(underp->width()!=underp->widthMin() ?" or "+cvtToStr(underp->widthMin()):"") <<" bits."); } if (bad || underp->width()!=expWidth) { // If we're in an NodeAssign, don't truncate the RHS if the LHS is // a NodeStream. The streaming operator changes the rules regarding // which bits to truncate. AstNodeAssign* assignp = nodep->castNodeAssign(); AstPin* pinp = nodep->castPin(); if (assignp && assignp->lhsp()->castNodeStream()) { } else if (pinp && !pinp->modVarp()->isInput()) { // V3Inst::pinReconnectSimple must deal UINFO(5,"pinInSizeMismatch: "<isDouble()) { nodep->v3error("Expected integral (non-real) input to "<backp()->prettyTypeName()); nodep = spliceCvtS(nodep, true); } return nodep; } AstNode* spliceCvtD(AstNode* nodep) { // For integer used in REAL context, convert to real // We don't warn here, "2.0 * 2" is common and reasonable if (nodep && !nodep->isDouble()) { UINFO(6," spliceCvtD: "<unlinkFrBack(&linker); AstNode* newp = new AstIToRD(nodep->fileline(), nodep); linker.relink(newp); return newp; } else { return nodep; } } AstNode* spliceCvtS(AstNode* nodep, bool warnOn) { // IEEE-2012 11.8.1: Signed: Type coercion creates signed // 11.8.2: Argument to convert is self-determined if (nodep && nodep->isDouble()) { UINFO(6," spliceCvtS: "<unlinkFrBack(&linker); if (warnOn) nodep->v3warn(REALCVT,"Implicit conversion of real to integer"); AstNode* newp = new AstRToIRoundS(nodep->fileline(), nodep); linker.relink(newp); return newp; } else { return nodep; } } AstNode* spliceCvtString(AstNode* nodep) { // IEEE-2012 11.8.1: Signed: Type coercion creates signed // 11.8.2: Argument to convert is self-determined if (nodep && !nodep->dtypep()->basicp()->isString()) { UINFO(6," spliceCvtString: "<unlinkFrBack(&linker); AstNode* newp = new AstCvtPackString(nodep->fileline(), nodep); linker.relink(newp); return newp; } else { return nodep; } } AstNodeBiop* replaceWithUOrSVersion(AstNodeBiop* nodep, bool signedFlavorNeeded) { // Given a signed/unsigned node type, create the opposite type // Return new node or NULL if nothing if (signedFlavorNeeded == nodep->signedFlavor()) { return NULL; } if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp()); // To simplify callers, some node types don't need to change switch (nodep->type()) { case AstType::atEQ: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atNEQ: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atEQCASE: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atNEQCASE: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atADD: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atSUB: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; case AstType::atSHIFTL: nodep->dtypeChgSigned(signedFlavorNeeded); return NULL; default: break; } FileLine* fl = nodep->fileline(); AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeBiop* newp = NULL; switch (nodep->type()) { case AstType::atGT: newp = new AstGtS (fl,lhsp,rhsp); break; case AstType::atGTS: newp = new AstGt (fl,lhsp,rhsp); break; case AstType::atGTE: newp = new AstGteS (fl,lhsp,rhsp); break; case AstType::atGTES: newp = new AstGte (fl,lhsp,rhsp); break; case AstType::atLT: newp = new AstLtS (fl,lhsp,rhsp); break; case AstType::atLTS: newp = new AstLt (fl,lhsp,rhsp); break; case AstType::atLTE: newp = new AstLteS (fl,lhsp,rhsp); break; case AstType::atLTES: newp = new AstLte (fl,lhsp,rhsp); break; case AstType::atDIV: newp = new AstDivS (fl,lhsp,rhsp); break; case AstType::atDIVS: newp = new AstDiv (fl,lhsp,rhsp); break; case AstType::atMODDIV: newp = new AstModDivS (fl,lhsp,rhsp); break; case AstType::atMODDIVS: newp = new AstModDiv (fl,lhsp,rhsp); break; case AstType::atMUL: newp = new AstMulS (fl,lhsp,rhsp); break; case AstType::atMULS: newp = new AstMul (fl,lhsp,rhsp); break; case AstType::atSHIFTR: newp = new AstShiftRS (fl,lhsp,rhsp); break; case AstType::atSHIFTRS: newp = new AstShiftR (fl,lhsp,rhsp); break; default: nodep->v3fatalSrc("Node needs sign change, but bad case: "<replaceWith(newp); newp->dtypeFrom(nodep); pushDeletep(nodep); nodep=NULL; return newp; } AstNodeBiop* replaceWithDVersion(AstNodeBiop* nodep) { // Given a signed/unsigned node type, create the opposite type // Return new node or NULL if nothing if (nodep->doubleFlavor()) { return NULL; } FileLine* fl = nodep->fileline(); AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeBiop* newp = NULL; // No width change on output;... // All below have bool or double outputs switch (nodep->type()) { case AstType::atADD: newp = new AstAddD (fl,lhsp,rhsp); break; case AstType::atSUB: newp = new AstSubD (fl,lhsp,rhsp); break; case AstType::atPOW: newp = new AstPowD (fl,lhsp,rhsp); break; case AstType::atEQ: case AstType::atEQCASE: newp = new AstEqD (fl,lhsp,rhsp); break; case AstType::atNEQ: case AstType::atNEQCASE: newp = new AstNeqD (fl,lhsp,rhsp); break; case AstType::atGT: case AstType::atGTS: newp = new AstGtD (fl,lhsp,rhsp); break; case AstType::atGTE: case AstType::atGTES: newp = new AstGteD (fl,lhsp,rhsp); break; case AstType::atLT: case AstType::atLTS: newp = new AstLtD (fl,lhsp,rhsp); break; case AstType::atLTE: case AstType::atLTES: newp = new AstLteD (fl,lhsp,rhsp); break; case AstType::atDIV: case AstType::atDIVS: newp = new AstDivD (fl,lhsp,rhsp); break; case AstType::atMUL: case AstType::atMULS: newp = new AstMulD (fl,lhsp,rhsp); break; default: nodep->v3fatalSrc("Node needs conversion to double, but bad case: "<replaceWith(newp); // No width change; the default created type (bool or double) is correct pushDeletep(nodep); nodep=NULL; return newp; } AstNodeBiop* replaceWithNVersion(AstNodeBiop* nodep) { // Given a signed/unsigned node type, replace with string version // Return new node or NULL if nothing if (nodep->stringFlavor()) { return NULL; } FileLine* fl = nodep->fileline(); AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeBiop* newp = NULL; // No width change on output;... // All below have bool or double outputs switch (nodep->type()) { case AstType::atEQ: case AstType::atEQCASE: newp = new AstEqN (fl,lhsp,rhsp); break; case AstType::atNEQ: case AstType::atNEQCASE: newp = new AstNeqN (fl,lhsp,rhsp); break; case AstType::atGT: case AstType::atGTS: newp = new AstGtN (fl,lhsp,rhsp); break; case AstType::atGTE: case AstType::atGTES: newp = new AstGteN (fl,lhsp,rhsp); break; case AstType::atLT: case AstType::atLTS: newp = new AstLtN (fl,lhsp,rhsp); break; case AstType::atLTE: case AstType::atLTES: newp = new AstLteN (fl,lhsp,rhsp); break; default: nodep->v3fatalSrc("Node needs conversion to string, but bad case: "<replaceWith(newp); // No width change; the default created type (bool or string) is correct pushDeletep(nodep); nodep=NULL; return newp; } AstNodeUniop* replaceWithDVersion(AstNodeUniop* nodep) { // Given a signed/unsigned node type, create the opposite type // Return new node or NULL if nothing if (nodep->doubleFlavor()) { return NULL; } FileLine* fl = nodep->fileline(); AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNodeUniop* newp = NULL; switch (nodep->type()) { case AstType::atNEGATE: newp = new AstNegateD (fl,lhsp); break; default: nodep->v3fatalSrc("Node needs conversion to double, but bad case: "<replaceWith(newp); newp->dtypeFrom(nodep); pushDeletep(nodep); nodep=NULL; return newp; } //---------------------------------------------------------------------- // METHODS - data types AstNodeDType* moveChildDTypeEdit(AstNode* nodep) { // DTypes at parse time get added as a childDType to some node types such as AstVars. // We move them to global scope, so removing/changing a variable won't lose the dtype. AstNodeDType* dtnodep = nodep->getChildDTypep(); if (!dtnodep) nodep->v3fatalSrc("Caller should check for NULL before calling moveChild"); UINFO(9,"moveChildDTypeEdit "<unlinkFrBack(); // Make non-child v3Global.rootp()->typeTablep()->addTypesp(dtnodep); return dtnodep; } AstNodeDType* iterateEditDTypep(AstNode* parentp, AstNodeDType* nodep) { // Iterate into a data type to resolve that type. This process // may eventually create a new data type, but not today // it may make a new datatype, need subChildDType() to point to it; // maybe we have user5p indicate a "replace me with" pointer. // Need to be careful with "implicit" types though. // // Alternative is to have WidthVP return information. // or have a call outside of normal visitor land. // or have a m_return type (but need to return if width called multiple times) if (!nodep) parentp->v3fatalSrc("Null dtype when widthing dtype"); nodep->iterate(*this); return nodep; } AstConst* dimensionValue(AstNodeDType* nodep, AstAttrType attrType, int dim) { // Return the dimension value for the specified attribute and constant dimension AstNodeDType* dtypep = nodep->skipRefp(); VNumRange declRange; // ranged() set false for (int i = 1; i <= dim; ++i) { //UINFO(9, " dim at "<castNodeArrayDType()) { declRange = adtypep->declRange(); if (isubDTypep()->skipRefp(); continue; } else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) { declRange = adtypep->declRange(); if (adtypep) {} // UNUSED break; // Sub elements don't look like arrays and can't iterate into } else if (AstBasicDType* adtypep = dtypep->castBasicDType()) { if (adtypep->isRanged()) declRange = adtypep->declRange(); break; } break; } AstConst* valp = NULL; // If NULL, construct from val int val = 0; switch (attrType) { case AstAttrType::DIM_BITS: { int bits = 1; while (dtypep) { //UINFO(9, " bits at "<castNodeArrayDType()) { bits *= adtypep->declRange().elements(); dtypep = adtypep->subDTypep()->skipRefp(); continue; } else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) { bits *= adtypep->width(); break; } else if (AstBasicDType* adtypep = dtypep->castBasicDType()) { bits *= adtypep->width(); break; } break; } if (dim == 0) { val = 0; } else if (dim == 1 && !declRange.ranged() && bits==1) { // $bits should be sane for non-arrays val = nodep->width(); } else { val = bits; } break; } case AstAttrType::DIM_HIGH: val = !declRange.ranged() ? 0 : declRange.hi(); break; case AstAttrType::DIM_LEFT: val = !declRange.ranged() ? 0 : declRange.left(); break; case AstAttrType::DIM_LOW: val = !declRange.ranged() ? 0 : declRange.lo(); break; case AstAttrType::DIM_RIGHT: val = !declRange.ranged() ? 0 : declRange.right(); break; case AstAttrType::DIM_INCREMENT: val = (declRange.ranged() && declRange.littleEndian()) ? -1 : 1; break; case AstAttrType::DIM_SIZE: val = !declRange.ranged() ? 0 : declRange.elements(); break; default: nodep->v3fatalSrc("Missing DIM ATTR type case"); break; } if (!valp) valp = new AstConst(nodep->fileline(), AstConst::Signed32(), val); UINFO(9," $dimension "<second; } AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(), nodep->findSigned32DType(), new AstRange(nodep->fileline(), msbdim, 0)); AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL); v3Global.rootp()->typeTablep()->addTypesp(vardtypep); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, "__Vdimtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++), vardtypep); varp->isConst(true); varp->isStatic(true); varp->valuep(initp); // Add to root, as don't know module we are in, and aids later structure sharing v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); // Element 0 is a non-index and has speced values initp->addInitsp(dimensionValue(nodep, attrType, 0)); for (unsigned i=1; iaddInitsp(dimensionValue(nodep, attrType, i)); } varp->iterate(*this); // May have already done $unit so must do this var m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp)); return varp; } AstVar* enumVarp(AstEnumDType* nodep, AstAttrType attrType, uint32_t msbdim) { // Return a variable table which has specified dimension properties for this variable TableMap::iterator pos = m_tableMap.find(make_pair(nodep,attrType)); if (pos != m_tableMap.end()) { return pos->second; } UINFO(9, "Construct Venumtab attr="<findStringDType(); } else { basep = nodep->findSigned32DType(); } AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(), basep, new AstRange(nodep->fileline(), msbdim, 0)); AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL); v3Global.rootp()->typeTablep()->addTypesp(vardtypep); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, "__Venumtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++), vardtypep); varp->isConst(true); varp->isStatic(true); varp->valuep(initp); // Add to root, as don't know module we are in, and aids later structure sharing v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp); // Find valid values and populate if (!nodep->itemsp()) nodep->v3fatalSrc("enum without items"); vector values; values.reserve(msbdim+1); for (unsigned i=0; i<(msbdim+1); ++i) { values[i] = NULL; } { AstEnumItem* firstp = nodep->itemsp(); AstEnumItem* prevp = firstp; // Prev must start with last item while (prevp->nextp()) prevp = prevp->nextp()->castEnumItem(); for (AstEnumItem* itemp = firstp; itemp;) { AstEnumItem* nextp = itemp->nextp()->castEnumItem(); AstConst* vconstp = itemp->valuep()->castConst(); if (!vconstp) nodep->v3fatalSrc("Enum item without constified value"); uint32_t i = vconstp->toUInt(); if (attrType == AstAttrType::ENUM_NAME) { values[i] = new AstConst(nodep->fileline(), AstConst::String(), itemp->name()); } else if (attrType == AstAttrType::ENUM_NEXT) { values[i] = (nextp ? nextp : firstp)->valuep()->cloneTree(false); // A const } else if (attrType == AstAttrType::ENUM_PREV) { values[i] = prevp->valuep()->cloneTree(false); // A const } else { nodep->v3fatalSrc("Bad case"); } prevp = itemp; itemp = nextp; } } // Fill in all unspecified values and add to table for (unsigned i=0; i<(msbdim+1); ++i) { AstNode* valp = values[i]; if (!valp) { if (attrType == AstAttrType::ENUM_NAME) { valp = new AstConst(nodep->fileline(), AstConst::String(), ""); } else if (attrType == AstAttrType::ENUM_NEXT || attrType == AstAttrType::ENUM_PREV) { valp = new AstConst(nodep->fileline(), V3Number(nodep->fileline(), nodep->width(), 0)); } else { nodep->v3fatalSrc("Bad case"); } } initp->addInitsp(valp); } varp->iterate(*this); // May have already done $unit so must do this var m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp)); return varp; } PatVecMap patVectorMap(AstPattern* nodep, const VNumRange& range) { PatVecMap patmap; int element = range.left(); for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) { if (patp->keyp()) { if (AstConst* constp = patp->keyp()->castConst()) { element = constp->toSInt(); } else { patp->keyp()->v3error("Assignment pattern key not supported/understood: "<keyp()->prettyTypeName()); } } if (patmap.find(element) != patmap.end()) { patp->v3error("Assignment pattern key used multiple times: "<c()->selfDtm())) { UINFO(1,"-: "<c()<v3fatalSrc("No dtype expected at statement "<prettyTypeName()); } } void checkConstantOrReplace(AstNode* nodep, const string& message) { // See also V3WidthSel::checkConstantOrReplace // Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us! if (!nodep->castConst()) { nodep->v3error(message); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1)); pushDeletep(nodep); nodep=NULL; } } public: // CONSTUCTORS WidthVisitor(bool paramsOnly, // [in] TRUE if we are considering parameters only. bool doGenerate) { // [in] TRUE if we are inside a generate statement and // // don't wish to trigger errors m_paramsOnly = paramsOnly; m_cellRangep = NULL; m_funcp = NULL; m_initialp = NULL; m_attrp = NULL; m_doGenerate = doGenerate; m_dtTables = 0; } AstNode* mainAcceptEdit(AstNode* nodep) { return nodep->acceptSubtreeReturnEdits(*this, WidthVP(SELF,BOTH).p()); } virtual ~WidthVisitor() {} }; //###################################################################### // Width class functions int V3Width::debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void V3Width::width(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } //! Single node parameter propagation //! Smaller step... Only do a single node for parameter propagation AstNode* V3Width::widthParamsEdit (AstNode* nodep) { UINFO(4,__FUNCTION__<<": "<= 6); } verilator-3.874/src/V3EmitC.cpp0000664000177100017500000025126412525172036016245 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit C++ for tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3String.h" #include "V3EmitC.h" #include "V3EmitCBase.h" #include "V3Number.h" #define VL_VALUE_STRING_MAX_WIDTH 8192 // We use a static char array in VL_VALUE_STRING //###################################################################### // Emit statements and math operators class EmitCStmts : public EmitCBaseVisitor { private: bool m_suppressSemi; AstVarRef* m_wideTempRefp; // Variable that _WW macros should be setting vector m_ctorVarsVec; // All variables in constructor order int m_splitSize; // # of cfunc nodes placed into output file int m_splitFilenum; // File number being created, 0 = primary public: // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // ACCESSORS int splitFilenum() const { return m_splitFilenum; } int splitFilenumInc() { m_splitSize = 0; return ++m_splitFilenum; } int splitSize() const { return m_splitSize; } void splitSizeInc(int count) { m_splitSize += count; } void splitSizeInc(AstNode* nodep) { splitSizeInc(EmitCBaseCounterVisitor(nodep).count()); } bool splitNeeded() { return (splitSize() && v3Global.opt.outputSplit() && v3Global.opt.outputSplit() < splitSize()); } // METHODS void displayNode(AstNode* nodep, AstScopeName* scopenamep, const string& vformat, AstNode* exprsp, bool isScan); void displayEmit(AstNode* nodep, bool isScan); void displayArg(AstNode* dispp, AstNode** elistp, bool isScan, string vfmt, char fmtLetter); void emitVarDecl(AstVar* nodep, const string& prefixIfImp); typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_PAR, EVL_ALL} EisWhich; void emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp); void emitVarCtors(); bool emitSimpleOk(AstNodeMath* nodep); void emitIQW(AstNode* nodep) { // Other abbrevs: "C"har, "S"hort, "F"loat, "D"ouble, stri"N"g puts (nodep->isString() ? "N" : nodep->isWide() ? "W" : nodep->isQuad() ? "Q" : "I"); } void emitScIQW(AstVar* nodep) { if (!nodep->isSc()) nodep->v3fatalSrc("emitting SystemC operator on non-SC variable"); puts (nodep->isScBigUint() ? "SB" : nodep->isScUint() ? "SU" : nodep->isScBv() ? "SW" : (nodep->isScQuad() ? "SQ" : "SI")); } void emitOpName(AstNode* nodep, const string& format, AstNode* lhsp, AstNode* rhsp, AstNode* thsp); void emitDeclArrayBrackets(AstVar* nodep) { // This isn't very robust and may need cleanup for other data types for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp; arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } } void emitTypedefs(AstNode* firstp) { bool first = true; for (AstNode* loopp=firstp; loopp; loopp = loopp->nextp()) { if (AstTypedef* nodep = loopp->castTypedef()) { if (nodep->attrPublic()) { if (first) { first = false; puts("\n// TYPEDEFS\n"); puts("// That were declared public\n"); } else { puts("\n"); } if (AstEnumDType* adtypep = nodep->dtypep()->skipRefToEnump()->castEnumDType()) { if (adtypep->width()>64) { puts("// enum "+nodep->name()+" // Ignored: Too wide for C++\n"); } else { puts("enum "+nodep->name()+" {\n"); for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp=itemp->nextp()->castEnumItem()) { puts(itemp->name()); puts(" = "); itemp->valuep()->iterateAndNext(*this); if (nodep->nextp()) puts(","); puts("\n"); } puts("};\n"); } } } } } } // VISITORS virtual void visit(AstNodeAssign* nodep, AstNUser*) { bool paren = true; bool decind = false; if (AstSel* selp=nodep->lhsp()->castSel()) { if (selp->widthMin()==1) { putbs("VL_ASSIGNBIT_"); emitIQW(selp->fromp()); if (nodep->rhsp()->isAllOnesV()) { puts("O("); } else { puts("I("); } puts(cvtToStr(nodep->widthMin())+","); selp->lsbp()->iterateAndNext(*this); puts(", "); selp->fromp()->iterateAndNext(*this); puts(", "); } else { putbs("VL_ASSIGNSEL_"); emitIQW (selp->fromp()); puts("II"); emitIQW(nodep->rhsp()); puts("("); puts(cvtToStr(nodep->widthMin())+","); selp->lsbp()->iterateAndNext(*this); puts(", "); selp->fromp()->iterateAndNext(*this); puts(", "); } } else if (AstVar* varp = AstVar::scVarRecurse(nodep->lhsp())) { putbs("VL_ASSIGN_"); // Set a systemC variable emitScIQW(varp); emitIQW(nodep); puts("("); puts(cvtToStr(nodep->widthMin())+","); nodep->lhsp()->iterateAndNext(*this); puts(", "); } else if (AstVar* varp = AstVar::scVarRecurse(nodep->rhsp())) { putbs("VL_ASSIGN_"); // Get a systemC variable emitIQW(nodep); emitScIQW(varp); puts("("); puts(cvtToStr(nodep->widthMin())+","); nodep->lhsp()->iterateAndNext(*this); puts(", "); } else if (nodep->isWide() && nodep->lhsp()->castVarRef() && !nodep->rhsp()->castCMath() && !nodep->rhsp()->castVarRef() && !nodep->rhsp()->castArraySel()) { // Wide functions assign into the array directly, don't need separate assign statement m_wideTempRefp = nodep->lhsp()->castVarRef(); paren = false; } else if (nodep->isWide()) { putbs("VL_ASSIGN_W("); puts(cvtToStr(nodep->widthMin())+","); nodep->lhsp()->iterateAndNext(*this); puts(", "); } else { paren = false; nodep->lhsp()->iterateAndNext(*this); puts(" "); ofp()->blockInc(); decind = true; if (!nodep->rhsp()->castConst()) ofp()->putBreak(); puts("= "); } nodep->rhsp()->iterateAndNext(*this); if (paren) puts(")"); if (decind) ofp()->blockDec(); if (!m_suppressSemi) puts(";\n"); } virtual void visit(AstAlwaysPublic*, AstNUser*) { } virtual void visit(AstCCall* nodep, AstNUser*) { puts(nodep->hiername()); puts(nodep->funcp()->name()); puts("("); puts(nodep->argTypes()); bool comma = (nodep->argTypes() != ""); for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) { if (comma) puts(", "); subnodep->accept(*this); comma = true; } if (nodep->backp()->castNodeMath() || nodep->backp()->castCReturn()) { // We should have a separate CCall for math and statement usage, but... puts(")"); } else { puts(");\n"); } } virtual void visit(AstNodeCase* nodep, AstNUser*) { // In V3Case... nodep->v3fatalSrc("Case statements should have been reduced out\n"); } virtual void visit(AstComment* nodep, AstNUser*) { puts((string)"// "+nodep->name()+" at "+nodep->fileline()->ascii()+"\n"); nodep->iterateChildren(*this); } virtual void visit(AstCoverDecl* nodep, AstNUser*) { puts("__vlCoverInsert("); // As Declared in emitCoverageDecl puts("&(vlSymsp->__Vcoverage["); puts(cvtToStr(nodep->dataDeclThisp()->binNum())); puts("])"); // If this isn't the first instantiation of this module under this // design, don't really count the bucket, and rely on verilator_cov to // aggregate counts. This is because Verilator combines all // hiearchies itself, and if verilator_cov also did it, you'd end up // with (number-of-instant) times too many counts in this bin. puts(", first"); // Enable, passed from __Vconfigure parameter puts(", "); putsQuoted(nodep->fileline()->filename()); puts(", "); puts(cvtToStr(nodep->fileline()->lineno())); puts(", "); puts(cvtToStr(nodep->column())); puts(", "); putsQuoted((nodep->hier()!=""?".":"")+nodep->hier()); puts(", "); putsQuoted(nodep->page()); puts(", "); putsQuoted(nodep->comment()); puts(");\n"); } virtual void visit(AstCoverInc* nodep, AstNUser*) { puts("++(vlSymsp->__Vcoverage["); puts(cvtToStr(nodep->declp()->dataDeclThisp()->binNum())); puts("]);\n"); } virtual void visit(AstCReturn* nodep, AstNUser*) { puts("return ("); nodep->lhsp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstDisplay* nodep, AstNUser*) { string text = nodep->fmtp()->text(); if (nodep->addNewline()) text += "\n"; displayNode(nodep, nodep->fmtp()->scopeNamep(), text, nodep->fmtp()->exprsp(), false); } virtual void visit(AstScopeName* nodep, AstNUser*) { // For use under AstCCalls for dpiImports. ScopeNames under displays are handled in AstDisplay if (!nodep->dpiExport()) { // this is where the DPI import context scope is set string scope = nodep->scopeDpiName(); putbs("(&(vlSymsp->__Vscope_"+scope+"))"); } } virtual void visit(AstSFormat* nodep, AstNUser*) { displayNode(nodep, nodep->fmtp()->scopeNamep(), nodep->fmtp()->text(), nodep->fmtp()->exprsp(), false); } virtual void visit(AstSFormatF* nodep, AstNUser*) { displayNode(nodep, nodep->scopeNamep(), nodep->text(), nodep->exprsp(), false); } virtual void visit(AstFScanF* nodep, AstNUser*) { displayNode(nodep, NULL, nodep->text(), nodep->exprsp(), true); } virtual void visit(AstSScanF* nodep, AstNUser*) { displayNode(nodep, NULL, nodep->text(), nodep->exprsp(), true); } virtual void visit(AstValuePlusArgs* nodep, AstNUser*) { string prefix; char format = '?'; bool pct=false; int got=0; string txt = nodep->text(); for (string::const_iterator it=txt.begin(); it!=txt.end(); ++it) { char ch = *it; if (pct) { pct = false; switch (tolower(ch)) { case '%': prefix += ch; break; case 'd': // FALLTHRU case 'o': // FALLTHRU case 'h': // FALLTHRU case 'x': // FALLTHRU case 'b': // FALLTHRU case 's': got++; format = tolower(ch); break; case 'e': // FALLTHRU case 'f': // FALLTHRU case 'g': got++; format = tolower(ch); nodep->v3error("Unsupported $value$plusargs format qualifier: '"<v3error("Illegal $value$plusargs format qualifier: '"<v3error("Missing or extra $value$plusargs format qualifier: '"<text()<<"'"<exprsp()); puts("("); puts(cvtToStr(nodep->exprsp()->widthMin())); // Note argument width, not node width (which is always 32) putbs(","); putsQuoted(prefix); putbs(","); puts("'"); puts(cvtToStr(format)); puts("'"); puts(","); nodep->exprsp()->iterateAndNext(*this); puts(")"); } virtual void visit(AstTestPlusArgs* nodep, AstNUser*) { puts("VL_TESTPLUSARGS_I("); putsQuoted(nodep->text()); puts(")"); } virtual void visit(AstFGetS* nodep, AstNUser*) { checkMaxWords(nodep); emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), NULL); } void checkMaxWords(AstNode* nodep) { if (nodep->widthWords() > VL_TO_STRING_MAX_WORDS) { nodep->v3error("String of "<width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h"); } } virtual void visit(AstFOpen* nodep, AstNUser*) { nodep->filep()->iterateAndNext(*this); puts(" = VL_FOPEN_"); emitIQW(nodep->filenamep()); emitIQW(nodep->modep()); if (nodep->modep()->width()>4*8) nodep->modep()->v3error("$fopen mode should be <= 4 characters"); puts("("); if (nodep->filenamep()->isWide()) { puts(cvtToStr(nodep->filenamep()->widthWords())); putbs(", "); } checkMaxWords(nodep->filenamep()); nodep->filenamep()->iterateAndNext(*this); putbs(", "); nodep->modep()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstReadMem* nodep, AstNUser*) { puts("VL_READMEM_"); emitIQW(nodep->filenamep()); puts(" ("); // We take a void* rather than emitIQW(nodep->memp()); puts(nodep->isHex()?"true":"false"); putbs(","); puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width putbs(","); uint32_t array_lsb = 0; { AstVarRef* varrefp = nodep->memp()->castVarRef(); if (!varrefp) { nodep->v3error("Readmem loading non-variable"); } else if (AstUnpackArrayDType* adtypep = varrefp->varp()->dtypeSkipRefp()->castUnpackArrayDType()) { puts(cvtToStr(varrefp->varp()->dtypep()->arrayUnpackedElements())); array_lsb = adtypep->lsb(); } else { nodep->v3error("Readmem loading other than unpacked-array variable"); } } putbs(", "); puts(cvtToStr(array_lsb)); putbs(","); puts(cvtToStr(nodep->filenamep()->widthWords())); checkMaxWords(nodep->filenamep()); putbs(", "); nodep->filenamep()->iterateAndNext(*this); putbs(", "); nodep->memp()->iterateAndNext(*this); putbs(","); if (nodep->lsbp()) { nodep->lsbp()->iterateAndNext(*this); } else puts(cvtToStr(array_lsb)); putbs(","); if (nodep->msbp()) { nodep->msbp()->iterateAndNext(*this); } else puts("~0"); puts(");\n"); } virtual void visit(AstFClose* nodep, AstNUser*) { puts("VL_FCLOSE_I("); nodep->filep()->iterateAndNext(*this); puts("); "); nodep->filep()->iterateAndNext(*this); // For saftey, so user doesn't later WRITE with it. puts("=0;\n"); } virtual void visit(AstFFlush* nodep, AstNUser*) { if (!nodep->filep()) { puts("fflush (stdout);\n"); } else { puts("if ("); nodep->filep()->iterateAndNext(*this); puts(") { fflush (VL_CVT_I_FP("); nodep->filep()->iterateAndNext(*this); puts(")); }\n"); } } virtual void visit(AstSystemT* nodep, AstNUser*) { puts("(void)VL_SYSTEM_I"); emitIQW(nodep->lhsp()); puts("("); if (nodep->lhsp()->isWide()) { puts(cvtToStr(nodep->lhsp()->widthWords())); putbs(", "); } checkMaxWords(nodep->lhsp()); nodep->lhsp()->iterateAndNext(*this); puts(");\n"); } virtual void visit(AstSystemF* nodep, AstNUser*) { puts("VL_SYSTEM_I"); emitIQW(nodep->lhsp()); puts("("); if (nodep->lhsp()->isWide()) { puts(cvtToStr(nodep->lhsp()->widthWords())); putbs(", "); } checkMaxWords(nodep->lhsp()); nodep->lhsp()->iterateAndNext(*this); puts(")"); } virtual void visit(AstJumpGo* nodep, AstNUser*) { puts("goto __Vlabel"+cvtToStr(nodep->labelp()->labelNum())+";\n"); } virtual void visit(AstJumpLabel* nodep, AstNUser*) { puts("{\n"); nodep->stmtsp()->iterateAndNext(*this); puts("}\n"); puts("__Vlabel"+cvtToStr(nodep->labelNum())+": ;\n"); } virtual void visit(AstWhile* nodep, AstNUser*) { nodep->precondsp()->iterateAndNext(*this); puts("while ("); nodep->condp()->iterateAndNext(*this); puts(") {\n"); nodep->bodysp()->iterateAndNext(*this); nodep->incsp()->iterateAndNext(*this); nodep->precondsp()->iterateAndNext(*this); // Need to recompute before next loop puts("}\n"); } virtual void visit(AstNodeIf* nodep, AstNUser*) { puts("if ("); if (nodep->branchPred() != AstBranchPred::BP_UNKNOWN) { puts(nodep->branchPred().ascii()); puts("("); } nodep->condp()->iterateAndNext(*this); if (nodep->branchPred() != AstBranchPred::BP_UNKNOWN) puts(")"); puts(") {\n"); nodep->ifsp()->iterateAndNext(*this); if (nodep->elsesp()) { puts("} else {\n"); nodep->elsesp()->iterateAndNext(*this); } puts("}\n"); } virtual void visit(AstStop* nodep, AstNUser*) { puts("vl_stop("); putsQuoted(nodep->fileline()->filename()); puts(","); puts(cvtToStr(nodep->fileline()->lineno())); puts(",\"\");\n"); } virtual void visit(AstFinish* nodep, AstNUser*) { puts("vl_finish("); putsQuoted(nodep->fileline()->filename()); puts(","); puts(cvtToStr(nodep->fileline()->lineno())); puts(",\"\");\n"); } virtual void visit(AstText* nodep, AstNUser*) { if (nodep->tracking()) { puts(nodep->text()); } else { ofp()->putsNoTracking(nodep->text()); } } virtual void visit(AstCStmt* nodep, AstNUser*) { putbs(""); nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstCMath* nodep, AstNUser*) { putbs(""); nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstUCStmt* nodep, AstNUser*) { puts("// $c statement at "+nodep->fileline()->ascii()+"\n"); nodep->bodysp()->iterateAndNext(*this); puts("\n"); } virtual void visit(AstUCFunc* nodep, AstNUser*) { puts("\n"); puts("// $c function at "+nodep->fileline()->ascii()+"\n"); nodep->bodysp()->iterateAndNext(*this); puts("\n"); } // Operators virtual void visit(AstNodeTermop* nodep, AstNUser*) { emitOpName(nodep, nodep->emitC(), NULL, NULL, NULL); } virtual void visit(AstNodeUniop* nodep, AstNUser*) { if (emitSimpleOk(nodep)) { putbs("("); puts(nodep->emitSimpleOperator()); puts(" "); nodep->lhsp()->iterateAndNext(*this); puts(")"); } else { emitOpName(nodep, nodep->emitC(), nodep->lhsp(), NULL, NULL); } } virtual void visit(AstNodeBiop* nodep, AstNUser*) { if (emitSimpleOk(nodep)) { putbs("("); nodep->lhsp()->iterateAndNext(*this); puts(" "); putbs(nodep->emitSimpleOperator()); puts(" "); nodep->rhsp()->iterateAndNext(*this); puts(")"); } else { emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), NULL); } } virtual void visit(AstRedXor* nodep, AstNUser* vup) { if (nodep->lhsp()->isWide()) { visit(nodep->castNodeUniop(), vup); } else { putbs("VL_REDXOR_"); puts(cvtToStr(nodep->lhsp()->dtypep()->widthPow2())); puts("("); nodep->lhsp()->iterateAndNext(*this); puts(")"); } } virtual void visit(AstMulS* nodep, AstNUser* vup) { if (nodep->widthWords() > VL_MULS_MAX_WORDS) { nodep->v3error("Unsupported: Signed multiply of "<width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h"); } visit(nodep->castNodeBiop(), vup); } virtual void visit(AstCCast* nodep, AstNUser*) { // Extending a value of the same word width is just a NOP. if (nodep->size()>VL_WORDSIZE) { puts("(QData)("); } else { puts("(IData)("); } nodep->lhsp()->iterateAndNext(*this); puts(")"); } virtual void visit(AstNodeCond* nodep, AstNUser*) { // Widths match up already, so we'll just use C++'s operator w/o any temps. if (nodep->expr1p()->isWide()) { emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->expr1p(), nodep->expr2p()); } else { putbs("("); nodep->condp()->iterateAndNext(*this); putbs(" ? "); nodep->expr1p()->iterateAndNext(*this); putbs(" : "); nodep->expr2p()->iterateAndNext(*this); puts(")"); } } virtual void visit(AstSel* nodep, AstNUser*) { // Note ASSIGN checks for this on a LHS emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->thsp()); } virtual void visit(AstReplicate* nodep, AstNUser*) { if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) { if (((int)nodep->rhsp()->castConst()->toUInt() * nodep->lhsp()->widthMin()) != nodep->widthMin()) nodep->v3fatalSrc("Replicate non-constant or width miscomputed"); puts("VL_REPLICATE_"); emitIQW(nodep); puts("OI("); puts(cvtToStr(nodep->widthMin())); if (nodep->lhsp()) { puts(","+cvtToStr(nodep->lhsp()->widthMin())); } if (nodep->rhsp()) { puts(","+cvtToStr(nodep->rhsp()->widthMin())); } puts(","); nodep->lhsp()->iterateAndNext(*this); puts(", "); nodep->rhsp()->iterateAndNext(*this); puts(")"); } else { emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), NULL); } } virtual void visit(AstStreamL* nodep, AstNUser*) { // Attempt to use a "fast" stream function for slice size = power of 2 if (!nodep->isWide()) { uint32_t isPow2 = nodep->rhsp()->castConst()->num().countOnes() == 1; uint32_t sliceSize = nodep->rhsp()->castConst()->toUInt(); if (isPow2 && sliceSize <= (nodep->isQuad() ? sizeof(uint64_t) : sizeof(uint32_t))) { puts("VL_STREAML_FAST_"); emitIQW(nodep); emitIQW(nodep->lhsp()); puts("I("); puts(cvtToStr(nodep->widthMin())); puts(","+cvtToStr(nodep->lhsp()->widthMin())); puts(","+cvtToStr(nodep->rhsp()->widthMin())); puts(","); nodep->lhsp()->iterateAndNext(*this); puts(", "); uint32_t rd_log2 = V3Number::log2b(nodep->rhsp()->castConst()->toUInt()); puts(cvtToStr(rd_log2)+")"); return; } } emitOpName(nodep, "VL_STREAML_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)", nodep->lhsp(), nodep->rhsp(), NULL); } // Terminals virtual void visit(AstVarRef* nodep, AstNUser*) { puts(nodep->hiername()); puts(nodep->varp()->name()); } void emitConstant(AstConst* nodep, AstVarRef* assigntop, const string& assignString) { // Put out constant set to the specified variable, or given variable in a string if (nodep->num().isFourState()) { nodep->v3error("Unsupported: 4-state numbers in this context"); } else if (nodep->num().isString()) { putbs("string("); putsQuoted(nodep->num().toString()); puts(")"); } else if (nodep->isWide()) { putbs("VL_CONST_W_"); puts(cvtToStr(VL_WORDS_I(nodep->num().widthMin()))); puts("X("); puts(cvtToStr(nodep->widthMin())); puts(","); if (!assigntop) { puts(assignString); } else if (assigntop->castVarRef()) { puts(assigntop->hiername()); puts(assigntop->varp()->name()); } else { assigntop->iterateAndNext(*this); } for (int word=VL_WORDS_I(nodep->num().widthMin())-1; word>0; word--) { // Only 32 bits - llx + long long here just to appease CPP format warning ofp()->printf(",0x%08" VL_PRI64 "x", (vluint64_t)(nodep->num().dataWord(word))); } ofp()->printf(",0x%08" VL_PRI64 "x)", (vluint64_t)(nodep->num().dataWord(0))); } else if (nodep->isDouble()) { if (int(nodep->num().toDouble()) == nodep->num().toDouble() && nodep->num().toDouble() < 1000 && nodep->num().toDouble() > -1000) { ofp()->printf("%3.1f", nodep->num().toDouble()); // Force decimal point } else { // Not %g as will not always put in decimal point, so not obvious to compiler // is a real number ofp()->printf("%.17e", nodep->num().toDouble()); } } else if (nodep->isQuad()) { vluint64_t num = nodep->toUQuad(); if (num<10) ofp()->printf("VL_ULL(%" VL_PRI64 "d)", num); else ofp()->printf("VL_ULL(0x%" VL_PRI64 "x)", num); } else { uint32_t num = nodep->toUInt(); // Only 32 bits - llx + long long here just to appease CPP format warning if (num<10) puts(cvtToStr(num)); else ofp()->printf("0x%" VL_PRI64 "x", (vluint64_t)num); // If signed, we'll do our own functions // But must be here, or <= comparisons etc may end up signed puts("U"); } } void emitSetVarConstant(const string& assignString, AstConst* constp) { if (!constp->isWide()) { puts(assignString); puts(" = "); } emitConstant(constp, NULL, assignString); puts(";\n"); } virtual void visit(AstConst* nodep, AstNUser*) { if (nodep->isWide()) { if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Constant w/ no temp"); emitConstant(nodep, m_wideTempRefp, ""); m_wideTempRefp = NULL; // We used it, barf if set it a second time } else { emitConstant(nodep, NULL, ""); } } // Just iterate virtual void visit(AstNetlist* nodep, AstNUser*) { nodep->iterateChildren(*this); } virtual void visit(AstTopScope* nodep, AstNUser*) { nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep, AstNUser*) { nodep->iterateChildren(*this); } // NOPs virtual void visit(AstTypedef*, AstNUser*) {} virtual void visit(AstPragma*, AstNUser*) {} virtual void visit(AstCell*, AstNUser*) {} // Handled outside the Visit class virtual void visit(AstVar*, AstNUser*) {} // Handled outside the Visit class virtual void visit(AstNodeText*, AstNUser*) {} // Handled outside the Visit class virtual void visit(AstTraceDecl*, AstNUser*) {} // Handled outside the Visit class virtual void visit(AstTraceInc*, AstNUser*) {} // Handled outside the Visit class virtual void visit(AstCFile*, AstNUser*) {} // Handled outside the Visit class // Default virtual void visit(AstNode* nodep, AstNUser*) { puts((string)"\n???? // "+nodep->prettyTypeName()+"\n"); nodep->iterateChildren(*this); nodep->v3fatalSrc("Unknown node type reached emitter: "<prettyTypeName()); } public: EmitCStmts() { m_suppressSemi = false; m_wideTempRefp = NULL; m_splitSize = 0; m_splitFilenum = 0; } virtual ~EmitCStmts() {} }; //###################################################################### // Internal EmitC implementation class EmitCImp : EmitCStmts { // MEMBERS AstNodeModule* m_modp; vector m_blkChangeDetVec; // All encountered changes in block bool m_slow; // Creating __Slow file bool m_fast; // Creating non __Slow file (or both) //--------------------------------------- // METHODS void doubleOrDetect(AstChangeDet* changep, bool& gotOne) { if (!changep->rhsp()) { if (!gotOne) gotOne = true; else puts(" | "); changep->lhsp()->iterateAndNext(*this); } else { AstNode* lhsp = changep->lhsp(); AstNode* rhsp = changep->rhsp(); static int addDoubleOr = 10; // Determined experimentally as best if (!lhsp->castVarRef() && !lhsp->castArraySel()) changep->v3fatalSrc("Not ref?"); if (!rhsp->castVarRef() && !rhsp->castArraySel()) changep->v3fatalSrc("Not ref?"); for (int word=0; wordlhsp()->widthWords(); word++) { if (!gotOne) { gotOne = true; addDoubleOr = 10; // Determined experimentally as best puts("("); } else if (--addDoubleOr == 0) { puts("|| ("); addDoubleOr = 10; } else { puts(" | ("); } changep->lhsp()->iterateAndNext(*this); if (changep->lhsp()->isWide()) puts("["+cvtToStr(word)+"]"); if (changep->lhsp()->isDouble()) puts(" != "); else puts(" ^ "); changep->rhsp()->iterateAndNext(*this); if (changep->lhsp()->isWide()) puts("["+cvtToStr(word)+"]"); puts(")"); } } } V3OutCFile* newOutCFile(AstNodeModule* modp, bool slow, bool source, int filenum=0) { string filenameNoExt = v3Global.opt.makeDir()+"/"+ modClassName(modp); if (filenum) filenameNoExt += "__"+cvtToStr(filenum); filenameNoExt += (slow ? "__Slow":""); V3OutCFile* ofp = NULL; if (v3Global.opt.lintOnly()) { // Unfortunately we have some lint checks here, so we can't just skip processing. // We should move them to a different stage. string filename = VL_DEV_NULL; newCFile(filename, slow, source); ofp = new V3OutSpFile (filename); } else if (optSystemPerl()) { string filename = filenameNoExt+".sp"; newCFile(filename, slow, source); ofp = new V3OutSpFile (filename); } else if (optSystemC()) { string filename = filenameNoExt+(source?".cpp":".h"); newCFile(filename, slow, source); ofp = new V3OutScFile (filename); } else { string filename = filenameNoExt+(source?".cpp":".h"); newCFile(filename, slow, source); ofp = new V3OutCFile (filename); } ofp->putsHeader(); if (modp->isTop() && !source) { ofp->puts("// DESCR" "IPTION: Verilator output: Primary design header\n"); ofp->puts("//\n"); ofp->puts("// This header should be included by all source files instantiating the design.\n"); ofp->puts("// The class here is then constructed to instantiate the design.\n"); ofp->puts("// See the Verilator manual for examples.\n"); } else { if (source) { ofp->puts("// DESCR" "IPTION: Verilator output: Design implementation internals\n"); } else { ofp->puts("// DESCR" "IPTION: Verilator output: Design internal header\n"); } ofp->puts("// See "+v3Global.opt.prefix()+".h for the primary calling header\n"); } ofp->puts("\n"); return ofp; } //--------------------------------------- // VISITORS using EmitCStmts::visit; // Suppress hidden overloaded virtual function warnng virtual void visit(AstCFunc* nodep, AstNUser*) { // TRACE_* and DPI handled elsewhere if (nodep->funcType().isTrace()) return; if (nodep->dpiImport()) return; if (!(nodep->slow() ? m_slow : m_fast)) return; m_blkChangeDetVec.clear(); splitSizeInc(nodep); puts("\n"); if (nodep->isInline()) puts("VL_INLINE_OPT "); puts(nodep->rtnTypeVoid()); puts(" "); puts(modClassName(m_modp)+"::"+nodep->name() +"("+cFuncArgs(nodep)+") {\n"); puts("VL_DEBUG_IF(VL_PRINTF(\" "); for (int i=0;ilevel();i++) { puts(" "); } puts(modClassName(m_modp)+"::"+nodep->name() +"\\n\"); );\n"); if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n"); if (nodep->initsp()) puts("// Variables\n"); ofp()->putAlign(V3OutFile::AL_AUTO, 4); for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) { if (AstVar* varp=subnodep->castVar()) { if (varp->isFuncReturn()) emitVarDecl(varp, ""); } } emitVarList(nodep->initsp(), EVL_ALL, ""); ofp()->putAlign(V3OutFile::AL_AUTO, 4); emitVarList(nodep->stmtsp(), EVL_ALL, ""); ofp()->putAlign(V3OutFile::AL_AUTO, 4); nodep->initsp()->iterateAndNext(*this); if (nodep->stmtsp()) puts("// Body\n"); nodep->stmtsp()->iterateAndNext(*this); if (!m_blkChangeDetVec.empty()) emitChangeDet(); if (nodep->finalsp()) puts("// Final\n"); nodep->finalsp()->iterateAndNext(*this); // if (!m_blkChangeDetVec.empty()) puts("return __req;\n"); //puts("__Vm_activity = true;\n"); puts("}\n"); } void emitChangeDet() { puts("// Change detection\n"); puts("QData __req = false; // Logically a bool\n"); // But not because it results in faster code bool gotOne = false; for (vector::iterator it = m_blkChangeDetVec.begin(); it != m_blkChangeDetVec.end(); ++it) { AstChangeDet* changep = *it; if (changep->lhsp()) { if (!gotOne) { // Not a clocked block puts("__req |= ("); } else puts("\n"); doubleOrDetect(changep, gotOne); } } if (gotOne) { puts(");\n"); //puts("VL_DEBUG_IF( if (__req) cout<<\"\tCLOCKREQ );"); for (vector::iterator it = m_blkChangeDetVec.begin(); it != m_blkChangeDetVec.end(); ++it) { AstChangeDet* nodep = *it; if (nodep->lhsp()) { puts("VL_DEBUG_IF( if(__req && ("); bool gotOneIgnore = false; doubleOrDetect(nodep, gotOneIgnore); string varname; if (nodep->lhsp()->castVarRef()) { varname = ": "+nodep->lhsp()->castVarRef()->varp()->prettyName(); } puts(")) VL_PRINTF(\"\tCHANGE: "+nodep->fileline()->ascii() +varname+"\\n\"); );\n"); } } } } virtual void visit(AstChangeDet* nodep, AstNUser*) { m_blkChangeDetVec.push_back(nodep); } //--------------------------------------- // ACCESSORS // METHODS // Low level void emitVarResets(AstNodeModule* modp); void emitCellCtors(AstNodeModule* modp); void emitSensitives(); // Medium level void emitCtorImp(AstNodeModule* modp); void emitConfigureImp(AstNodeModule* modp); void emitCoverageDecl(AstNodeModule* modp); void emitCoverageImp(AstNodeModule* modp); void emitDestructorImp(AstNodeModule* modp); void emitSavableImp(AstNodeModule* modp); void emitTextSection(AstType type); void emitIntFuncDecls(AstNodeModule* modp); // High level void emitImp(AstNodeModule* modp); void emitStaticDecl(AstNodeModule* modp); void emitWrapEval(AstNodeModule* modp); void emitInt(AstNodeModule* modp); void writeMakefile(string filename); public: EmitCImp() { m_modp = NULL; m_slow = false; m_fast = false; } virtual ~EmitCImp() {} void main(AstNodeModule* modp, bool slow, bool fast); void mainDoFunc(AstCFunc* nodep) { nodep->accept(*this); } }; //###################################################################### // Internal EmitCStmts void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) { AstBasicDType* basicp = nodep->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type"); if (nodep->isIO()) { if (nodep->isSc()) { m_ctorVarsVec.push_back(nodep); ofp()->putAlign(nodep->isStatic(), 4); // sc stuff is a structure, so bigger alignment if (nodep->attrScClocked() && nodep->isInput()) { puts("sc_in_clk\t"); } else { if (nodep->isInout()) puts("sc_inout<"); else if (nodep->isInput()) puts("sc_in<"); else if (nodep->isOutput()) puts("sc_out<"); else nodep->v3fatalSrc("Unknown type"); puts(nodep->scType()); puts(">\t"); } puts(nodep->name()); emitDeclArrayBrackets(nodep); puts(";\n"); } else if (basicp && basicp->isOpaque()) { // strings and other fundamental c types; no VL_ macro can be used puts(nodep->vlArgType(true,false,false)); emitDeclArrayBrackets(nodep); puts(";\n"); } else { // C++ signals ofp()->putAlign(nodep->isStatic(), nodep->dtypeSkipRefp()->widthAlignBytes(), nodep->dtypeSkipRefp()->widthTotalBytes()); if (nodep->isInout()) puts("VL_INOUT"); else if (nodep->isInput()) puts("VL_IN"); else if (nodep->isOutput()) puts("VL_OUT"); else nodep->v3fatalSrc("Unknown type"); if (nodep->isQuad()) puts("64"); else if (nodep->widthMin() <= 8) puts("8"); else if (nodep->widthMin() <= 16) puts("16"); else if (nodep->isWide()) puts("W"); puts("("+nodep->name()); emitDeclArrayBrackets(nodep); // If it's a packed struct/array then nodep->width is the whole thing, msb/lsb is just lowest dimension puts(","+cvtToStr(basicp->lsb()+nodep->width()-1) +","+cvtToStr(basicp->lsb())); if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords())); puts(");\n"); } } else if (basicp && basicp->isOpaque()) { // strings and other fundamental c types puts(nodep->vlArgType(true,false,false)); emitDeclArrayBrackets(nodep); puts(";\n"); } else { // Arrays need a small alignment, but may need different padding after. // For example three VL_SIG8's needs alignment 1 but size 3. ofp()->putAlign(nodep->isStatic(), nodep->dtypeSkipRefp()->widthAlignBytes(), nodep->dtypeSkipRefp()->widthTotalBytes()); if (nodep->isStatic() && prefixIfImp=="") puts("static "); if (nodep->isStatic()) puts("VL_ST_"); else puts("VL_"); if (nodep->widthMin() <= 8) { puts("SIG8("); } else if (nodep->widthMin() <= 16) { puts("SIG16("); } else if (nodep->isQuad()) { puts("SIG64("); } else if (!nodep->isWide()) { puts("SIG("); } else { puts("SIGW("); } if (prefixIfImp!="") { puts(prefixIfImp); puts("::"); } puts(nodep->name()); emitDeclArrayBrackets(nodep); // If it's a packed struct/array then nodep->width is the whole thing, msb/lsb is just lowest dimension puts(","+cvtToStr(basicp->lsb()+nodep->width()-1) +","+cvtToStr(basicp->lsb())); if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords())); puts(");\n"); } } void EmitCStmts::emitVarCtors() { if (!m_ctorVarsVec.empty()) { ofp()->indentInc(); puts("\n"); puts("#if (SYSTEMC_VERSION>20011000)\n"); // SystemC 2.0.1 and newer bool first = true; for (vector::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) { AstVar* varp = *it; bool isArray = !varp->dtypeSkipRefp()->castBasicDType(); if (isArray) { puts("// Skipping array: "); puts(varp->name()); puts("\n"); } else { if (first) { puts(" : "); first=false; } else puts(", "); if (ofp()->exceededWidth()) puts("\n "); puts(varp->name()); puts("("); putsQuoted(varp->name()); puts(")"); } } puts ("\n#endif\n"); ofp()->indentDec(); } } bool EmitCStmts::emitSimpleOk(AstNodeMath* nodep) { // Can we put out a simple (A + B) instead of VL_ADD_III(A,B)? if (nodep->emitSimpleOperator() == "") return false; if (nodep->isWide()) return false; if (nodep->op1p()) { if (nodep->op1p()->isWide()) return false; } if (nodep->op2p()) { if (nodep->op2p()->isWide()) return false; } if (nodep->op3p()) { if (nodep->op3p()->isWide()) return false; } return true; } void EmitCStmts::emitOpName(AstNode* nodep, const string& format, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) { // Look at emitOperator() format for term/uni/dual/triops, // and write out appropriate text. // %n* node // %nq emitIQW on the [node] // %nw width in bits // %nW width in words // %ni iterate // %l* lhsp - if appropriate, then second char as above // %r* rhsp - if appropriate, then second char as above // %t* thsp - if appropriate, then second char as above // %k Potential line break // %P Wide temporary name // , Commas suppressed if the previous field is suppressed string nextComma; bool needComma = false; #define COMMA { if (nextComma!="") { puts(nextComma); nextComma=""; } } putbs(""); for (string::const_iterator pos = format.begin(); pos != format.end(); ++pos) { if (pos[0]==',') { // Remember we need to add one, but don't do yet to avoid ",)" if (needComma) { if (pos[1]==' ') { nextComma=", "; } else nextComma = ","; needComma = false; } if (pos[1]==' ') { ++pos; } // Must do even if no nextComma } else if (pos[0]=='%') { ++pos; bool detail = false; AstNode* detailp = NULL; switch (pos[0]) { case '%': puts("%"); break; case 'k': putbs(""); break; case 'n': detail = true; detailp = nodep; break; case 'l': detail = true; detailp = lhsp; break; case 'r': detail = true; detailp = rhsp; break; case 't': detail = true; detailp = thsp; break; case 'P': if (nodep->isWide()) { if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Op w/ no temp, perhaps missing op in V3EmitC?"); COMMA; puts(m_wideTempRefp->hiername()); puts(m_wideTempRefp->varp()->name()); m_wideTempRefp = NULL; needComma = true; } break; default: nodep->v3fatalSrc("Unknown emitOperator format code: %"<widthMin())); needComma = true; break; case 'W': if (lhsp->isWide()) { COMMA; puts(cvtToStr(lhsp->widthWords())); needComma = true; } break; case 'i': COMMA; if (!detailp) { nodep->v3fatalSrc("emitOperator() references undef node"); } else detailp->iterateAndNext(*this); needComma = true; break; default: nodep->v3fatalSrc("Unknown emitOperator format code: %[nlrt]"< m_argsChar; // Format of each argument to be printed vector m_argsp; // Each argument to be printed vector m_argsFunc; // Function before each argument to be printed EmitDispState() { clear(); } void clear() { m_format = ""; m_argsChar.clear(); m_argsp.clear(); m_argsFunc.clear(); } void pushFormat(const string& fmt) { m_format += fmt; } void pushFormat(char fmt) { m_format += fmt; } void pushArg(char fmtChar, AstNode* nodep, const string& func) { m_argsChar.push_back(fmtChar); m_argsp.push_back(nodep); m_argsFunc.push_back(func); } } emitDispState; void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) { if (emitDispState.m_format == "" && nodep->castDisplay()) { // not fscanf etc, as they need to return value // NOP } else { // Format bool isStmt = false; if (AstFScanF* dispp = nodep->castFScanF()) { isStmt = false; puts("VL_FSCANF_IX("); dispp->filep()->iterate(*this); puts(","); } else if (AstSScanF* dispp = nodep->castSScanF()) { isStmt = false; checkMaxWords(dispp->fromp()); puts("VL_SSCANF_I"); emitIQW(dispp->fromp()); puts("X("); puts(cvtToStr(dispp->fromp()->widthMin())); puts(","); dispp->fromp()->iterate(*this); puts(","); } else if (AstDisplay* dispp = nodep->castDisplay()) { isStmt = true; if (dispp->filep()) { puts("VL_FWRITEF("); dispp->filep()->iterate(*this); puts(","); } else { puts("VL_WRITEF("); } } else if (AstSFormat* dispp = nodep->castSFormat()) { isStmt = true; puts("VL_SFORMAT_X("); puts(cvtToStr(dispp->lhsp()->widthMin())); putbs(","); dispp->lhsp()->iterate(*this); putbs(","); } else if (AstSFormatF* dispp = nodep->castSFormatF()) { isStmt = false; if (dispp) {} puts("VL_SFORMATF_NX("); } else { isStmt = true; nodep->v3fatalSrc("Unknown displayEmit node type"); } ofp()->putsQuoted(emitDispState.m_format); // Arguments for (unsigned i=0; i < emitDispState.m_argsp.size(); i++) { puts(","); char fmt = emitDispState.m_argsChar[i]; AstNode* argp = emitDispState.m_argsp[i]; string func = emitDispState.m_argsFunc[i]; ofp()->indentInc(); ofp()->putbs(""); if (func!="") puts(func); if (argp) { if (isScan) puts("&("); else if (fmt == '@') puts("&("); argp->iterate(*this); if (isScan) puts(")"); else if (fmt == '@') puts(")"); } ofp()->indentDec(); } // End puts(")"); if (isStmt) puts(";\n"); else puts(" "); // Prep for next emitDispState.clear(); } } void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, string vfmt, char fmtLetter) { // Print display argument, edits elistp AstNode* argp = *elistp; if (!argp) { // expectDisplay() checks this first, so internal error if found here dispp->v3error("Internal: Missing arguments for $display-like format"); return; } if (argp->widthMin() > VL_VALUE_STRING_MAX_WIDTH) { dispp->v3error("Exceeded limit of "+cvtToStr(VL_VALUE_STRING_MAX_WIDTH)+" bits for any $display-like arguments"); } if (argp && argp->isWide() && (fmtLetter=='d'||fmtLetter=='u')) { argp->v3error("Unsupported: "<verilogKwd()<<" of dec format of > 64 bit results (use hex format instead)"); } if (argp && argp->widthMin()>8 && fmtLetter=='c') { // Technically legal, but surely not what the user intended. argp->v3error(dispp->verilogKwd()<<" of char format of > 8 bit result"); } //string pfmt = "%"+displayFormat(argp, vfmt, fmtLetter)+fmtLetter; string pfmt; if ((fmtLetter=='u' || fmtLetter=='d' || fmtLetter=='t') && !isScan && vfmt == "") { // Size decimal output. Spec says leading spaces, not zeros double mantissabits = argp->widthMin() - ((fmtLetter=='d')?1:0); double maxval = pow(2.0, mantissabits); double dchars = log10(maxval)+1.0; if (fmtLetter=='d') dchars++; // space for sign int nchars = int(dchars); pfmt = string("%") + cvtToStr(nchars) + fmtLetter; } else { pfmt = string("%") + vfmt + fmtLetter; } emitDispState.pushFormat(pfmt); emitDispState.pushArg(' ',NULL,cvtToStr(argp->widthMin())); emitDispState.pushArg(fmtLetter,argp,""); // Next parameter *elistp = (*elistp)->nextp(); } void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, const string& vformat, AstNode* exprsp, bool isScan) { AstNode* elistp = exprsp; // Convert Verilog display to C printf formats // "%0t" becomes "%d" emitDispState.clear(); string vfmt = ""; string::const_iterator pos = vformat.begin(); bool inPct = false; for (; pos != vformat.end(); ++pos) { //UINFO(1,"Parse '"<<*pos<<"' IP"<v3fatalSrc("Display with %m but no AstScopeName"); string suffix = scopenamep->scopePrettyName(); if (suffix=="") emitDispState.pushFormat("%S"); else emitDispState.pushFormat("%N"); // Add a . when needed emitDispState.pushArg(' ',NULL, "vlSymsp->name()"); emitDispState.pushFormat(suffix); break; } case 'u': case 'z': case 'l': case 'v': nodep->v3error("Unsupported: $display-like format code: %"<v3error("Unknown $display-like format code: %"<v3error("Internal: Extra arguments for $display-like format"); } displayEmit(nodep, isScan); } //###################################################################### // Internal EmitC void EmitCImp::emitVarResets(AstNodeModule* modp) { puts("// Reset internal values\n"); if (modp->isTop()) { if (v3Global.opt.inhibitSim()) puts("__Vm_inhibitSim = false;\n"); puts("\n"); } puts("// Reset structure values\n"); for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstVar* varp = nodep->castVar()) { if (varp->isIO() && modp->isTop() && optSystemC()) { // System C top I/O doesn't need loading, as the lower level subinst code does it. } else if (varp->isParam()) { if (!varp->valuep()) nodep->v3fatalSrc("No init for a param?"); // If a simple CONST value we initialize it using an enum // If an ARRAYINIT we initialize it using an initial block similar to a signal //puts("// parameter "+varp->name()+" = "+varp->valuep()->name()+"\n"); } else if (AstInitArray* initarp = varp->valuep()->castInitArray()) { AstConst* constsp = initarp->initsp()->castConst(); if (AstUnpackArrayDType* arrayp = varp->dtypeSkipRefp()->castUnpackArrayDType()) { for (int i=0; ielementsConst(); i++) { if (!constsp) initarp->v3fatalSrc("Not enough values in array initalizement"); emitSetVarConstant(varp->name()+"["+cvtToStr(i)+"]", constsp); constsp = constsp->nextp()->castConst(); } } else { varp->v3fatalSrc("InitArray under non-arrayed var"); } } else if (varp->basicp() && varp->basicp()->keyword() == AstBasicDTypeKwd::STRING) { // Constructor deals with it } else { int vects = 0; // This isn't very robust and may need cleanup for other data types for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp; arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) { int vecnum = vects++; if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); string ivar = string("__Vi")+cvtToStr(vecnum); // MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";"); puts(" for (; "+ivar+"<"+cvtToStr(arrayp->elementsConst())); puts("; ++"+ivar+") {\n"); } bool zeroit = (varp->attrFileDescr() // Zero it out, so we don't core dump if never call $fopen || (varp->basicp() && varp->basicp()->isZeroInit()) || (varp->name().size()>=1 && varp->name()[0]=='_' && v3Global.opt.underlineZero())); if (varp->isWide()) { // DOCUMENT: We randomize everything. If the user wants a _var to be zero, // there should be a initial statement. (Different from verilator2.) if (zeroit) puts("VL_ZERO_RESET_W("); else puts("VL_RAND_RESET_W("); puts(cvtToStr(varp->widthMin())); puts(","); puts(varp->name()); for (int v=0; vname()); for (int v=0; visUsedClock())) { puts(" = 0;\n"); } else if (v3Global.opt.xInitialEdge() && (0 == varp->name().find("__Vclklast__"))) { puts(" = 1;\n"); } else { puts(" = VL_RAND_RESET_"); emitIQW(varp); puts("("); puts(cvtToStr(varp->widthMin())); puts(");\n"); } } for (int v=0; vputsPrivate(true); puts("// Coverage\n"); puts("void __vlCoverInsert(uint32_t* countp, bool enable, const char* filenamep, int lineno, int column,\n"); puts( "const char* hierp, const char* pagep, const char* commentp);\n"); } } void EmitCImp::emitCtorImp(AstNodeModule* modp) { puts("\n"); if (optSystemPerl() && modp->isTop()) { puts("SP_CTOR_IMP("+modClassName(modp)+")"); } else if (optSystemC() && modp->isTop()) { puts("VL_SC_CTOR_IMP("+modClassName(modp)+")"); } else { puts("VL_CTOR_IMP("+modClassName(modp)+")"); } emitVarCtors(); puts(" {\n"); emitCellCtors(modp); emitSensitives(); emitVarResets(modp); emitTextSection(AstType::atSCCTOR); if (optSystemPerl()) puts("SP_AUTO_CTOR;\n"); puts("}\n"); } void EmitCImp::emitConfigureImp(AstNodeModule* modp) { puts("\nvoid "+modClassName(modp)+"::__Vconfigure("+symClassName()+"* vlSymsp, bool first) {\n"); puts( "if (0 && first) {} // Prevent unused\n"); puts( "this->__VlSymsp = vlSymsp;\n"); // First, as later stuff needs it. bool first=true; for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (nodep->castCoverDecl()) { if (first) { first = false; puts("// Coverage Declarations\n"); } nodep->accept(*this); splitSizeInc(nodep); } } puts("}\n"); splitSizeInc(10); } void EmitCImp::emitCoverageImp(AstNodeModule* modp) { if (v3Global.opt.coverage() ) { puts("\n// Coverage\n"); // Rather than putting out VL_COVER_INSERT calls directly, we do it via this function // This gets around gcc slowness constructing all of the template arguments // SystemPerl 1.301 is much faster, but it's nice to remain back // compatible, and have a common wrapper. puts("void "+modClassName(m_modp)+"::__vlCoverInsert(uint32_t* countp, bool enable, const char* filenamep, int lineno, int column,\n"); puts( "const char* hierp, const char* pagep, const char* commentp) {\n"); puts( "static uint32_t fake_zero_count = 0;\n"); // static doesn't need save-restore as constant puts( "if (!enable) countp = &fake_zero_count;\n"); // Used for second++ instantiation of identical bin puts( "*countp = 0;\n"); puts( "VL_COVER_INSERT(countp,"); puts( " \"filename\",filenamep,"); puts( " \"lineno\",lineno,"); puts( " \"column\",column,\n"); //puts( "\"hier\",string(__VlSymsp->name())+hierp,"); // Need to move hier into scopes and back out if do this puts( "\"hier\",string(name())+hierp,"); puts( " \"page\",pagep,"); puts( " \"comment\",commentp);\n"); puts("}\n"); splitSizeInc(10); } } void EmitCImp::emitDestructorImp(AstNodeModule* modp) { puts("\n"); puts(modClassName(modp)+"::~"+modClassName(modp)+"() {\n"); emitTextSection(AstType::atSCDTOR); if (modp->isTop()) puts("delete __VlSymsp; __VlSymsp=NULL;\n"); puts("}\n"); splitSizeInc(10); } void EmitCImp::emitSavableImp(AstNodeModule* modp) { if (v3Global.opt.savable() ) { puts("\n// Savable\n"); for (int de=0; de<2; ++de) { string classname = de ? "VerilatedDeserialize" : "VerilatedSerialize"; string funcname = de ? "__Vdeserialize" : "__Vserialize"; string writeread = de ? "read" : "write"; string op = de ? ">>" : "<<"; puts("void "+modClassName(modp)+"::"+funcname+"("+classname+"& os) {\n"); // Place a computed checksum to insure proper structure save/restore formatting // OK if this hash includes some things we won't dump, since just looking for loading the wrong model VHashFnv hash; for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstVar* varp = nodep->castVar()) { hash.hash(varp->name()); hash.hash(varp->dtypep()->width()); } } ofp()->printf( "vluint64_t __Vcheckval = VL_ULL(0x%" VL_PRI64 "x);\n", hash.value()); if (de) { puts("os.readAssert(__Vcheckval);\n"); } else { puts("os<<__Vcheckval;\n"); } // Save all members if (v3Global.opt.inhibitSim()) puts("os"+op+"__Vm_inhibitSim;\n"); for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstVar* varp = nodep->castVar()) { if (varp->isIO() && modp->isTop() && optSystemC()) { // System C top I/O doesn't need loading, as the lower level subinst code does it. } else if (varp->isParam()) {} else if (varp->isStatic() && varp->isConst()) {} else { int vects = 0; // This isn't very robust and may need cleanup for other data types for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp; arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) { int vecnum = vects++; if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); string ivar = string("__Vi")+cvtToStr(vecnum); // MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(0)+";"); puts(" for (; "+ivar+"<"+cvtToStr(arrayp->elementsConst())); puts("; ++"+ivar+") {\n"); } if (varp->basicp() && (varp->basicp()->keyword() == AstBasicDTypeKwd::STRING || !varp->basicp()->isWide())) { puts("os"+op+varp->name()); for (int v=0; vname()); for (int v=0; vname()); for (int v=0; visTop()) { // Save the children puts( "__VlSymsp->"+funcname+"(os);\n"); } puts("}\n"); } } } void EmitCImp::emitStaticDecl(AstNodeModule* modp) { // Need implementation here. Be careful of alignment code; needs to be uniquified // with module name to avoid multiple symbols. //emitVarList(modp->stmtsp(), EVL_ALL, modp->name()); puts(""); // NOP for cppcheck, otherwise const function } void EmitCImp::emitTextSection(AstType type) { int last_line = -999; for (AstNode* nodep = m_modp->stmtsp(); nodep != NULL; nodep = nodep->nextp()) { if (AstNodeText* textp = nodep->castNodeText()) { if (nodep->type() == type) { if (last_line != nodep->fileline()->lineno()) { if (last_line < 0) { puts("\n//*** Below code from `systemc in Verilog file\n"); } ofp()->putsNoTracking("//#line "+cvtToStr(nodep->fileline()->lineno()) +" "); ofp()->putsQuoted(nodep->fileline()->filename()); ofp()->putsNoTracking("\n"); last_line = nodep->fileline()->lineno(); } ofp()->putsNoTracking(textp->text()); last_line++; } } } if (last_line > 0) { puts("//*** Above code from `systemc in Verilog file\n\n"); } } void EmitCImp::emitCellCtors(AstNodeModule* modp) { if (modp->isTop()) { // Must be before other constructors, as __vlCoverInsert calls it puts(EmitCBaseVisitor::symClassVar()+" = __VlSymsp = new "+symClassName()+"(this, name());\n"); puts(EmitCBaseVisitor::symTopAssign()+"\n"); } for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstCell* cellp=nodep->castCell()) { puts("VL_CELL ("+cellp->name()+", "+modClassName(cellp->modp())+");\n"); } } } void EmitCImp::emitSensitives() { // Create sensitivity list for when to evaluate the model. // If C++ code, the user must call this routine themself. if (m_modp->isTop() && optSystemC()) { puts("// Sensitivities on all clocks and combo inputs\n"); puts("SC_METHOD(eval);\n"); for (AstNode* nodep=m_modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstVar* varp = nodep->castVar()) { if (varp->isInput() && (varp->isScSensitive() || varp->isUsedClock())) { int vects = 0; // This isn't very robust and may need cleanup for other data types for (AstUnpackArrayDType* arrayp=varp->dtypeSkipRefp()->castUnpackArrayDType(); arrayp; arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) { int vecnum = vects++; if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); string ivar = string("__Vi")+cvtToStr(vecnum); // MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(arrayp->lsb())+";"); puts(" for (; "+ivar+"<="+cvtToStr(arrayp->msb())); puts("; ++"+ivar+") {\n"); } puts("sensitive << "+varp->name()); for (int v=0; v__VlSymsp; // Setup global symbol table\n"); puts(EmitCBaseVisitor::symTopAssign()+"\n"); puts("// Initialize\n"); puts("if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) _eval_initial_loop(vlSymsp);\n"); if (v3Global.opt.inhibitSim()) { puts("if (VL_UNLIKELY(__Vm_inhibitSim)) return;\n"); } puts("// Evaluate till stable\n"); puts("VL_DEBUG_IF(VL_PRINTF(\"\\n----TOP Evaluate "+modClassName(modp)+"::eval\\n\"); );\n"); puts("int __VclockLoop = 0;\n"); puts("QData __Vchange=1;\n"); puts("while (VL_LIKELY(__Vchange)) {\n"); puts( "VL_DEBUG_IF(VL_PRINTF(\" Clock loop\\n\"););\n"); puts( "vlSymsp->__Vm_activity = true;\n"); puts( "_eval(vlSymsp);\n"); puts( "__Vchange = _change_request(vlSymsp);\n"); puts( "if (++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit()) +") vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n"); puts("}\n"); puts("}\n"); splitSizeInc(10); // puts("\nvoid "+modClassName(modp)+"::_eval_initial_loop("+EmitCBaseVisitor::symClassVar()+") {\n"); puts("vlSymsp->__Vm_didInit = true;\n"); puts("_eval_initial(vlSymsp);\n"); puts( "vlSymsp->__Vm_activity = true;\n"); puts( "int __VclockLoop = 0;\n"); puts( "QData __Vchange=1;\n"); puts( "while (VL_LIKELY(__Vchange)) {\n"); puts( "_eval_settle(vlSymsp);\n"); puts( "_eval(vlSymsp);\n"); puts( "__Vchange = _change_request(vlSymsp);\n"); puts( "if (++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit()) +") vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't DC converge\");\n"); puts( "}\n"); puts("}\n"); splitSizeInc(10); } //---------------------------------------------------------------------- // Top interface/ implementation void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp) { // Put out a list of signal declarations // in order of 0:clocks, 1:vluint8, 2:vluint16, 4:vluint32, 5:vluint64, 6:wide, 7:arrays // This aids cache packing and locality // Largest->smallest reduces the number of pad variables. // But for now, Smallest->largest makes it more likely a small offset will allow access to the signal. for (int isstatic=1; isstatic>=0; isstatic--) { if (prefixIfImp!="" && !isstatic) continue; const int sortmax = 9; for (int sort=0; sortnextp()) { if (AstVar* varp = nodep->castVar()) { bool doit = true; switch (which) { case EVL_ALL: doit = true; break; case EVL_IO: doit = varp->isIO(); break; case EVL_SIG: doit = (varp->isSignal() && !varp->isIO()); break; case EVL_TEMP: doit = (varp->isTemp() && !varp->isIO()); break; case EVL_PAR: doit = (varp->isParam() && !varp->valuep()->castConst()); break; default: v3fatalSrc("Bad Case"); } if (varp->isStatic() ? !isstatic : isstatic) doit=false; if (doit) { int sigbytes = varp->dtypeSkipRefp()->widthAlignBytes(); int sortbytes = sortmax-1; if (varp->isUsedClock() && varp->widthMin()==1) sortbytes = 0; else if (varp->dtypeSkipRefp()->castUnpackArrayDType()) sortbytes=8; else if (varp->basicp() && varp->basicp()->isOpaque()) sortbytes=7; else if (varp->isScBv() || varp->isScBigUint()) sortbytes=6; else if (sigbytes==8) sortbytes=5; else if (sigbytes==4) sortbytes=4; else if (sigbytes==2) sortbytes=2; else if (sigbytes==1) sortbytes=1; if (sort==sortbytes) { emitVarDecl(varp, prefixIfImp); } } } } } ofp()->putAlign(isstatic, 4, 0, prefixIfImp.c_str()); } } struct CmpName { inline bool operator () (const AstNode* lhsp, const AstNode* rhsp) const { return lhsp->name() < rhsp->name(); } }; void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) { vector funcsp; for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstCFunc* funcp = nodep->castCFunc()) { if (!funcp->skipDecl()) { funcsp.push_back(funcp); } } } stable_sort(funcsp.begin(), funcsp.end(), CmpName()); for (vector::iterator it = funcsp.begin(); it != funcsp.end(); ++it) { AstCFunc* funcp = *it; if (!funcp->dpiImport()) { // DPI is prototyped in __Dpi.h ofp()->putsPrivate(funcp->declPrivate()); if (funcp->isStatic()) puts("static "); puts(funcp->rtnTypeVoid()); puts("\t"); puts(funcp->name()); puts("("+cFuncArgs(funcp)+");\n"); } } } void EmitCImp::emitInt(AstNodeModule* modp) { // Always have this first; gcc has short circuiting if #ifdef is first in a file if (!optSystemPerl()) { // else done for us automatically puts("#ifndef _"+modClassName(modp)+"_H_\n"); puts("#define _"+modClassName(modp)+"_H_\n"); puts("\n"); } ofp()->putsIntTopInclude(); if (v3Global.needHeavy()) { puts("#include \"verilated_heavy.h\"\n"); } else { puts("#include \"verilated.h\"\n"); } if (v3Global.opt.savable()) { puts("#include \"verilated_save.h\"\n"); } if (v3Global.opt.coverage()) { puts("#include \"verilated_cov.h\"\n"); if (v3Global.opt.savable()) v3error("--coverage and --savable not supported together"); } if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us puts("#include \""+topClassName()+"__Inlines.h\"\n"); } if (v3Global.dpi()) { // do this before including our main .h file so that any references to // types defined in svdpi.h are available puts("#include \""+ topClassName() +"__Dpi.h\"\n"); puts("\n"); } // Declare foreign instances up front to make C++ happy puts("class "+symClassName()+";\n"); for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstCell* cellp=nodep->castCell()) { puts("class "+modClassName(cellp->modp())+";\n"); } } if (v3Global.opt.trace()) { puts("class "+v3Global.opt.traceClassBase()+";\n"); } puts("\n//----------\n\n"); emitTextSection(AstType::atSCHDR); if (optSystemC() && modp->isTop()) { puts("SC_MODULE("+modClassName(modp)+") {\n"); } else { puts("VL_MODULE("+modClassName(modp)+") {\n"); } if (optSystemPerl()) puts("/*AUTOATTR(verilated)*/\n\n"); ofp()->resetPrivate(); ofp()->putsPrivate(false); // public: // Instantiated modules if (optSystemPerl()) { puts("/*AUTOSUBCELLS*/\n\n"); } else { puts("// CELLS\n"); if (modp->isTop()) puts("// Public to allow access to /*verilator_public*/ items;\n"); if (modp->isTop()) puts("// otherwise the application code can consider these internals.\n"); for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstCell* cellp=nodep->castCell()) { ofp()->putsCellDecl(modClassName(cellp->modp()), cellp->name()); } } } emitTypedefs(modp->stmtsp()); puts("\n// PORTS\n"); if (modp->isTop()) puts("// The application code writes and reads these signals to\n"); if (modp->isTop()) puts("// propagate new values into/out from the Verilated model.\n"); emitVarList(modp->stmtsp(), EVL_IO, ""); puts("\n// LOCAL SIGNALS\n"); if (modp->isTop()) puts("// Internals; generally not touched by application code\n"); emitVarList(modp->stmtsp(), EVL_SIG, ""); puts("\n// LOCAL VARIABLES\n"); if (modp->isTop()) puts("// Internals; generally not touched by application code\n"); emitVarList(modp->stmtsp(), EVL_TEMP, ""); puts("\n// INTERNAL VARIABLES\n"); if (modp->isTop()) puts("// Internals; generally not touched by application code\n"); ofp()->putsPrivate(!modp->isTop()); // private: unless top ofp()->putAlign(V3OutFile::AL_AUTO, 8); puts(symClassName()+"*\t__VlSymsp;\t\t// Symbol table\n"); ofp()->putsPrivate(false); // public: if (modp->isTop()) { if (v3Global.opt.inhibitSim()) { ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool)); puts("bool\t__Vm_inhibitSim;\t///< Set true to disable evaluation of module\n"); } } ofp()->putAlign(V3OutFile::AL_AUTO, 8); emitCoverageDecl(modp); // may flip public/private ofp()->putAlign(V3OutFile::AL_AUTO, 8); puts("\n// PARAMETERS\n"); if (modp->isTop()) puts("// Parameters marked /*verilator public*/ for use by application code\n"); ofp()->putsPrivate(false); // public: emitVarList(modp->stmtsp(), EVL_PAR, ""); // Only those that are non-CONST for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { if (AstVar* varp = nodep->castVar()) { if (varp->isParam() && (varp->isUsedParam() || varp->isSigPublic())) { if (!varp->valuep()) nodep->v3fatalSrc("No init for a param?"); // These should be static const values, however microsloth VC++ doesn't // support them. They also cause problems with GDB under GCC2.95. if (varp->isWide()) { // Unsupported for output puts("// enum WData "+varp->name()+" //wide"); } else if (!varp->valuep()->castConst()) { // Unsupported for output //puts("// enum ..... "+varp->name()+" //not simple value, see variable above instead"); } else { puts("enum "); puts(varp->isQuad()?"_QData":"_IData"); puts(""+varp->name()+" { "+varp->name()+" = "); varp->valuep()->iterateAndNext(*this); puts("};"); } puts("\n"); } } } puts("\n// CONSTRUCTORS\n"); ofp()->resetPrivate(); // We don't need a private copy constructor, as VerilatedModule has one for us. ofp()->putsPrivate(true); puts(modClassName(modp)+"& operator= (const "+modClassName(modp)+"&);\t///< Copying not allowed\n"); puts(modClassName(modp)+"(const "+modClassName(modp)+"&);\t///< Copying not allowed\n"); ofp()->putsPrivate(false); // public: if (optSystemC() && modp->isTop()) { puts("SC_CTOR("+modClassName(modp)+");\n"); puts("virtual ~"+modClassName(modp)+"();\n"); } else if (optSystemC()) { puts("VL_CTOR("+modClassName(modp)+");\n"); puts("~"+modClassName(modp)+"();\n"); } else { if (modp->isTop()) { puts("/// Construct the model; called by application code\n"); puts("/// The special name "" may be used to make a wrapper with a\n"); puts("/// single model invisible WRT DPI scope names.\n"); } puts(modClassName(modp)+"(const char* name=\"TOP\");\n"); if (modp->isTop()) puts("/// Destroy the model; called (often implicitly) by application code\n"); puts("~"+modClassName(modp)+"();\n"); } if (v3Global.opt.trace() && !optSystemPerl()) { if (modp->isTop()) puts("/// Trace signals in the model; called by application code\n"); puts("void trace (VerilatedVcdC* tfp, int levels, int options=0);\n"); if (modp->isTop() && optSystemC()) { puts("/// SC tracing; avoid overloaded virtual function lint warning\n"); puts("virtual void trace (sc_trace_file* tfp) const { ::sc_core::sc_module::trace(tfp); }\n"); } } puts("\n// USER METHODS\n"); if (optSystemPerl()) puts("/*AUTOMETHODS*/\n"); emitTextSection(AstType::atSCINT); puts("\n// API METHODS\n"); if (modp->isTop()) { if (optSystemC()) ofp()->putsPrivate(true); ///< eval() is invoked by our sensitive() calls. else puts("/// Evaluate the model. Application must call when inputs change.\n"); puts("void eval();\n"); ofp()->putsPrivate(false); // public: if (!optSystemC()) puts("/// Simulation complete, run final blocks. Application must call on completion.\n"); puts("void final();\n"); if (v3Global.opt.inhibitSim()) { puts("void inhibitSim(bool flag) { __Vm_inhibitSim=flag; }\t///< Set true to disable evaluation of module\n"); } } puts("\n// INTERNAL METHODS\n"); if (modp->isTop()) { ofp()->putsPrivate(true); // private: puts("static void _eval_initial_loop("+EmitCBaseVisitor::symClassVar()+");\n"); } ofp()->putsPrivate(false); // public: puts("void __Vconfigure("+symClassName()+"* symsp, bool first);\n"); emitIntFuncDecls(modp); if (!optSystemPerl() && v3Global.opt.trace()) { ofp()->putsPrivate(false); // public: puts("static void traceInit ("+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code);\n"); puts("static void traceFull ("+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code);\n"); puts("static void traceChg ("+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code);\n"); } if (v3Global.opt.savable()) { puts("void __Vserialize(VerilatedSerialize& os);\n"); puts("void __Vdeserialize(VerilatedDeserialize& os);\n"); puts("\n"); } puts("} VL_ATTR_ALIGNED(128);\n"); puts("\n"); // Save/restore if (v3Global.opt.savable() && modp->isTop()) { puts("inline VerilatedSerialize& operator<<(VerilatedSerialize& os, "+modClassName(modp)+"& rhs) {rhs.__Vserialize(os); return os;}\n"); puts("inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, "+modClassName(modp)+"& rhs) {rhs.__Vdeserialize(os); return os;}\n"); puts("\n"); } // finish up h-file if (!optSystemPerl()) { puts("#endif /*guard*/\n"); } } //---------------------------------------------------------------------- void EmitCImp::emitImp(AstNodeModule* modp) { if (optSystemPerl()) { puts("//############################################################\n"); puts("#sp implementation\n"); } ofp()->printf("#include \"%-20s // For This\n", (modClassName(modp)+".h\"").c_str()); // Us puts("#include \""+ symClassName() +".h\"\n"); if (v3Global.dpi()) { puts("\n"); puts("#include \"verilated_dpi.h\"\n"); } if (optSystemPerl() && (splitFilenum() || !m_fast)) { puts("\n"); puts("SP_MODULE_CONTINUED("+modClassName(modp)+");\n"); } emitTextSection(AstType::atSCIMPHDR); if (m_slow && splitFilenum()==0) { puts("\n//--------------------\n"); puts("// STATIC VARIABLES\n\n"); emitVarList(modp->stmtsp(), EVL_ALL, modClassName(modp)); } if (m_fast && splitFilenum()==0) { emitTextSection(AstType::atSCIMP); emitStaticDecl(modp); } if (m_slow && splitFilenum()==0) { puts("\n//--------------------\n"); emitCtorImp(modp); emitConfigureImp(modp); emitDestructorImp(modp); emitSavableImp(modp); emitCoverageImp(modp); } if (m_fast && splitFilenum()==0) { if (modp->isTop()) { emitStaticDecl(modp); puts("\n//--------------------\n"); puts("\n"); emitWrapEval(modp); } } if (m_fast && splitFilenum()==0) { if (v3Global.opt.trace() && optSystemPerl() && m_modp->isTop()) { puts("\n"); puts("\n/*AUTOTRACE(__MODULE__,recurse,activity,exists)*/\n\n"); } } // Blocks puts("\n//--------------------\n"); puts("// Internal Methods\n"); } //###################################################################### void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) { // Output a module m_modp = modp; m_slow = slow; m_fast = fast; if (debug()>=5) { UINFO(0," Emitting "<stmtsp(); nodep; nodep = nodep->nextp()) { if (AstCFunc* funcp = nodep->castCFunc()) { if (splitNeeded()) { // Close old file delete m_ofp; m_ofp=NULL; // Open a new file m_ofp = newOutCFile (modp, !m_fast, true/*source*/, splitFilenumInc()); emitImp (modp); } splitSizeInc(10); // Even blank functions get a file with a low csplit mainDoFunc(funcp); } } delete m_ofp; m_ofp=NULL; } //###################################################################### // Tracing routines class EmitCTrace : EmitCStmts { AstCFunc* m_funcp; // Function we're in now bool m_slow; // Making slow file // METHODS void newOutCFile(int filenum) { string filename = (v3Global.opt.makeDir()+"/"+ topClassName() + (m_slow?"__Trace__Slow":"__Trace")); if (filenum) filename += "__"+cvtToStr(filenum); filename += ".cpp"; AstCFile* cfilep = newCFile(filename, m_slow, true/*source*/); cfilep->support(true); if (m_ofp) v3fatalSrc("Previous file not closed"); m_ofp = new V3OutCFile (filename); m_ofp->putsHeader(); m_ofp->puts("// DESCR" "IPTION: Verilator output: Tracing implementation internals\n"); emitTraceHeader(); } void emitTraceHeader() { // Includes if (optSystemPerl()) { puts("#include \"SpTraceVcd.h\"\n"); } else { puts("#include \"verilated_vcd_c.h\"\n"); } puts("#include \""+ symClassName() +".h\"\n"); puts("\n"); } void emitTraceSlow() { puts("\n//======================\n\n"); puts("void "+topClassName()+"::trace ("); if (optSystemPerl()) { puts("SpTraceFile* tfp, int, int) {\n"); } else { puts("VerilatedVcdC* tfp, int, int) {\n"); } puts( "tfp->spTrace()->addCallback (" "&"+topClassName()+"::traceInit" +", &"+topClassName()+"::traceFull" +", &"+topClassName()+"::traceChg, this);\n"); puts("}\n"); splitSizeInc(10); puts("void "+topClassName()+"::traceInit(" +v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n"); puts("// Callback from vcd->open()\n"); puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n"); puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n"); puts("if (!Verilated::calcUnusedSigs()) vl_fatal(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n"); puts("vcdp->scopeEscape(' ');\n"); puts("t->traceInitThis (vlSymsp, vcdp, code);\n"); puts("vcdp->scopeEscape('.');\n"); // Restore so SystemPerl traced files won't break puts("}\n"); splitSizeInc(10); puts("void "+topClassName()+"::traceFull(" +v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n"); puts("// Callback from vcd->dump()\n"); puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n"); puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n"); puts("t->traceFullThis (vlSymsp, vcdp, code);\n"); puts("}\n"); splitSizeInc(10); puts("\n//======================\n\n"); } void emitTraceFast() { puts("\n//======================\n\n"); puts("void "+topClassName()+"::traceChg(" +v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n"); puts("// Callback from vcd->dump()\n"); puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n"); puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n"); puts("if (vlSymsp->getClearActivity()) {\n"); puts("t->traceChgThis (vlSymsp, vcdp, code);\n"); puts("}\n"); puts("}\n"); splitSizeInc(10); puts("\n//======================\n\n"); } bool emitTraceIsScBv(AstTraceInc* nodep) { AstVarRef* varrefp = nodep->valuep()->castVarRef(); if (!varrefp) return false; AstVar* varp = varrefp->varp(); return varp->isSc() && varp->isScBv(); } bool emitTraceIsScBigUint(AstTraceInc* nodep) { AstVarRef* varrefp = nodep->valuep()->castVarRef(); if (!varrefp) return false; AstVar* varp = varrefp->varp(); return varp->isSc() && varp->isScBigUint(); } bool emitTraceIsScUint(AstTraceInc* nodep) { AstVarRef* varrefp = nodep->valuep()->castVarRef(); if (!varrefp) return false; AstVar* varp = varrefp->varp(); return varp->isSc() && varp->isScUint(); } void emitTraceInitOne(AstTraceDecl* nodep) { if (nodep->dtypep()->basicp()->isDouble()) { puts("vcdp->declDouble"); } else if (nodep->isWide()) { puts("vcdp->declArray"); } else if (nodep->isQuad()) { puts("vcdp->declQuad "); } else if (nodep->bitRange().ranged()) { puts("vcdp->declBus "); } else { puts("vcdp->declBit "); } puts("(c+"+cvtToStr(nodep->code())); if (nodep->arrayRange().ranged()) puts("+i*"+cvtToStr(nodep->widthWords())); puts(","); putsQuoted(nodep->showname()); if (nodep->arrayRange().ranged()) { puts(",(i+"+cvtToStr(nodep->arrayRange().lo())+")"); } else { puts(",-1"); } if (!nodep->dtypep()->basicp()->isDouble() // When float/double no longer have widths this can go && nodep->bitRange().ranged()) { puts(","+cvtToStr(nodep->bitRange().left())+","+cvtToStr(nodep->bitRange().right())); } puts(");"); } void emitTraceChangeOne(AstTraceInc* nodep, int arrayindex) { nodep->precondsp()->iterateAndNext(*this); string full = ((m_funcp->funcType() == AstCFuncType::TRACE_FULL || m_funcp->funcType() == AstCFuncType::TRACE_FULL_SUB) ? "full":"chg"); if (nodep->dtypep()->basicp()->isDouble()) { puts("vcdp->"+full+"Double"); } else if (nodep->isWide() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep)) { puts("vcdp->"+full+"Array"); } else if (nodep->isQuad()) { puts("vcdp->"+full+"Quad "); } else if (nodep->declp()->bitRange().ranged()) { puts("vcdp->"+full+"Bus "); } else { puts("vcdp->"+full+"Bit "); } puts("(c+"+cvtToStr(nodep->declp()->code() + ((arrayindex<0) ? 0 : (arrayindex*nodep->declp()->widthWords())))); puts(","); emitTraceValue(nodep, arrayindex); if (!nodep->dtypep()->basicp()->isDouble() // When float/double no longer have widths this can go && (nodep->declp()->bitRange().ranged() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep))) { puts(","+cvtToStr(nodep->declp()->widthMin())); } puts(");\n"); } void emitTraceValue(AstTraceInc* nodep, int arrayindex) { if (nodep->valuep()->castVarRef()) { AstVarRef* varrefp = nodep->valuep()->castVarRef(); AstVar* varp = varrefp->varp(); puts("("); if (emitTraceIsScBigUint(nodep)) puts("(vluint32_t*)"); else if (emitTraceIsScBv(nodep)) puts("VL_SC_BV_DATAP("); varrefp->iterate(*this); // Put var name out // Tracing only supports 1D arrays if (nodep->declp()->arrayRange().ranged()) { if (arrayindex==-2) puts("[i]"); else if (arrayindex==-1) puts("[0]"); else puts("["+cvtToStr(arrayindex)+"]"); } if (varp->isSc()) puts(".read()"); if (emitTraceIsScUint(nodep)) puts(nodep->isQuad() ? ".to_uint64()" : ".to_uint()"); else if (emitTraceIsScBigUint(nodep)) puts(".get_raw()"); else if (emitTraceIsScBv(nodep)) puts(")"); puts(")"); } else { puts("("); nodep->valuep()->iterate(*this); puts(")"); } } // VISITORS using EmitCStmts::visit; // Suppress hidden overloaded virtual function warnng virtual void visit(AstNetlist* nodep, AstNUser*) { // Top module only nodep->topModulep()->accept(*this); } virtual void visit(AstNodeModule* nodep, AstNUser*) { nodep->iterateChildren(*this); } virtual void visit(AstCFunc* nodep, AstNUser*) { if (nodep->slow() != m_slow) return; if (nodep->funcType().isTrace()) { // TRACE_* m_funcp = nodep; if (splitNeeded()) { // Close old file delete m_ofp; m_ofp=NULL; // Open a new file newOutCFile (splitFilenumInc()); } splitSizeInc(nodep); puts("\n"); puts(nodep->rtnTypeVoid()); puts(" "); puts(topClassName()+"::"+nodep->name() +"("+cFuncArgs(nodep)+") {\n"); if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n"); puts("int c=code;\n"); puts("if (0 && vcdp && c) {} // Prevent unused\n"); if (nodep->funcType() == AstCFuncType::TRACE_INIT) { puts("vcdp->module(vlSymsp->name()); // Setup signal names\n"); } else if (nodep->funcType() == AstCFuncType::TRACE_INIT_SUB) { } else if (nodep->funcType() == AstCFuncType::TRACE_FULL) { } else if (nodep->funcType() == AstCFuncType::TRACE_FULL_SUB) { } else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE) { } else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE_SUB) { } else nodep->v3fatalSrc("Bad Case"); if (nodep->initsp()) puts("// Variables\n"); emitVarList(nodep->initsp(), EVL_ALL, ""); nodep->initsp()->iterateAndNext(*this); ofp()->putAlign(V3OutFile::AL_AUTO, 4); puts("// Body\n"); puts("{\n"); nodep->stmtsp()->iterateAndNext(*this); puts("}\n"); if (nodep->finalsp()) puts("// Final\n"); nodep->finalsp()->iterateAndNext(*this); puts("}\n"); } m_funcp = NULL; } virtual void visit(AstTraceDecl* nodep, AstNUser*) { if (nodep->arrayRange().ranged()) { puts("{int i; for (i=0; i<"+cvtToStr(nodep->arrayRange().elements())+"; i++) {\n"); emitTraceInitOne(nodep); puts("}}\n"); } else { emitTraceInitOne(nodep); puts("\n"); } } virtual void visit(AstTraceInc* nodep, AstNUser*) { if (nodep->declp()->arrayRange().ranged()) { // It traces faster if we unroll the loop for (int i=0; ideclp()->arrayRange().elements(); i++) { emitTraceChangeOne(nodep, i); } } else { emitTraceChangeOne(nodep, -1); } } virtual void visit(AstCoverDecl* nodep, AstNUser*) { } virtual void visit(AstCoverInc* nodep, AstNUser*) { } public: EmitCTrace(bool slow) { m_funcp = NULL; m_slow = slow; } virtual ~EmitCTrace() {} void main() { // Put out the file newOutCFile(0); if (m_slow) emitTraceSlow(); else emitTraceFast(); v3Global.rootp()->accept(*this); delete m_ofp; m_ofp=NULL; } }; //###################################################################### // EmitC class functions void V3EmitC::emitc() { UINFO(2,__FUNCTION__<<": "<modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) { if (v3Global.opt.outputSplit()) { { EmitCImp imp; imp.main(nodep, false, true); } { EmitCImp imp; imp.main(nodep, true, false); } } else { { EmitCImp imp; imp.main(nodep, true, true); } } } } void V3EmitC::emitcTrace() { UINFO(2,__FUNCTION__<<": "< #include #include #include #include "V3Global.h" #include "V3Clock.h" #include "V3Ast.h" #include "V3EmitCBase.h" //###################################################################### // Clock state, as a visitor of each AstNode class ClockVisitor : public AstNVisitor { private: // NODE STATE // Cleared each Module: // AstVarScope::user1p() -> AstVarScope*. Temporary signal that was created. // AstVarScope::user2p() -> AstVarScope*. Temporary signal for change detects AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // TYPES enum { DOUBLE_OR_RATE = 10 }; // How many | per ||, Determined experimentally as best // STATE AstNodeModule* m_modp; // Current module AstTopScope* m_topScopep; // Current top scope AstScope* m_scopep; // Current scope AstActive* m_activep; // Current block AstUntilStable* m_untilp; // Current until AstCFunc* m_evalFuncp; // Top eval function we are creating AstCFunc* m_initFuncp; // Top initial function we are creating AstCFunc* m_finalFuncp; // Top final function we are creating AstCFunc* m_settleFuncp; // Top settlement function we are creating AstSenTree* m_lastSenp; // Last sensitivity match, so we can detect duplicates. AstIf* m_lastIfp; // Last sensitivity if active to add more under int m_stableNum; // Number of each untilstable // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } AstVarScope* getCreateLastClk(AstVarScope* vscp) { if (vscp->user1p()) return ((AstVarScope*)vscp->user1p()); AstVar* varp = vscp->varp(); if (!varp->width1()) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<prettyName()); string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->name()); AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1); m_modp->addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp); vscp->user1p(newvscp); m_scopep->addVarp(newvscp); // At bottom, assign them AstAssign* finalp = new AstAssign (vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, true), new AstVarRef(vscp->fileline(), vscp, false)); m_evalFuncp->addFinalsp(finalp); // UINFO(4,"New Last: "<varrefp()->varScopep(); if (nodep->edgeType()==AstEdgeType::ET_POSEDGE) { AstVarScope* lastVscp = getCreateLastClk(clkvscp); newp = new AstAnd(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep->varrefp()->varScopep(), false), new AstNot(nodep->fileline(), new AstVarRef(nodep->fileline(), lastVscp, false))); } else if (nodep->edgeType()==AstEdgeType::ET_NEGEDGE) { AstVarScope* lastVscp = getCreateLastClk(clkvscp); newp = new AstAnd(nodep->fileline(), new AstNot(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep->varrefp()->varScopep(), false)), new AstVarRef(nodep->fileline(), lastVscp, false)); } else if (nodep->edgeType()==AstEdgeType::ET_BOTHEDGE) { AstVarScope* lastVscp = getCreateLastClk(clkvscp); newp = new AstXor(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep->varrefp()->varScopep(), false), new AstVarRef(nodep->fileline(), lastVscp, false)); } else if (nodep->edgeType()==AstEdgeType::ET_HIGHEDGE) { newp = new AstVarRef(nodep->fileline(), clkvscp, false); } else if (nodep->edgeType()==AstEdgeType::ET_LOWEDGE) { newp = new AstNot(nodep->fileline(), new AstVarRef(nodep->fileline(), clkvscp, false)); } else { nodep->v3fatalSrc("Bad edge type"); } return newp; } AstNode* createSenGateEquation(AstSenGate* nodep) { AstNode* newp = new AstAnd(nodep->fileline(), createSenseEquation(nodep->sensesp()), nodep->rhsp()->cloneTree(true)); return newp; } AstNode* createSenseEquation(AstNodeSenItem* nodesp) { // Nodep may be a list of elements; we need to walk it AstNode* senEqnp = NULL; for (AstNodeSenItem* senp = nodesp; senp; senp=senp->nextp()->castNodeSenItem()) { AstNode* senOnep = NULL; if (AstSenItem* itemp = senp->castSenItem()) { senOnep = createSenItemEquation(itemp); } else if (AstSenGate* itemp = senp->castSenGate()) { senOnep = createSenGateEquation(itemp); } else { senp->v3fatalSrc("Strange node under sentree"); } if (senEqnp) { // Add new OR to the sensitivity list equation senEqnp = new AstOr(senp->fileline(), senEqnp, senOnep); } else { senEqnp = senOnep; } } return senEqnp; } AstIf* makeActiveIf(AstSenTree* sensesp) { AstNode* senEqnp = createSenseEquation(sensesp->sensesp()); if (!senEqnp) sensesp->v3fatalSrc("No sense equation, shouldn't be in sequent activation."); AstIf* newifp = new AstIf (sensesp->fileline(), senEqnp, NULL, NULL); return (newifp); } void clearLastSen() { m_lastSenp = NULL; m_lastIfp = NULL; } // VISITORS virtual void visit(AstTopScope* nodep, AstNUser*) { UINFO(4," TOPSCOPE "<scopep(); if (!m_scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?\n"); //VV***** We reset all user1p() AstNode::user1ClearTree(); // Make top functions { AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_eval", m_scopep); funcp->argTypes(EmitCBaseVisitor::symClassVar()); funcp->dontCombine(true); funcp->symProlog(true); funcp->isStatic(true); funcp->entryPoint(true); m_scopep->addActivep(funcp); m_evalFuncp = funcp; } { AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_eval_initial", m_scopep); funcp->argTypes(EmitCBaseVisitor::symClassVar()); funcp->dontCombine(true); funcp->slow(true); funcp->symProlog(true); funcp->isStatic(true); funcp->entryPoint(true); m_scopep->addActivep(funcp); m_initFuncp = funcp; } { AstCFunc* funcp = new AstCFunc(nodep->fileline(), "final", m_scopep); funcp->skipDecl(true); funcp->dontCombine(true); funcp->slow(true); funcp->isStatic(false); funcp->entryPoint(true); funcp->addInitsp(new AstCStmt(nodep->fileline(), EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n")); funcp->addInitsp(new AstCStmt(nodep->fileline(), EmitCBaseVisitor::symTopAssign()+"\n")); m_scopep->addActivep(funcp); m_finalFuncp = funcp; } { AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_eval_settle", m_scopep); funcp->argTypes(EmitCBaseVisitor::symClassVar()); funcp->dontCombine(true); funcp->slow(true); funcp->isStatic(true); funcp->symProlog(true); funcp->entryPoint(true); m_scopep->addActivep(funcp); m_settleFuncp = funcp; } // Process the activates nodep->iterateChildren(*this); // Done, clear so we can detect errors UINFO(4," TOPSCOPEDONE "<iterateChildren(*this); m_modp= NULL; } virtual void visit(AstScope* nodep, AstNUser*) { //UINFO(4," SCOPE "<iterateChildren(*this); if (AstNode* movep = nodep->finalClksp()) { if (!m_topScopep) nodep->v3fatalSrc("Final clocks under non-top scope"); movep->unlinkFrBackWithNext(); m_evalFuncp->addFinalsp(movep); } m_scopep = NULL; } virtual void visit(AstAlways* nodep, AstNUser*) { AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName()); nodep->replaceWith(cmtp); if (AstNode* stmtsp = nodep->bodysp()) { stmtsp->unlinkFrBackWithNext(); cmtp->addNextHere(stmtsp); } nodep->deleteTree(); nodep = NULL; } virtual void visit(AstAlwaysPost* nodep, AstNUser*) { AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName()); nodep->replaceWith(cmtp); if (AstNode* stmtsp = nodep->bodysp()) { stmtsp->unlinkFrBackWithNext(); cmtp->addNextHere(stmtsp); } nodep->deleteTree(); nodep = NULL; } virtual void visit(AstCoverToggle* nodep, AstNUser*) { //nodep->dumpTree(cout,"ct:"); //COVERTOGGLE(INC, ORIG, CHANGE) -> // IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; } AstNode* incp = nodep->incp()->unlinkFrBack(); AstNode* origp = nodep->origp()->unlinkFrBack(); AstNode* changep = nodep->changep()->unlinkFrBack(); AstIf* newp = new AstIf(nodep->fileline(), new AstXor(nodep->fileline(), origp, changep), incp, NULL); // We could add another IF to detect posedges, and only increment if so. // It's another whole branch though verus a potential memory miss. // We'll go with the miss. newp->addIfsp(new AstAssign(nodep->fileline(), changep->cloneTree(false), origp->cloneTree(false))); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } virtual void visit(AstInitial* nodep, AstNUser*) { AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName()); nodep->replaceWith(cmtp); if (AstNode* stmtsp = nodep->bodysp()) { stmtsp->unlinkFrBackWithNext(); cmtp->addNextHere(stmtsp); } nodep->deleteTree(); nodep = NULL; } virtual void visit(AstCFunc* nodep, AstNUser*) { nodep->iterateChildren(*this); // Link to global function if (nodep->formCallTree()) { UINFO(4, " formCallTree "<fileline(), nodep); callp->argTypes("vlSymsp"); m_finalFuncp->addStmtsp(callp); } } virtual void visit(AstSenTree* nodep, AstNUser*) { // Delete it later; Actives still pointing to it nodep->unlinkFrBack(); pushDeletep(nodep); } void addToEvalLoop(AstNode* stmtsp) { if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body else m_evalFuncp->addStmtsp(stmtsp); // else add to top level function } void addToSettleLoop(AstNode* stmtsp) { if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body else m_settleFuncp->addStmtsp(stmtsp); // else add to top level function } void addToInitial(AstNode* stmtsp) { if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body else m_initFuncp->addStmtsp(stmtsp); // else add to top level function } virtual void visit(AstActive* nodep, AstNUser*) { // Careful if adding variables here, ACTIVES can be under other ACTIVES // Need to save and restore any member state in AstUntilStable block if (!m_topScopep || !nodep->stmtsp()) { // Not at the top or empty block... // Only empty blocks should be leftover on the non-top. Killem. if (nodep->stmtsp()) nodep->v3fatalSrc("Non-empty lower active"); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else { UINFO(4," ACTIVE "<stmtsp()->unlinkFrBackWithNext(); if (nodep->hasClocked()) { // Remember the latest sensitivity so we can compare it next time if (nodep->hasInitial()) nodep->v3fatalSrc("Initial block should not have clock sensitivity"); if (m_lastSenp && nodep->sensesp()->sameTree(m_lastSenp)) { UINFO(4," sameSenseTree\n"); } else { clearLastSen(); m_lastSenp = nodep->sensesp(); // Make a new if statement m_lastIfp = makeActiveIf(m_lastSenp); addToEvalLoop(m_lastIfp); } // Move statements to if m_lastIfp->addIfsp(stmtsp); } else if (nodep->hasInitial()) { // Don't need to: clearLastSen();, as we're adding it to different cfunc // Move statements to function addToInitial(stmtsp); } else if (nodep->hasSettle()) { // Don't need to: clearLastSen();, as we're adding it to different cfunc // Move statements to function addToSettleLoop(stmtsp); } else { // Combo clearLastSen(); // Move statements to function addToEvalLoop(stmtsp); } nodep->unlinkFrBack()->deleteTree(); nodep = NULL; } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ClockVisitor(AstNetlist* nodep) { m_modp=NULL; m_activep=NULL; m_evalFuncp = NULL; m_topScopep=NULL; m_lastSenp=NULL; m_lastIfp = NULL; m_scopep = NULL; m_stableNum = 0; m_untilp = NULL; // nodep->accept(*this); } virtual ~ClockVisitor() {} }; //###################################################################### // Clock class functions void V3Clock::clockAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Depth.h0000664000177100017500000000224712525171733015753 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Prevent very deep expressions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3DEPTH_H_ #define _V3DEPTH_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Depth { public: static void depthAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3PreProc.cpp0000664000177100017500000013706512525172076016624 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilog::Preproc: Internal implementation of default preprocessor // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2000-2015 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. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include #include "V3Error.h" #include "V3Global.h" #include "V3File.h" #include "V3PreLex.h" #include "V3PreProc.h" #include "V3PreShell.h" //====================================================================== // Build in LEX script #define yyFlexLexer V3Lexer #include "V3PreLex.yy.cpp" #undef yyFlexLexer //YYSTYPE yylval; //************************************************************************* class V3Define { // Define class. One for each define. //string m_name; // Name of the define (list is keyed by this) FileLine* m_fileline; // Where it was declared string m_value; // Value of define string m_params; // Parameters bool m_cmdline; // Set on command line, don't `undefineall public: V3Define(FileLine* fl, const string& value, const string& params, bool cmdline) : m_fileline(fl), m_value(value), m_params(params), m_cmdline(cmdline) {} FileLine* fileline() const { return m_fileline; } string value() const { return m_value; } string params() const { return m_params; } bool cmdline() const { return m_cmdline; } }; //************************************************************************* class V3DefineRef { // One for each pending define substitution string m_name; // Define last name being defined string m_params; // Define parameter list for next expansion string m_nextarg; // String being built for next argument int m_parenLevel; // Parenthesis counting inside def args (for PARENT not child) vector m_args; // List of define arguments public: string name() const { return m_name; } string params() const { return m_params; } string nextarg() const { return m_nextarg; } void nextarg(const string& value) { m_nextarg = value; } int parenLevel() const { return m_parenLevel; } void parenLevel(int value) { m_parenLevel = value; } vector& args() { return m_args; } V3DefineRef(const string& name, const string& params) : m_name(name), m_params(params), m_parenLevel(0) {} ~V3DefineRef() {} }; //************************************************************************* /// Data for parsing on/off class VPreIfEntry { // One for each pending ifdef/ifndef bool m_on; // Current parse for this ifdef level is "on" bool m_everOn; // Some if term in elsif tree has been on public: bool on() const { return m_on; } bool everOn() const { return m_everOn; } VPreIfEntry(bool on, bool everOn) : m_on(on), m_everOn(everOn || on) {} // Note everOn includes new state ~VPreIfEntry() {} }; //************************************************************************* // Data for a preprocessor instantiation. class V3PreProcImp : public V3PreProc { public: // TYPES typedef std::map DefinesMap; typedef V3InFilter::StrList StrList; // debug() -> see V3PreShellImp::debug; use --debugi-V3PreShell // Defines list DefinesMap m_defines; ///< Map of defines // STATE V3PreProc* m_preprocp; ///< Object we're holding data for V3PreLex* m_lexp; ///< Current lexer state (NULL = closed) stack m_includeStack; ///< Stack of includers above current m_lexp enum ProcState { ps_TOP, ps_DEFNAME_UNDEF, ps_DEFNAME_DEFINE, ps_DEFNAME_IFDEF, ps_DEFNAME_IFNDEF, ps_DEFNAME_ELSIF, ps_DEFFORM, ps_DEFVALUE, ps_DEFPAREN, ps_DEFARG, ps_INCNAME, ps_ERRORNAME, ps_JOIN, ps_STRIFY }; static const char* procStateName(ProcState s) { static const char* states[] = {"ps_TOP", "ps_DEFNAME_UNDEF", "ps_DEFNAME_DEFINE", "ps_DEFNAME_IFDEF", "ps_DEFNAME_IFNDEF", "ps_DEFNAME_ELSIF", "ps_DEFFORM", "ps_DEFVALUE", "ps_DEFPAREN", "ps_DEFARG", "ps_INCNAME", "ps_ERRORNAME", "ps_JOIN", "ps_STRIFY"}; return states[s]; }; stack m_states; ///< Current state of parser int m_off; ///< If non-zero, ifdef level is turned off, don't dump text string m_lastSym; ///< Last symbol name found. string m_formals; ///< Last formals found // For getRawToken/ `line insertion string m_lineCmt; ///< Line comment(s) to be returned bool m_lineCmtNl; ///< Newline needed before inserting lineCmt int m_lineAdd; ///< Empty lines to return to maintain line count bool m_rawAtBol; ///< Last rawToken left us at beginning of line // For getFinalToken bool m_finAhead; ///< Have read a token ahead int m_finToken; ///< Last token read string m_finBuf; ///< Last yytext read bool m_finAtBol; ///< Last getFinalToken left us at beginning of line FileLine* m_finFilelinep; ///< Location of last returned token (internal only) // For stringification string m_strify; ///< Text to be stringified // For defines stack m_defRefs; // Pending definine substitution stack m_ifdefStack; ///< Stack of true/false emitting evaluations unsigned m_defDepth; ///< How many `defines deep bool m_defPutJoin; ///< Insert `` after substitution // For `` join stack m_joinStack; ///< Text on lhs of join // For getline() string m_lineChars; ///< Characters left for next line void v3errorEnd(ostringstream& str) { fileline()->v3errorEnd(str); } const char* tokenName(int tok); void debugToken(int tok, const char* cmtp); void parseTop(); void parseUndef(); private: // Internal methods void endOfOneFile(); string defineSubst(V3DefineRef* refp); bool defExists(const string& name); string defValue(const string& name); string defParams(const string& name); FileLine* defFileline(const string& name); bool commentTokenMatch(string& cmdr, const char* strg); string trimWhitespace(const string& strg, bool trailing); void unputString(const string& strg); void unputDefrefString(const string& strg); void parsingOn() { m_off--; if (m_off<0) fatalSrc("Underflow of parsing cmds"); // addLineComment no longer needed; getFinalToken will correct. } void parsingOff() { m_off++; } int getRawToken(); int getStateToken(); int getFinalToken(string& buf); void statePush(ProcState state) { m_states.push(state); } void statePop() { m_states.pop(); if (m_states.empty()) { error("InternalError: Pop of parser state with nothing on stack"); m_states.push(ps_TOP); } } void stateChange(ProcState state) { statePop(); statePush(state); } public: // METHODS, called from upper level shell void openFile(FileLine* fl, V3InFilter* filterp, const string& filename); bool isEof() const { return m_lexp->curStreamp()->m_eof; } string getline(); void insertUnreadback(const string& text) { m_lineCmt += text; } void insertUnreadbackAtBol(const string& text); void addLineComment(int enter_exit_level); // METHODS, callbacks virtual void comment(const string& cmt); // Comment detected (if keepComments==2) virtual void include(const string& filename); // Request a include file be processed virtual void undef (const string& name); virtual void undefineall(); virtual void define (FileLine* fl, const string& name, const string& value, const string& params, bool cmdline); virtual string removeDefines(const string& text); // Remove defines in a text string // CONSTRUCTORS V3PreProcImp() : V3PreProc() { m_debug = 0; m_states.push(ps_TOP); m_off = 0; m_lineChars = ""; m_lastSym = ""; m_lineAdd = 0; m_lineCmtNl = false; m_rawAtBol = true; m_finAhead = false; m_finAtBol = true; m_defDepth = 0; m_defPutJoin = false; m_finToken = 0; m_finFilelinep = NULL; m_lexp = NULL; m_preprocp = NULL; } void configure(FileLine* filelinep) { // configure() separate from constructor to avoid calling abstract functions m_preprocp = this; // Silly, but to make code more similar to Verilog-Perl m_finFilelinep = filelinep->create(1); // Create lexer m_lexp = new V3PreLex (this, filelinep); m_lexp->m_keepComments = m_preprocp->keepComments(); m_lexp->m_keepWhitespace = m_preprocp->keepWhitespace(); m_lexp->m_pedantic = m_preprocp->pedantic(); m_lexp->debug(debug()>=5 ? debug() : 0); // See also V3PreProc::debug() method } ~V3PreProcImp() { if (m_lexp) { delete m_lexp; m_lexp = NULL; } } }; //************************************************************************* // Creation V3PreProc* V3PreProc::createPreProc(FileLine* fl) { V3PreProcImp* preprocp = new V3PreProcImp(); preprocp->configure(fl); return preprocp; } //************************************************************************* // Defines void V3PreProcImp::undef(const string& name) { m_defines.erase(name); } void V3PreProcImp::undefineall() { for (DefinesMap::iterator nextit, it = m_defines.begin(); it != m_defines.end(); it=nextit) { nextit = it; ++nextit; if (!it->second.cmdline()) m_defines.erase(it); } } bool V3PreProcImp::defExists(const string& name) { DefinesMap::iterator iter = m_defines.find(name); if (iter == m_defines.end()) return false; return true; } string V3PreProcImp::defValue(const string& name) { DefinesMap::iterator iter = m_defines.find(name); if (iter == m_defines.end()) { fileline()->v3error("Define or directive not defined: `"+name); return ""; } return iter->second.value(); } string V3PreProcImp::defParams(const string& name) { DefinesMap::iterator iter = m_defines.find(name); if (iter == m_defines.end()) { fileline()->v3error("Define or directive not defined: `"+name); return ""; } return iter->second.params(); } FileLine* V3PreProcImp::defFileline(const string& name) { DefinesMap::iterator iter = m_defines.find(name); if (iter == m_defines.end()) return NULL; return iter->second.fileline(); } void V3PreProcImp::define(FileLine* fl, const string& name, const string& value, const string& params, bool cmdline) { UINFO(4,"DEFINE '"<v3warn(REDEFMACRO,"Redefining existing define: "<v3warn(REDEFMACRO,"Previous definition is here, with value: "<v3error("Extra underscore in meta-comment; use /*verilator {...}*/ not /*verilator_{...}*/"); } else if (0==(strncmp(cp,"synopsys",strlen("synopsys")))) { cp+=strlen("synopsys"); synth = true; if (*cp == '_') fileline()->v3error("Extra underscore in meta-comment; use /*synopsys {...}*/ not /*synopsys_{...}*/"); } else if (0==(strncmp(cp,"cadence",strlen("cadence")))) { cp+=strlen("cadence"); synth = true; } else if (0==(strncmp(cp,"pragma",strlen("pragma")))) { cp+=strlen("pragma"); synth = true; } else if (0==(strncmp(cp,"ambit synthesis",strlen("ambit synthesis")))) { cp+=strlen("ambit synthesis"); synth = true; } else { return; } if (*cp && !isspace(*cp)) return; while (isspace(*cp)) cp++; const char* ep = cp+strlen(cp); if (ep>cp && (ep[-1]=='/' || cp[-2]=='*')) ep-=2; while (ep>cp && (isspace(ep[-1]))) ep--; string cmd (cp, ep-cp); string::size_type pos; while ((pos=cmd.find("\"")) != string::npos) cmd.replace(pos, 1, " "); while ((pos=cmd.find("\t")) != string::npos) cmd.replace(pos, 1, " "); while ((pos=cmd.find(" ")) != string::npos) cmd.replace(pos, 2, " "); if (synth) { if (v3Global.opt.assertOn()) { // one_hot, one_cold, (full_case, parallel_case) if (commentTokenMatch(cmd/*ref*/, "full_case")) { insertUnreadback ("/*verilator full_case*/"); } if (commentTokenMatch(cmd/*ref*/, "parallel_case")) { insertUnreadback ("/*verilator parallel_case*/"); } //if (commentTokenMatch(cmd/*ref*/, "one_hot")) { // insertUnreadback ("/*verilator one_hot*/ "+cmd+";"); //} //if (commentTokenMatch(cmd/*ref*/, "one_cold")) { // insertUnreadback ("/*verilator one_cold*/ "+cmd+";"); //} // else ignore the comment we don't recognize } // else no assertions } else if ((pos=cmd.find("public_flat_rw")) != string::npos) { // "/*verilator public_flat_rw @(foo) */" -> "/*verilator public_flat_rw*/ @(foo)" cmd = cmd.substr(pos+strlen("public_flat_rw")); while (isspace(cmd[0])) cmd = cmd.substr(1); if ((pos=cmd.find("*/")) != string::npos) cmd.replace(pos, 2, ""); insertUnreadback ("/*verilator public_flat_rw*/ "+cmd+" /**/"); } else { insertUnreadback ("/*verilator "+cmd+"*/"); } } //************************************************************************* // VPreProc Methods. FileLine* V3PreProc::fileline() { V3PreProcImp* idatap = static_cast(this); return idatap->m_lexp->m_tokFilelinep; } //********************************************************************** // Parser Utilities const char* V3PreProcImp::tokenName(int tok) { switch (tok) { case VP_BACKQUOTE : return("BACKQUOTE"); case VP_COMMENT : return("COMMENT"); case VP_DEFARG : return("DEFARG"); case VP_DEFFORM : return("DEFFORM"); case VP_DEFINE : return("DEFINE"); case VP_DEFREF : return("DEFREF"); case VP_DEFREF_JOIN : return("DEFREF_JOIN"); case VP_DEFVALUE : return("DEFVALUE"); case VP_ELSE : return("ELSE"); case VP_ELSIF : return("ELSIF"); case VP_ENDIF : return("ENDIF"); case VP_EOF : return("EOF"); case VP_ERROR : return("ERROR"); case VP_IFDEF : return("IFDEF"); case VP_IFNDEF : return("IFNDEF"); case VP_INCLUDE : return("INCLUDE"); case VP_LINE : return("LINE"); case VP_STRIFY : return("STRIFY"); case VP_STRING : return("STRING"); case VP_SYMBOL : return("SYMBOL"); case VP_SYMBOL_JOIN : return("SYMBOL_JOIN"); case VP_TEXT : return("TEXT"); case VP_UNDEF : return("UNDEF"); case VP_UNDEFINEALL : return("UNDEFINEALL"); case VP_WHITE : return("WHITE"); default: return("?"); } } void V3PreProcImp::unputString(const string& strg) { // Note: The preliminary call in ::openFile bypasses this function // We used to just m_lexp->unputString(strg.c_str()); // However this can lead to "flex scanner push-back overflow" // so instead we scan from a temporary buffer, then on EOF return. // This is also faster than the old scheme, amazingly. if (m_lexp->m_bufferState!=m_lexp->currentBuffer()) { fatalSrc("bufferStack missing current buffer; will return incorrectly"); // Hard to debug lost text as won't know till much later } m_lexp->scanBytes(strg); } void V3PreProcImp::unputDefrefString(const string& strg) { int multiline = 0; for (size_t i=0; icurStreamp()->m_ignNewlines += multiline; // Must be after unput - applies to new stream } string V3PreProcImp::trimWhitespace(const string& strg, bool trailing) { // Remove leading whitespace string out = strg; string::size_type leadspace = 0; while (out.length() > leadspace && isspace(out[leadspace])) leadspace++; if (leadspace) out.erase(0,leadspace); // Remove trailing whitespace if (trailing) { string::size_type trailspace = 0; while (out.length() > trailspace && isspace(out[out.length()-1-trailspace])) trailspace++; // Don't remove \{space_or_newline} if (trailspace && out.length() > trailspace && out[out.length()-1-trailspace]=='\\') trailspace--; if (trailspace) out.erase(out.length()-trailspace,trailspace); } return out; } string V3PreProcImp::defineSubst(V3DefineRef* refp) { // Substitute out defines in a define reference. // (We also need to call here on non-param defines to handle `") // We could push the define text back into the lexer, but that's slow // and would make recursive definitions and parameter handling nasty. // // Note we parse the definition parameters and value here. If a // parametrized define is used many, many times, we could cache the // parsed result. UINFO(4,"defineSubstIn `"<name()<<" "<params()<args().size(); i++) { UINFO(4,"defineArg["<args()[i]<<"'"<name()); UINFO(4,"defineValue '"< argValueByName; { // Parse argument list into map unsigned numArgs=0; string argName; int paren = 1; // (), {} and [] can use same counter, as must be matched pair per spec string token; bool quote = false; bool haveDefault = false; // Note there's a leading ( and trailing ), so parens==1 is the base parsing level string params = refp->params(); // Must keep in scope const char* cp=params.c_str(); if (*cp == '(') cp++; for (; *cp; cp++) { //UINFO(4," Parse Paren="<args().size() > numArgs) { // A call `def( a ) must be equivelent to `def(a ), so trimWhitespace // At one point we didn't trim trailing whitespace, but this confuses `" string arg = trimWhitespace(refp->args()[numArgs], true); if (arg != "") value = arg; } else if (!haveDefault) { error("Define missing argument '"+argName+"' for: "+refp->name()+"\n"); return " `"+refp->name()+" "; } numArgs++; } argValueByName[argName] = value; // Prepare for next argName = ""; token = ""; haveDefault = false; continue; } else if (*cp=='=') { haveDefault = true; argName = token; token = ""; continue; } } if (cp[0]=='\\' && cp[1]) { token += cp[0]; // \{any} Put out literal next character token += cp[1]; cp++; continue; } if (!quote) { if (*cp=='(' || *cp=='{' || *cp=='[') paren++; else if (*cp==')' || *cp=='}' || *cp==']') paren--; } if (*cp=='"') quote=!quote; if (*cp) token += *cp; } if (refp->args().size() > numArgs // `define X() is ok to call with nothing && !(refp->args().size()==1 && numArgs==0 && trimWhitespace(refp->args()[0],false)=="")) { error("Define passed too many arguments: "+refp->name()+"\n"); return " `"+refp->name()+" "; } } string out = ""; { // Parse substitution define using arguments string argName; bool quote = false; bool backslashesc = false; // In \.....{space} block // Note we go through the loop once more at the NULL end-of-string for (const char* cp=value.c_str(); (*cp) || argName!=""; cp=(*cp?cp+1:cp)) { //UINFO(4, "CH "<<*cp<<" an "<::iterator iter = argValueByName.find(argName); if (iter != argValueByName.end()) { // Substitute string subst = iter->second; out += subst; } else { out += argName; } argName = ""; } if (!quote) { // Check for `` only after we've detected end-of-argname if (cp[0]=='`' && cp[1]=='`') { if (backslashesc) { // Don't put out the ``, we're forming an escape which will not expand further later } else { out += "``"; // `` must get removed later, as `FOO```BAR must pre-expand FOO and BAR } cp++; continue; } else if (cp[0]=='`' && cp[1]=='"') { out += "`\""; // `" means to put out a " without enabling quote mode (sort of) // however we must expand any macro calls inside it first. // So keep it `", so we don't enter quote mode. cp++; continue; } else if (cp[0]=='`' && cp[1]=='\\' && cp[2]=='`' && cp[3]=='"') { out += "`\\`\""; // `\`" means to put out a backslash quote // Leave it literal until we parse the VP_STRIFY string cp+=3; continue; } else if (cp[0]=='`' && cp[1]=='\\') { out += '\\'; // `\ means to put out a backslash cp++; continue; } else if (cp[0]=='\\' && cp[1]=='\n') { // We kept the \\n when we lexed because we don't want whitespace // trimming to mis-drop the final \\n // At replacement time we need the standard newline. out += "\n"; // \\n newline cp++; continue; } } if (cp[0]=='\\' && cp[1]=='\"') { out += cp[0]; // \{any} Put out literal next character out += cp[1]; cp++; continue; } else if (cp[0]=='\\') { // Normally \{any} would put out literal next character // Instead we allow "`define A(nm) \nm" to expand, per proposed mantis1537 out += cp[0]; continue; } if (*cp=='"') quote=!quote; if (*cp) out += *cp; } } UINFO(4,"defineSubstOut '"< with the whole file. StrList wholefile; bool ok = filterp->readWholefile(filename, wholefile/*ref*/); if (!ok) { error("File not found: "+filename+"\n"); return; } if (!m_preprocp->isEof()) { // IE not the first file. // We allow the same include file twice, because occasionally it pops // up, with guards preventing a real recursion. if (m_lexp->m_streampStack.size()>V3PreProc::INCLUDE_DEPTH_MAX) { error("Recursive inclusion of file: "+filename); return; } // There's already a file active. Push it to work on the new one. addLineComment(0); } // Create new stream structure m_lexp->scanNewFile(m_preprocp->fileline()->create(filename, 1)); addLineComment(1); // Enter // Filter all DOS CR's en-mass. This avoids bugs with lexing CRs in the wrong places. // This will also strip them from strings, but strings aren't supposed to be multi-line without a "\" for (StrList::iterator it=wholefile.begin(); it!=wholefile.end(); ++it) { // We don't end-loop at \0 as we allow and strip mid-string '\0's (for now). bool strip = false; const char* sp = it->data(); const char* ep = sp + it->length(); // Only process if needed, as saves extra string allocations for (const char* cp=sp; cplength()); for (const char* cp=sp; cpscanBytesBack(*it); // Reclaim memory; the push saved the string contents for us *it = ""; } } void V3PreProcImp::insertUnreadbackAtBol(const string& text) { // Insert insuring we're at the beginning of line, for `line // We don't always add a leading newline, as it may result in extra unreadback(newlines). if (m_lineCmt == "") { m_lineCmtNl = true; } else if (m_lineCmt[m_lineCmt.length()-1]!='\n') { insertUnreadback("\n"); } insertUnreadback(text); } void V3PreProcImp::addLineComment(int enter_exit_level) { if (lineDirectives()) { insertUnreadbackAtBol(m_lexp->curFilelinep()->lineDirectiveStrg(enter_exit_level)); } } int V3PreProcImp::getRawToken() { // Get a token from the file, whatever it may be. while (1) { next_tok: if (m_lineAdd) { m_lineAdd--; m_rawAtBol = true; yyourtext("\n",1); if (debug()>=5) debugToken(VP_WHITE, "LNA"); return (VP_WHITE); } if (m_lineCmt!="") { // We have some `line directive or other processed data to return to the user. static string rtncmt; // Keep the c string till next call rtncmt = m_lineCmt; if (m_lineCmtNl) { if (!m_rawAtBol) rtncmt = "\n"+rtncmt; m_lineCmtNl = false; } yyourtext(rtncmt.c_str(), rtncmt.length()); m_lineCmt = ""; if (yyourleng()) m_rawAtBol = (yyourtext()[yyourleng()-1]=='\n'); if (m_states.top()==ps_DEFVALUE) { V3PreLex::s_currentLexp->appendDefValue(yyourtext(),yyourleng()); goto next_tok; } else { if (debug()>=5) debugToken(VP_TEXT, "LCM"); return (VP_TEXT); } } if (isEof()) return (VP_EOF); // Snarf next token from the file int tok = m_lexp->lex(); if (debug()>=5) debugToken(tok, "RAW"); // A EOF on an include, so we can print `line and detect mis-matched "s if (tok==VP_EOF) { goto next_tok; // find the EOF, after adding needed lines } if (yyourleng()) m_rawAtBol = (yyourtext()[yyourleng()-1]=='\n'); return tok; } } void V3PreProcImp::debugToken(int tok, const char* cmtp) { if (debug()>=5) { string buf = string (yyourtext(), yyourleng()); string::size_type pos; while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); } while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); } fprintf (stderr, "%d: %s %s %s(%d) dr%d: <%d>%-10s: %s\n", m_lexp->m_tokFilelinep->lineno(), cmtp, m_off?"of":"on", procStateName(m_states.top()), (int)m_states.size(), (int)m_defRefs.size(), m_lexp->currentStartState(), tokenName(tok), buf.c_str()); } } // Sorry, we're not using bison/yacc. It doesn't handle returning white space // in the middle of parsing other tokens. int V3PreProcImp::getStateToken() { // Return the next state-determined token while (1) { next_tok: if (isEof()) return VP_EOF; int tok = getRawToken(); ProcState state = m_states.top(); // Most states emit white space and comments between tokens. (Unless collecting a string) if (tok==VP_WHITE && state !=ps_STRIFY) return (tok); if (tok==VP_BACKQUOTE && state !=ps_STRIFY) { tok = VP_TEXT; } if (tok==VP_COMMENT) { if (!m_off) { if (m_lexp->m_keepComments == KEEPCMT_SUB) { string rtn; rtn.assign(yyourtext(),yyourleng()); comment(rtn); // Need to insure "foo/**/bar" becomes two tokens insertUnreadback (" "); } else if (m_lexp->m_keepComments) { return (tok); } else { // Need to insure "foo/**/bar" becomes two tokens insertUnreadback (" "); } } // We're off or processed the comment specially. If there are newlines // in it, we also return the newlines as TEXT so that the linenumber // count is maintained for downstream tools for (size_t len=0; len<(size_t)yyourleng(); len++) { if (yyourtext()[len]=='\n') m_lineAdd++; } goto next_tok; } if (tok==VP_LINE) { addLineComment(m_lexp->m_enterExit); goto next_tok; } if (tok==VP_DEFREF_JOIN) { // Here's something fun and unspecified as yet: // The existance of non-existance of a base define changes `` expansion // `define QA_b zzz // `define Q1 `QA``_b // 1Q1 -> zzz // `define QA a // `Q1 -> a_b // Note parenthesis make this unambiguous // `define Q1 `QA()``_b // -> a_b // This may be a side effect of how `UNDEFINED remains as `UNDEFINED, // but it screws up our method here. So hardcode it. string name (yyourtext()+1,yyourleng()-1); if (defExists(name)) { // JOIN(DEFREF) // Put back the `` and process the defref UINFO(5,"```: define "< string doesn't include the ``, so can just grab next and continue string out (yyourtext(),yyourleng()); UINFO(5,"`` LHS:"<pushStateDefForm(); goto next_tok; } else fatalSrc("Bad case\n"); goto next_tok; } else if (tok==VP_TEXT) { // IE, something like comment between define and symbol if (!m_off) return tok; else goto next_tok; } else if (tok==VP_DEFREF) { // IE, `ifdef `MACRO(x): Substitue and come back here when state pops. break; } else { error((string)"Expecting define name. Found: "+tokenName(tok)+"\n"); goto next_tok; } } case ps_DEFFORM: { if (tok==VP_DEFFORM) { m_formals = m_lexp->m_defValue; if (debug()>=5) cout<<"DefFormals='"<pushStateDefValue(); goto next_tok; } else if (tok==VP_TEXT) { // IE, something like comment in formals if (!m_off) return tok; else goto next_tok; } else { error((string)"Expecting define formal arguments. Found: "+tokenName(tok)+"\n"); goto next_tok; } } case ps_DEFVALUE: { static string newlines; newlines = "\n"; // Always start with trailing return if (tok == VP_DEFVALUE) { if (debug()>=5) cout<<"DefValue='"<m_defValue) <<"' formals='"<m_defValue; // Remove returns // Not removing returns in values has two problems, // 1. we need to correct line numbers with `line after each substitution // 2. Substituting in " .... " with embedded returns requires \ escape. // This is very difficult in the presence of `", so we keep the \ before the newline. for (size_t i=0; iname()+"\n"); statePop(); goto next_tok; } } case ps_DEFARG: { if (m_defRefs.empty()) fatalSrc("Shouldn't be in DEFARG w/o active defref"); V3DefineRef* refp = &(m_defRefs.top()); refp->nextarg(refp->nextarg()+m_lexp->m_defValue); m_lexp->m_defValue=""; UINFO(4,"defarg++ "<nextarg()<args().push_back(refp->nextarg()); stateChange(ps_DEFARG); m_lexp->pushStateDefArg(1); refp->nextarg(""); goto next_tok; } else if (tok==VP_DEFARG && yyourleng()==1 && yyourtext()[0]==')') { // Substitute in and prepare for next action // Similar code in non-parenthesized define (Search for END_OF_DEFARG) refp->args().push_back(refp->nextarg()); string out; if (!m_off) { out = defineSubst(refp); //NOP: out = m_preprocp->defSubstitute(out); } m_defRefs.pop(); refp=NULL; if (m_defRefs.empty()) { statePop(); if (!m_off) unputDefrefString(out); m_lexp->m_parenLevel = 0; } else { // Finished a defref inside a upper defref // Can't subst now, or // `define a(ign) x,y // foo(`a(ign),`b) would break because a contains comma refp = &(m_defRefs.top()); // We popped, so new top refp->nextarg(refp->nextarg()+m_lexp->m_defValue+out); m_lexp->m_defValue=""; m_lexp->m_parenLevel = refp->parenLevel(); statePop(); // Will go to ps_DEFARG, as we're under another define } goto next_tok; } else if (tok==VP_DEFREF) { // Expand it, then state will come back here // Value of building argument is data before the lower defref // we'll append it when we push the argument. break; } else if (tok==VP_SYMBOL || tok==VP_STRING || VP_TEXT || VP_WHITE) { string rtn; rtn.assign(yyourtext(),yyourleng()); refp->nextarg(refp->nextarg()+rtn); goto next_tok; } else { error((string)"Expecting ) or , to end argument list for define reference. Found: "+tokenName(tok)); statePop(); goto next_tok; } } case ps_INCNAME: { if (tok==VP_STRING) { statePop(); m_lastSym.assign(yyourtext(),yyourleng()); UINFO(4,"Include "< stateChange(ps_INCNAME); // Still m_lexp->pushStateIncFilename(); goto next_tok; } else if (tok==VP_DEFREF || tok==VP_STRIFY) { // Expand it, then state will come back here break; } else { statePop(); error((string)"Expecting include filename. Found: "+tokenName(tok)+"\n"); goto next_tok; } } case ps_ERRORNAME: { if (tok==VP_STRING) { if (!m_off) { m_lastSym.assign(yyourtext(),yyourleng()); error(m_lastSym); } statePop(); goto next_tok; } else { error((string)"Expecting `error string. Found: "+tokenName(tok)+"\n"); statePop(); goto next_tok; } } case ps_JOIN: { if (tok==VP_SYMBOL || tok==VP_TEXT) { if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``"); string lhs = m_joinStack.top(); m_joinStack.pop(); UINFO(5,"`` LHS:"< V3PreProc::DEFINE_RECURSION_LEVEL_MAX) { error("Recursive `define substitution: `"+name); goto next_tok; } // substitute if (!defExists(name)) { // Not found, return original string as-is m_defDepth = 0; UINFO(4,"Defref `"< not_defined"<defSubstitute(out); if (m_defRefs.empty()) { // Just output the substitution unputDefrefString(out); } else { // Inside another define. // Can't subst now, or // `define a x,y // foo(`a,`b) would break because a contains comma V3DefineRef* refp = &(m_defRefs.top()); refp->nextarg(refp->nextarg()+m_lexp->m_defValue+out); m_lexp->m_defValue=""; } goto next_tok; } } else { // Found, with parameters UINFO(4,"Defref `"< parameterized"<m_parenLevel); m_defRefs.push(V3DefineRef(name, params)); statePush(ps_DEFPAREN); m_lexp->pushStateDefArg(0); goto next_tok; } } fatalSrc("Bad case\n"); } case VP_ERROR: { statePush(ps_ERRORNAME); goto next_tok; } case VP_EOF: if (!m_ifdefStack.empty()) { error("`ifdef not terminated at EOF\n"); } return tok; case VP_UNDEFINEALL: if (!m_off) { UINFO(4,"Undefineall "<=5) { string bufcln = V3PreLex::cleanDbgStrg(buf); fprintf (stderr,"%d: FIN: %-10s: %s\n", m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str()); } // Track `line const char* bufp = buf.c_str(); while (*bufp == '\n') bufp++; if ((tok == VP_TEXT || tok == VP_LINE) && 0==strncmp(bufp,"`line ",6)) { int enter; m_finFilelinep->lineDirective(bufp, enter/*ref*/); } else { if (m_finAtBol && !(tok==VP_TEXT && buf=="\n") && m_preprocp->lineDirectives()) { if (int outBehind = m_lexp->m_tokFilelinep->lineno() - m_finFilelinep->lineno()) { if (debug()>=5) fprintf(stderr,"%d: FIN: readjust, fin at %d request at %d\n", m_lexp->m_tokFilelinep->lineno(), m_finFilelinep->lineno(), m_lexp->m_tokFilelinep->lineno()); m_finFilelinep = m_finFilelinep->create(m_lexp->m_tokFilelinep->filename(),m_lexp->m_tokFilelinep->lineno()); if (outBehind > 0 && outBehind <= (int)V3PreProc::NEWLINES_VS_TICKLINE) { // Output stream is behind, send newlines to get back in sync // (Most likely because we're completing a disabled `endif) if (m_preprocp->keepWhitespace()) { buf = string(outBehind,'\n'); return VP_TEXT; } } else { // Need to backup, use `line buf = m_finFilelinep->lineDirectiveStrg(0); return VP_LINE; } } } // Track newlines in prep for next token for (string::iterator cp=buf.begin(); cp!=buf.end(); ++cp) { if (*cp == '\n') { m_finAtBol = true; m_finFilelinep->linenoIncInPlace(); // Increment in place to avoid new/delete calls. It's private data. } else { m_finAtBol = false; } } } m_finAhead = false; // Consumed the token return tok; } string V3PreProcImp::getline() { // Get a single line from the parse stream. Buffer unreturned text until the newline. if (isEof()) return ""; const char* rtnp; bool gotEof = false; while (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n')) && !gotEof) { string buf; int tok = getFinalToken(buf/*ref*/); if (debug()>=5) { string bufcln = V3PreLex::cleanDbgStrg(buf); fprintf (stderr,"%d: GETFETC: %-10s: %s\n", m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str()); } if (tok==VP_EOF) { // Add a final newline, if the user forgot the final \n. if (m_lineChars != "" && m_lineChars[m_lineChars.length()-1] != '\n') { m_lineChars.append("\n"); } gotEof = true; } else { m_lineChars.append(buf); } } // Make new string with data up to the newline. int len = rtnp-m_lineChars.c_str()+1; string theLine(m_lineChars, 0, len); m_lineChars = m_lineChars.erase(0,len); // Remove returned characters if (debug()>=4) { string lncln = V3PreLex::cleanDbgStrg(theLine); fprintf (stderr,"%d: GETLINE: %s\n", m_lexp->m_tokFilelinep->lineno(), lncln.c_str()); } return theLine; } verilator-3.874/src/V3Subst.h0000664000177100017500000000230212525171733015777 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Substitute constants and expressions in expr temp's // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3SUBST_H_ #define _V3SUBST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Subst { public: static void substituteAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Config.h0000664000177100017500000000240712525171733016112 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Configuration Files // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2010-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CONFIG_H_ #define _V3CONFIG_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.h" #include "V3FileLine.h" //###################################################################### class V3Config { public: static void addIgnore(V3ErrorCode code, string filename, int min, int max); static void applyIgnores(FileLine* filelinep); }; #endif // Guard verilator-3.874/src/V3EmitCInlines.cpp0000664000177100017500000000766312525171733017574 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit C++ for tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3EmitC.h" #include "V3EmitCBase.h" #include "V3Stats.h" #define EMITCINLINES_NUM_CONSTW 10 // Number of VL_CONST_W_*X's in verilated.h (IE VL_CONST_W_9X is last) //###################################################################### class EmitCInlines : EmitCBaseVisitor { // STATE vector m_wordWidths; // What sizes are used? // METHODS void emitInt(); // VISITORS virtual void visit(AstVar* nodep, AstNUser*) { // All wide constants load into variables, so we can just hunt for them nodep->iterateChildren(*this); int words = nodep->widthWords(); if (words >= EMITCINLINES_NUM_CONSTW ) { if (int(m_wordWidths.size()) <= words) { m_wordWidths.resize(words+5); } ++ m_wordWidths.at(words); v3Global.needHInlines(true); } } virtual void visit(AstBasicDType* nodep, AstNUser*) { if (nodep->keyword() == AstBasicDTypeKwd::STRING) { v3Global.needHeavy(true); // #include via verilated_heavy.h when we create symbol file } } // NOPs virtual void visit(AstNodeStmt*, AstNUser*) {} // Default virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } //--------------------------------------- // ACCESSORS public: EmitCInlines(AstNetlist* nodep) { nodep->accept(*this); if (v3Global.needHInlines()) { emitInt(); } } }; void EmitCInlines::emitInt() { string filename = v3Global.opt.makeDir()+"/"+topClassName()+"__Inlines.h"; newCFile(filename, false/*slow*/, false/*source*/); V3OutCFile hf (filename); m_ofp = &hf; ofp()->putsHeader(); puts("#ifndef _"+topClassName()+"__Inlines_H_\n"); puts("#define _"+topClassName()+"__Inlines_H_\n"); puts("\n"); puts("#include \"verilated.h\"\n"); puts("\n//======================\n\n"); for (unsigned words=0; words=0; --i) { puts(",IData d"+cvtToStr(i)); if (i && (i % 8 == 0)) puts("\n\t"); } puts(") {\n"); puts(" "); for (int i=words-1; i>=0; --i) { puts(" o["+cvtToStr(i)+"]=d"+cvtToStr(i)+";"); if (i && (i % 8 == 0)) puts("\n "); } puts("\n"); puts(" for(int i="+cvtToStr(words)+";i #include #include #include "V3Global.h" #include "V3String.h" #include "V3Config.h" //###################################################################### class V3ConfigLine { public: int m_lineno; // Line number to make change at V3ErrorCode m_code; // Error code bool m_on; // True to enaable message V3ConfigLine(V3ErrorCode code, int lineno, bool on) : m_lineno(lineno), m_code(code), m_on(on) {} ~V3ConfigLine() {} inline bool operator< (const V3ConfigLine& rh) const { if (m_linenorh.m_lineno) return false; if (m_coderh.m_code) return false; // Always turn "on" before "off" so that overlapping lines will end up finally with the error "off" return (m_on>rh.m_on); } }; ostream& operator<<(ostream& os, V3ConfigLine rhs) { return os< IgnLines; // list of {line,code,on} typedef map IgnFiles; // {filename} => list of {line,code,on} // MEMBERS string m_lastFilename; // Last filename looked up int m_lastLineno; // Last linenumber looked up IgnLines::const_iterator m_lastIt; // Point with next linenumber > current line number IgnLines::const_iterator m_lastEnd; // Point with end() IgnFiles m_ignWilds; // Ignores for each wildcarded filename IgnFiles m_ignFiles; // Ignores for each non-wildcarded filename static V3ConfigIgnores s_singleton; // Singleton (not via local static, as that's slow) V3ConfigIgnores() { m_lastLineno = -1; } ~V3ConfigIgnores() {} // METHODS inline IgnLines* findWilds(const string& wildname) { IgnFiles::iterator it = m_ignWilds.find(wildname); if (it != m_ignWilds.end()) { return &(it->second); } else { m_ignWilds.insert(make_pair(wildname, IgnLines())); it = m_ignWilds.find(wildname); return &(it->second); } } inline void absBuild(const string& filename) { // Given a filename, find all wildcard matches against it and build // hash with the specific filename. This avoids having to wildmatch // more than once against any filename. IgnFiles::iterator it = m_ignFiles.find(filename); if (it == m_ignFiles.end()) { // Haven't seen this filename before m_ignFiles.insert(make_pair(filename, IgnLines())); it = m_ignFiles.find(filename); // Make new list for this file of all matches for (IgnFiles::iterator fnit = m_ignWilds.begin(); fnit != m_ignWilds.end(); ++fnit) { if (VString::wildmatch(filename.c_str(), fnit->first.c_str())) { for (IgnLines::iterator lit = fnit->second.begin(); lit != fnit->second.end(); ++lit) { it->second.insert(*lit); } } } } m_lastIt = it->second.begin(); m_lastEnd = it->second.end(); } public: inline static V3ConfigIgnores& singleton() { return s_singleton; } void addIgnore(V3ErrorCode code, string wildname, int lineno, bool on) { // Insert IgnLines* linesp = findWilds(wildname); UINFO(9,"config addIgnore "<insert(V3ConfigLine(code, lineno, on)); // Flush the match cache, due to a change in the rules. m_ignFiles.clear(); m_lastFilename = " "; } inline void applyIgnores(FileLine* filelinep) { // HOT routine, called each parsed token line if (m_lastLineno != filelinep->lineno() || m_lastFilename != filelinep->filename()) { //UINFO(9," ApplyIgnores for "<ascii()<filename())) { absBuild(filelinep->filename()); m_lastFilename = filelinep->filename(); } // Process all on/offs for lines up to and including the current line int curlineno = filelinep->lineno(); for (; m_lastIt != m_lastEnd; ++m_lastIt) { if (m_lastIt->m_lineno > curlineno) break; //UINFO(9," Hit "<<*m_lastIt<warnOn(m_lastIt->m_code, m_lastIt->m_on); } if (0 && debug() >= 9) { for (IgnLines::const_iterator it=m_lastIt; it != m_lastEnd; ++it) { UINFO(9," NXT "<<*it<lineno(); } } }; V3ConfigIgnores V3ConfigIgnores::s_singleton; //###################################################################### // V3Config void V3Config::addIgnore(V3ErrorCode code, string filename, int min, int max) { if (filename=="*") { FileLine::globalWarnOff(code,true); } else { V3ConfigIgnores::singleton().addIgnore(code, filename, min, false); if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, true); } } void V3Config::applyIgnores(FileLine* filelinep) { V3ConfigIgnores::singleton().applyIgnores(filelinep); } verilator-3.874/src/V3String.cpp0000664000177100017500000000374512525171733016514 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Options parsing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include "V3String.h" //###################################################################### // Wildcard // Double procedures, inlined, unrolls loop much better inline bool VString::wildmatchi(const char* s, const char* p) { for ( ; *p; s++, p++) { if (*p!='*') { if (((*s)!=(*p)) && *p != '?') return false; } else { // Trailing star matches everything. if (!*++p) return true; while (wildmatch(s, p) == false) if (*++s == '\0') return false; return true; } } return (*s == '\0'); } bool VString::wildmatch(const char* s, const char* p) { for ( ; *p; s++, p++) { if (*p!='*') { if (((*s)!=(*p)) && *p != '?') return false; } else { // Trailing star matches everything. if (!*++p) return true; while (wildmatchi(s, p) == false) if (*++s == '\0') return false; return true; } } return (*s == '\0'); } string VString::downcase(const string& str) { string out = str; for (string::iterator pos = out.begin(); pos != out.end(); ++pos) { *pos = tolower(*pos); } return out; } verilator-3.874/src/V3PreShell.cpp0000664000177100017500000001356212525171733016762 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Preprocessing wrapper // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include "V3Global.h" #include "V3PreShell.h" #include "V3PreProc.h" #include "V3File.h" #include "V3Parse.h" //###################################################################### class V3PreShellImp { protected: friend class V3PreShell; static V3PreShellImp s_preImp; static V3PreProc* s_preprocp; static V3InFilter* s_filterp; //--------------------------------------- // METHODS static int debug(bool reset=false) { static int level = -1; if (VL_UNLIKELY(level < 0) || reset) { level = v3Global.opt.debugSrcLevel(__FILE__); if (s_preprocp) s_preprocp->debug(debug()); } return level; } void boot(char** env) { // Create the implementation pointer if (env) {} if (!s_preprocp) { FileLine* cmdfl = new FileLine("COMMAND_LINE",0); s_preprocp = V3PreProc::createPreProc(cmdfl); s_preprocp->debug(debug()); // Default defines FileLine* prefl = new FileLine("INTERNAL_VERILATOR_DEFINE",0); s_preprocp->defineCmdLine(prefl,"VERILATOR", "1"); // LEAK_OK s_preprocp->defineCmdLine(prefl,"verilator", "1"); // LEAK_OK s_preprocp->defineCmdLine(prefl,"verilator3", "1"); // LEAK_OK s_preprocp->defineCmdLine(prefl,"systemc_clock", "/*verilator systemc_clock*/"); // LEAK_OK s_preprocp->defineCmdLine(prefl,"coverage_block_off", "/*verilator coverage_block_off*/"); // LEAK_OK if (prefl->language().systemVerilog()) { // Synthesis compatibility s_preprocp->defineCmdLine(prefl,"SYSTEMVERILOG", "1"); // LEAK_OK // IEEE predefined s_preprocp->defineCmdLine(prefl,"SV_COV_START", "0"); s_preprocp->defineCmdLine(prefl,"SV_COV_STOP", "1"); s_preprocp->defineCmdLine(prefl,"SV_COV_RESET", "2"); s_preprocp->defineCmdLine(prefl,"SV_COV_CHECK", "3"); s_preprocp->defineCmdLine(prefl,"SV_COV_MODULE", "10"); s_preprocp->defineCmdLine(prefl,"SV_COV_HIER", "11"); s_preprocp->defineCmdLine(prefl,"SV_COV_ASSERTION", "20"); s_preprocp->defineCmdLine(prefl,"SV_COV_FSM_STATE", "21"); s_preprocp->defineCmdLine(prefl,"SV_COV_STATEMENT", "22"); s_preprocp->defineCmdLine(prefl,"SV_COV_TOGGLE", "23"); s_preprocp->defineCmdLine(prefl,"SV_COV_OVERFLOW", "-2"); s_preprocp->defineCmdLine(prefl,"SV_COV_ERROR", "-1"); s_preprocp->defineCmdLine(prefl,"SV_COV_NOCOV", "0"); s_preprocp->defineCmdLine(prefl,"SV_COV_OK", "1"); s_preprocp->defineCmdLine(prefl,"SV_COV_PARTIAL", "2"); } } } bool preproc (FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep, const string& errmsg) { // "" for no error debug(true); // Recheck if debug on - first check was before command line passed // Preprocess the given module, putting output in vppFilename UINFONL(1," Preprocessing "<isEof()) { string line = s_preprocp->getline(); V3Parse::ppPushText(parsep, line); } return true; } void preprocInclude (FileLine* fl, const string& modname) { if (modname[0]=='/' || modname[0]=='\\') { fl->v3warn(INCABSPATH,"Suggest `include with absolute path be made relative, and use +include: "<removeDefines (modname); // Open include or master file string filename = v3Global.opt.filePath (fl, ppmodname, errmsg); if (filename=="") return false; // Not found UINFO(2," Reading "<openFile(fl, filterp, filename); return true; } // CONSTRUCTORS V3PreShellImp() {} ~V3PreShellImp() {} }; V3PreShellImp V3PreShellImp::s_preImp; V3PreProc* V3PreShellImp::s_preprocp = NULL; V3InFilter* V3PreShellImp::s_filterp = NULL; //###################################################################### // Perl class functions void V3PreShell::boot(char** env) { V3PreShellImp::s_preImp.boot(env); } bool V3PreShell::preproc(FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep, const string& errmsg) { return V3PreShellImp::s_preImp.preproc(fl, modname, filterp, parsep, errmsg); } void V3PreShell::preprocInclude(FileLine* fl, const string& modname) { V3PreShellImp::s_preImp.preprocInclude(fl, modname); } void V3PreShell::defineCmdLine(const string& name, const string& value) { FileLine* prefl = new FileLine("COMMAND_LINE_DEFINE",0); V3PreShellImp::s_preprocp->defineCmdLine(prefl, name, value); } void V3PreShell::undef(const string& name) { V3PreShellImp::s_preprocp->undef(name); } verilator-3.874/src/V3Number.h0000664000177100017500000003650412525172076016143 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Large 4-state numbers // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3NUMBER_H_ #define _V3NUMBER_H_ 1 #include "config_build.h" #include "verilatedos.h" #include #include "V3Error.h" #include "V3FileLine.h" //============================================================================ class V3Number { // Large 4-state number handling int m_width; // Width as specified/calculated. bool m_sized:1; // True if the user specified the width, else we track it. bool m_signed:1; // True if signed value bool m_double:1; // True if double real value bool m_isString:1; // True if string bool m_fromString:1; // True if from string literal bool m_autoExtend:1; // True if SystemVerilog extend-to-any-width FileLine* m_fileline; vector m_value; // The Value, with bit 0 being in bit 0 of this vector (unless X/Z) vector m_valueX; // Each bit is true if it's X or Z, 10=z, 11=x string m_stringVal; // If isString, the value of the string // METHODS V3Number& setSingleBits(char value); V3Number& setString(const string& str) { m_isString=true; m_stringVal=str; return *this; } void opCleanThis(); public: FileLine* fileline() const { return m_fileline; } void fileline(FileLine* fl) { m_fileline=fl; } V3Number& setZero(); V3Number& setQuad(vluint64_t value); V3Number& setLong(uint32_t value); V3Number& setLongS(vlsint32_t value); V3Number& setDouble(double value); void setBit (int bit, char value) { // Note must be pre-zeroed! if (bit>=m_width) return; if (value=='0'||value==0) m_value [bit/32] &= ~(1UL<<(bit&31)); else { if (value=='1'||value=='x'||value==1||value==3) m_value [bit/32] |= (1UL<<(bit&31)); if (value=='z'||value=='x'||value==2||value==3) m_valueX[bit/32] |= (1UL<<(bit&31)); } } private: char bitIs (int bit) const { if (bit>=m_width || bit<0) { // We never sign extend return '0'; } return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0) | ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); } char bitIsExtend (int bit, int lbits) const { // lbits usually = width, but for C optimizations width=32_bits, lbits = 32_or_less if (bit<0) return '0'; UASSERT(lbits<=m_width, "Extend of wrong size"); if (bit>=lbits) { bit = lbits ? lbits-1 : 0; // We do sign extend return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0) | ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); } return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0) | ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); } bool bitIs0 (int bit) const { if (bit<0) return false; if (bit>=m_width) return !bitIsXZ(m_width-1); return ( (m_value[bit/32] & (1UL<<(bit&31)))==0 && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); } bool bitIs1 (int bit) const { if (bit<0) return false; if (bit>=m_width) return false; return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); } bool bitIs1Extend (int bit) const { if (bit<0) return false; if (bit>=m_width) return bitIs1Extend(m_width-1); return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); } bool bitIsX (int bit) const { if (bit<0) return false; if (bit>=m_width) return bitIsZ(m_width-1); return ( (m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); } bool bitIsXZ(int bit) const { if (bit<0) return false; if (bit>=m_width) return bitIsXZ(m_width-1); return ( (m_valueX[bit/32] & (1UL<<(bit&31)))); } bool bitIsZ (int bit) const { if (bit<0) return false; if (bit>=m_width) return bitIsZ(m_width-1); return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); } uint32_t bitsValue(int lsb, int nbits) const { uint32_t v=0; for (int bitn=0; bitn0b11, if 3->0b111 etc // ACCESSORS string ascii(bool prefixed=true, bool cleanVerilog=false) const; static string quoteNameControls(const string& namein); // Add backslash quotes to strings string displayed(const string& format) const; static bool displayedFmtLegal(char format); // Is this a valid format letter? int width() const { return m_width; } int widthMin() const; // Minimum width that can represent this number (~== log2(num)+1) bool sized() const { return m_sized; } bool autoExtend() const { return m_autoExtend; } bool isFromString() const { return m_fromString; } bool isSigned() const { return m_signed; } // Only correct for parsing of numbers from strings, otherwise not used (use AstConst::isSigned()) bool isDouble() const { return m_double; } // Only correct for parsing of numbers from strings, otherwise not used (use AstConst::isSigned()) void isDouble(bool flag) { m_double=flag; } // Only if have 64 bit value loaded, and want to indicate it's real bool isString() const { return m_isString; } void isString(bool flag) { m_isString=flag; } bool isNegative() const { return bitIs1(width()-1); } bool isFourState() const { for (int i=0;i1, X/Z->0 V3Number& opBitsOne (const V3Number& lhs); // 1->1, 0/X/Z->0 V3Number& opBitsXZ (const V3Number& lhs); // 0/1->0, X/Z->1 V3Number& opBitsZ (const V3Number& lhs); // Z->1, 0/1/X->0 V3Number& opBitsNonZ(const V3Number& lhs); // Z->0, 0/1/X->1 // V3Number& opAssign (const V3Number& lhs); V3Number& opExtendS (const V3Number& lhs, uint32_t lbits); // Sign extension V3Number& opRedOr (const V3Number& lhs); V3Number& opRedAnd (const V3Number& lhs); V3Number& opRedXor (const V3Number& lhs); V3Number& opRedXnor (const V3Number& lhs); V3Number& opCountOnes(const V3Number& lhs); V3Number& opIsUnknown(const V3Number& lhs); V3Number& opOneHot (const V3Number& lhs); V3Number& opOneHot0 (const V3Number& lhs); V3Number& opCLog2 (const V3Number& lhs); V3Number& opClean (const V3Number& lhs, uint32_t bits); V3Number& opConcat (const V3Number& lhs, const V3Number& rhs); V3Number& opRepl (const V3Number& lhs, const V3Number& rhs); V3Number& opRepl (const V3Number& lhs, uint32_t rhs); V3Number& opStreamL (const V3Number& lhs, const V3Number& rhs); V3Number& opSel (const V3Number& lhs, const V3Number& rhs, const V3Number& ths); V3Number& opSel (const V3Number& lhs, uint32_t rhs, uint32_t ths); V3Number& opSelInto (const V3Number& lhs, const V3Number& lsb, int width); V3Number& opSelInto (const V3Number& lhs, int lsb, int width); V3Number& opCond (const V3Number& lhs, const V3Number& rhs, const V3Number& ths); V3Number& opCaseEq (const V3Number& lhs, const V3Number& rhs); V3Number& opCaseNeq (const V3Number& lhs, const V3Number& rhs); V3Number& opWildEq (const V3Number& lhs, const V3Number& rhs); V3Number& opWildNeq (const V3Number& lhs, const V3Number& rhs); V3Number& opBufIf1 (const V3Number& lhs, const V3Number& rhs); // "standard" math V3Number& opNot (const V3Number& lhs); V3Number& opLogNot (const V3Number& lhs); V3Number& opLogAnd (const V3Number& lhs, const V3Number& rhs); V3Number& opLogOr (const V3Number& lhs, const V3Number& rhs); V3Number& opLogIf (const V3Number& lhs, const V3Number& rhs); V3Number& opLogIff (const V3Number& lhs, const V3Number& rhs); V3Number& opAbsS (const V3Number& lhs); V3Number& opNegate (const V3Number& lhs); V3Number& opAdd (const V3Number& lhs, const V3Number& rhs); V3Number& opSub (const V3Number& lhs, const V3Number& rhs); V3Number& opMul (const V3Number& lhs, const V3Number& rhs); V3Number& opMulS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opDiv (const V3Number& lhs, const V3Number& rhs); V3Number& opDivS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opModDiv (const V3Number& lhs, const V3Number& rhs); V3Number& opModDivS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opPow (const V3Number& lhs, const V3Number& rhs, bool lsign=false, bool rsign=false); V3Number& opPowSU (const V3Number& lhs, const V3Number& rhs); // Signed lhs, unsigned rhs V3Number& opPowSS (const V3Number& lhs, const V3Number& rhs); // Signed lhs, signed rhs V3Number& opPowUS (const V3Number& lhs, const V3Number& rhs); // Unsigned lhs, signed rhs V3Number& opAnd (const V3Number& lhs, const V3Number& rhs); V3Number& opChangeXor(const V3Number& lhs, const V3Number& rhs); V3Number& opXor (const V3Number& lhs, const V3Number& rhs); V3Number& opXnor (const V3Number& lhs, const V3Number& rhs); V3Number& opOr (const V3Number& lhs, const V3Number& rhs); V3Number& opRotR (const V3Number& lhs, const V3Number& rhs); V3Number& opRotL (const V3Number& lhs, const V3Number& rhs); V3Number& opShiftR (const V3Number& lhs, const V3Number& rhs); V3Number& opShiftRS (const V3Number& lhs, const V3Number& rhs, uint32_t lbits); // Arithmetic w/carry V3Number& opShiftL (const V3Number& lhs, const V3Number& rhs); // Comparisons V3Number& opEq (const V3Number& lhs, const V3Number& rhs); V3Number& opNeq (const V3Number& lhs, const V3Number& rhs); V3Number& opGt (const V3Number& lhs, const V3Number& rhs); V3Number& opGtS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opGte (const V3Number& lhs, const V3Number& rhs); V3Number& opGteS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opLt (const V3Number& lhs, const V3Number& rhs); V3Number& opLtS (const V3Number& lhs, const V3Number& rhs); // Signed V3Number& opLte (const V3Number& lhs, const V3Number& rhs); V3Number& opLteS (const V3Number& lhs, const V3Number& rhs); // Signed // "D" - double (aka real) math V3Number& opIToRD (const V3Number& lhs); V3Number& opRToIS (const V3Number& lhs); V3Number& opRToIRoundS (const V3Number& lhs); V3Number& opRealToBits (const V3Number& lhs); V3Number& opBitsToRealD(const V3Number& lhs); V3Number& opNegateD (const V3Number& lhs); V3Number& opAddD (const V3Number& lhs, const V3Number& rhs); V3Number& opSubD (const V3Number& lhs, const V3Number& rhs); V3Number& opMulD (const V3Number& lhs, const V3Number& rhs); V3Number& opDivD (const V3Number& lhs, const V3Number& rhs); V3Number& opPowD (const V3Number& lhs, const V3Number& rhs); // Comparisons V3Number& opEqD (const V3Number& lhs, const V3Number& rhs); V3Number& opNeqD (const V3Number& lhs, const V3Number& rhs); V3Number& opGtD (const V3Number& lhs, const V3Number& rhs); V3Number& opGteD (const V3Number& lhs, const V3Number& rhs); V3Number& opLtD (const V3Number& lhs, const V3Number& rhs); V3Number& opLteD (const V3Number& lhs, const V3Number& rhs); // "N" - string operations V3Number& opConcatN (const V3Number& lhs, const V3Number& rhs); V3Number& opReplN (const V3Number& lhs, const V3Number& rhs); V3Number& opReplN (const V3Number& lhs, uint32_t rhs); V3Number& opEqN (const V3Number& lhs, const V3Number& rhs); V3Number& opNeqN (const V3Number& lhs, const V3Number& rhs); V3Number& opGtN (const V3Number& lhs, const V3Number& rhs); V3Number& opGteN (const V3Number& lhs, const V3Number& rhs); V3Number& opLtN (const V3Number& lhs, const V3Number& rhs); V3Number& opLteN (const V3Number& lhs, const V3Number& rhs); }; inline ostream& operator<<(ostream& os, V3Number rhs) { return os< #include #include #include #include "V3Global.h" #include "V3Branch.h" #include "V3Ast.h" //###################################################################### // Branch state, as a visitor of each AstNode class BranchVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstFTask::user1() -> int. Number of references AstUser1InUse m_inuser1; // TYPES typedef vector CFuncVec; // STATE int m_likely; // Excuses for branch likely taken int m_unlikely; // Excuses for branch likely not taken CFuncVec m_cfuncsp; // List of all tasks // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void reset() { m_likely = false; m_unlikely = false; } void checkUnlikely(AstNode* nodep) { if (nodep->isUnlikely()) { UINFO(4," UNLIKELY: "<ifsp()->iterateAndNext(*this); int ifLikely = m_likely; int ifUnlikely = m_unlikely; // Do else reset(); nodep->elsesp()->iterateAndNext(*this); int elseLikely = m_likely; int elseUnlikely = m_unlikely; // Compute int likeness = ifLikely - ifUnlikely - (elseLikely - elseUnlikely); if (likeness>0) { nodep->branchPred(AstBranchPred::BP_LIKELY); } else if (likeness<0) { nodep->branchPred(AstBranchPred::BP_UNLIKELY); } // else leave unknown } m_likely = lastLikely; m_unlikely = lastUnlikely; } virtual void visit(AstCCall* nodep, AstNUser*) { checkUnlikely(nodep); nodep->funcp()->user1Inc(); nodep->iterateChildren(*this); } virtual void visit(AstCFunc* nodep, AstNUser*) { checkUnlikely(nodep); m_cfuncsp.push_back(nodep); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep, AstNUser*) { checkUnlikely(nodep); nodep->iterateChildren(*this); } // METHODS void calc_tasks() { for (CFuncVec::iterator it=m_cfuncsp.begin(); it!=m_cfuncsp.end(); ++it) { AstCFunc* nodep = *it; if (!nodep->dontInline()) { nodep->isInline(true); } } } public: // CONSTUCTORS BranchVisitor(AstNetlist* nodep) { reset(); nodep->iterateChildren(*this); calc_tasks(); } virtual ~BranchVisitor() {} }; //###################################################################### // Branch class functions void V3Branch::branchAll(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "< #include #include #include #include "V3Global.h" #include "V3Unroll.h" #include "V3Stats.h" #include "V3Const.h" #include "V3Ast.h" //###################################################################### // Unroll state, as a visitor of each AstNode class UnrollVisitor : public AstNVisitor { private: // STATE AstVar* m_forVarp; // Iterator variable AstVarScope* m_forVscp; // Iterator variable scope (NULL for generate pass) AstConst* m_varValuep; // Current value of loop AstNode* m_ignoreIncp; // Increment node to ignore AstAttrOf* m_attrp; // Current attribute bool m_varModeCheck; // Just checking RHS assignments bool m_varModeReplace; // Replacing varrefs bool m_varAssignHit; // Assign var hit bool m_generate; // Expand single generate For loop string m_beginName; // What name to give begin iterations V3Double0 m_statLoops; // Statistic tracking V3Double0 m_statIters; // Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS bool cantUnroll(AstNode* nodep, const char* reason) { if (m_generate) { nodep->v3error("Unsupported: Can't unroll generate for; "<=9) nodep->dumpTree(cout,"-cant-"); V3Stats::addStatSum(string("Unrolling gave up, ")+reason, 1); return false; } int unrollCount() { return m_generate ? v3Global.opt.unrollCount()*16 : v3Global.opt.unrollCount(); } bool bodySizeOverRecurse(AstNode* nodep, int& bodySize, int bodyLimit) { if (!nodep) return false; bodySize++; // Exit once exceeds limits, rather than always total // so don't go O(n^2) when can't unroll if (bodySize > bodyLimit) return true; if (bodySizeOverRecurse(nodep->op1p(), bodySize, bodyLimit)) return true; if (bodySizeOverRecurse(nodep->op2p(), bodySize, bodyLimit)) return true; if (bodySizeOverRecurse(nodep->op3p(), bodySize, bodyLimit)) return true; if (bodySizeOverRecurse(nodep->op4p(), bodySize, bodyLimit)) return true; // Tail recurse. return bodySizeOverRecurse(nodep->nextp(), bodySize, bodyLimit); } bool forUnrollCheck(AstNode* nodep, AstNode* initp, // Maybe under nodep (no nextp), or standalone (ignore nextp) AstNode* precondsp, AstNode* condp, AstNode* incp, // Maybe under nodep or in bodysp AstNode* bodysp) { // To keep the IF levels low, we return as each test fails. UINFO(4, " FOR Check "<castAssign(); if (!initAssp) return cantUnroll(nodep, "no initial assignment"); if (initp->nextp() && initp->nextp()!=nodep) nodep->v3fatalSrc("initial assignment shouldn't be a list"); if (!initAssp->lhsp()->castVarRef()) return cantUnroll(nodep, "no initial assignment to simple variable"); m_forVarp = initAssp->lhsp()->castVarRef()->varp(); m_forVscp = initAssp->lhsp()->castVarRef()->varScopep(); if (nodep->castGenFor() && !m_forVarp->isGenVar()) { nodep->v3error("Non-genvar used in generate for: "<prettyName()<rhsp()); // rhsp may change AstConst* constInitp = initAssp->rhsp()->castConst(); if (!constInitp) return cantUnroll(nodep, "non-constant initializer"); // // Condition check if (condp->nextp()) nodep->v3fatalSrc("conditional shouldn't be a list"); // // Assignment of next value check AstAssign* incAssp = incp->castAssign(); if (!incAssp) return cantUnroll(nodep, "no increment assignment"); if (incAssp->nextp()) nodep->v3fatalSrc("increment shouldn't be a list"); AstNodeBiop* incInstrp = incAssp->rhsp()->castNodeBiop(); // if (m_forVscp) { UINFO(8, " Loop Variable: "<=9) nodep->dumpTree(cout,"- for: "); // // Extract the constant loop bounds bool subtract = incInstrp->castSub(); { if (!subtract && !incInstrp->castAdd()) return cantUnroll(nodep, "missing add/sub for incrementer"); AstVarRef* incVarrp = (subtract ? incInstrp->lhsp()->castVarRef() : incInstrp->rhsp()->castVarRef()); if (!incVarrp) return cantUnroll(nodep, "missing variable in incrementer"); if (incVarrp->varp() != m_forVarp || incVarrp->varScopep() != m_forVscp) { return cantUnroll(nodep, "different variables in incrementer"); } } // // Adds have the # on the lhsp because V3Const pushes rhs consts over to the lhs // Subtracts have it on the rhs, because you write i=i-1; i=1-i is non-sensible. AstConst* preconstIncp = (subtract ? incInstrp->rhsp()->castConst() : incInstrp->lhsp()->castConst()); if (m_generate) preconstIncp = V3Const::constifyParamsEdit(preconstIncp)->castConst(); AstConst* constIncp = (subtract ? incInstrp->rhsp()->castConst() : incInstrp->lhsp()->castConst()); UINFO(8, " Inc expr ok: "<isZero()) return cantUnroll(nodep, "zero increment"); // Or we could loop forever below... bool lt = condp->castLt() || condp->castLtS(); bool lte = condp->castLte() || condp->castLteS(); bool gt = condp->castGt() || condp->castGtS(); bool gte = condp->castGte() || condp->castGteS(); if (!lt && !lte && !gt && !gte) return cantUnroll(nodep, "condition not <=, <, >= or >"); AstNodeBiop* cmpInstrp = condp->castNodeBiop(); bool cmpVarLhs; if (cmpInstrp->lhsp()->castVarRef() && cmpInstrp->lhsp()->castVarRef()->varp() == m_forVarp && cmpInstrp->lhsp()->castVarRef()->varScopep() == m_forVscp) { cmpVarLhs = true; } else if (cmpInstrp->rhsp()->castVarRef() && cmpInstrp->rhsp()->castVarRef()->varp() == m_forVarp && cmpInstrp->rhsp()->castVarRef()->varScopep() == m_forVscp) { cmpVarLhs = false; } else if (!cmpInstrp->rhsp()->castVarRef()) { return cantUnroll(nodep, "no variable on rhs of condition"); } else { return cantUnroll(nodep, "different variable in condition"); } if (m_generate) V3Const::constifyParamsEdit(cmpVarLhs ? cmpInstrp->rhsp() : cmpInstrp->lhsp()); // rhsp/lhsp may change AstConst* constStopp = (cmpVarLhs ? cmpInstrp->rhsp()->castConst() : cmpInstrp->lhsp()->castConst()); if (!constStopp) return cantUnroll(nodep, "non-constant final value"); UINFO(8, " Stop expr ok: "<width()>32 || constInitp->num().isFourState() || constStopp->width()>32 || constStopp->num().isFourState() || constIncp->width()>32 || constIncp->num().isFourState()) return cantUnroll(nodep, "init/final/increment too large or four state"); vlsint32_t valInit = constInitp->num().toSInt(); vlsint32_t valStop = constStopp->num().toSInt(); if (gte) valStop++; if (lte) valStop--; // 23 >= a, handle as if 24 > a vlsint32_t valInc = constIncp->num().toSInt(); if (subtract) valInc = -valInc; UINFO(8," In Numbers: for (v="<width()); } // Will roll around UINFO(8, " ~Iters: "<0) bodyLimit = v3Global.opt.unrollStmts() / loops; if (bodySizeOverRecurse(precondsp, bodySize/*ref*/, bodyLimit) || bodySizeOverRecurse(bodysp, bodySize/*ref*/, bodyLimit) || bodySizeOverRecurse(incp, bodySize/*ref*/, bodyLimit)) { return cantUnroll(nodep, "too many statements"); } } // // Now, make sure there's no assignment to this variable in the loop m_varModeCheck = true; m_varAssignHit = false; m_ignoreIncp = incp; precondsp->iterateAndNext(*this); bodysp->iterateAndNext(*this); incp->iterateAndNext(*this); m_varModeCheck = false; m_ignoreIncp = NULL; if (m_varAssignHit) return cantUnroll(nodep, "genvar assigned *inside* loop"); // // Finally, we can do it forUnroller(nodep, initp, precondsp, incp, bodysp, constInitp->num(), cmpInstrp, constStopp->num(), cmpVarLhs, incInstrp, constIncp->num()); nodep = NULL; // Cleanup return true; } void forUnroller(AstNode* nodep, AstNode* initp, AstNode* precondsp, AstNode* incp, AstNode* bodysp, const V3Number& numInit, AstNodeBiop* cmpInstrp, const V3Number& numStop, bool cmpVarLhs, AstNodeBiop* incInstrp, const V3Number& numInc) { UINFO(4, " Unroll for var="<unlinkFrBack(); // Always a single statement; nextp() may be nodep // Don't add to list, we do it once, and setting loop index isn't needed as we're constant propagating it } if (precondsp) { precondsp->unlinkFrBackWithNext(); // cppcheck-suppress nullPointer // addNextNull deals with it stmtsp = stmtsp->addNextNull(precondsp); } if (bodysp) { bodysp->unlinkFrBackWithNext(); // cppcheck-suppress nullPointer // addNextNull deals with it stmtsp = stmtsp->addNextNull(bodysp); // Maybe null if no body } if (incp && !nodep->castGenFor()) { // Generates don't need to increment loop index incp->unlinkFrBackWithNext(); // cppcheck-suppress nullPointer // addNextNull deals with it stmtsp = stmtsp->addNextNull(incp); // Maybe null if no body } // Mark variable to disable some later warnings m_forVarp->usedLoopIdx(true); // If it's a While, then incp is already part of bodysp. V3Number loopValue(nodep->fileline(), m_forVarp->width()); // May differ in size from numInitp loopValue.opAssign(numInit); AstNode* newbodysp = NULL; ++m_statLoops; if (stmtsp) { int times = 0; while (1) { UINFO(8," Looping "<fileline(), 1); if (cmpVarLhs) { cmpInstrp->numberOperate(contin, loopValue, numStop); } else { cmpInstrp->numberOperate(contin, numStop, loopValue); } if (contin.isEqZero()) { break; // Done with the loop } else { // Replace iterator values with constant. AstNode* oneloopp = stmtsp->cloneTree(true); m_varValuep = new AstConst(nodep->fileline(), loopValue); // Iteration requires a back, so put under temporary node if (oneloopp) { AstBegin* tempp = new AstBegin(oneloopp->fileline(),"[EditWrapper]",oneloopp); m_varModeReplace = true; tempp->stmtsp()->iterateAndNext(*this); m_varModeReplace = false; oneloopp = tempp->stmtsp()->unlinkFrBackWithNext(); tempp->deleteTree(); tempp=NULL; } if (m_generate) { string index = AstNode::encodeNumber(m_varValuep->toSInt()); string nname = m_beginName + "__BRA__" + index + "__KET__"; oneloopp = new AstBegin(oneloopp->fileline(),nname,oneloopp,true); } if (newbodysp) newbodysp->addNext(oneloopp); else newbodysp = oneloopp; ++m_statIters; if (++times > unrollCount()*3) { nodep->v3error("Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above "<fileline(), m_forVarp->width()); // Can't increment in-place incInstrp->numberOperate(newnum, loopValue, numInc); loopValue.opAssign(newnum); pushDeletep(m_varValuep); m_varValuep=NULL; } } } // Replace the FOR() if (newbodysp) nodep->replaceWith(newbodysp); else nodep->unlinkFrBack(); if (bodysp) { pushDeletep(bodysp); bodysp=NULL; } if (precondsp) { pushDeletep(precondsp); precondsp=NULL; } if (initp) { pushDeletep(initp); initp=NULL; } if (incp && !incp->backp()) { pushDeletep(incp); incp=NULL; } if (debug()>=9) newbodysp->dumpTree(cout,"- _new: "); } virtual void visit(AstWhile* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_varModeCheck || m_varModeReplace) { } else { // Constify before unroll call, as it may change what is underneath. if (nodep->precondsp()) V3Const::constifyEdit(nodep->precondsp()); // precondsp may change if (nodep->condp()) V3Const::constifyEdit(nodep->condp()); //condp may change // Grab initial value AstNode* initp = NULL; // Should be statement before the while. if (nodep->backp()->nextp() == nodep) initp=nodep->backp(); if (initp) { V3Const::constifyEdit(initp); initp=NULL; } if (nodep->backp()->nextp() == nodep) initp=nodep->backp(); // Grab assignment AstNode* incp = NULL; // Should be last statement if (nodep->incsp()) V3Const::constifyEdit(nodep->incsp()); if (nodep->incsp()) incp = nodep->incsp(); else { for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} if (incp) { V3Const::constifyEdit(incp); incp=NULL; } for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} // Again, as may have changed } // And check it if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, nodep->bodysp())) { pushDeletep(nodep); nodep=NULL; // Did replacement } } } virtual void visit(AstGenFor* nodep, AstNUser*) { if (!m_generate || m_varModeReplace) { nodep->iterateChildren(*this); } // else V3Param will recursively call each for loop to be unrolled for us if (m_varModeCheck || m_varModeReplace) { } else { // Constify before unroll call, as it may change what is underneath. if (nodep->initsp()) V3Const::constifyEdit(nodep->initsp()); // initsp may change if (nodep->condp()) V3Const::constifyEdit(nodep->condp()); // condp may change if (nodep->incsp()) V3Const::constifyEdit(nodep->incsp()); // incsp may change if (nodep->condp()->isZero()) { // We don't need to do any loops. Remove the GenFor, // Genvar's don't care about any initial assignments. // // Note normal For's can't do exactly this deletion, as // we'd need to initialize the variable to the initial // condition, but they'll become while's which can be // deleted by V3Const. nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else if (forUnrollCheck(nodep, nodep->initsp(), NULL, nodep->condp(), nodep->incsp(), nodep->bodysp())) { pushDeletep(nodep); nodep=NULL; // Did replacement } else { nodep->v3error("For loop doesn't have genvar index, or is malformed"); } } } virtual void visit(AstNodeFor* nodep, AstNUser*) { if (m_generate) { // Ignore for's when expanding genfor's nodep->iterateChildren(*this); } else { nodep->v3error("V3Begin should have removed standard FORs"); } } virtual void visit(AstAttrOf* nodep, AstNUser*) { AstAttrOf* oldAttr = m_attrp; m_attrp = nodep; nodep->iterateChildren(*this); m_attrp = oldAttr; } virtual void visit(AstVarRef* nodep, AstNUser*) { if (m_varModeCheck && nodep->varp() == m_forVarp && nodep->varScopep() == m_forVscp && nodep->lvalue()) { UINFO(8," Itervar assigned to: "<varp() == m_forVarp && nodep->varScopep() == m_forVscp && !nodep->lvalue() && !m_attrp) { // Most likely under a select AstNode* newconstp = m_varValuep->cloneTree(false); nodep->replaceWith(newconstp); pushDeletep(nodep); } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { if (m_varModeCheck && nodep == m_ignoreIncp) { // Ignore subtree that is the increment } else { nodep->iterateChildren(*this); } } public: // CONSTUCTORS UnrollVisitor(AstNode* nodep, bool generate, string beginName) { m_forVarp = NULL; m_forVscp = NULL; m_ignoreIncp = NULL; m_varModeCheck = false; m_varModeReplace = false; m_generate = generate; m_beginName = beginName; m_attrp = NULL; // nodep->accept(*this); } virtual ~UnrollVisitor() { V3Stats::addStat("Optimizations, Unrolled Loops", m_statLoops); V3Stats::addStat("Optimizations, Unrolled Iterations", m_statIters); } }; //###################################################################### // Unroll class functions void V3Unroll::unrollAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } void V3Unroll::unrollGen(AstNodeFor* nodep, string beginName) { UINFO(2,__FUNCTION__<<": "<, or >= // // Signed values are always sign extended on promotion or right shift, // even if assigning to a unsigned. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Cast.h" #include "V3Ast.h" //###################################################################### // Cast state, as a visitor of each AstNode class CastVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstNode::user() // bool. Indicates node is of known size AstUser1InUse m_inuser1; // STATE // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void insertCast(AstNode* nodep, int needsize) { // We'll insert ABOVE passed node UINFO(4," NeedCast "<unlinkFrBack(&relinkHandle); // AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize, nodep->widthMin()); relinkHandle.relink(castp); //if (debug()>8) castp->dumpTree(cout,"-castins: "); // insureLower32Cast(castp); nodep->user1(1); // Now must be of known size } int castSize (AstNode* nodep) { if (nodep->isQuad()) return VL_QUADSIZE; else if (nodep->width()<=8) return 8; else if (nodep->width()<=16) return 16; else return VL_WORDSIZE; } void insureCast(AstNode* nodep) { if (castSize(nodep->backp()) != castSize(nodep) || !nodep->user1()) { insertCast(nodep, castSize(nodep->backp())); } } void insureLower32Cast(AstCCast* nodep) { // If we have uint64 = CAST(uint64(x)) then the upcasting // really needs to be CAST(uint64(CAST(uint32(x))). // Otherwise a (uint64)(a>b) would return wrong value, as // less than has undeterministic signedness. if (nodep->isQuad() && !nodep->lhsp()->isQuad() && !nodep->lhsp()->castCCast()) { insertCast(nodep->lhsp(), VL_WORDSIZE); } } // VISITORS virtual void visit(AstNodeUniop* nodep, AstNUser*) { nodep->iterateChildren(*this); nodep->user1(nodep->lhsp()->user1()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); } virtual void visit(AstNodeBiop* nodep, AstNUser*) { nodep->iterateChildren(*this); nodep->user1(nodep->lhsp()->user1() | nodep->rhsp()->user1()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp()); } virtual void visit(AstNodeTriop* nodep, AstNUser*) { nodep->iterateChildren(*this); nodep->user1(nodep->lhsp()->user1() | nodep->rhsp()->user1() | nodep->thsp()->user1()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp()); if (nodep->sizeMattersThs()) insureCast(nodep->thsp()); } virtual void visit(AstCCast* nodep, AstNUser*) { nodep->iterateChildren(*this); insureLower32Cast(nodep); nodep->user1(1); } virtual void visit(AstNegate* nodep, AstNUser*) { nodep->iterateChildren(*this); nodep->user1(nodep->lhsp()->user1()); if (nodep->lhsp()->widthMin()==1) { // We want to avoid a GCC "converting of negative value" warning // from our expansion of // out = {32{a out = - (alhsp(), castSize(nodep)); } else { insureCast(nodep->lhsp()); } } virtual void visit(AstVarRef* nodep, AstNUser*) { if (!nodep->lvalue() && !nodep->backp()->castCCast() && nodep->backp()->castNodeMath() && !nodep->backp()->castArraySel() && nodep->backp()->width() && castSize(nodep) != castSize(nodep->varp())) { // Cast vars to IData first, else below has upper bits wrongly set // CData x=3; out = (QData)(x<<30); insertCast (nodep, castSize(nodep)); } nodep->user1(1); } virtual void visit(AstConst* nodep, AstNUser*) { // Constants are of unknown size if smaller than 33 bits, becase // we're too lazy to wrap every constant in the universe in // ((IData)#). nodep->user1(nodep->isQuad() || nodep->isWide()); } // NOPs virtual void visit(AstVar* nodep, AstNUser*) {} //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS CastVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~CastVisitor() {} }; //###################################################################### // Cast class functions void V3Cast::castAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/config_rev.h0000664000177100017500000000010212534632351016601 0ustar wsnyderwsnyderstatic const char* DTVERSION_rev = "verilator_3_872-20-g0d43051"; verilator-3.874/src/V3File.cpp0000664000177100017500000005736212525172076016132 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: File stream wrapper that understands indentation // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include #if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) # define INFILTER_PIPE // Allow pipe filtering. Needs fork() #endif #ifdef INFILTER_PIPE # include #endif #include "V3Global.h" #include "V3File.h" #include "V3Os.h" #include "V3PreShell.h" #include "V3Ast.h" // If change this code, run a test with the below size set very small //#define INFILTER_IPC_BUFSIZ 16 #define INFILTER_IPC_BUFSIZ 64*1024 // For debug, try this as a small number #define INFILTER_CACHE_MAX 64*1024 // Maximum bytes to cache if same file read twice //###################################################################### // V3File Internal state class V3FileDependImp { // TYPES class DependFile { // A single file bool m_target; // True if write, else read string m_filename; // Filename struct stat m_stat; // Stat information public: DependFile(const string& filename, bool target) : m_target(target), m_filename(filename) { m_stat.st_mtime = 0; } ~DependFile() {} const string& filename() const { return m_filename; } bool target() const { return m_target; } off_t size() const { return m_stat.st_size; } ino_t ino() const { return m_stat.st_ino; } time_t mtime() const { return m_stat.st_mtime; } void loadStats() { if (!m_stat.st_mtime) { string fn = filename(); int err = stat(fn.c_str(), &m_stat); if (err!=0) { m_stat.st_mtime = 1; // Not a error... This can occur due to `line directives in the .vpp files UINFO(1,"-Info: File not statable: "< m_filenameSet; // Files generated (elim duplicates) set m_filenameList; // Files sourced/generated static string stripQuotes(const string& in) { string pretty = in; string::size_type pos; while ((pos=pretty.find("\"")) != string::npos) pretty.replace(pos, 1, "_"); while ((pos=pretty.find("\n")) != string::npos) pretty.replace(pos, 1, "_"); return pretty; } public: // ACCESSOR METHODS void addSrcDepend(const string& filename) { if (m_filenameSet.find(filename) == m_filenameSet.end()) { m_filenameSet.insert(filename); DependFile df (filename, false); df.loadStats(); // Get size now, in case changes during the run m_filenameList.insert(df); } } void addTgtDepend(const string& filename) { if (m_filenameSet.find(filename) == m_filenameSet.end()) { m_filenameSet.insert(filename); m_filenameList.insert(DependFile (filename, true)); } } void writeDepend(const string& filename); void writeTimes(const string& filename, const string& cmdline); bool checkTimes(const string& filename, const string& cmdline); }; V3FileDependImp dependImp; // Depend implementation class //###################################################################### // V3FileDependImp inline void V3FileDependImp::writeDepend(const string& filename) { const VL_UNIQUE_PTR ofp (V3File::new_ofstream(filename)); if (ofp->fail()) v3fatalSrc("Can't write "<::iterator iter=m_filenameList.begin(); iter!=m_filenameList.end(); ++iter) { if (iter->target()) { *ofp<filename()<<" "; } } *ofp<<" : "; *ofp<::iterator iter=m_filenameList.begin(); iter!=m_filenameList.end(); ++iter) { if (!iter->target()) { *ofp<filename()<<" "; } } *ofp<::iterator iter=m_filenameList.begin(); iter!=m_filenameList.end(); ++iter) { if (!iter->target()) { *ofp<filename()<<":"< ofp (V3File::new_ofstream(filename)); if (ofp->fail()) v3fatalSrc("Can't write "<::iterator iter=m_filenameList.begin(); iter!=m_filenameList.end(); ++iter) { // Read stats of files we create after we're done making them (execpt for this file, of course) DependFile* dfp = (DependFile*)&(*iter); V3Options::fileNfsFlush(dfp->filename()); dfp->loadStats(); off_t showSize = iter->size(); ino_t showIno = iter->ino(); if (dfp->filename() == filename) { showSize=0; showIno=0; } // We're writing it, so need to ignore it *ofp<<(iter->target()?"T":"S")<<" "; *ofp<<" "<mtime(); *ofp<<" \""<filename()<<"\""; *ofp< ifp (V3File::new_ifstream_nodepend(filename)); if (ifp->fail()) { UINFO(2," --check-times failed: no input "<>chkDir; char quote; *ifp>>quote; string chkCmdline; getline(*ifp, chkCmdline, '"'); string cmdline = stripQuotes(cmdlineIn); if (cmdline != chkCmdline) { UINFO(2," --check-times failed: different command line\n"); return false; } } while (!ifp->eof()) { char chkDir; *ifp>>chkDir; off_t chkSize; *ifp>>chkSize; ino_t chkIno; *ifp>>chkIno; if (ifp->eof()) break; // Needed to read final whitespace before found eof time_t chkMtime; *ifp>>chkMtime; char quote; *ifp>>quote; string chkFilename; getline(*ifp, chkFilename, '"'); //UINFO(9," got d="<= chkSize && chkStat.st_ino == chkIno && chkStat.st_mtime >= chkMtime && chkStat.st_mtime <= (chkMtime + 20))) { UINFO(2," --check-times failed: out-of-date "< FileContentsMap; typedef V3InFilter::StrList StrList; FileContentsMap m_contentsMap; // Cache of file contents bool m_readEof; // Received EOF on read #ifdef INFILTER_PIPE pid_t m_pid; // fork() process id #else int m_pid; // fork() process id - always zero as disabled #endif bool m_pidExited; int m_pidStatus; int m_writeFd; // File descriptor TO filter int m_readFd; // File descriptor FROM filter private: // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } bool readContents(const string& filename, StrList& outl) { if (m_pid) return readContentsFilter(filename,outl); else return readContentsFile(filename,outl); } bool readContentsFile(const string& filename, StrList& outl) { int fd = open (filename.c_str(), O_RDONLY); if (fd<0) return false; m_readEof = false; readBlocks(fd, -1, outl); close(fd); return true; } bool readContentsFilter(const string& filename, StrList& outl) { if (filename!="" || outl.empty()) {} // Prevent unused #ifdef INFILTER_PIPE writeFilter("read \""+filename+"\"\n"); string line = readFilterLine(); if (line.find("Content-Length") != string::npos) { int len = 0; sscanf(line.c_str(), "Content-Length: %d\n", &len); readBlocks(m_readFd, len, outl); return true; } else { if (line!="") v3error("--pipe-filter protocol error, unexpected: "<sizegot)) { ssize_t todo = INFILTER_IPC_BUFSIZ; if (size>0 && size0) { outl.push_back(string(buf, got)); sizegot += got; } else if (errno == EINTR || errno == EAGAIN #ifdef EWOULDBLOCK || errno == EWOULDBLOCK #endif ) { // cppcheck-suppress obsoleteFunctionsusleep checkFilter(false); usleep(1000); continue; } else { m_readEof = true; break; } } return out; } string readFilterLine() { // Slow, but we don't need it much UINFO(9,"readFilterLine\n"); string line; while (!m_readEof) { StrList outl; readBlocks(m_readFd, 1, outl); string onechar = listString(outl); line += onechar; if (onechar == "\n") { if (line == "\n") { line=""; continue; } else break; } } UINFO(6,"filter-line-in: "<=6) { UINFO(6,"filter-out: "<offset) { errno = 0; int got = write (m_writeFd, (out.c_str())+offset, out.length()-offset); //UINFO(9,"WR GOT g "<< got<<" e "<0) offset += got; else if (errno == EINTR || errno == EAGAIN #ifdef EWOULDBLOCK || errno == EWOULDBLOCK #endif ) { // cppcheck-suppress obsoleteFunctionsusleep checkFilter(false); usleep(1000); continue; } else break; } } // Start the filter void start(const string& command) { if (command=="") { m_pid = 0; // Disabled } else { startFilter(command); } } void startFilter(const string& command) { if (command=="") {} // Prevent Unused #ifdef INFILTER_PIPE int fd_stdin[2], fd_stdout[2]; static const int P_RD = 0; static const int P_WR = 1; if (pipe(fd_stdin) != 0 || pipe(fd_stdout) != 0) { v3fatal("--pipe-filter: Can't pipe: "<"<"<second); return true; } if (!readContents(filename, outl)) return false; if (listSize(outl) < INFILTER_CACHE_MAX) { // Cache small files (only to save space) // It's quite common to `include "timescale" thousands of times // This isn't so important if it's just a open(), but filtering can be slow m_contentsMap.insert(make_pair(filename,listString(outl))); } return true; } size_t listSize(StrList& sl) { size_t out = 0; for (StrList::iterator it=sl.begin(); it!=sl.end(); ++it) { out += it->length(); } return out; } string listString(StrList& sl) { string out; for (StrList::iterator it=sl.begin(); it!=sl.end(); ++it) { out += *it; } return out; } // CONSTRUCTORS V3InFilterImp(const string& command) { m_readEof = false; m_pid = 0; m_pidExited = false; m_pidStatus = 0; m_writeFd = 0; m_readFd = 0; start(command); } ~V3InFilterImp() { stop(); } }; //###################################################################### // V3InFilter // Just dispatch to the implementation V3InFilter::V3InFilter(const string& command) { m_impp = new V3InFilterImp(command); } V3InFilter::~V3InFilter() { if (m_impp) delete m_impp; m_impp=NULL; } bool V3InFilter::readWholefile(const string& filename, V3InFilter::StrList& outl) { if (!m_impp) v3fatalSrc("readWholefile on invalid filter"); return m_impp->readWholefile(filename, outl); } //###################################################################### // V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code. V3OutFormatter::V3OutFormatter(const string& filename, V3OutFormatter::Language lang) : m_filename(filename), m_lang(lang) , m_lineno(1), m_column(0) , m_nobreak(false), m_prependIndent(true), m_indentLevel(0) , m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) { } //---------------------------------------------------------------------- const char* V3OutFormatter::indentStr(int num) { // Indent the specified number of spaces. Use tabs as possible. static char str[MAXSPACE+20]; char* cp = str; if (num>MAXSPACE) num=MAXSPACE; if (m_lang!=LA_VERILOG) { // verilogPrefixedTree doesn't want tabs while (num>=8) { *cp++ = '\t'; num -= 8; } } while (num>0) { *cp++ = ' '; num --; } *cp++ = '\0'; return (str); } const string V3OutFormatter::indentSpaces(int num) { // Indent the specified number of spaces. Use spaces. static char str[MAXSPACE+20]; char* cp = str; if (num>MAXSPACE) num=MAXSPACE; while (num>0) { *cp++ = ' '; num --; } *cp++ = '\0'; string st (str); return (st); } bool V3OutFormatter::tokenStart(const char* cp, const char* cmp) { while (*cmp == *cp) { cp++; cmp++; } if (*cmp) return false; if (*cp && !isspace(*cp)) return false; return true; } bool V3OutFormatter::tokenEnd(const char* cp) { return (tokenStart(cp,"end") || tokenStart(cp,"endcase") || tokenStart(cp,"endmodule")); } int V3OutFormatter::endLevels (const char *strg) { int levels=m_indentLevel; const char* cp=strg; while (isspace(*cp)) cp++; switch (*cp) { case '\n': // Newlines.. No need for whitespace before it return (0); case '#': // Preproc directive return (0); } { // label/public/private: Deindent by 2 spaces const char* mp=cp; for (; isalnum(*mp); mp++) ; if (mp[0]==':' && mp[1]!=':') return (levels-INDBLK/2); } // We want "} else {" to be one level to the left of normal for (const char* cp=strg; *cp; cp++) { switch (*cp) { case '}': case ')': levels-=INDBLK; break; case '<': if (m_lang==LA_XML) { if (cp[1] == '/') levels-=INDBLK; } break; case 'e': if (m_lang==LA_VERILOG && tokenEnd(cp)) { levels-=INDBLK; } break; case '\t': case ' ': break; // Continue default: return (levels); // Letter } } return (levels); } void V3OutFormatter::puts (const char *strg) { if (m_prependIndent) { putsNoTracking(indentStr(endLevels(strg))); m_prependIndent = false; } bool wordstart = true; for (const char* cp=strg; *cp; cp++) { putcNoTracking (*cp); switch (*cp) { case '\n': m_lineno++; wordstart = true; if (cp[1]=='\0') { m_prependIndent = true; // Add the indent later, may be a indentInc/indentDec called between now and then } else { m_prependIndent = false; putsNoTracking(indentStr(endLevels(cp+1))); } break; case ' ': wordstart = true; break; case '\t': wordstart = true; break; case '{': indentInc(); break; case '}': indentDec(); break; case '(': indentInc(); m_parenVec.push(m_column); break; case ')': if (!m_parenVec.empty()) m_parenVec.pop(); indentDec(); break; case '<': if (m_lang==LA_XML) { if (cp[1] == '/') {} // Zero as the > will result in net decrease by one else if (cp[1] == '!' || cp[1] == '?') { indentInc(); } // net same indent else { indentInc(); indentInc(); } // net increase by one } break; case '>': if (m_lang==LA_XML) { indentDec(); if (cp>strg && cp[-1]=='/') indentDec(); // < ..... /> stays same level } break; case 'b': if (wordstart && m_lang==LA_VERILOG && tokenStart(cp,"begin")) { indentInc(); } wordstart = false; break; case 'c': if (wordstart && m_lang==LA_VERILOG && (tokenStart(cp,"case") || tokenStart(cp,"casex") || tokenStart(cp,"casez"))) { indentInc(); } wordstart = false; break; case 'e': if (wordstart && m_lang==LA_VERILOG && tokenEnd(cp)) { indentDec(); } wordstart = false; break; case 'm': if (wordstart && m_lang==LA_VERILOG && tokenStart(cp,"module")) { indentInc(); } wordstart = false; break; default: wordstart = false; break; } } } void V3OutFormatter::putBreakExpr () { if (!m_parenVec.empty()) putBreak(); } // Add a line break if too wide void V3OutFormatter::putBreak () { if (!m_nobreak) { //char s[1000]; sprintf(s,"{%d,%d}",m_column,m_parenVec.top()); putsNoTracking(s); if (exceededWidth()) { putcNoTracking('\n'); if (!m_parenVec.empty()) putsNoTracking(indentStr(m_parenVec.top())); } } } void V3OutFormatter::putsQuoted(const char* strg) { // Quote \ and " for use inside C programs // Don't use to quote a filename for #include - #include doesn't \ escape. putcNoTracking('"'); string quoted = V3Number::quoteNameControls(strg); for (const char* cp=quoted.c_str(); *cp; cp++) { putcNoTracking (*cp); } putcNoTracking('"'); } void V3OutFormatter::putsNoTracking (const char *strg) { // Don't track {}'s, probably because it's a $display format string for (const char* cp=strg; *cp; cp++) { putcNoTracking (*cp); } } void V3OutFormatter::putcNoTracking (char chr) { switch (chr) { case '\n': m_lineno++; m_column=0; m_nobreak=true; break; case '\t': m_column = ((m_column + 9)/8)*8; break; case ' ': case '(': case '|': case '&': m_column++; break; default: m_column++; m_nobreak=false; break; } putcOutput (chr); } void V3OutFormatter::putAlign (bool/*AlignClass*/ isStatic, int align, int size, const char* prefix) { if (size==0) size=align; int alignSize = size; if (alignSize>8) alignSize=8; int& alignr = isStatic ? m_declSAlign : m_declNSAlign; int padsize = alignSize - (alignr % alignSize); if (padsize && padsize!=alignSize) { // Modern versions of GCC no longer need this, they'll pad for us, so // we'll save the work and danger of getting it wrong. puts("//char\t"); puts(prefix); puts("__VpadToAlign"+cvtToStr(alignr) +"["+cvtToStr(padsize)+"];\n"); alignr += padsize; m_declPadNum++; } alignr += size; } //---------------------------------------------------------------------- // Simple wrappers void V3OutFormatter::printf (const char *fmt...) { char sbuff[5000]; va_list ap; va_start(ap,fmt); vsprintf(sbuff,fmt,ap); va_end(ap); this->puts(sbuff); } //###################################################################### // V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code. V3OutFile::V3OutFile(const string& filename, V3OutFormatter::Language lang) : V3OutFormatter(filename, lang) { if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) { v3fatal("Cannot write "< #include #include #include #include #include "V3Global.h" #include "V3Stats.h" #include "V3Ast.h" #include "V3File.h" // This visitor does not edit nodes, and is called at error-exit, so should use constant iterators #include "V3AstConstOnly.h" //###################################################################### // Stats class functions class StatsVisitor : public AstNVisitor { private: // NODE STATE/TYPES typedef map NameMap; // Number of times a name appears // STATE string m_stage; // Name of the stage we are scanning bool m_fast; // Counting only fastpath AstCFunc* m_cfuncp; // Current CFUNC V3Double0 m_statInstrLong; // Instruction count bool m_counting; // Currently counting double m_instrs; // Current instr count vector m_statTypeCount; // Nodes of given type V3Double0 m_statAbove[AstType::_ENUM_END][AstType::_ENUM_END]; // Nodes of given type V3Double0 m_statPred[AstBranchPred::_ENUM_END]; // Nodes of given type V3Double0 m_statInstr; // Instruction count V3Double0 m_statInstrFast; // Instruction count vector m_statVarWidths; // Variables of given width vector m_statVarWidthNames; // Var names of given width V3Double0 m_statVarArray; // Statistic tracking V3Double0 m_statVarBytes; // Statistic tracking V3Double0 m_statVarClock; // Statistic tracking V3Double0 m_statVarScpBytes; // Statistic tracking // METHODS void allNodes(AstNode* nodep) { m_instrs += nodep->instrCount(); if (m_counting) { ++m_statTypeCount[nodep->type()]; if (nodep->firstAbovep()) { // Grab only those above, not those "back" ++m_statAbove[nodep->firstAbovep()->type()][nodep->type()]; } m_statInstr += nodep->instrCount(); if (m_cfuncp && !m_cfuncp->slow()) m_statInstrFast += nodep->instrCount(); } } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { allNodes(nodep); if (!m_fast) { nodep->iterateChildrenConst(*this); } else { for (AstNode* searchp = nodep->stmtsp(); searchp; searchp=searchp->nextp()) { if (AstCFunc* funcp = searchp->castCFunc()) { if (funcp->name() == "_eval") { m_instrs=0; m_counting = true; funcp->iterateChildrenConst(*this); m_counting = false; } } } } } virtual void visit(AstVar* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildrenConst(*this); if (m_counting && nodep->dtypep()) { if (nodep->isUsedClock()) ++m_statVarClock; if (nodep->dtypeSkipRefp()->castUnpackArrayDType()) ++m_statVarArray; else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes(); if (int(m_statVarWidths.size()) <= nodep->width()) { m_statVarWidths.resize(nodep->width()+5); if (v3Global.opt.statsVars()) m_statVarWidthNames.resize(nodep->width()+5); } ++ m_statVarWidths.at(nodep->width()); string pn = nodep->prettyName(); if (v3Global.opt.statsVars()) { NameMap& nameMapr = m_statVarWidthNames.at(nodep->width()); if (nameMapr.find(pn) != nameMapr.end()) { nameMapr[pn]++; } else { nameMapr[pn]=1; } } } } virtual void visit(AstVarScope* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildrenConst(*this); if (m_counting) { if (nodep->varp()->dtypeSkipRefp()->castBasicDType()) { m_statVarScpBytes += nodep->varp()->dtypeSkipRefp()->widthTotalBytes(); } } } virtual void visit(AstNodeIf* nodep, AstNUser*) { UINFO(4," IF "<condp()->iterateAndNextConst(*this); // Track prediction if (m_counting) { ++m_statPred[nodep->branchPred()]; } if (!m_fast) { nodep->iterateChildrenConst(*this); } else { // See which path we want to take bool takeElse = false; if (!nodep->elsesp() || (nodep->branchPred()==AstBranchPred::BP_LIKELY)) { // Always take the if } else if (!nodep->ifsp() || (nodep->branchPred()==AstBranchPred::BP_UNLIKELY)) { // Always take the else } else { // Take the longer path bool prevCounting = m_counting; double prevInstr = m_instrs; m_counting = false; // Check if m_instrs = 0; nodep->ifsp()->iterateAndNextConst(*this); double instrIf = m_instrs; // Check else m_instrs = 0; nodep->elsesp()->iterateAndNextConst(*this); double instrElse = m_instrs; // Max of if or else condition takeElse = (instrElse > instrIf); // Restore m_counting = prevCounting; m_instrs = prevInstr + (takeElse?instrElse:instrIf); } // Count the block if (m_counting) { if (takeElse) { nodep->elsesp()->iterateAndNextConst(*this); } else { nodep->ifsp()->iterateAndNextConst(*this); } } } } // While's we assume evaluate once. //virtual void visit(AstWhile* nodep, AstNUser*) { virtual void visit(AstCCall* nodep, AstNUser*) { //UINFO(4," CCALL "<iterateChildrenConst(*this); if (m_fast) { // Enter the function and trace it nodep->funcp()->accept(*this); } } virtual void visit(AstCFunc* nodep, AstNUser*) { m_cfuncp = nodep; allNodes(nodep); nodep->iterateChildrenConst(*this); m_cfuncp = NULL; } virtual void visit(AstNode* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildrenConst(*this); } public: // CONSTRUCTORS StatsVisitor(AstNetlist* nodep, const string& stage, bool fast) : m_stage(stage), m_fast(fast) { m_cfuncp = NULL; m_counting = !m_fast; m_instrs = 0; // Initialize arrays m_statTypeCount.resize(AstType::_ENUM_END); // Process nodep->accept(*this); } virtual ~StatsVisitor() { // Done. Publish statistics V3Stats::addStat(m_stage, "Instruction count, TOTAL", m_statInstr); V3Stats::addStat(m_stage, "Instruction count, fast", m_statInstrFast); // Vars V3Stats::addStat(m_stage, "Vars, unpacked arrayed", m_statVarArray); V3Stats::addStat(m_stage, "Vars, clock attribute", m_statVarClock); V3Stats::addStat(m_stage, "Var space, non-arrays, bytes", m_statVarBytes); if (m_statVarScpBytes) { V3Stats::addStat(m_stage, "Var space, scoped, bytes", m_statVarScpBytes); } for (unsigned i=0; ifirst; V3Stats::addStat(m_stage, os.str(), it->second); } } else { ostringstream os; os<<"Vars, width "< #include #include #include #include "V3Global.h" #include "V3Localize.h" #include "V3Stats.h" #include "V3Ast.h" //###################################################################### // Localize base class class LocalizeBaseVisitor : public AstNVisitor { protected: // NODE STATE // Cleared on entire tree // AstVar::user1p() -> CFunc which references the variable // AstVar::user2() -> VarFlags. Flag state // AstVar::user4() -> AstVarRef*. First place signal set; must be first assignment // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // TYPES union VarFlags { // Per-variable flags // Used in user()'s so initializes to all zeros struct { int m_notOpt:1; // NOT optimizable int m_notStd:1; // NOT optimizable if a non-blocktemp signal int m_stdFuncAsn:1; // Found simple assignment int m_done:1; // Removed }; uint32_t m_flags; VarFlags(AstNode* nodep) { m_flags = nodep->user2(); } void setNodeFlags(AstNode* nodep) { nodep->user2(m_flags); } }; }; //###################################################################### // Localize class functions class LocalizeDehierVisitor : public LocalizeBaseVisitor { private: // NODE STATE/TYPES // See above // METHODS virtual void visit(AstVarRef* nodep, AstNUser*) { VarFlags flags (nodep->varp()); if (flags.m_done) { nodep->hiername(""); // Remove thisp-> nodep->hierThis(true); } } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS LocalizeDehierVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~LocalizeDehierVisitor() {} }; //###################################################################### // Localize class functions class LocalizeVisitor : public LocalizeBaseVisitor { private: // NODE STATE/TYPES // See above AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser4InUse m_inuser4; // STATE V3Double0 m_statLocVars; // Statistic tracking AstCFunc* m_cfuncp; // Current active function vector m_varps; // List of variables to consider for deletion // METHODS void clearOptimizable(AstVar* nodep, const char* reason) { UINFO(4," NoOpt "<::iterator it = m_varps.begin(); it != m_varps.end(); ++it) { AstVar* nodep = *it; if (nodep->valuep()) clearOptimizable(nodep,"HasInitValue"); if (!VarFlags(nodep).m_stdFuncAsn) clearStdOptimizable(nodep,"NoStdAssign"); VarFlags flags (nodep); if ((nodep->isMovableToBlock() // Blocktemp || !flags.m_notStd) // Or used only in block && !flags.m_notOpt // Optimizable && nodep->user1p()) { // Single cfunc // We don't need to test for tracing; it would be in the tracefunc if it was needed UINFO(4," ModVar->BlkVar "<user1p()->castNode()->castCFunc(); nodep->unlinkFrBack(); newfuncp->addInitsp(nodep); // Done flags.m_done = true; flags.setNodeFlags(nodep); } else { clearOptimizable(nodep, "NotDone"); } } m_varps.clear(); } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { nodep->iterateChildren(*this); moveVars(); } virtual void visit(AstCFunc* nodep, AstNUser*) { UINFO(4," CFUNC "<argsp()); searchFuncStmts(nodep->initsp()); searchFuncStmts(nodep->stmtsp()); searchFuncStmts(nodep->finalsp()); nodep->iterateChildren(*this); m_cfuncp = NULL; } void searchFuncStmts(AstNode* nodep) { // Search for basic assignments to allow moving non-blocktemps // For now we only find simple assignments not under any other statement. // This could be more complicated; allow always-set under both branches of a IF. // If so, check for ArrayRef's and such, as they aren't acceptable. for (; nodep; nodep=nodep->nextp()) { if (nodep->castNodeAssign()) { if (AstVarRef* varrefp = nodep->castNodeAssign()->lhsp()->castVarRef()) { if (!varrefp->lvalue()) varrefp->v3fatalSrc("LHS assignment not lvalue"); if (!varrefp->varp()->user4p()) { UINFO(4," FuncAsn "<varp()->user4p(varrefp); VarFlags flags (varrefp->varp()); flags.m_stdFuncAsn = true; flags.setNodeFlags(varrefp->varp()); } } } } } virtual void visit(AstVar* nodep, AstNUser*) { if (!nodep->isSigPublic() && !nodep->isPrimaryIO() && !m_cfuncp) { // Not already inside a function UINFO(4," BLKVAR "<varp()).m_notOpt) { if (!m_cfuncp) { // Not in function, can't optimize clearOptimizable(nodep->varp(), "BVnofunc"); } else { // If we're scoping down to it, it isn't really in the same block if (!nodep->hierThis()) clearOptimizable(nodep->varp(),"HierRef"); // Allow a variable to appear in only a single function AstNode* oldfunc = nodep->varp()->user1p()->castNode(); if (!oldfunc) { UINFO(4," BVnewref "<varp()->user1p(m_cfuncp); // Remember where it was used } else if (m_cfuncp == oldfunc) { // Same usage } else { // Used in multiple functions clearOptimizable(nodep->varp(),"BVmultiF"); } // First varref in function must be assignment found earlier AstVarRef* firstasn = (AstVarRef*)(nodep->varp()->user4p()); if (firstasn && nodep!=firstasn) { clearStdOptimizable(nodep->varp(),"notFirstAsn"); nodep->varp()->user4p(NULL); } } } // No iterate; Don't want varrefs under it } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTRUCTORS LocalizeVisitor(AstNetlist* nodep) { m_cfuncp = NULL; nodep->accept(*this); } virtual ~LocalizeVisitor() { V3Stats::addStat("Optimizations, Vars localized", m_statLocVars); } }; //###################################################################### // Localize class functions void V3Localize::localizeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); } verilator-3.874/src/V3SenTree.h0000664000177100017500000001021412525171733016245 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity block domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Block's Transformations: // // Note this can be called multiple times. // Create a IBLOCK(initial), SBLOCK(combo) // ALWAYS: Remove any-edges from sense list // If no POS/NEG in senselist, Fold into SBLOCK(combo) // Else fold into SBLOCK(sequent). // OPTIMIZE: When support async clocks, fold into that block if possible // INITIAL: Move into IBLOCK // WIRE: Move into SBLOCK(combo) // //************************************************************************* #ifndef _V3SENTREE_H_ #define _V3SENTREE_H_ #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Ast.h" //###################################################################### // Collect SenTrees under the entire scope // And provide functions to find/add a new one class SenTreeFinder : public AstNVisitor { private: // STATE AstTopScope* m_topscopep; // Top scope to add statement to vector m_treesp; // List of sensitive blocks, for folding // VISITORS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } virtual void visit(AstNodeModule* nodep, AstNUser*) { // Only do the top if (nodep->isTop()) { nodep->iterateChildren(*this); } } virtual void visit(AstTopScope* nodep, AstNUser*) { m_topscopep = nodep; nodep->iterateChildren(*this); // Don't clear topscopep, the namer persists beyond this visit } virtual void visit(AstScope* nodep, AstNUser*) { // But no SenTrees under TopScope's scope } // Memorize existing block names virtual void visit(AstActive* nodep, AstNUser*) { // Don't grab SenTrees under Actives, only those that are global (under Scope directly) nodep->iterateChildren(*this); } virtual void visit(AstSenTree* nodep, AstNUser*) { m_treesp.push_back(nodep); } // Empty visitors, speed things up virtual void visit(AstNodeStmt* nodep, AstNUser*) { } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } // METHODS public: void clear() { m_topscopep = NULL; m_treesp.clear(); } AstSenTree* getSenTree(FileLine* fl, AstSenTree* sensesp) { // Return a global sentree that matches given sense list. // Not the fastest, but there tend to be few clocks AstSenTree* treep = NULL; //sensesp->dumpTree(cout," Lookingfor: "); for (vector::iterator it = m_treesp.begin(); it!=m_treesp.end(); ++it) { treep = *it; if (treep) { // Not deleted if (treep->sameTree(sensesp)) { UINFO(8," Found SBLOCK "<cloneTree(false); m_topscopep->addStmtsp(treep); UINFO(8," New SENTREE "<accept(*this); } }; #endif // Guard verilator-3.874/src/V3Const.cpp0000664000177100017500000032423112525171733016330 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Constant folding // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // CONST TRANSFORMATIONS: // Call on one node for PARAM values, or netlist for overall constant folding: // Bottom up traversal: // Attempt to convert operands to constants // If operands are constant, replace this node with constant. //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Const.h" #include "V3Ast.h" #include "V3Width.h" #include "V3Simulate.h" //###################################################################### // Utilities class ConstVarMarkVisitor : public AstNVisitor { // NODE STATE // AstVar::user4p -> bool, Var marked, 0=not set yet private: // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->varp()) nodep->varp()->user4(1); } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ConstVarMarkVisitor(AstNode* nodep) { AstNode::user4ClearTree(); // Check marked InUse before we're called nodep->accept(*this); } virtual ~ConstVarMarkVisitor() {} }; class ConstVarFindVisitor : public AstNVisitor { // NODE STATE // AstVar::user4p -> bool, input from ConstVarMarkVisitor // MEMBERS bool m_found; private: // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->varp() && nodep->varp()->user4()) m_found = true; } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ConstVarFindVisitor(AstNode* nodep) { m_found = false; nodep->iterateAndNext(*this, NULL); } virtual ~ConstVarFindVisitor() {} // METHODS bool found() const { return m_found; } }; //###################################################################### // Const state, as a visitor of each AstNode class ConstVisitor : public AstNVisitor { private: // NODE STATE // ** only when m_warn/m_doExpensive is set. If state is needed other times, // ** must track down everywhere V3Const is called and make sure no overlaps. // AstVar::user4p -> Used by ConstVarMarkVisitor/ConstVarFindVisitor // AstJumpLabel::user4 -> bool. Set when AstJumpGo uses this label // STATE bool m_params; // If true, propogate parameterized and true numbers only bool m_required; // If true, must become a constant bool m_wremove; // Inside scope, no assignw removal bool m_warn; // Output warnings bool m_doExpensive; // Enable computationally expensive optimizations bool m_doNConst; // Enable non-constant-child simplifications bool m_doShort; // Remove expressions that short circuit bool m_doV; // Verilog, not C++ conversion bool m_doGenerate; // Postpone width checking inside generate AstNodeModule* m_modp; // Current module AstArraySel* m_selp; // Current select AstNode* m_scopep; // Current scope AstAttrOf* m_attrp; // Current attribute // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } bool operandConst (AstNode* nodep) { return (nodep->castConst()); } bool operandAsvConst (AstNode* nodep) { // BIASV(CONST, BIASV(CONST,...)) -> BIASV( BIASV_CONSTED(a,b), ...) AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv(); if (!bnodep) return false; if (!bnodep->lhsp()->castConst()) return false; AstNodeBiComAsv* rnodep = bnodep->rhsp()->castNodeBiComAsv(); if (!rnodep) return false; if (rnodep->type() != bnodep->type()) return false; if (rnodep->width() != bnodep->width()) return false; if (rnodep->lhsp()->width() != bnodep->lhsp()->width()) return false; if (!rnodep->lhsp()->castConst()) return false; return true; } bool operandAsvSame (AstNode* nodep) { // BIASV(SAMEa, BIASV(SAMEb,...)) -> BIASV( BIASV(SAMEa,SAMEb), ...) AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv(); if (!bnodep) return false; AstNodeBiComAsv* rnodep = bnodep->rhsp()->castNodeBiComAsv(); if (!rnodep) return false; if (rnodep->type() != bnodep->type()) return false; if (rnodep->width() != bnodep->width()) return false; return operandsSame(bnodep->lhsp(), rnodep->lhsp()); } bool operandAsvLUp (AstNode* nodep) { // BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r)) // // Example of how this is useful: // BIASV(BIASV(CONSTa,b...),BIASV(CONSTc,d...)) // hits operandAsvUp // BIASV(CONSTa,BIASV(b...,BIASV(CONSTc,d...))) // hits operandAsvUp // BIASV(CONSTa,BIASV(CONSTc,BIASV(c...,d...))) // hits operandAsvConst // BIASV(BIASV(CONSTa,CONSTc),BIASV(c...,d...))) // hits normal constant propagation // BIASV(CONST_a_c,BIASV(c...,d...))) // // Idea for the future: All BiComAsvs could be lists, sorted by if they're constant AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv(); if (!bnodep) return false; AstNodeBiComAsv* lnodep = bnodep->lhsp()->castNodeBiComAsv(); if (!lnodep) return false; if (lnodep->type() != bnodep->type()) return false; if (lnodep->width() != bnodep->width()) return false; return lnodep->lhsp()->castConst(); } bool operandAsvRUp (AstNode* nodep) { // BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr)) AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv(); if (!bnodep) return false; AstNodeBiComAsv* rnodep = bnodep->rhsp()->castNodeBiComAsv(); if (!rnodep) return false; if (rnodep->type() != bnodep->type()) return false; if (rnodep->width() != bnodep->width()) return false; return rnodep->lhsp()->castConst(); } static bool operandSubAdd(AstNode* nodep) { // SUB( ADD(CONSTx,y), CONSTz) -> ADD(SUB(CONSTx,CONSTz), y) AstNodeBiop* np = nodep->castNodeBiop(); AstNodeBiop* lp = np->lhsp()->castNodeBiop(); return (lp && lp->lhsp()->castConst() && np->rhsp()->castConst() && lp->width()==np->width()); } static bool operandAndOrSame(AstNode* nodep) { // OR( AND(VAL,x), AND(VAL,y)) -> AND(VAL,OR(x,y)) // OR( AND(x,VAL), AND(y,VAL)) -> AND(OR(x,y),VAL) AstNodeBiop* np = nodep->castNodeBiop(); AstNodeBiop* lp = np->lhsp()->castNodeBiop(); AstNodeBiop* rp = np->rhsp()->castNodeBiop(); return (lp && rp && lp->width()==rp->width() && lp->type()==rp->type() && (operandsSame(lp->lhsp(),rp->lhsp()) || operandsSame(lp->rhsp(),rp->rhsp()))); } static bool matchOrAndNot(AstNodeBiop* nodep) { // AstOr{$a, AstAnd{AstNot{$b}, $c}} if $a.width1, $a==$b => AstOr{$a,$c} // Someday we'll sort the biops completely and this can be simplified // This often results from our simplified clock generation: // if (rst) ... else if (enable)... -> OR(rst,AND(!rst,enable)) AstNode* ap; AstNodeBiop* andp; if (nodep->lhsp()->castAnd()) { andp=nodep->lhsp()->castAnd(); ap=nodep->rhsp(); } else if (nodep->rhsp()->castAnd()) { andp=nodep->rhsp()->castAnd(); ap=nodep->lhsp(); } else return false; AstNodeUniop* notp; AstNode* cp; if (andp->lhsp()->castNot()) { notp=andp->lhsp()->castNot(); cp=andp->rhsp(); } else if (andp->rhsp()->castNot()) { notp=andp->rhsp()->castNot(); cp=andp->lhsp(); } else return false; AstNode* bp = notp->lhsp(); if (!operandsSame(ap, bp)) return false; // Do it cp->unlinkFrBack(); andp->unlinkFrBack()->deleteTree(); andp=NULL; notp=NULL; // Replace whichever branch is now dangling if (nodep->rhsp()) nodep->lhsp(cp); else nodep->rhsp(cp); return true; } static bool operandShiftSame(AstNode* nodep) { AstNodeBiop* np = nodep->castNodeBiop(); { AstShiftL* lp = np->lhsp()->castShiftL(); AstShiftL* rp = np->rhsp()->castShiftL(); if (lp && rp) { return (lp->width() == rp->width() && lp->lhsp()->width() == rp->lhsp()->width() && operandsSame(lp->rhsp(), rp->rhsp())); } } { AstShiftR* lp = np->lhsp()->castShiftR(); AstShiftR* rp = np->rhsp()->castShiftR(); if (lp && rp) { return (lp->width() == rp->width() && lp->lhsp()->width() == rp->lhsp()->width() && operandsSame(lp->rhsp(), rp->rhsp())); } } return false; } bool operandHugeShiftL(AstNodeBiop* nodep) { return (nodep->rhsp()->castConst() && !nodep->rhsp()->castConst()->num().isFourState() && nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->width()) && isTPure(nodep->lhsp())); } bool operandHugeShiftR(AstNodeBiop* nodep) { return (nodep->rhsp()->castConst() && !nodep->rhsp()->castConst()->num().isFourState() && nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->lhsp()->width()) && isTPure(nodep->lhsp())); } bool operandIsTwo(AstNode* nodep) { return (nodep->castConst() && !nodep->castConst()->num().isFourState() && nodep->width() <= VL_QUADSIZE && nodep->castConst()->toUQuad()==2); } bool operandIsTwostate(AstNode* nodep) { return (nodep->castConst() && !nodep->castConst()->num().isFourState()); } bool operandIsPowTwo(AstNode* nodep) { if (!operandIsTwostate(nodep)) return false; return (1==nodep->castConst()->num().countOnes()); } bool operandShiftOp(AstNodeBiop* nodep) { if (!nodep->rhsp()->castConst()) return false; AstNodeBiop* lhsp = nodep->lhsp()->castNodeBiop(); if (!lhsp || !(lhsp->castAnd()||lhsp->castOr()||lhsp->castXor())) return false; if (nodep->width()!=lhsp->width()) return false; if (nodep->width()!=lhsp->lhsp()->width()) return false; if (nodep->width()!=lhsp->rhsp()->width()) return false; return true; } bool operandShiftShift(AstNodeBiop* nodep) { // We could add a AND though. AstNodeBiop* lhsp = nodep->lhsp()->castNodeBiop(); if (!lhsp || !(lhsp->castShiftL()||lhsp->castShiftR())) return false; // We can only get rid of a<>c or a<rhsp()->castConst() && lhsp->rhsp()->castConst())) return false; if (nodep->rhsp()->castConst()->num().isFourState() || lhsp->rhsp()->castConst()->num().isFourState()) return false; if (nodep->width()!=lhsp->width()) return false; if (nodep->width()!=lhsp->lhsp()->width()) return false; return true; } bool operandWordOOB(AstWordSel* nodep) { // V3Expand may make a arraysel that exceeds the bounds of the array // It was an expression, then got constified. In reality, the WordSel // must be wrapped in a Cond, that will be false. return (nodep->rhsp()->castConst() && nodep->fromp()->castNodeVarRef() && !nodep->fromp()->castNodeVarRef()->lvalue() && ((int)(nodep->rhsp()->castConst()->toUInt()) >= nodep->fromp()->castNodeVarRef()->varp()->widthWords())); } bool operandSelFull(AstSel* nodep) { return (nodep->lsbp()->castConst() && nodep->widthp()->castConst() && nodep->lsbConst()==0 && (int)nodep->widthConst()==nodep->fromp()->width() && 1); } bool operandSelExtend(AstSel* nodep) { // A pattern created by []'s after offsets have been removed // SEL(EXTEND(any,width,...),(width-1),0) -> ... // Since select's return unsigned, this is always an extend AstExtend* extendp = nodep->fromp()->castExtend(); if (!(m_doV && extendp && nodep->lsbp()->castConst() && nodep->widthp()->castConst() && nodep->lsbConst()==0 && (int)nodep->widthConst()==extendp->lhsp()->width() )) return false; replaceWChild(nodep, extendp->lhsp()); nodep=NULL; return true; } bool operandSelBiLower(AstSel* nodep) { // SEL(ADD(a,b),(width-1),0) -> ADD(SEL(a),SEL(b)) // Add or any operation which doesn't care if we discard top bits AstNodeBiop* bip = nodep->fromp()->castNodeBiop(); if (!(m_doV && bip && nodep->lsbp()->castConst() && nodep->widthp()->castConst() && nodep->lsbConst()==0 )) return false; if (debug()>=9) nodep->dumpTree(cout,"SEL(BI)-in:"); AstNode* bilhsp = bip->lhsp()->unlinkFrBack(); AstNode* birhsp = bip->rhsp()->unlinkFrBack(); bip->lhsp(new AstSel(nodep->fileline(), bilhsp, 0, nodep->widthConst())); bip->rhsp(new AstSel(nodep->fileline(), birhsp, 0, nodep->widthConst())); if (debug()>=9) bip->dumpTree(cout,"SEL(BI)-ou:"); replaceWChild(nodep, bip); nodep=NULL; return true; } bool operandBiExtendConst(AstNodeBiop* nodep) { // Loop unrolling favors standalone compares // EQ(const{width32}, EXTEND(xx{width3})) -> EQ(const{3}, xx{3}) // Beware that the constant must have zero bits (+ 1 if signed) or compare // would be incorrect AstExtend* extendp = nodep->rhsp()->castExtend(); if (!extendp) return false; AstNode* smallerp = extendp->lhsp(); int subsize = smallerp->width(); AstConst* constp = nodep->lhsp()->castConst(); if (!constp) return false; if (!constp->num().isBitsZero(constp->width()-1, subsize)) return false; // if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-in:"); smallerp->unlinkFrBack(); extendp->unlinkFrBack()->deleteTree(); // aka nodep->lhsp. nodep->rhsp(smallerp); constp->unlinkFrBack(); V3Number num (constp->fileline(), subsize); num.opAssign(constp->num()); nodep->lhsp(new AstConst(constp->fileline(), num)); constp->deleteTree(); constp=NULL; if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-ou:"); return true; } AstNode* afterComment(AstNode* nodep) { // Ignore comments, such as to determine if a AstIf is empty. // nodep may be null, if so return null. while (nodep && nodep->castComment()) { nodep = nodep->nextp(); } return nodep; } bool isTPure(AstNode* nodep) { // Pure checks - if this node and all nodes under it are free of // side effects can do this optimization // Eventually we'll recurse through tree when unknown, memoizing results so far, // but for now can disable en-mass until V3Purify takes effect. return m_doShort || nodep->castVarRef() || nodep->castConst(); } // Extraction checks bool warnSelect(AstSel* nodep) { if (m_doGenerate) { // Never checked yet V3Width::widthParamsEdit(nodep); nodep->iterateChildren(*this); // May need "constifying" } // Find range of dtype we are selecting from // Similar code in V3Unknown::AstSel bool doit = true; if (m_warn && nodep->lsbp()->castConst() && nodep->widthp()->castConst() && doit) { int maxDeclBit = nodep->declRange().hiMaxSelect()*nodep->declElWidth() + (nodep->declElWidth()-1); if (nodep->lsbp()->castConst()->num().isFourState() || nodep->widthp()->castConst()->num().isFourState()) { nodep->v3error("Selection index is constantly unknown or tristated: " "lsb="<lsbp()->name()<<" width="<widthp()->name()); // Replacing nodep will make a mess above, so we replace the offender replaceZero(nodep->lsbp()); } else if (nodep->declRange().ranged() && (nodep->msbConst() > maxDeclBit || nodep->lsbConst() > maxDeclBit)) { // See also warning in V3Width // Must adjust by element width as declRange() is in number of elements nodep->v3warn(SELRANGE, "Selection index out of range: " <<(nodep->msbConst()/nodep->declElWidth()) <<":"<<(nodep->lsbConst()/nodep->declElWidth()) <<" outside "<declRange().hiMaxSelect()<<":0" <<(nodep->declRange().lo()>=0 ? "" :(" (adjusted +"+cvtToStr(-nodep->declRange().lo()) +" to account for negative lsb)"))); UINFO(1," Related Raw index is "<msbConst()<<":"<lsbConst()<castConst() && node2p->castConst()) { return node1p->sameGateTree(node2p); } else if (node1p->castVarRef() && node2p->castVarRef()) { // Avoid comparing widthMin's, which results in lost optimization attempts // If cleanup sameGateTree to be smarter, this can be restored. //return node1p->sameGateTree(node2p); return node1p->same(node2p); } else { return false; } } bool ifSameAssign(AstNodeIf* nodep) { AstNodeAssign* ifp = nodep->ifsp()->castNodeAssign(); AstNodeAssign* elsep = nodep->elsesp()->castNodeAssign(); if (!ifp || ifp->nextp()) return false; // Must be SINGLE statement if (!elsep || elsep->nextp()) return false; if (ifp->type() != elsep->type()) return false; // Can't mix an assigndly and an assign AstVarRef* ifvarp = ifp->lhsp()->castVarRef(); AstVarRef* elsevarp = elsep->lhsp()->castVarRef(); if (!ifvarp || !elsevarp) return false; if (ifvarp->isWide()) return false; // Would need temporaries, so not worth it if (!ifvarp->sameGateTree(elsevarp)) return false; return true; } bool operandIfIf(AstNodeIf* nodep) { if (nodep->elsesp()) return false; AstNodeIf* lowerIfp = nodep->ifsp()->castNodeIf(); if (!lowerIfp || lowerIfp->nextp()) return false; if (nodep->type() != lowerIfp->type()) return false; if (afterComment(lowerIfp->elsesp())) return false; return true; } bool ifConcatMergeableBiop(AstNode* nodep) { return (nodep->castAnd() || nodep->castOr() || nodep->castXor() || nodep->castXnor()); } bool ifAdjacentSel(AstSel* lhsp, AstSel* rhsp) { if (!v3Global.opt.oAssemble()) return false; // opt disabled if (!lhsp || !rhsp) return false; AstNode* lfromp = lhsp->fromp(); AstNode* rfromp = rhsp->fromp(); if (!lfromp || !rfromp || !lfromp->sameGateTree(rfromp)) return false; AstConst* lstart = lhsp->lsbp()->castConst(); AstConst* rstart = rhsp->lsbp()->castConst(); AstConst* lwidth = lhsp->widthp()->castConst(); AstConst* rwidth = rhsp->widthp()->castConst(); if (!lstart || !rstart || !lwidth || !rwidth) return false; // too complicated int rend = (rstart->toSInt() + rwidth->toSInt()); if (rend == lstart->toSInt()) return true; return false; } bool ifMergeAdjacent(AstNode* lhsp, AstNode* rhsp) { // called by concatmergeable to determine if {lhsp, rhsp} make sense if (!v3Global.opt.oAssemble()) return false; // opt disabled // two same varref if (operandsSame(lhsp, rhsp)) return true; AstSel* lselp = lhsp->castSel(); AstSel* rselp = rhsp->castSel(); // a[i:0] a if (lselp && !rselp && rhsp->sameGateTree(lselp->fromp())) rselp = new AstSel(rhsp->fileline(), rhsp->cloneTree(false), 0, rhsp->width()); // a[i:j] {a[j-1:k], b} if (lselp && !rselp && rhsp->castConcat()) return ifMergeAdjacent(lhsp, rhsp->castConcat()->lhsp()); // a a[msb:j] if (rselp && !lselp && lhsp->sameGateTree(rselp->fromp())) lselp = new AstSel(lhsp->fileline(), lhsp->cloneTree(false), 0, lhsp->width()); // {b, a[j:k]} a[k-1:i] if (rselp && !lselp && lhsp->castConcat()) return ifMergeAdjacent(lhsp->castConcat()->rhsp(), rhsp); if (!lselp || !rselp) return false; // a[a:b] a[b-1:c] are adjacent AstNode* lfromp = lselp->fromp(); AstNode* rfromp = rselp->fromp(); if (!lfromp || !rfromp || !lfromp->sameGateTree(rfromp)) return false; AstConst* lstart = lselp->lsbp()->castConst(); AstConst* rstart = rselp->lsbp()->castConst(); AstConst* lwidth = lselp->widthp()->castConst(); AstConst* rwidth = rselp->widthp()->castConst(); if (!lstart || !rstart || !lwidth || !rwidth) return false; // too complicated int rend = (rstart->toSInt() + rwidth->toSInt()); // a[i:j] a[j-1:k] if (rend == lstart->toSInt()) return true; // a[i:0] a[msb:j] if (rend == rfromp->width() && lstart->toSInt() == 0) return true; return false; } bool concatMergeable(AstNode* lhsp, AstNode* rhsp) { // determine if {a OP b, c OP d} => {a, c} OP {b, d} is advantagous if (!v3Global.opt.oAssemble()) return false; // opt disabled if (lhsp->type() != rhsp->type()) return false; if (!ifConcatMergeableBiop(lhsp)) return false; AstNodeBiop* lp = lhsp->castNodeBiop(); AstNodeBiop* rp = rhsp->castNodeBiop(); if (!lp || !rp) return false; // {a[]&b[], a[]&b[]} bool lad = ifMergeAdjacent(lp->lhsp(), rp->lhsp()); bool rad = ifMergeAdjacent(lp->rhsp(), rp->rhsp()); if (lad && rad) return true; // {a[] & b[]&c[], a[] & b[]&c[]} else if (lad && concatMergeable(lp->rhsp(), rp->rhsp())) return true; // {a[]&b[] & c[], a[]&b[] & c[]} else if (rad && concatMergeable(lp->lhsp(), rp->lhsp())) return true; else { // {(a[]&b[])&(c[]&d[]), (a[]&b[])&(c[]&d[])} if (concatMergeable(lp->lhsp(), rp->lhsp()) && concatMergeable(lp->rhsp(), rp->rhsp())) return true; } return false; } //---------------------------------------- // Constant Replacement functions. // These all take a node, delete its tree, and replaces it with a constant void replaceNum (AstNode* oldp, const V3Number& num) { // Replace oldp node with a constant set to specified value UASSERT (oldp, "Null old\n"); if (oldp->castConst() && !oldp->castConst()->num().isFourState()) { oldp->v3fatalSrc("Already constant??\n"); } AstNode* newp = new AstConst(oldp->fileline(), num); newp->dtypeFrom(oldp); if (debug()>5) oldp->dumpTree(cout," const_old: "); if (debug()>5) newp->dumpTree(cout," _new: "); oldp->replaceWith(newp); oldp->deleteTree(); oldp=NULL; } void replaceNum (AstNode* nodep, uint32_t val) { V3Number num (nodep->fileline(), nodep->width(), val); replaceNum(nodep, num); nodep=NULL; } void replaceNumSigned(AstNodeBiop* nodep, uint32_t val) { // We allow both sides to be constant, as one may have come from parameter propagation, etc. if (m_warn && !(nodep->lhsp()->castConst() && nodep->rhsp()->castConst())) { nodep->v3warn(UNSIGNED,"Comparison is constant due to unsigned arithmetic"); } replaceNum(nodep, val); nodep=NULL; } void replaceNumLimited(AstNodeBiop* nodep, uint32_t val) { // Avoids gcc warning about same if (m_warn) nodep->v3warn(CMPCONST,"Comparison is constant due to limited range"); replaceNum(nodep, val); nodep=NULL; } void replaceZero(AstNode* nodep) { replaceNum(nodep, 0); nodep=NULL; } void replaceZeroChkPure(AstNode* nodep, AstNode* checkp) { // For example, "0 * n" -> 0 if n has no side effects // Else strength reduce it to 0 & n. // If ever change the operation note AstAnd rule specially ignores this created pattern if (isTPure(checkp)) { replaceNum(nodep, 0); nodep=NULL; } else { AstNode* newp = new AstAnd(nodep->fileline(), new AstConst(nodep->fileline(), 0), checkp->unlinkFrBack()); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } } void replaceAllOnes (AstNode* nodep) { V3Number ones (nodep->fileline(), nodep->width(), 0); ones.setMask(nodep->width()); replaceNum(nodep, ones); nodep=NULL; } void replaceConst(AstNodeUniop* nodep) { V3Number num (nodep->fileline(), nodep->width()); nodep->numberOperate(num, nodep->lhsp()->castConst()->num()); UINFO(4,"UNICONST -> "<fileline(), nodep->width()); nodep->numberOperate(num, nodep->lhsp()->castConst()->num(), nodep->rhsp()->castConst()->num()); UINFO(4,"BICONST -> "<fileline(), nodep->width()); nodep->numberOperate(num, nodep->lhsp()->castConst()->num(), nodep->rhsp()->castConst()->num(), nodep->thsp()->castConst()->num()); UINFO(4,"TRICONST -> "<fileline(), AstConst::String(), num); if (debug()>5) oldp->dumpTree(cout," const_old: "); if (debug()>5) newp->dumpTree(cout," _new: "); oldp->replaceWith(newp); oldp->deleteTree(); oldp=NULL; } //---------------------------------------- // Replacement functions. // These all take a node and replace it with something else void replaceWChild(AstNode* nodep, AstNode* childp) { // NODE(..., CHILD(...)) -> CHILD(...) childp->unlinkFrBackWithNext(); // If replacing a SEL for example, the data type comes from the parent (is less wide). // This may adversly affect the operation of the node being replaced. childp->dtypeFrom(nodep); nodep->replaceWith(childp); nodep->deleteTree(); nodep=NULL; } //! Replace a ternary node with its RHS after iterating //! Used with short-circuting, where the RHS has not yet been iterated. void replaceWIteratedRhs(AstNodeTriop* nodep) { if (AstNode *rhsp = nodep->rhsp()) rhsp->iterateAndNext(*this); replaceWChild(nodep, nodep->rhsp()); // May have changed } //! Replace a ternary node with its THS after iterating //! Used with short-circuting, where the THS has not yet been iterated. void replaceWIteratedThs(AstNodeTriop* nodep) { if (AstNode *thsp = nodep->thsp()) thsp->iterateAndNext(*this); replaceWChild(nodep, nodep->thsp()); // May have changed } void replaceWLhs(AstNodeUniop* nodep) { // Keep LHS, remove RHS replaceWChild(nodep, nodep->lhsp()); } void replaceWLhs(AstNodeBiop* nodep) { // Keep LHS, remove RHS replaceWChild(nodep, nodep->lhsp()); } void replaceWRhs(AstNodeBiop* nodep) { // Keep RHS, remove LHS replaceWChild(nodep, nodep->rhsp()); } void replaceAsv (AstNodeBiop* nodep) { // BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c) // BIASV(SAMEa, BIASV(SAMEb, c)) -> BIASV( BIASV(SAMEa,SAMEb), c) //nodep->dumpTree(cout, " repAsvConst_old: "); AstNode* ap = nodep->lhsp(); AstNodeBiop* rp = nodep->rhsp()->castNodeBiop(); AstNode* bp = rp->lhsp(); AstNode* cp = rp->rhsp(); ap->unlinkFrBack(); bp->unlinkFrBack(); cp->unlinkFrBack(); rp->unlinkFrBack(); nodep->lhsp(rp); nodep->rhsp(cp); rp->lhsp(ap); rp->rhsp(bp); if (rp->lhsp()->castConst() && rp->rhsp()->castConst()) replaceConst(rp); //nodep->dumpTree(cout, " repAsvConst_new: "); } void replaceAsvLUp (AstNodeBiop* nodep) { // BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r)) AstNodeBiop* lp = nodep->lhsp()->unlinkFrBack()->castNodeBiop(); AstNode* llp = lp->lhsp()->unlinkFrBack(); AstNode* lrp = lp->rhsp()->unlinkFrBack(); AstNode* rp = nodep->rhsp()->unlinkFrBack(); nodep->lhsp(llp); nodep->rhsp(lp); lp->lhsp(lrp); lp->rhsp(rp); //nodep->dumpTree(cout, " repAsvLUp_new: "); } void replaceAsvRUp (AstNodeBiop* nodep) { // BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr)) AstNode* lp = nodep->lhsp()->unlinkFrBack(); AstNodeBiop* rp = nodep->rhsp()->unlinkFrBack()->castNodeBiop(); AstNode* rlp = rp->lhsp()->unlinkFrBack(); AstNode* rrp = rp->rhsp()->unlinkFrBack(); nodep->lhsp(rlp); nodep->rhsp(rp); rp->lhsp(lp); rp->rhsp(rrp); //nodep->dumpTree(cout, " repAsvRUp_new: "); } void replaceAndOr (AstNodeBiop* nodep) { // OR (AND (CONSTll,lr), AND(CONSTrl==ll,rr)) -> AND (CONSTll, OR(lr,rr)) // OR (AND (CONSTll,lr), AND(CONSTrl, rr=lr)) -> AND (OR(ll,rl), rr) // nodep ^lp ^llp ^lrp ^rp ^rlp ^rrp // (Or/And may also be reversed) AstNodeBiop* lp = nodep->lhsp()->unlinkFrBack()->castNodeBiop(); AstNode* llp = lp->lhsp()->unlinkFrBack(); AstNode* lrp = lp->rhsp()->unlinkFrBack(); AstNodeBiop* rp = nodep->rhsp()->unlinkFrBack()->castNodeBiop(); AstNode* rlp = rp->lhsp()->unlinkFrBack(); AstNode* rrp = rp->rhsp()->unlinkFrBack(); nodep->replaceWith(lp); if (operandsSame(llp,rlp)) { lp->lhsp(llp); lp->rhsp(nodep); nodep->lhsp(lrp); nodep->rhsp(rrp); rp->deleteTree(); rlp->deleteTree(); } else if (operandsSame(lrp, rrp)) { lp->lhsp(nodep); lp->rhsp(rrp); nodep->lhsp(llp); nodep->rhsp(rlp); rp->deleteTree(); lrp->deleteTree(); } else { nodep->v3fatalSrc("replaceAndOr on something operandAndOrSame shouldn't have matched"); } //nodep->dumpTree(cout, " repAndOr_new: "); } void replaceShiftSame (AstNodeBiop* nodep) { // Or(Shift(ll,CONSTlr),Shift(rl,CONSTrr==lr)) -> Shift(Or(ll,rl),CONSTlr) // (Or/And may also be reversed) AstNodeBiop* lp = nodep->lhsp()->unlinkFrBack()->castNodeBiop(); AstNode* llp = lp->lhsp()->unlinkFrBack(); AstNode* lrp = lp->rhsp()->unlinkFrBack(); AstNodeBiop* rp = nodep->rhsp()->unlinkFrBack()->castNodeBiop(); AstNode* rlp = rp->lhsp()->unlinkFrBack(); AstNode* rrp = rp->rhsp()->unlinkFrBack(); nodep->replaceWith(lp); lp->lhsp(nodep); lp->rhsp(lrp); nodep->lhsp(llp); nodep->rhsp(rlp); rp->deleteTree(); rrp->deleteTree(); //nodep->dumpTree(cout, " repShiftSame_new: "); } void replaceConcatSel(AstConcat* nodep) { // {a[1], a[0]} -> a[1:0] AstSel* lselp = nodep->lhsp()->unlinkFrBack()->castSel(); AstSel* rselp = nodep->rhsp()->unlinkFrBack()->castSel(); int lstart = lselp->lsbConst(); int lwidth = lselp->widthConst(); int rstart = rselp->lsbConst(); int rwidth = rselp->widthConst(); if ((rstart + rwidth) != lstart) nodep->v3fatalSrc("tried to merge two selects which are not adjacent"); AstSel* newselp = new AstSel(lselp->fromp()->fileline(), rselp->fromp()->cloneTree(false), rstart, lwidth+rwidth); UINFO(5, "merged two adjacent sel "<replaceWith(newselp); lselp->deleteTree(); lselp = NULL; rselp->deleteTree(); rselp = NULL; nodep->deleteTree(); nodep = NULL; } void replaceConcatMerge(AstConcat* nodep) { AstNodeBiop* lp = nodep->lhsp()->castNodeBiop(); AstNodeBiop* rp = nodep->rhsp()->castNodeBiop(); AstNode* llp = lp->lhsp()->cloneTree(false); AstNode* lrp = lp->rhsp()->cloneTree(false); AstNode* rlp = rp->lhsp()->cloneTree(false); AstNode* rrp = rp->rhsp()->cloneTree(false); if (concatMergeable(lp, rp)) { AstConcat* newlp = new AstConcat(rlp->fileline(), llp, rlp); AstConcat* newrp = new AstConcat(rrp->fileline(), lrp, rrp); // use the lhs to replace the parent concat lp->lhsp()->replaceWith(newlp); lp->rhsp()->replaceWith(newrp); lp->dtypeChgWidthSigned(newlp->width(), newlp->width(), AstNumeric::fromBool(true)); UINFO(5, "merged "<< nodep <unlinkFrBack()->deleteTree(); rp = NULL; nodep->replaceWith(lp->unlinkFrBack()); nodep->deleteTree(); nodep = NULL; lp->lhsp()->accept(*this); lp->rhsp()->accept(*this); } else nodep->v3fatalSrc("tried to merge two Concat which are not adjacent"); } void replaceExtend (AstNode* nodep, AstNode* arg0p) { // -> EXTEND(nodep) // like a AstExtend{$rhsp}, but we need to set the width correctly from base node arg0p->unlinkFrBack(); AstNode* newp = (nodep->castExtendS() ? (new AstExtendS(nodep->fileline(), arg0p))->castNode() : (new AstExtend (nodep->fileline(), arg0p))->castNode()); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } void replacePowShift (AstNodeBiop* nodep) { // Pow or PowS UINFO(5,"POW(2,b)->SHIFTL(1,b) "<rhsp()->unlinkFrBack(); AstShiftL* newp = new AstShiftL(nodep->fileline(), new AstConst(nodep->fileline(), 1), rhsp); newp->dtypeFrom(nodep); newp->lhsp()->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } void replaceMulShift (AstMul* nodep) { // Mul, but not MulS as not simple shift UINFO(5,"MUL(2^n,b)->SHIFTL(b,n) "<lhsp()->castConst()->num().mostSetBitP1()-1; // 2^n->n+1 AstNode* opp = nodep->rhsp()->unlinkFrBack(); AstShiftL* newp = new AstShiftL(nodep->fileline(), opp, new AstConst(nodep->fileline(), amount)); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } void replaceDivShift (AstDiv* nodep) { // Mul, but not MulS as not simple shift UINFO(5,"DIV(b,2^n)->SHIFTR(b,n) "<rhsp()->castConst()->num().mostSetBitP1()-1; // 2^n->n+1 AstNode* opp = nodep->lhsp()->unlinkFrBack(); AstShiftR* newp = new AstShiftR(nodep->fileline(), opp, new AstConst(nodep->fileline(), amount)); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } void replaceShiftOp (AstNodeBiop* nodep) { UINFO(5,"SHIFT(AND(a,b),CONST)->AND(SHIFT(a,CONST),SHIFT(b,CONST)) "<unlinkFrBack(&handle); AstNodeBiop* lhsp = nodep->lhsp()->castNodeBiop(); lhsp->unlinkFrBack(); AstNode* shiftp = nodep->rhsp()->unlinkFrBack(); AstNode* ap = lhsp->lhsp()->unlinkFrBack(); AstNode* bp = lhsp->rhsp()->unlinkFrBack(); AstNodeBiop* shift1p = nodep; AstNodeBiop* shift2p = nodep->cloneTree(true); shift1p->lhsp(ap); shift1p->rhsp(shiftp->cloneTree(true)); shift2p->lhsp(bp); shift2p->rhsp(shiftp); AstNodeBiop* newp = lhsp; newp->lhsp(shift1p); newp->rhsp(shift2p); handle.relink(newp); newp->accept(*this); // Further reduce, either node may have more reductions. } void replaceShiftShift (AstNodeBiop* nodep) { UINFO(4,"SHIFT(SHIFT(a,s1),s2)->SHIFT(a,ADD(s1,s2)) "<=9) nodep->dumpTree(cout, " repShiftShift_old: "); AstNodeBiop* lhsp = nodep->lhsp()->castNodeBiop(); lhsp->unlinkFrBack(); AstNode* ap = lhsp->lhsp()->unlinkFrBack(); AstNode* shift1p = lhsp->rhsp()->unlinkFrBack(); AstNode* shift2p = nodep->rhsp()->unlinkFrBack(); // Shift1p and shift2p may have different sizes, both are self-determined so sum with infinite width if (nodep->type()==lhsp->type()) { int shift1 = shift1p->castConst()->toUInt(); int shift2 = shift2p->castConst()->toUInt(); int newshift = shift1+shift2; shift1p->deleteTree(); shift1p=NULL; shift2p->deleteTree(); shift2p=NULL; nodep->lhsp(ap); nodep->rhsp(new AstConst(nodep->fileline(), newshift)); nodep->accept(*this); // Further reduce, either node may have more reductions. } else { // We know shift amounts are constant, but might be a mixed left/right shift int shift1 = shift1p->castConst()->toUInt(); if (lhsp->castShiftR()) shift1=-shift1; int shift2 = shift2p->castConst()->toUInt(); if (nodep->castShiftR()) shift2=-shift2; int newshift = shift1+shift2; shift1p->deleteTree(); shift1p=NULL; shift2p->deleteTree(); shift2p=NULL; AstNode* newp; V3Number mask1 (nodep->fileline(), nodep->width()); V3Number ones (nodep->fileline(), nodep->width()); ones.setMask(nodep->width()); if (shift1<0) { mask1.opShiftR(ones,V3Number(nodep->fileline(),VL_WORDSIZE,-shift1)); } else { mask1.opShiftL(ones,V3Number(nodep->fileline(),VL_WORDSIZE,shift1)); } V3Number mask (nodep->fileline(), nodep->width()); if (shift2<0) { mask.opShiftR(mask1,V3Number(nodep->fileline(),VL_WORDSIZE,-shift2)); } else { mask.opShiftL(mask1,V3Number(nodep->fileline(),VL_WORDSIZE,shift2)); } if (newshift<0) { newp = new AstShiftR(nodep->fileline(), ap, new AstConst(nodep->fileline(), -newshift)); } else { newp = new AstShiftL(nodep->fileline(), ap, new AstConst(nodep->fileline(), newshift)); } newp->dtypeFrom(nodep); newp = new AstAnd (nodep->fileline(), newp, new AstConst (nodep->fileline(), mask)); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; //newp->dumpTree(cout, " repShiftShift_new: "); newp->accept(*this); // Further reduce, either node may have more reductions. } lhsp->deleteTree(); lhsp=NULL; } bool replaceAssignMultiSel(AstNodeAssign* nodep) { // Multiple assignments to sequential bits can be concated // ASSIGN(SEL(a),aq), ASSIGN(SEL(a+1),bq) -> ASSIGN(SEL(a:b),CONCAT(aq,bq) // ie. assign var[2]=a, assign var[3]=b -> assign var[3:2]={b,a} if (!m_modp) return false; // Skip if we're not const'ing an entire module (IE doing only one assign, etc) AstSel* sel1p = nodep->lhsp()->castSel(); if (!sel1p) return false; AstNodeAssign* nextp = nodep->nextp()->castNodeAssign(); if (!nextp) return false; if (nodep->type() != nextp->type()) return false; AstSel* sel2p = nextp->lhsp()->castSel(); if (!sel2p) return false; AstVarRef* varref1p = sel1p->fromp()->castVarRef(); if (!varref1p) return false; AstVarRef* varref2p = sel2p->fromp()->castVarRef(); if (!varref2p) return false; if (!varref1p->sameGateTree(varref2p)) return false; AstConst* con1p = sel1p->lsbp()->castConst(); if (!con1p) return false; AstConst* con2p = sel2p->lsbp()->castConst(); if (!con2p) return false; // We need to make sure there's no self-references involved in either // assignment. For speed, we only look 3 deep, then give up. if (!varNotReferenced(nodep->rhsp(), varref1p->varp())) return false; if (!varNotReferenced(nextp->rhsp(), varref2p->varp())) return false; // Swap? if (( con1p->toSInt() != con2p->toSInt() + sel2p->width()) &&(con2p->toSInt() != con1p->toSInt() + sel1p->width())) return false; bool lsbFirstAssign = (con1p->toUInt() < con2p->toUInt()); // If the user already has nice 32-bit divisions, keep them to aid later subdivision //if (VL_BITBIT_I(con1p->toUInt()) == 0) return false; UINFO(4,"replaceAssignMultiSel "<dumpTree(cout, "comb1: "); //nextp->dumpTree(cout, "comb2: "); AstNode* rhs1p = nodep->rhsp()->unlinkFrBack(); AstNode* rhs2p = nextp->rhsp()->unlinkFrBack(); AstNode* newp; if (lsbFirstAssign) { newp = nodep->cloneType (new AstSel(sel1p->fileline(), varref1p->unlinkFrBack(), sel1p->lsbConst(), sel1p->width() + sel2p->width()), new AstConcat(rhs1p->fileline(), rhs2p, rhs1p)); } else { newp = nodep->cloneType (new AstSel(sel1p->fileline(), varref1p->unlinkFrBack(), sel2p->lsbConst(), sel1p->width() + sel2p->width()), new AstConcat(rhs1p->fileline(), rhs1p, rhs2p)); } //pnewp->dumpTree(cout, "conew: "); nodep->replaceWith(newp); nodep->deleteTree(); nextp->unlinkFrBack()->deleteTree(); return true; } bool varNotReferenced(AstNode* nodep, AstVar* varp, int level=0) { // Return true if varp never referenced under node. // Return false if referenced, or tree too deep to be worth it, or side effects if (!nodep) return true; if (level>2) return false; if (nodep->isPure()) return false; // For example a $fgetc can't be reordered if (nodep->castNodeVarRef() && nodep->castNodeVarRef()->varp()==varp) return false; return (varNotReferenced (nodep->nextp(),varp,level+1) && varNotReferenced(nodep->op1p(),varp,level+1) && varNotReferenced(nodep->op2p(),varp,level+1) && varNotReferenced(nodep->op3p(),varp,level+1) && varNotReferenced(nodep->op4p(),varp,level+1)); } bool replaceNodeAssign(AstNodeAssign* nodep) { if (nodep->lhsp()->castVarRef() && nodep->rhsp()->castVarRef() && nodep->lhsp()->castVarRef()->sameNoLvalue(nodep->rhsp()->castVarRef()) && !nodep->castAssignDly()) { // X = X. Quite pointless, though X <= X may override another earlier assignment if (nodep->castAssignW()) { nodep->v3error("Wire inputs its own output, creating circular logic (wire x=x)"); return false; // Don't delete the assign, or V3Gate will freak out } else { nodep->unlinkFrBack()->deleteTree(); nodep=NULL; return true; } } else if (m_doV && nodep->lhsp()->castConcat()) { bool need_temp = false; if (m_warn && !nodep->castAssignDly()) { // Is same var on LHS and RHS? // Note only do this (need user4) when m_warn, which is // done as unique visitor AstUser4InUse m_inuser4; ConstVarMarkVisitor mark(nodep->lhsp()); ConstVarFindVisitor find(nodep->rhsp()); if (find.found()) need_temp = true; } if (need_temp) { // The first time we constify, there may be the same variable on the LHS // and RHS. In that case, we must use temporaries, or {a,b}={b,a} will break. UINFO(4," ASSITEMP "< ASSIGN(temp1,SEL(rhs,{size})), // ASSIGN(temp2,SEL(newrhs,{size})) // ASSIGN(lc1,temp1), // ASSIGN(lc2,temp2) } else { UINFO(4," ASSI "< ASSIGN(lc1,SEL(rhs,{size})), // ASSIGN(lc2,SEL(newrhs,{size})) } if (debug()>=9) nodep->dumpTree(cout," Ass_old: "); // Unlink the stuff AstNode* lc1p = nodep->lhsp()->castConcat()->lhsp()->unlinkFrBack(); AstNode* lc2p = nodep->lhsp()->castConcat()->rhsp()->unlinkFrBack(); AstNode* conp = nodep->lhsp()->castConcat()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* rhs2p = rhsp->cloneTree(false); // Calc widths int lsb2 = 0; int msb2 = lsb2+lc2p->width()-1; int lsb1 = msb2+1; int msb1 = lsb1+lc1p->width()-1; if (msb1!=(conp->width()-1)) nodep->v3fatalSrc("Width calc mismatch"); // Form ranges AstSel* sel1p = new AstSel(conp->fileline(), rhsp, lsb1, msb1-lsb1+1); AstSel* sel2p = new AstSel(conp->fileline(), rhs2p, lsb2, msb2-lsb2+1); // Make new assigns of same flavor as old one //*** Not cloneTree; just one node. AstNode* newp = NULL; if (!need_temp) { AstNodeAssign* asn1ap=nodep->cloneType(lc1p, sel1p)->castNodeAssign(); AstNodeAssign* asn2ap=nodep->cloneType(lc2p, sel2p)->castNodeAssign(); asn1ap->dtypeFrom(sel1p); asn2ap->dtypeFrom(sel2p); // cppcheck-suppress nullPointer // addNext deals with it newp = newp->addNext(asn1ap); // cppcheck-suppress nullPointer // addNext deals with it newp = newp->addNext(asn2ap); } else { if (!m_modp) nodep->v3fatalSrc("Not under module"); // We could create just one temp variable, but we'll get better optimization // if we make one per term. string name1 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc())); string name2 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc())); AstVar* temp1p = new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP, name1, VFlagLogicPacked(), msb1-lsb1+1); AstVar* temp2p = new AstVar(sel2p->fileline(), AstVarType::BLOCKTEMP, name2, VFlagLogicPacked(), msb2-lsb2+1); m_modp->addStmtp(temp1p); m_modp->addStmtp(temp2p); AstNodeAssign* asn1ap=nodep->cloneType (new AstVarRef(sel1p->fileline(), temp1p, true), sel1p)->castNodeAssign(); AstNodeAssign* asn2ap=nodep->cloneType (new AstVarRef(sel2p->fileline(), temp2p, true), sel2p)->castNodeAssign(); AstNodeAssign* asn1bp=nodep->cloneType (lc1p, new AstVarRef(sel1p->fileline(), temp1p, false)) ->castNodeAssign(); AstNodeAssign* asn2bp=nodep->cloneType (lc2p, new AstVarRef(sel2p->fileline(), temp2p, false)) ->castNodeAssign(); asn1ap->dtypeFrom(temp1p); asn1bp->dtypeFrom(temp1p); asn2ap->dtypeFrom(temp2p); asn2bp->dtypeFrom(temp2p); // This order matters // cppcheck-suppress nullPointer // addNext deals with it newp = newp->addNext(asn1ap); // cppcheck-suppress nullPointer // addNext deals with it newp = newp->addNext(asn2ap); // cppcheck-suppress nullPointer // addNext deals with it newp = newp->addNext(asn1bp); // cppcheck-suppress nullPointer // addNext deals with it newp = newp->addNext(asn2bp); } if (debug()>=9 && newp) newp->dumpTreeAndNext(cout," _new: "); nodep->addNextHere(newp); // Cleanup nodep->unlinkFrBack()->deleteTree(); nodep=NULL; conp->deleteTree(); conp=NULL; // Further reduce, either node may have more reductions. return true; } else if (m_doV && nodep->rhsp()->castStreamR()) { // The right-streaming operator on rhs of assignment does not // change the order of bits. Eliminate stream but keep its lhsp // Unlink the stuff AstNode* srcp = nodep->rhsp()->castStreamR()->lhsp()->unlinkFrBack(); AstNode* sizep = nodep->rhsp()->castStreamR()->rhsp()->unlinkFrBack(); AstNode* streamp = nodep->rhsp()->castStreamR()->unlinkFrBack(); nodep->rhsp(srcp); // Cleanup sizep->deleteTree(); sizep=NULL; streamp->deleteTree(); streamp=NULL; // Further reduce, any of the nodes may have more reductions. return true; } else if (m_doV && nodep->lhsp()->castStreamL()) { // Push the stream operator to the rhs of the assignment statement int dWidth = nodep->lhsp()->castStreamL()->lhsp()->width(); int sWidth = nodep->rhsp()->width(); // Unlink the stuff AstNode* dstp = nodep->lhsp()->castStreamL()->lhsp()->unlinkFrBack(); AstNode* streamp = nodep->lhsp()->castStreamL()->unlinkFrBack(); AstNode* srcp = nodep->rhsp()->unlinkFrBack(); // Connect the rhs to the stream operator and update its width streamp->castStreamL()->lhsp(srcp); streamp->dtypeSetLogicSized((srcp->width()), (srcp->widthMin()), AstNumeric::UNSIGNED); // Shrink the RHS if necessary if (sWidth > dWidth) { streamp = new AstSel(streamp->fileline(), streamp, sWidth-dWidth, dWidth); } // Link the nodes back in nodep->lhsp(dstp); nodep->rhsp(streamp); return true; } else if (m_doV && nodep->lhsp()->castStreamR()) { // The right stream operator on lhs of assignment statement does // not reorder bits. However, if the rhs is wider than the lhs, // then we select bits from the left-most, not the right-most. int dWidth = nodep->lhsp()->castStreamR()->lhsp()->width(); int sWidth = nodep->rhsp()->width(); // Unlink the stuff AstNode* dstp = nodep->lhsp()->castStreamR()->lhsp()->unlinkFrBack(); AstNode* sizep = nodep->lhsp()->castStreamR()->rhsp()->unlinkFrBack(); AstNode* streamp = nodep->lhsp()->castStreamR()->unlinkFrBack(); AstNode* srcp = nodep->rhsp()->unlinkFrBack(); if (sWidth > dWidth) { srcp = new AstSel(streamp->fileline(), srcp, sWidth-dWidth, dWidth); } nodep->lhsp(dstp); nodep->rhsp(srcp); // Cleanup sizep->deleteTree(); sizep=NULL; streamp->deleteTree(); streamp=NULL; // Further reduce, any of the nodes may have more reductions. return true; } else if (replaceAssignMultiSel(nodep)) { return true; } return false; } // Boolean replacements bool operandBoolShift(AstNode* nodep) { // boolean test of AND(const,SHIFTR(x,const)) -> test of AND(SHIFTL(x,const), x) if (!nodep->castAnd()) return false; if (!nodep->castAnd()->lhsp()->castConst()) return false; if (!nodep->castAnd()->rhsp()->castShiftR()) return false; AstShiftR* shiftp = nodep->castAnd()->rhsp()->castShiftR(); if (!shiftp->rhsp()->castConst()) return false; if ((uint32_t)(nodep->width()) <= shiftp->rhsp()->castConst()->toUInt()) return false; return true; } void replaceBoolShift(AstNode* nodep) { if (debug()>=9) nodep->dumpTree(cout," bshft_old: "); AstConst* andConstp = nodep->castAnd()->lhsp()->castConst(); AstNode* fromp = nodep->castAnd()->rhsp()->castShiftR()->lhsp()->unlinkFrBack(); AstConst* shiftConstp = nodep->castAnd()->rhsp()->castShiftR()->rhsp()->castConst(); V3Number val (andConstp->fileline(), andConstp->width()); val.opShiftL(andConstp->num(), shiftConstp->num()); AstAnd* newp = new AstAnd(nodep->fileline(), new AstConst(nodep->fileline(), val), fromp); newp->dtypeSetLogicSized(nodep->width(), nodep->width(), AstNumeric::UNSIGNED); // widthMin no longer applicable if different C-expanded width nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; if (debug()>=9) newp->dumpTree(cout," _new: "); } void replaceWithSimulation(AstNode* nodep) { SimulateVisitor simvis; // Run it - may be unoptimizable due to large for loop, etc simvis.mainParamEmulate(nodep); if (!simvis.optimizable()) { AstNode* errorp = simvis.whyNotNodep(); if (!errorp) errorp = nodep; nodep->v3error("Expecting expression to be constant, but can't determine constant for " <prettyTypeName()<warnMore()<<"... Location of non-constant " <prettyTypeName()<<": "<v3fatalSrc("No number returned from simulation"); // Replace it replaceNum(nodep,*outnump); nodep=NULL; } } //---------------------------------------- // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { // Iterate modules backwards, in bottom-up order. That's faster nodep->iterateChildrenBackwards(*this); } virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstCFunc* nodep, AstNUser*) { // No ASSIGNW removals under funcs, we've long eliminated INITIALs // (We should perhaps rename the assignw's to just assigns) m_wremove = false; nodep->iterateChildren(*this); m_wremove = true; } virtual void visit(AstScope* nodep, AstNUser*) { // No ASSIGNW removals under scope, we've long eliminated INITIALs m_scopep = nodep; m_wremove = false; nodep->iterateChildren(*this); m_wremove = true; m_scopep = NULL; } void swapSides(AstNodeBiCom* nodep) { // COMMUNATIVE({a},CONST) -> COMMUNATIVE(CONST,{a}) // This simplifies later optimizations AstNode* lhsp = nodep->lhsp()->unlinkFrBackWithNext(); AstNode* rhsp = nodep->rhsp()->unlinkFrBackWithNext(); nodep->lhsp(rhsp); nodep->rhsp(lhsp); nodep->accept(*this); // Again? } int operandConcatMove(AstConcat* nodep) { // CONCAT under concat (See moveConcat) // Return value: true indicates to do it; 2 means move to LHS AstConcat* abConcp = nodep->lhsp()->castConcat(); AstConcat* bcConcp = nodep->rhsp()->castConcat(); if (!abConcp && !bcConcp) return 0; if (bcConcp) { AstNode* ap = nodep->lhsp(); AstNode* bp = bcConcp->lhsp(); // If a+b == 32,64,96 etc, then we want to have a+b together on LHS if (VL_BITBIT_I(ap->width()+bp->width())==0) return 2; // Transform 2: to abConc } else { //abConcp // Unless lhs is already 32 bits due to above, reorder it if (VL_BITBIT_I(nodep->lhsp()->width())!=0) return 1; // Transform 1: to bcConc } return 0; // ok } void moveConcat(AstConcat* nodep) { // 1: CONCAT(CONCAT({a},{b}),{c}) -> CONCAT({a},CONCAT({b}, {c})) // or 2: CONCAT({a}, CONCAT({b},{c})) -> CONCAT(CONCAT({a},{b}),{c}) // Because the lhs of a concat needs a shift but the rhs doesn't, // putting additional CONCATs on the RHS leads to fewer assembler operations. // However, we'll end up with lots of wide moves if we make huge trees // like that, so on 32 bit boundaries, we'll do the opposite form. UINFO(4,"Move concat: "<1) { AstNode* ap = nodep->lhsp()->unlinkFrBack(); AstConcat* bcConcp = nodep->rhsp()->castConcat(); bcConcp->unlinkFrBack(); AstNode* bp = bcConcp->lhsp()->unlinkFrBack(); AstNode* cp = bcConcp->rhsp()->unlinkFrBack(); AstConcat* abConcp = new AstConcat(bcConcp->fileline(), ap, bp); nodep->lhsp(abConcp); nodep->rhsp(cp); // If bp was a concat, then we have this exact same form again! // Recurse rather then calling node->iterate to prevent 2^n recursion! if (operandConcatMove(abConcp)) moveConcat(abConcp); bcConcp->deleteTree(); bcConcp=NULL; } else { AstConcat* abConcp = nodep->lhsp()->castConcat(); abConcp->unlinkFrBack(); AstNode* ap = abConcp->lhsp()->unlinkFrBack(); AstNode* bp = abConcp->rhsp()->unlinkFrBack(); AstNode* cp = nodep->rhsp()->unlinkFrBack(); AstConcat* bcConcp = new AstConcat(abConcp->fileline(), bp, cp); nodep->lhsp(ap); nodep->rhsp(bcConcp); if (operandConcatMove(bcConcp)) moveConcat(bcConcp); abConcp->deleteTree(); abConcp=NULL; } } // Special cases virtual void visit(AstConst* nodep, AstNUser*) {} // Already constant virtual void visit(AstCell* nodep, AstNUser*) { if (m_params) { nodep->paramsp()->iterateAndNext(*this); } else { nodep->iterateChildren(*this); } } virtual void visit(AstPin* nodep, AstNUser*) { nodep->iterateChildren(*this); } void replaceSelSel(AstSel* nodep) { // SEL(SEL({x},a,b),c,d) => SEL({x},a+c,d) AstSel* belowp = nodep->fromp()->castSel(); AstNode* fromp = belowp->fromp()->unlinkFrBack(); AstNode* widthp = nodep->widthp()->unlinkFrBack(); AstNode* lsb1p = nodep->lsbp()->unlinkFrBack(); AstNode* lsb2p = belowp->lsbp()->unlinkFrBack(); // Eliminate lower range UINFO(4,"Elim Lower range: "<castConst() && lsb2p->castConst()) { newlsbp = new AstConst(lsb1p->fileline(), lsb1p->castConst()->toUInt() + lsb2p->castConst()->toUInt()); lsb1p->deleteTree(); lsb1p=NULL; lsb2p->deleteTree(); lsb2p=NULL; } else { // Width is important, we need the width of the fromp's // expression, not the potentially smaller lsb1p's width newlsbp = new AstAdd(lsb1p->fileline(), lsb2p, new AstExtend(lsb1p->fileline(), lsb1p)); newlsbp->dtypeFrom(lsb2p); // Unsigned newlsbp->castAdd()->rhsp()->dtypeFrom(lsb2p); } AstSel* newp = new AstSel(nodep->fileline(), fromp, newlsbp, widthp); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } void replaceSelConcat(AstSel* nodep) { // SEL(CONCAT(a,b),c,d) => SEL(a or b, . .) AstConcat* conp = nodep->fromp()->castConcat(); AstNode* conLhsp = conp->lhsp(); AstNode* conRhsp = conp->rhsp(); if ((int)nodep->lsbConst() >= conRhsp->width()) { conLhsp->unlinkFrBack(); AstSel* newp = new AstSel(nodep->fileline(), conLhsp, nodep->lsbConst() - conRhsp->width(), nodep->widthConst()); nodep->replaceWith(newp); } else if ((int)nodep->msbConst() < conRhsp->width()) { conRhsp->unlinkFrBack(); AstSel* newp = new AstSel(nodep->fileline(), conRhsp, nodep->lsbConst(), nodep->widthConst()); nodep->replaceWith(newp); } else { // Yuk, split between the two conRhsp->unlinkFrBack(); conLhsp->unlinkFrBack(); AstConcat* newp = new AstConcat (nodep->fileline(), new AstSel(nodep->fileline(), conLhsp, 0, nodep->msbConst() - conRhsp->width() + 1), new AstSel(nodep->fileline(), conRhsp, nodep->lsbConst(), conRhsp->width()-nodep->lsbConst())); nodep->replaceWith(newp); } nodep->deleteTree(); nodep=NULL; } void replaceSelReplicate(AstSel* nodep) { // SEL(REPLICATE(a,b),1,bit) => SEL(a,1,bit) AstReplicate* repp = nodep->fromp()->castReplicate(); AstNode* fromp = repp->lhsp()->unlinkFrBack(); AstConst* lsbp = nodep->lsbp()->castConst(); AstNode* widthp = nodep->widthp()->unlinkFrBack(); AstSel* newp = new AstSel(nodep->fileline(), fromp, new AstConst(lsbp->fileline(), lsbp->toUInt() % fromp->width()), widthp); newp->dtypeFrom(nodep); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } void replaceSelIntoBiop(AstSel* nodep) { // SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit)) AstNodeBiop* fromp = nodep->fromp()->unlinkFrBack()->castNodeBiop(); if (!fromp) nodep->v3fatalSrc("Called on non biop"); AstNode* lsbp = nodep->lsbp()->unlinkFrBack(); AstNode* widthp = nodep->widthp()->unlinkFrBack(); // AstNode* bilhsp = fromp->lhsp()->unlinkFrBack(); AstNode* birhsp = fromp->rhsp()->unlinkFrBack(); // fromp->lhsp(new AstSel(nodep->fileline(), bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true))); fromp->rhsp(new AstSel(nodep->fileline(), birhsp, lsbp, widthp)); fromp->dtypeFrom(nodep); nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL; } void replaceSelIntoUniop(AstSel* nodep) { // SEL(NOT(a),1,bit) => NOT(SEL(a,bit)) AstNodeUniop* fromp = nodep->fromp()->unlinkFrBack()->castNodeUniop(); if (!fromp) nodep->v3fatalSrc("Called on non biop"); AstNode* lsbp = nodep->lsbp()->unlinkFrBack(); AstNode* widthp = nodep->widthp()->unlinkFrBack(); // AstNode* bilhsp = fromp->lhsp()->unlinkFrBack(); // fromp->lhsp(new AstSel(nodep->fileline(), bilhsp, lsbp, widthp)); fromp->dtypeFrom(nodep); nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL; } virtual void visit(AstAttrOf* nodep, AstNUser*) { AstAttrOf* oldAttr = m_attrp; m_attrp = nodep; nodep->iterateChildren(*this); m_attrp = oldAttr; } virtual void visit(AstArraySel* nodep, AstNUser*) { nodep->bitp()->iterateAndNext(*this); if (nodep->bitp()->castConst() && nodep->fromp()->castVarRef() // Need to make sure it's an array object so don't mis-allow a constant (bug509.) && nodep->fromp()->castVarRef()->varp() && nodep->fromp()->castVarRef()->varp()->valuep()->castInitArray()) { m_selp = nodep; // Ask visit(AstVarRef) to replace varref with const } nodep->fromp()->iterateAndNext(*this); if (nodep->fromp()->castConst()) { // It did. if (!m_selp) { nodep->v3error("Illegal assignment of constant to unpacked array"); } else { nodep->replaceWith(nodep->fromp()->unlinkFrBack()); } } m_selp = NULL; } virtual void visit(AstVarRef* nodep, AstNUser*) { nodep->iterateChildren(*this); if (!nodep->varp()) nodep->v3fatalSrc("Not linked"); bool did=false; if (m_doV && nodep->varp()->valuep() && !m_attrp) { //if (debug()) valuep->dumpTree(cout," visitvaref: "); nodep->varp()->valuep()->iterateAndNext(*this); // May change nodep->varp()->valuep() AstNode* valuep = nodep->varp()->valuep(); if (!nodep->lvalue() && ((!m_params // Can reduce constant wires into equations && m_doNConst && v3Global.opt.oConst() && !(nodep->varp()->isFuncLocal() // Default value, not a "known" constant for this usage && nodep->varp()->isInput()) && !nodep->varp()->noSubst() && !nodep->varp()->isSigPublic()) || nodep->varp()->isParam())) { if (operandConst(valuep)) { const V3Number& num = valuep->castConst()->num(); //UINFO(2,"constVisit "<<(void*)valuep<<" "<castInitArray()) { int bit = m_selp->bitConst(); AstNode* itemp = valuep->castInitArray()->initsp(); for (int n=0; nnextp()) {} if (itemp->castConst()) { const V3Number& num = itemp->castConst()->num(); //UINFO(2,"constVisit "<<(void*)valuep<<" "<v3error("Expecting expression to be constant, but variable isn't const: "<varp()->prettyName()); } } virtual void visit(AstEnumItemRef* nodep, AstNUser*) { nodep->iterateChildren(*this); if (!nodep->itemp()) nodep->v3fatalSrc("Not linked"); bool did=false; if (nodep->itemp()->valuep()) { //if (debug()) nodep->varp()->valuep()->dumpTree(cout," visitvaref: "); nodep->itemp()->valuep()->iterateAndNext(*this); if (AstConst* valuep = nodep->itemp()->valuep()->castConst()) { const V3Number& num = valuep->num(); replaceNum(nodep, num); nodep=NULL; did=true; } } if (!did && m_required) { nodep->v3error("Expecting expression to be constant, but variable isn't const: "<itemp()->prettyName()); } } // virtual void visit(AstCvtPackString* nodep, AstNUser*) { // Not constant propagated (for today) because AstMath::isOpaque is set // Someday if lower is constant, convert to quoted "string". bool onlySenItemInSenTree(AstNodeSenItem* nodep) { // Only one if it's not in a list return (!nodep->nextp() && nodep->backp()->nextp() != nodep); } virtual void visit(AstSenItem* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_doNConst && (nodep->sensp()->castConst() || nodep->sensp()->castEnumItemRef() || (nodep->varrefp() && nodep->varrefp()->varp()->isParam()))) { // Constants in sensitivity lists may be removed (we'll simplify later) if (nodep->isClocked()) { // A constant can never get a pos/negexge if (onlySenItemInSenTree(nodep)) { nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Never())); nodep->deleteTree(); nodep=NULL; } else { nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } } else { // Otherwise it may compute a result that needs to settle out nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Combo())); nodep->deleteTree(); nodep=NULL; } } else if (m_doNConst && nodep->sensp()->castNot()) { // V3Gate may propagate NOTs into clocks... Just deal with it AstNode* sensp = nodep->sensp(); AstNode* lastSensp = sensp; bool invert = false; while (lastSensp->castNot()) { lastSensp = lastSensp->castNot()->lhsp(); invert = !invert; } UINFO(8,"senItem(NOT...) "<edgeType( nodep->edgeType().invert() ); AstNodeVarRef* senvarp = lastSensp->unlinkFrBack()->castNodeVarRef(); if (!senvarp) sensp->v3fatalSrc("Non-varref sensitivity variable"); sensp->replaceWith(senvarp); sensp->deleteTree(); sensp=NULL; } else if (!m_doNConst // Deal with later when doNConst missing && (nodep->sensp()->castEnumItemRef() || nodep->sensp()->castConst())) { } else { if (nodep->hasVar() && !nodep->varrefp()) nodep->v3fatalSrc("Null sensitivity variable"); } } virtual void visit(AstSenGate* nodep, AstNUser*) { nodep->iterateChildren(*this); if (AstConst* constp = nodep->rhsp()->castConst()) { if (constp->isZero()) { UINFO(4,"SENGATE(...,0)->NEVER"<replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Never())); nodep->deleteTree(); nodep=NULL; } else { nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } } else { UINFO(4,"SENGATE(SENITEM,0)->ALWAYS SENITEM"<sensesp()->unlinkFrBack(); nodep->replaceWith(senitemp); nodep->deleteTree(); nodep=NULL; } } } struct SenItemCmp { inline bool operator () (AstNodeSenItem* lhsp, AstNodeSenItem* rhsp) const { if (lhsp->type() < rhsp->type()) return true; if (lhsp->type() > rhsp->type()) return false; const AstSenItem* litemp = lhsp->castSenItem(); const AstSenItem* ritemp = rhsp->castSenItem(); if (litemp && ritemp) { // Looks visually better if we keep sorted by name if (!litemp->varrefp() && ritemp->varrefp()) return true; if ( litemp->varrefp() && !ritemp->varrefp()) return false; if (litemp->varrefp() && ritemp->varrefp()) { if (litemp->varrefp()->name() < ritemp->varrefp()->name()) return true; if (litemp->varrefp()->name() > ritemp->varrefp()->name()) return false; // But might be same name with different scopes if (litemp->varrefp()->varScopep() < ritemp->varrefp()->varScopep()) return true; if (litemp->varrefp()->varScopep() > ritemp->varrefp()->varScopep()) return false; } // Sort by edge, AFTER variable, as we want multiple edges for same var adjacent // note the SenTree optimizer requires this order (more general firsst, less general last) if (litemp->edgeType() < ritemp->edgeType()) return true; if (litemp->edgeType() > ritemp->edgeType()) return false; } return false; } }; virtual void visit(AstSenTree* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_doExpensive) { //cout<dumpTree(cout,"ssin: "); // Optimize ideas for the future: // SENTREE(... SENGATE(x,a), SENGATE(SENITEM(x),b) ...) => SENGATE(x,OR(a,b)) // SENTREE(... SENITEM(x), SENGATE(SENITEM(x),*) ...) => SENITEM(x) // Do we need the SENITEM's to be identical? No because we're // ORing between them; we just need to insure that the result is at // least as frequently activating. So we simply // SENGATE(SENITEM(x)) -> SENITEM(x), then let it collapse with the // other SENITEM(x). { AstUser4InUse m_inuse4; // Mark x in SENITEM(x) for (AstNodeSenItem* senp = nodep->sensesp()->castNodeSenItem(); senp; senp=senp->nextp()->castNodeSenItem()) { if (AstSenItem* itemp = senp->castSenItem()) { if (itemp->varrefp() && itemp->varrefp()->varScopep()) { itemp->varrefp()->varScopep()->user4(1); } } } // Find x in SENTREE(SENITEM(x)) for (AstNodeSenItem* nextp, * senp = nodep->sensesp()->castNodeSenItem(); senp; senp=nextp) { nextp=senp->nextp()->castNodeSenItem(); if (AstSenGate* gatep = senp->castSenGate()) { if (AstSenItem* itemp = gatep->sensesp()->castSenItem()) { if (itemp->varrefp() && itemp->varrefp()->varScopep()) { if (itemp->varrefp()->varScopep()->user4()) { // Found, push this item up to the top itemp->unlinkFrBack(); nodep->addSensesp(itemp); gatep->unlinkFrBack()->deleteTree(); gatep=NULL; senp=NULL; } } } } } } // Sort the sensitivity names so "posedge a or b" and "posedge b or a" end up together. // Also, remove duplicate assignments, and fold POS&NEGs into ANYEDGEs // Make things a little faster; check first if we need a sort for (AstNodeSenItem* nextp, * senp = nodep->sensesp()->castNodeSenItem(); senp; senp=nextp) { nextp=senp->nextp()->castNodeSenItem(); // cppcheck-suppress unassignedVariable // cppcheck bug SenItemCmp cmp; if (nextp && !cmp(senp, nextp)) { // Something's out of order, sort it senp = NULL; vector vec; for (AstNodeSenItem* senp = nodep->sensesp()->castNodeSenItem(); senp; senp=senp->nextp()->castNodeSenItem()) { vec.push_back(senp); } stable_sort(vec.begin(), vec.end(), SenItemCmp()); for (vector::iterator it=vec.begin(); it!=vec.end(); ++it) { (*it)->unlinkFrBack(); } for (vector::iterator it=vec.begin(); it!=vec.end(); ++it) { nodep->addSensesp(*it); } break; } } // Pass2, remove dup edges for (AstNodeSenItem* nextp, * senp = nodep->sensesp()->castNodeSenItem(); senp; senp=nextp) { nextp=senp->nextp()->castNodeSenItem(); AstNodeSenItem* cmpp = nextp; AstSenItem* litemp = senp->castSenItem(); AstSenItem* ritemp = cmpp->castSenItem(); if (litemp && ritemp) { if ((litemp->varrefp() && ritemp->varrefp() && litemp->varrefp()->sameGateTree(ritemp->varrefp())) || (!litemp->varrefp() && !ritemp->varrefp())) { // We've sorted in the order ANY, BOTH, POS, NEG, so we don't need to try opposite orders if (( litemp->edgeType()==AstEdgeType::ET_ANYEDGE) // ANY or {BOTH|POS|NEG} -> ANY || (litemp->edgeType()==AstEdgeType::ET_BOTHEDGE) // BOTH or {POS|NEG} -> BOTH || (litemp->edgeType()==AstEdgeType::ET_POSEDGE // POS or NEG -> BOTH && ritemp->edgeType()==AstEdgeType::ET_NEGEDGE) || (litemp->edgeType()==ritemp->edgeType()) // Identical edges ) { // Fix edge of old node if (litemp->edgeType()==AstEdgeType::ET_POSEDGE && ritemp->edgeType()==AstEdgeType::ET_NEGEDGE) litemp->edgeType(AstEdgeType::ET_BOTHEDGE); // Remove redundant node ritemp->unlinkFrBack()->deleteTree(); ritemp=NULL; cmpp=NULL; // Try to collapse again nextp=litemp; } } } } //nodep->dumpTree(cout,"ssou: "); } } //----- // Zero elimination virtual void visit(AstNodeAssign* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_doNConst && replaceNodeAssign(nodep)) return; } virtual void visit(AstAssignAlias* nodep, AstNUser*) { // Don't perform any optimizations, keep the alias around } virtual void visit(AstAssignVarScope* nodep, AstNUser*) { // Don't perform any optimizations, the node won't be linked yet } virtual void visit(AstAssignW* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_doNConst && replaceNodeAssign(nodep)) return; AstNodeVarRef* varrefp = nodep->lhsp()->castVarRef(); // Not VarXRef, as different refs may set different values to each hierarchy if (m_wremove && !m_params && m_doNConst && m_modp && operandConst(nodep->rhsp()) && !nodep->rhsp()->castConst()->num().isFourState() && varrefp // Don't do messes with BITREFs/ARRAYREFs && !varrefp->varp()->valuep() // Not already constified && !varrefp->varScopep()) { // Not scoped (or each scope may have different initial value) // ASSIGNW (VARREF, const) -> INITIAL ( ASSIGN (VARREF, const) ) UINFO(4,"constAssignW "<rhsp()->unlinkFrBack(); varrefp->unlinkFrBack(); AstInitial* newinitp = new AstInitial(nodep->fileline(), new AstAssign(nodep->fileline(), varrefp, exprp)); m_modp->addStmtp(newinitp); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Set the initial value right in the variable so we can constant propagate AstNode* initvaluep = exprp->cloneTree(false); varrefp->varp()->valuep(initvaluep); } } virtual void visit(AstNodeIf* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_doNConst) { if (AstConst* constp = nodep->condp()->castConst()) { AstNode* keepp = NULL; if (constp->isZero()) { UINFO(4,"IF(0,{any},{x}) => {x}: "<elsesp(); } else { UINFO(4,"IF(!0,{x},{any}) => {x}: "<ifsp(); } if (keepp) { keepp->unlinkFrBackWithNext(); nodep->replaceWith(keepp); } else { nodep->unlinkFrBack(); } nodep->deleteTree(); nodep=NULL; } else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) { // Empty block, remove it // Note if we support more C++ then there might be side effects in the condition itself nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else if (!afterComment(nodep->ifsp())) { UINFO(4,"IF({x}) NULL {...} => IF(NOT{x}}: "<condp(); AstNode* elsesp = nodep->elsesp(); condp->unlinkFrBackWithNext(); elsesp->unlinkFrBackWithNext(); if (nodep->ifsp()) { nodep->ifsp()->unlinkFrBackWithNext()->deleteTree(); } // Must have been comment nodep->condp(new AstLogNot(condp->fileline(), condp)); // LogNot, as C++ optimization also possible nodep->addIfsp(elsesp); } else if (((nodep->condp()->castNot() && nodep->condp()->width()==1) || (nodep->condp()->castLogNot())) && nodep->ifsp() && nodep->elsesp()) { UINFO(4,"IF(NOT {x}) => IF(x) swapped if/else"<condp()->castNot()->lhsp()->unlinkFrBackWithNext(); AstNode* ifsp = nodep->ifsp()->unlinkFrBackWithNext(); AstNode* elsesp = nodep->elsesp()->unlinkFrBackWithNext(); AstIf* ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp); ifp->branchPred(nodep->branchPred().invert()); nodep->replaceWith(ifp); nodep->deleteTree(); nodep=NULL; } else if (ifSameAssign(nodep)) { UINFO(4,"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})"<ifsp()->castNodeAssign(); AstNodeAssign* elsep = nodep->elsesp()->castNodeAssign(); ifp->unlinkFrBack(); AstNode* condp = nodep->condp()->unlinkFrBack(); AstNode* truep = ifp->rhsp()->unlinkFrBack(); AstNode* falsep = elsep->rhsp()->unlinkFrBack(); ifp->rhsp(new AstCond(truep->fileline(), condp, truep, falsep)); nodep->replaceWith(ifp); nodep->deleteTree(); nodep=NULL; } else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting && operandIfIf(nodep)) { UINFO(0,"IF({a}) IF({b}) => IF({a} && {b})"<ifsp()->castNodeIf(); AstNode* condp = nodep->condp()->unlinkFrBack(); AstNode* lowerIfsp = lowerIfp->ifsp()->unlinkFrBackWithNext(); AstNode* lowerCondp = lowerIfp->condp()->unlinkFrBackWithNext(); nodep->condp(new AstLogAnd(lowerIfp->fileline(), condp, lowerCondp)); lowerIfp->replaceWith(lowerIfsp); lowerIfp->deleteTree(); lowerIfp=NULL; } else if (operandBoolShift(nodep->condp())) { replaceBoolShift(nodep->condp()); } } } virtual void visit(AstSFormatF* nodep, AstNUser*) { // Substitute constants into displays. The main point of this is to // simplify assertion methodologies which call functions with display's. // This eliminates a pile of wide temps, and makes the C a whole lot more readable. nodep->iterateChildren(*this); bool anyconst = false; for (AstNode* argp = nodep->exprsp(); argp; argp=argp->nextp()) { if (argp->castConst()) { anyconst=true; break; } } if (m_doNConst && anyconst) { //UINFO(9," Display in "<text()<exprsp(); string text = nodep->text(); for (string::const_iterator it = text.begin(); it!=text.end(); ++it) { char ch = *it; if (!inPct && ch=='%') { inPct = true; fmt = ch; } else if (inPct && (isdigit(ch) || ch=='.')) { fmt += ch; } else if (inPct) { inPct = false; fmt += ch; switch (tolower(ch)) { case '%': break; // %% - just output a % case 'm': break; // %m - auto insert "name" default: // Most operators, just move to next argument if (argp) { AstNode* nextp=argp->nextp(); if (argp && argp->castConst()) { // Convert it string out = argp->castConst()->num().displayed(fmt); UINFO(9," DispConst: "< "<unlinkFrBack()->deleteTree(); } argp=nextp; } break; } // switch dispout += fmt; } else { dispout += ch; } } nodep->text(dispout); //UINFO(9," Display out "<text()<exprsp() && nodep->name().find("%") == string::npos && !nodep->hidden()) { // Just a simple constant string - the formatting is pointless replaceConstString(nodep, nodep->name()); nodep=NULL; } } virtual void visit(AstFuncRef* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_params) { // Only parameters force us to do constant function call propagation replaceWithSimulation(nodep); } } virtual void visit(AstArg* nodep, AstNUser*) { // replaceWithSimulation on the Arg's parent FuncRef replaces these nodep->iterateChildren(*this); } virtual void visit(AstWhile* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_doNConst) { if (nodep->condp()->isZero()) { UINFO(4,"WHILE(0) => nop "<precondsp()) nodep->replaceWith(nodep->precondsp()); else nodep->unlinkFrBack(); nodep->deleteTree(); nodep=NULL; } else if (operandBoolShift(nodep->condp())) { replaceBoolShift(nodep->condp()); } } } virtual void visit(AstInitArray* nodep, AstNUser*) { // Constant if all children are constant nodep->iterateChildren(*this); } // These are converted by V3Param. Don't constify as we don't want the from() VARREF to disappear, if any // If output of a presel didn't get consted, chances are V3Param didn't visit properly virtual void visit(AstNodePreSel* nodep, AstNUser*) {} // Ignored, can eliminate early virtual void visit(AstSysIgnore* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_doNConst) { nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } } // Simplify virtual void visit(AstBasicDType* nodep, AstNUser*) { nodep->iterateChildren(*this); nodep->cvtRangeConst(); } //----- // Jump elimination virtual void visit(AstJumpGo* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_doExpensive) { nodep->labelp()->user4(true); } } virtual void visit(AstJumpLabel* nodep, AstNUser*) { // Because JumpLabels disable many optimizations, // remove JumpLabels that are not pointed to by any AstJumpGos // Note this assumes all AstJumpGos are underneath the given label; V3Broken asserts this nodep->iterateChildren(*this); // AstJumpGo's below here that point to this node will set user4 if (m_doExpensive && !nodep->user4()) { UINFO(4,"JUMPLABEL => unused "<stmtsp()) underp = nodep->stmtsp()->unlinkFrBackWithNext(); if (underp) nodep->replaceWith(underp); else nodep->unlinkFrBack(); nodep->deleteTree(); nodep=NULL; } } //----- // Below lines are magic expressions processed by astgen // TREE_SKIP_VISIT("AstNODETYPE") # Rename normal visit to visitGen and don't iterate //----- TREE_SKIP_VISIT("ArraySel"); //----- // "AstNODETYPE { # bracket not paren // $accessor_name, ... // # ,, gets replaced with a , rather than && // }" # bracket not paren // ,"what to call" // // Where "what_to_call" is: // "function to call" // "AstREPLACEMENT_TYPE{ $accessor }" // "! # Print line number when matches, so can see operations // "NEVER" # Print error message // "DONE" # Process of matching did the transform already // In the future maybe support more complicated match & replace: // ("AstOr {%a, AstAnd{AstNot{%b}, %c}} if %a.width1 if %a==%b", "AstOr{%a,%c}; %b.delete"); // Lhs/rhs would be implied; for non math operations you'd need $lhsp etc. // Lint Checks // v--- *1* These ops are always first, as we warn before replacing // v--- *V* This op is a verilog op, only in m_doV mode // v--- *C* This op works on all constant children, allowed in m_doConst mode // v--- *S* This op specifies a type should use short-circuting of its lhs op TREEOP1("AstSel{warnSelect(nodep)}", "NEVER"); // Generic constants on both side. Do this first to avoid other replacements TREEOPC("AstNodeBiop {$lhsp.castConst, $rhsp.castConst}", "replaceConst(nodep)"); TREEOPC("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque()}", "replaceConst(nodep)"); // Zero on one side or the other TREEOP ("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstAnd {$lhsp.isZero, $rhsp, isTPure($rhsp)}", "replaceZero(nodep)"); // Can't use replaceZeroChkPure as we make this pattern in ChkPure // This visit function here must allow for short-circuiting. TREEOPS("AstLogAnd {$lhsp.isZero}", "replaceZero(nodep)"); TREEOP ("AstLogAnd{$lhsp.isZero, $rhsp}", "replaceZero(nodep)"); // This visit function here must allow for short-circuiting. TREEOPS("AstLogOr {$lhsp.isOne}", "replaceNum(nodep, 1)"); TREEOP ("AstLogOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstDiv {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstDivS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstMul {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstMulS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstPow {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule TREEOP ("AstPowSS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule TREEOP ("AstPowSU {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule TREEOP ("AstPowUS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule TREEOP ("AstPow {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstPowSU {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstPowUS {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstPowSU {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstShiftL{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstShiftR{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstShiftRS{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)"); TREEOP ("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstXnor {$lhsp.isZero, $rhsp}", "AstNot{$rhsp}"); TREEOP ("AstSub {$lhsp.isZero, $rhsp}", "AstNegate{$rhsp}"); TREEOP ("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstAnd {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)"); TREEOP ("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)"); TREEOP ("AstLogOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstMul {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)"); TREEOP ("AstMulS {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)"); TREEOP ("AstOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstShiftL{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstShiftR{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstShiftRS{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstSub {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstXor {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOP ("AstXnor {$lhsp, $rhsp.isZero}", "AstNot{$lhsp}"); // Non-zero on one side or the other TREEOP ("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstOr {$lhsp.isAllOnes, $rhsp, isTPure($rhsp)}", "replaceWLhs(nodep)"); //->allOnes TREEOP ("AstLogOr {$lhsp.isNeqZero, $rhsp}", "replaceNum(nodep,1)"); TREEOP ("AstAnd {$lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)"); TREEOP ("AstLogAnd{$lhsp, $rhsp.isNeqZero}", "replaceWLhs(nodep)"); TREEOP ("AstOr {$lhsp, $rhsp.isAllOnes, isTPure($lhsp)}", "replaceWRhs(nodep)"); //->allOnes TREEOP ("AstLogOr {$lhsp, $rhsp.isNeqZero, isTPure($lhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}"); TREEOP ("AstXnor {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstMulS {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstDiv {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)"); TREEOP ("AstDivS {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)"); TREEOP ("AstMul {operandIsPowTwo($lhsp), $rhsp}", "replaceMulShift(nodep)"); // a*2^n -> a< a>>n TREEOP ("AstPow {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<castAdd()->lhsp(),$rhsp}, $lhsp->castAdd()->rhsp()}"); // ((a+x)-y) -> (a+(x-y)) // Trinary ops // Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump! TREEOP ("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)"); TREEOP ("AstNodeCond{$condp.isNeqZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr1p)"); TREEOPC("AstNodeCond{$condp.isZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr2p)"); TREEOPC("AstNodeCond{$condp.isNeqZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr1p)"); TREEOP ("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)"); // This visit function here must allow for short-circuiting. TREEOPS("AstCond {$lhsp.isZero}", "replaceWIteratedThs(nodep)"); TREEOPS("AstCond {$lhsp.isNeqZero}", "replaceWIteratedRhs(nodep)"); TREEOP ("AstCond{$condp->castNot(), $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}"); TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstLogOr {$condp, $expr2p}"); // a?1:b == a||b TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstLogAnd{$condp, $expr1p}"); // a?b:0 == a&&b TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstLogOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a||b TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstLogAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&&b TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())"); // Prefer constants on left, since that often needs a shift, it lets constant red remove the shift TREEOP ("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)"); TREEOP ("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)"); TREEOP ("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)"); TREEOP ("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)"); TREEOP ("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)"); TREEOP ("AstLt {!$lhsp.castConst,$rhsp.castConst}", "AstGt {$rhsp,$lhsp}"); TREEOP ("AstLtS {!$lhsp.castConst,$rhsp.castConst}", "AstGtS {$rhsp,$lhsp}"); TREEOP ("AstLte {!$lhsp.castConst,$rhsp.castConst}", "AstGte {$rhsp,$lhsp}"); TREEOP ("AstLteS {!$lhsp.castConst,$rhsp.castConst}", "AstGteS{$rhsp,$lhsp}"); TREEOP ("AstGt {!$lhsp.castConst,$rhsp.castConst}", "AstLt {$rhsp,$lhsp}"); TREEOP ("AstGtS {!$lhsp.castConst,$rhsp.castConst}", "AstLtS {$rhsp,$lhsp}"); TREEOP ("AstGte {!$lhsp.castConst,$rhsp.castConst}", "AstLte {$rhsp,$lhsp}"); TREEOP ("AstGteS {!$lhsp.castConst,$rhsp.castConst}", "AstLteS{$rhsp,$lhsp}"); // v--- *1* as These ops are always first, as we warn before replacing TREEOP1("AstLt {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,0)"); TREEOP1("AstGte {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,1)"); TREEOP1("AstGt {$lhsp.isZero, $rhsp}", "replaceNumSigned(nodep,0)"); TREEOP1("AstLte {$lhsp.isZero, $rhsp}", "replaceNumSigned(nodep,1)"); TREEOP1("AstGt {$lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,0)"); TREEOP1("AstLte {$lhsp, $rhsp.isAllOnes, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)"); TREEOP1("AstLt {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,0)"); TREEOP1("AstGte {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)"); // Two level bubble pushing TREEOP ("AstNot {$lhsp.castNot, $lhsp->width()==$lhsp->castNot()->lhsp()->width()}", "replaceWChild(nodep, $lhsp->op1p())"); // NOT(NOT(x))->x TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->op1p())"); // LOGNOT(LOGNOT(x))->x TREEOPV("AstNot {$lhsp.castEqCase, $lhsp.width1}","AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castEqWild, $lhsp.width1}","AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEqWild}", "AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeqWild, $lhsp.width1}","AstEqWild {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castNeqWild}", "AstEqWild {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castNeq}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castLt, $lhsp.width1}", "AstGte {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castLt}", "AstGte {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castLtS, $lhsp.width1}", "AstGteS{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castLtS}", "AstGteS{$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castLte, $lhsp.width1}", "AstGt {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castLte}", "AstGt {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castLteS, $lhsp.width1}", "AstGtS {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castLteS}", "AstGtS {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castGt, $lhsp.width1}", "AstLte {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castGt}", "AstLte {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castGtS, $lhsp.width1}", "AstLteS{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castGtS}", "AstLteS{$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castGte, $lhsp.width1}", "AstLt {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castGte}", "AstLt {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castGteS, $lhsp.width1}", "AstLtS {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castGteS}", "AstLtS {$lhsp->op1p(),$lhsp->op2p()}"); // Not common, but avoids compiler warnings about over shifting TREEOP ("AstShiftL{operandHugeShiftL(nodep)}", "replaceZero(nodep)"); TREEOP ("AstShiftR{operandHugeShiftR(nodep)}", "replaceZero(nodep)"); TREEOP ("AstShiftL{operandShiftOp(nodep)}", "replaceShiftOp(nodep)"); TREEOP ("AstShiftR{operandShiftOp(nodep)}", "replaceShiftOp(nodep)"); TREEOP ("AstShiftL{operandShiftShift(nodep)}", "replaceShiftShift(nodep)"); TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)"); TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)"); // Compress out EXTENDs to appease loop unroller TREEOPV("AstEq {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE"); TREEOPV("AstNeq {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE"); TREEOPV("AstGt {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE"); TREEOPV("AstGte {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE"); TREEOPV("AstLt {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE"); TREEOPV("AstLte {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE"); // Identical operands on both sides // AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules // AstAdd->ShiftL(#,1) but uncommon TREEOP ("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)"); TREEOP ("AstChangeXor{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)"); TREEOP ("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstXnor {operandsSame($lhsp,,$rhsp)}", "replaceAllOnes(nodep)"); TREEOP ("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X. TREEOP ("AstEqD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X. TREEOP ("AstEqN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X. TREEOP ("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstGtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstGtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstGteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstGteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstLteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstLteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP ("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstNeqD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstNeqN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP ("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)"); TREEOP ("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)"); ///=== Verilog operators // Comparison against 1'b0/1'b1; must be careful about widths. // These use Not, so must be Verilog only TREEOPV("AstEq {$rhsp.width1, $lhsp.isZero, $rhsp}", "AstNot{$rhsp}"); TREEOPV("AstEq {$lhsp.width1, $lhsp, $rhsp.isZero}", "AstNot{$lhsp}"); TREEOPV("AstEq {$rhsp.width1, $lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)"); TREEOPV("AstEq {$lhsp.width1, $lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)"); TREEOPV("AstNeq {$rhsp.width1, $lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOPV("AstNeq {$lhsp.width1, $lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); TREEOPV("AstNeq {$rhsp.width1, $lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}"); TREEOPV("AstNeq {$lhsp.width1, $lhsp, $rhsp.isAllOnes}", "AstNot{$lhsp}"); TREEOPV("AstLt {$rhsp.width1, $lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); // Because not signed #s TREEOPV("AstGt {$lhsp.width1, $lhsp, $rhsp.isZero}", "replaceWLhs(nodep)"); // Because not signed #s // Useful for CONDs added around ARRAYSEL's in V3Case step TREEOPV("AstLte {$lhsp->width()==$rhsp->width(), $rhsp.isAllOnes}", "replaceNum(nodep,1)"); // Simplify reduction operators // This also gets &{...,0,....} => const 0 (Common for unused_ok signals) TREEOPV("AstRedAnd{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)"); TREEOPV("AstRedOr {$lhsp, $lhsp.width1}", "replaceWLhs(nodep)"); TREEOPV("AstRedXor{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)"); TREEOPV("AstRedAnd{$lhsp->castConcat()}", "AstAnd{AstRedAnd{$lhsp->castConcat()->lhsp()}, AstRedAnd{$lhsp->castConcat()->rhsp()}}"); // &{a,b} => {&a}&{&b} TREEOPV("AstRedOr {$lhsp->castConcat()}", "AstOr {AstRedOr {$lhsp->castConcat()->lhsp()}, AstRedOr {$lhsp->castConcat()->rhsp()}}"); // |{a,b} => {|a}|{|b} TREEOPV("AstRedXor{$lhsp->castConcat()}", "AstXor{AstRedXor{$lhsp->castConcat()->lhsp()}, AstRedXor{$lhsp->castConcat()->rhsp()}}"); // ^{a,b} => {^a}^{^b} TREEOPV("AstRedAnd{$lhsp->castExtend(), $lhsp->width()>$lhsp->castExtend()->lhsp()->width()}", "replaceZero(nodep)"); // &{0,...} => 0 Prevents compiler limited range error TREEOPV("AstRedOr {$lhsp->castExtend()}", "AstRedOr {$lhsp->castExtend()->lhsp()}"); TREEOPV("AstRedXor{$lhsp->castExtend()}", "AstRedXor{$lhsp->castExtend()->lhsp()}"); TREEOPV("AstOneHot{$lhsp.width1}", "replaceWLhs(nodep)"); TREEOPV("AstOneHot0{$lhsp.width1}", "replaceNum(nodep,1)"); // Binary AND/OR is faster than logical and/or (usually) TREEOPV("AstLogAnd{$lhsp.width1, $rhsp.width1, isTPure($lhsp), isTPure($rhsp)}", "AstAnd{$lhsp,$rhsp}"); TREEOPV("AstLogOr {$lhsp.width1, $rhsp.width1, isTPure($lhsp), isTPure($rhsp)}", "AstOr{$lhsp,$rhsp}"); TREEOPV("AstLogNot{$lhsp.width1, isTPure($lhsp)}", "AstNot{$lhsp}"); // CONCAT(CONCAT({a},{b}),{c}) -> CONCAT({a},CONCAT({b},{c})) // CONCAT({const},CONCAT({const},{c})) -> CONCAT((constifiedCONC{const|const},{c})) TREEOPV("AstConcat{operandConcatMove(nodep)}", "moveConcat(nodep)"); TREEOPV("AstConcat{$lhsp.isZero, $rhsp}", "replaceExtend(nodep, nodep->rhsp())"); // CONCAT(a[1],a[0]) -> a[1:0] TREEOPV("AstConcat{$lhsp->castSel(), $rhsp->castSel(), ifAdjacentSel($lhsp->castSel(),,$rhsp->castSel())}", "replaceConcatSel(nodep)"); TREEOPV("AstConcat{ifConcatMergeableBiop($lhsp), concatMergeable($lhsp,,$rhsp)}", "replaceConcatMerge(nodep)"); // Common two-level operations that can be simplified TREEOP ("AstAnd {$lhsp.castOr, $rhsp.castOr, operandAndOrSame(nodep)}", "replaceAndOr(nodep)"); TREEOP ("AstOr {$lhsp.castAnd,$rhsp.castAnd,operandAndOrSame(nodep)}", "replaceAndOr(nodep)"); TREEOP ("AstOr {matchOrAndNot(nodep)}", "DONE"); TREEOP ("AstAnd {operandShiftSame(nodep)}", "replaceShiftSame(nodep)"); TREEOP ("AstOr {operandShiftSame(nodep)}", "replaceShiftSame(nodep)"); TREEOP ("AstXor {operandShiftSame(nodep)}", "replaceShiftSame(nodep)"); // "AstXnor{operandShiftSame(nodep)}", // Cannot ShiftSame as the shifted-in zeros might create a one // Note can't simplify a extend{extends}, extends{extend}, as the sign bits end up in the wrong places TREEOPV("AstExtend {$lhsp.castExtend}", "replaceExtend(nodep, nodep->lhsp()->castExtend()->lhsp())"); TREEOPV("AstExtendS{$lhsp.castExtendS}", "replaceExtend(nodep, nodep->lhsp()->castExtendS()->lhsp())"); TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs TREEOPV("AstReplicateN{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs // Next rule because AUTOINST puts the width of bits in // to pins, even when the widths are exactly the same across the hierarchy. TREEOPV("AstSel{operandSelExtend(nodep)}", "DONE"); TREEOPV("AstSel{operandSelFull(nodep)}", "replaceWChild(nodep, nodep->fromp())"); TREEOPV("AstSel{$fromp.castSel}", "replaceSelSel(nodep)"); TREEOPV("AstSel{$fromp.castAdd, operandSelBiLower(nodep)}", "DONE"); TREEOPV("AstSel{$fromp.castAnd, operandSelBiLower(nodep)}", "DONE"); TREEOPV("AstSel{$fromp.castOr, operandSelBiLower(nodep)}", "DONE"); TREEOPV("AstSel{$fromp.castSub, operandSelBiLower(nodep)}", "DONE"); TREEOPV("AstSel{$fromp.castXnor,operandSelBiLower(nodep)}", "DONE"); TREEOPV("AstSel{$fromp.castXor, operandSelBiLower(nodep)}", "DONE"); TREEOPC("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)"); TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)"); TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.isOne, }", "replaceSelReplicate(nodep)"); // V3Tristate requires selects below BufIf1. // Also do additional operators that are bit-independent, but only definite // win if bit select is a constant (otherwise we may need to compute bit index several times) TREEOPV("AstSel{$fromp.castBufIf1}", "replaceSelIntoBiop(nodep)"); TREEOPV("AstSel{$fromp.castNot}", "replaceSelIntoUniop(nodep)"); TREEOPV("AstSel{$fromp.castAnd,$lhsp.castConst}", "replaceSelIntoUniop(nodep)"); TREEOPV("AstSel{$fromp.castOr,$lhsp.castConst}", "replaceSelIntoUniop(nodep)"); TREEOPV("AstSel{$fromp.castXor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)"); TREEOPV("AstSel{$fromp.castXnor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)"); // Conversions TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's // This visit function here must allow for short-circuiting. TREEOPS("AstLogIf {$lhsp.isZero}", "replaceNum(nodep, 1)"); TREEOPV("AstLogIf {$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}"); TREEOPV("AstLogIff{$lhsp, $rhsp}", "AstLogNot{AstXor{$lhsp,$rhsp}}"); // Strings TREEOPC("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, nodep->lhsp()->castConst()->num().toString())"); // Possible futures: // (a?(b?y:x):y) -> (a&&!b)?x:y // (a?(b?x:y):y) -> (a&&b)?x:y // (a?x:(b?x:y)) -> (a||b)?x:y // (a?x:(b?y:x)) -> (a||!b)?x:y // Note we can't convert EqCase/NeqCase to Eq/Neq here because that would break 3'b1x1==3'b101 //----- virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate if (m_required) { nodep->v3error("Expecting expression to be constant, but can't convert a " <prettyTypeName()<<" to constant."); } else { // Calculate the width of this operation if (m_params && !nodep->width()) { nodep = V3Width::widthParamsEdit(nodep); } nodep->iterateChildren(*this); } } public: // Processing Mode Enum enum ProcMode { PROC_PARAMS, PROC_GENERATE, PROC_LIVE, PROC_V_WARN, PROC_V_NOWARN, PROC_V_EXPENSIVE, PROC_CPP }; // CONSTUCTORS ConstVisitor(ProcMode pmode) { m_params = false; m_required = false; m_doExpensive = false; m_doNConst = false; m_doShort = true; // Presently always done m_doV = false; m_doGenerate = false; // Inside generate conditionals m_warn = false; m_wremove = true; // Overridden in visitors m_modp = NULL; m_selp = NULL; m_scopep = NULL; m_attrp = NULL; // switch (pmode) { case PROC_PARAMS: m_doV = true; m_doNConst = true; m_params = true; m_required = true; break; case PROC_GENERATE: m_doV = true; m_doNConst = true; m_params = true; m_required = true; m_doGenerate = true; break; case PROC_LIVE: break; case PROC_V_WARN: m_doV = true; m_doNConst = true; m_warn = true; break; case PROC_V_NOWARN: m_doV = true; m_doNConst = true; break; case PROC_V_EXPENSIVE: m_doV = true; m_doNConst = true; m_doExpensive = true; break; case PROC_CPP: m_doV = false; m_doNConst = true; break; default: v3fatalSrc("Bad case"); break; } } virtual ~ConstVisitor() {} AstNode* mainAcceptEdit(AstNode* nodep) { // Operate starting at a random place return nodep->acceptSubtreeReturnEdits(*this); } }; //###################################################################### // Const class functions //! Force this cell node's parameter list to become a constant //! @return Pointer to the edited node. AstNode* V3Const::constifyParamsEdit(AstNode* nodep) { //if (debug()>0) nodep->dumpTree(cout," forceConPRE : "); // Resize even if the node already has a width, because buried in the tree // we may have a node we just created with signing, etc, that isn't sized yet. // Make sure we've sized everything first nodep = V3Width::widthParamsEdit(nodep); ConstVisitor visitor(ConstVisitor::PROC_PARAMS); if (AstVar* varp=nodep->castVar()) { // If a var wants to be constified, it's really a param, and // we want the value to be constant. We aren't passed just the // init value because we need widthing above to handle the var's type. if (varp->valuep()) visitor.mainAcceptEdit(varp->valuep()); } else { nodep = visitor.mainAcceptEdit(nodep); } // Because we do edits, nodep links may get trashed and core dump this. //if (debug()>0) nodep->dumpTree(cout," forceConDONE: "); return nodep; } //! Force this cell node's parameter list to become a constant inside generate. //! If we are inside a generated "if", "case" or "for", we don't want to //! trigger warnings when we deal with the width. It is possible that these //! are spurious, existing within sub-expressions that will not actually be //! generated. Since such occurrences, must be constant, in order to be //! someting a generate block can depend on, we can wait until later to do the //! width check. //! @return Pointer to the edited node. AstNode* V3Const::constifyGenerateParamsEdit(AstNode* nodep) { //if (debug()>0) nodep->dumpTree(cout," forceConPRE : "); // Resize even if the node already has a width, because buried in the tree // we may have a node we just created with signing, etc, that isn't sized // yet. // Make sure we've sized everything first nodep = V3Width::widthGenerateParamsEdit(nodep); ConstVisitor visitor(ConstVisitor::PROC_GENERATE); if (AstVar* varp=nodep->castVar()) { // If a var wants to be constified, it's really a param, and // we want the value to be constant. We aren't passed just the // init value because we need widthing above to handle the var's type. if (varp->valuep()) visitor.mainAcceptEdit(varp->valuep()); } else { nodep = visitor.mainAcceptEdit(nodep); } // Because we do edits, nodep links may get trashed and core dump this. //if (debug()>0) nodep->dumpTree(cout," forceConDONE: "); return nodep; } void V3Const::constifyAllLint(AstNetlist* nodep) { // Only call from Verilator.cpp, as it uses user#'s UINFO(2,__FUNCTION__<<": "<= 3); } void V3Const::constifyCpp(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } AstNode* V3Const::constifyEdit(AstNode* nodep) { ConstVisitor visitor (ConstVisitor::PROC_V_NOWARN); nodep = visitor.mainAcceptEdit(nodep); return nodep; } void V3Const::constifyAllLive(AstNetlist* nodep) { // Only call from Verilator.cpp, as it uses user#'s // This only pushes constants up, doesn't make any other edits // IE doesn't prune dead statements, as we need to do some usability checks after this UINFO(2,__FUNCTION__<<": "<= 3); } void V3Const::constifyAll(AstNetlist* nodep) { // Only call from Verilator.cpp, as it uses user#'s UINFO(2,__FUNCTION__<<": "<= 3); } AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) { ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE); nodep = visitor.mainAcceptEdit(nodep); return nodep; } verilator-3.874/src/V3Active.cpp0000664000177100017500000003607012525171733016456 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity active domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Active's Transformations: // // Note this can be called multiple times. // Create a IACTIVE(initial), SACTIVE(combo) // ALWAYS: Remove any-edges from sense list // If no POS/NEG in senselist, Fold into SACTIVE(combo) // Else fold into SACTIVE(sequent). // OPTIMIZE: When support async clocks, fold into that active if possible // INITIAL: Move into IACTIVE // WIRE: Move into SACTIVE(combo) // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Active.h" #include "V3Ast.h" #include "V3EmitCBase.h" #include "V3Const.h" //***** See below for main transformation engine //###################################################################### // Collect existing active names class ActiveBaseVisitor : public AstNVisitor { protected: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; class ActiveNamer : public ActiveBaseVisitor { private: typedef std::map ActiveNameMap; // STATE AstScope* m_scopep; // Current scope to add statement to AstActive* m_iActivep; // For current scope, the IActive we're building AstActive* m_cActivep; // For current scope, the SActive(combo) we're building vector m_activeVec; // List of sensitive actives, for folding // METHODS void addActive(AstActive* nodep) { if (!m_scopep) nodep->v3fatalSrc("NULL scope"); m_scopep->addActivep(nodep); } // VISITORS virtual void visit(AstScope* nodep, AstNUser*) { m_scopep = nodep; m_iActivep = NULL; m_cActivep = NULL; m_activeVec.clear(); nodep->iterateChildren(*this); // Don't clear scopep, the namer persists beyond this visit } virtual void visit(AstSenTree* nodep, AstNUser*) { // Simplify sensitivity list V3Const::constifyExpensiveEdit(nodep); nodep=NULL; } // Empty visitors, speed things up virtual void visit(AstNodeStmt* nodep, AstNUser*) { } //-------------------- // Default virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); } // METHODS public: AstScope* scopep() { return m_scopep; } AstActive* getCActive(FileLine* fl) { if (!m_cActivep) { m_cActivep = new AstActive(fl, "combo", new AstSenTree(fl, new AstSenItem(fl,AstSenItem::Combo()))); m_cActivep->sensesStorep(m_cActivep->sensesp()); addActive(m_cActivep); } return m_cActivep; } AstActive* getIActive(FileLine* fl) { if (!m_iActivep) { m_iActivep = new AstActive(fl, "initial", new AstSenTree(fl, new AstSenItem(fl,AstSenItem::Initial()))); m_iActivep->sensesStorep(m_iActivep->sensesp()); addActive(m_iActivep); } return m_iActivep; } AstActive* getActive(FileLine* fl, AstSenTree* sensesp) { // Return a sentree in this scope that matches given sense list. // Not the fastest, but scopes tend to have few clocks AstActive* activep = NULL; //sitemsp->dumpTree(cout," Lookingfor: "); for (vector::iterator it = m_activeVec.begin(); it!=m_activeVec.end(); ++it) { activep = *it; if (activep) { // Not deleted // Compare the list AstSenTree* asenp = activep->sensesp(); if (asenp->sameTree(sensesp)) { UINFO(8," Found ACTIVE "<cloneTree(false); activep = new AstActive(fl, "sequent", newsenp); activep->sensesStorep(activep->sensesp()); UINFO(8," New ACTIVE "<accept(*this); } }; //###################################################################### // Active AssignDly replacement functions class ActiveDlyVisitor : public ActiveBaseVisitor { public: enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL, CT_LATCH }; private: CheckType m_check; // Combo logic or other AstNode* m_alwaysp; // Always we're under AstNode* m_assignp; // In assign // VISITORS virtual void visit(AstAssignDly* nodep, AstNUser*) { if (m_check != CT_SEQ) { // Convert to a non-delayed assignment UINFO(5," ASSIGNDLY "<v3warn(INITIALDLY,"Delayed assignments (<=) in initial or final block; suggest blocking assignments (=)."); } else if (m_check == CT_LATCH) { // Suppress. Shouldn't matter that the interior of the latch races } else { nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=)."); } AstNode* newp = new AstAssign (nodep->fileline(), nodep->lhsp()->unlinkFrBack(), nodep->rhsp()->unlinkFrBack()); nodep->replaceWith(newp); nodep->deleteTree(); nodep = NULL; } } virtual void visit(AstAssign* nodep, AstNUser*) { if (m_check == CT_SEQ) { AstNode* las = m_assignp; m_assignp = nodep; nodep->lhsp()->iterateAndNext(*this); m_assignp = las; } } virtual void visit(AstVarRef* nodep, AstNUser*) { AstVar* varp=nodep->varp(); if (m_check == CT_SEQ && m_assignp && !varp->isUsedLoopIdx() // Ignore loop indicies && !varp->isTemp() ) { // Allow turning off warnings on the always, or the variable also if (!m_alwaysp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ) && !m_assignp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ) && !varp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ) ) { m_alwaysp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Complain just once for the entire always varp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); nodep->v3warn(BLKSEQ,"Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=)."); } } } //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ActiveDlyVisitor(AstNode* nodep, CheckType check) { m_alwaysp = nodep; m_check = check; m_assignp = NULL; nodep->accept(*this); } virtual ~ActiveDlyVisitor() {} }; //###################################################################### // Active class functions class ActiveVisitor : public ActiveBaseVisitor { private: // NODE STATE // Each call to V3Const::constify // AstNode::user4() Used by V3Const::constify, called below // STATE ActiveNamer m_namer; // Tracking of active names AstCFunc* m_scopeFinalp; // Final function for this scope bool m_itemCombo; // Found a SenItem combo bool m_itemSequent; // Found a SenItem sequential // VISITORS virtual void visit(AstScope* nodep, AstNUser*) { // Create required actives and add to scope UINFO(4," SCOPE "<iterateChildren(*this); } virtual void visit(AstActive* nodep, AstNUser*) { // Actives are being formed, so we can ignore any already made } virtual void visit(AstInitial* nodep, AstNUser*) { // Relink to IACTIVE, unless already under it UINFO(4," INITIAL "<fileline()); nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); } virtual void visit(AstAssignAlias* nodep, AstNUser*) { // Relink to CACTIVE, unless already under it UINFO(4," ASSIGNW "<fileline()); nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); } virtual void visit(AstAssignW* nodep, AstNUser*) { // Relink to CACTIVE, unless already under it UINFO(4," ASSIGNW "<fileline()); nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); } virtual void visit(AstCoverToggle* nodep, AstNUser*) { // Relink to CACTIVE, unless already under it UINFO(4," COVERTOGGLE "<fileline()); nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); } virtual void visit(AstFinal* nodep, AstNUser*) { // Relink to CFUNC for the final UINFO(4," FINAL "<bodysp()) { // Empty, Kill it. nodep->unlinkFrBack()->deleteTree(); nodep=NULL; return; } ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL); if (!m_scopeFinalp) { m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final_"+m_namer.scopep()->nameDotless(), m_namer.scopep()); m_scopeFinalp->argTypes(EmitCBaseVisitor::symClassVar()); m_scopeFinalp->addInitsp(new AstCStmt(nodep->fileline(), EmitCBaseVisitor::symTopAssign()+"\n")); m_scopeFinalp->dontCombine(true); m_scopeFinalp->formCallTree(true); m_scopeFinalp->slow(true); m_namer.scopep()->addActivep(m_scopeFinalp); } nodep->unlinkFrBack(); m_scopeFinalp->addStmtsp(new AstComment(nodep->fileline(), nodep->typeName())); m_scopeFinalp->addStmtsp(nodep->bodysp()->unlinkFrBackWithNext()); nodep->deleteTree(); nodep = NULL; } // METHODS void visitAlways(AstNode* nodep, AstSenTree* oldsensesp, VAlwaysKwd kwd) { // Move always to appropriate ACTIVE based on its sense list if (oldsensesp && oldsensesp->sensesp() && oldsensesp->sensesp()->castSenItem() && oldsensesp->sensesp()->castSenItem()->isNever()) { // Never executing. Kill it. if (oldsensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated."); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; return; } // Read sensitivitues m_itemCombo = false; m_itemSequent = false; oldsensesp->iterateAndNext(*this); bool combo = m_itemCombo; bool sequent = m_itemSequent; if (!combo && !sequent) combo=true; // If no list, Verilog 2000: always @ (*) if (combo && sequent) { nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list"); sequent = false; } AstActive* wantactivep = NULL; if (combo && !sequent) { // Combo: Relink to ACTIVE(combo) wantactivep = m_namer.getCActive(nodep->fileline()); } else { // Sequential: Build a ACTIVE(name) // OPTIMIZE: We could substitute a constant for things in the sense list, for example // always (posedge RESET) { if (RESET).... } we know RESET is true. // Summarize a long list of combo inputs as just "combo" #ifndef __COVERITY__ // Else dead code on next line. if (combo) oldsensesp->addSensesp (new AstSenItem(nodep->fileline(),AstSenItem::Combo())); #endif wantactivep = m_namer.getActive(nodep->fileline(), oldsensesp); } // Delete sensitivity list if (oldsensesp) { oldsensesp->unlinkFrBackWithNext()->deleteTree(); oldsensesp=NULL; } // Move node to new active nodep->unlinkFrBack(); wantactivep->addStmtsp(nodep); // Warn and/or convert any delayed assignments if (combo && !sequent) { if (kwd == VAlwaysKwd::ALWAYS_LATCH) { ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_LATCH); } else { ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_COMBO); } } else if (!combo && sequent) { ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_SEQ); } } virtual void visit(AstAlways* nodep, AstNUser*) { // Move always to appropriate ACTIVE based on its sense list UINFO(4," ALW "<=9) nodep->dumpTree(cout," Alw: "); if (!nodep->bodysp()) { // Empty always. Kill it. nodep->unlinkFrBack()->deleteTree(); nodep=NULL; return; } visitAlways(nodep, nodep->sensesp(), nodep->keyword()); } virtual void visit(AstAlwaysPublic* nodep, AstNUser*) { // Move always to appropriate ACTIVE based on its sense list UINFO(4," ALWPub "<=9) nodep->dumpTree(cout," Alw: "); visitAlways(nodep, nodep->sensesp(), VAlwaysKwd::ALWAYS); } virtual void visit(AstSenGate* nodep, AstNUser*) { AstSenItem* subitemp = nodep->sensesp(); if (subitemp->edgeType() != AstEdgeType::ET_ANYEDGE && subitemp->edgeType() != AstEdgeType::ET_POSEDGE && subitemp->edgeType() != AstEdgeType::ET_NEGEDGE) { nodep->v3fatalSrc("Strange activity type under SenGate"); } nodep->iterateChildren(*this); } virtual void visit(AstSenItem* nodep, AstNUser*) { if (nodep->edgeType() == AstEdgeType::ET_ANYEDGE) { m_itemCombo = true; // Delete the sensitivity // We'll add it as a generic COMBO SenItem in a moment. nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else if (nodep->varrefp()) { // V3LinkResolve should have cleaned most of these up if (!nodep->varrefp()->width1()) nodep->v3error("Unsupported: Non-single bit wide signal pos/negedge sensitivity: " <varrefp()->prettyName()); m_itemSequent = true; nodep->varrefp()->varp()->usedClock(true); } } // Empty visitors, speed things up virtual void visit(AstNodeMath* nodep, AstNUser*) {} virtual void visit(AstVarScope* nodep, AstNUser*) {} //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ActiveVisitor(AstNetlist* nodep) { m_scopeFinalp = NULL; m_itemCombo = false; m_itemSequent = false; nodep->accept(*this); } virtual ~ActiveVisitor() {} }; //###################################################################### // Active class functions void V3Active::activeAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3ParseImp.cpp0000664000177100017500000001421712525171733016762 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Netlist (top level) functions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // Overview of files involved in parsing // V3Parse.h External consumer interface to V3ParseImp // V3ParseImp Internals to parser, common to across flex & bison // V3ParseGrammar Wrapper that includes V3ParseBison // V3ParseBison Bison output // V3ParseLex Wrapper that includes lex output // V3Lexer.yy.cpp Flex output //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Error.h" #include "V3Global.h" #include "V3Os.h" #include "V3Ast.h" #include "V3File.h" #include "V3ParseImp.h" #include "V3PreShell.h" //====================================================================== // Globals V3ParseImp* V3ParseImp::s_parsep = NULL; int V3ParseSym::s_anonNum = 0; //###################################################################### // Read class functions V3ParseImp::~V3ParseImp() { for (deque::iterator it = m_stringps.begin(); it != m_stringps.end(); ++it) { delete (*it); } m_stringps.clear(); for (deque::iterator it = m_numberps.begin(); it != m_numberps.end(); ++it) { delete (*it); } m_numberps.clear(); lexDestroy(); parserClear(); if (debug()>=9) { UINFO(0,"~V3ParseImp\n"); symp()->dump(cout, "-vpi: "); } } size_t V3ParseImp::ppInputToLex(char* buf, size_t max_size) { size_t got = 0; while (got < max_size // Haven't got enough && !m_ppBuffers.empty()) { // And something buffered string front = m_ppBuffers.front(); m_ppBuffers.pop_front(); size_t len = front.length(); if (len > (max_size-got)) { // Front string too big string remainder = front.substr(max_size-got); front = front.substr(0, max_size-got); m_ppBuffers.push_front(remainder); // Put back remainder for next time len = (max_size-got); } strncpy(buf+got, front.c_str(), len); got += len; } if (debug()>=9) { string out = string(buf,got); cout<<" inputToLex got="<ext+ options since it was first ecountered. FileLine *modfileline = new FileLine (modfilename, 0); modfileline->language(v3Global.opt.fileLanguage(modfilename)); ppPushText((string)"`begin_keywords \""+modfileline->language().ascii()+"\"\n"); } // Preprocess into m_ppBuffer bool ok = V3PreShell::preproc(fileline, modfilename, m_filterp, this, errmsg); if (!ok) { if (errmsg != "") return; // Threw error already // Create fake node for later error reporting AstNodeModule* nodep = new AstNotFoundModule(fileline, modname); v3Global.rootp()->addModulep(nodep); return; } if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) { // Create output file with all the preprocessor output we buffered up string vppfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_"+modname+".vpp"; ofstream* ofp = NULL; ostream* osp; bool noblanks = v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine(); if (v3Global.opt.preprocOnly()) { osp = &cout; } else { osp = ofp = V3File::new_ofstream(vppfilename); } if (osp->fail()) { fileline->v3error("Cannot write preprocessor output: "+vppfilename); return; } else { for (deque::iterator it = m_ppBuffers.begin(); it!=m_ppBuffers.end(); ++it) { if (noblanks) { bool blank = true; for (string::iterator its = it->begin(); its != it->end(); ++its) { if (!isspace(*its) && *its!='\n') { blank=false; break; } } if (blank) continue; } *osp << *it; } if (ofp) { ofp->close(); delete ofp; ofp = NULL; } } } // Parse it if (!v3Global.opt.preprocOnly()) { lexFile (modfilename); } } void V3ParseImp::lexFile(const string& modname) { // Prepare for lexing UINFO(3,"Lexing "<warnResetDefault(); // Reenable warnings on each file lexDestroy(); // Restart from clean slate. lexNew(debugFlex()>=9); // Lex it if (bisonParse()) v3fatal("Cannot continue\n"); } //====================================================================== // V3Parse functions V3Parse::V3Parse(AstNetlist* rootp, V3InFilter* filterp, V3ParseSym* symp) { m_impp = new V3ParseImp (rootp, filterp, symp); } V3Parse::~V3Parse() { delete m_impp; m_impp = NULL; } void V3Parse::parseFile(FileLine* fileline, const string& modname, bool inLibrary, const string& errmsg) { m_impp->parseFile(fileline, modname, inLibrary, errmsg); } void V3Parse::ppPushText(V3ParseImp* impp, const string& text) { impp->ppPushText(text); } verilator-3.874/src/V3Options.cpp0000664000177100017500000012744612525172036016703 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Options parsing // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #ifndef _WIN32 # include #endif #include #include #include #include #include #include #include #include #include "V3Global.h" #include "V3String.h" #include "V3Os.h" #include "V3Options.h" #include "V3Error.h" #include "V3File.h" #include "V3PreShell.h" #include "config_rev.h" //###################################################################### // V3 Internal state class V3OptionsImp { public: // TYPES typedef std::map > DirMap; // Directory listing // STATE list m_allArgs; // List of every argument encountered list m_incDirUsers; // Include directories (ordered) set m_incDirUserSet; // Include directories (for removing duplicates) list m_incDirFallbacks; // Include directories (ordered) set m_incDirFallbackSet; // Include directories (for removing duplicates) map m_langExts; // Language extension map list m_libExtVs; // Library extensions (ordered) set m_libExtVSet; // Library extensions (for removing duplicates) DirMap m_dirMap; // Directory listing // ACCESSOR METHODS void addIncDirUser(const string& incdir) { if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) { m_incDirUserSet.insert(incdir); m_incDirUsers.push_back(incdir); m_incDirFallbacks.remove(incdir); // User has priority over Fallback m_incDirFallbackSet.erase(incdir); // User has priority over Fallback } } void addIncDirFallback(const string& incdir) { if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) { // User has priority over Fallback if (m_incDirFallbackSet.find(incdir) == m_incDirFallbackSet.end()) { m_incDirFallbackSet.insert(incdir); m_incDirFallbacks.push_back(incdir); } } } void addLangExt(const string& langext, const V3LangCode& lc) { // New language extension replaces any pre-existing one. (void)m_langExts.erase(langext); m_langExts[langext] = lc; } void addLibExtV(const string& libext) { if (m_libExtVSet.find(libext) == m_libExtVSet.end()) { m_libExtVSet.insert(libext); m_libExtVs.push_back(libext); } } V3OptionsImp() {} ~V3OptionsImp() {} }; void V3Options::addIncDirUser(const string& incdir) { m_impp->addIncDirUser(incdir); } void V3Options::addIncDirFallback(const string& incdir) { m_impp->addIncDirFallback(incdir); } void V3Options::addLangExt(const string& langext, const V3LangCode& lc) { m_impp->addLangExt(langext, lc); } void V3Options::addLibExtV(const string& libext) { m_impp->addLibExtV(libext); } void V3Options::addDefine(const string& defline, bool allowPlus) { // Split +define+foo=value into the appropriate parts and parse // Optional + says to allow multiple defines on the line // + is not quotable, as other simulators do not allow that string left = defline; while (left != "") { string def = left; string::size_type pos; if (allowPlus && ((pos=left.find("+")) != string::npos)) { left = left.substr(pos+1); def.erase(pos); } else { left = ""; } string value; if ((pos=def.find("=")) != string::npos) { value = def.substr(pos+1); def.erase(pos); } V3PreShell::defineCmdLine(def,value); } } void V3Options::addCppFile(const string& filename) { if (m_cppFiles.find(filename) == m_cppFiles.end()) { m_cppFiles.insert(filename); } } void V3Options::addCFlags(const string& filename) { if (m_cFlags.find(filename) == m_cFlags.end()) { m_cFlags.insert(filename); } } void V3Options::addLdLibs(const string& filename) { if (m_ldLibs.find(filename) == m_ldLibs.end()) { m_ldLibs.insert(filename); } } void V3Options::addFuture(const string& flag) { if (m_futures.find(flag) == m_futures.end()) { m_futures.insert(flag); } } bool V3Options::isFuture(const string& flag) const { return m_futures.find(flag) != m_futures.end(); } bool V3Options::isLibraryFile(const string& filename) const { return m_libraryFiles.find(filename) != m_libraryFiles.end(); } void V3Options::addLibraryFile(const string& filename) { if (m_libraryFiles.find(filename) == m_libraryFiles.end()) { m_libraryFiles.insert(filename); } } bool V3Options::isClocker(const string& signame) const { return m_clockers.find(signame) != m_clockers.end(); } void V3Options::addClocker(const string& signame) { if (m_clockers.find(signame) == m_clockers.end()) { m_clockers.insert(signame); } } bool V3Options::isNoClocker(const string& signame) const { return m_noClockers.find(signame) != m_noClockers.end(); } void V3Options::addNoClocker(const string& signame) { if (m_noClockers.find(signame) == m_noClockers.end()) { m_noClockers.insert(signame); } } void V3Options::addVFile(const string& filename) { // We use a list for v files, because it's legal to have includes // in a specific order and multiple of them. m_vFiles.push_back(filename); } void V3Options::addArg(const string& arg) { m_impp->m_allArgs.push_back(arg); } string V3Options::allArgsString() { string out; for (list::iterator it=m_impp->m_allArgs.begin(); it!=m_impp->m_allArgs.end(); ++it) { if (out != "") out += " "; out += *it; } return out; } //###################################################################### // V3LangCode class functions V3LangCode::V3LangCode (const char* textp) { // Return code for given string, or ERROR, which is a bad code for (int codei=V3LangCode::L_ERROR; codei0) ::close(fd); } } string V3Options::fileExists (const string& filename) { // Surprisingly, for VCS and other simulators, this process // is quite slow; presumably because of re-reading each directory // many times. So we read a whole dir at once and cache it string dir = V3Os::filenameDir(filename); string basename = V3Os::filenameNonDir(filename); V3OptionsImp::DirMap::iterator diriter = m_impp->m_dirMap.find(dir); if (diriter == m_impp->m_dirMap.end()) { // Read the listing m_impp->m_dirMap.insert(make_pair(dir, set() )); diriter = m_impp->m_dirMap.find(dir); set* setp = &(diriter->second); if (DIR* dirp = opendir(dir.c_str())) { while (struct dirent* direntp = readdir(dirp)) { setp->insert(direntp->d_name); } closedir(dirp); } } // Find it set* filesetp = &(diriter->second); set::iterator fileiter = filesetp->find(basename); if (fileiter == filesetp->end()) { return ""; // Not found } // Check if it is a directory, ignore if so string filenameOut = V3Os::filenameFromDirBase (dir, basename); if (!fileStatNormal(filenameOut)) return ""; // Directory return filenameOut; } string V3Options::filePathCheckOneDir(const string& modname, const string& dirname) { for (list::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) { string fn = V3Os::filenameFromDirBase(dirname, modname+*extIter); string exists = fileExists(fn); if (exists!="") { // Strip ./, it just looks ugly if (exists.substr(0,2)=="./") exists.erase(0,2); return exists; } } return ""; } string V3Options::filePath (FileLine* fl, const string& modname, const string& errmsg) { // Error prefix or "" to suppress error // Find a filename to read the specified module name, // using the incdir and libext's. // Return "" if not found. for (list::iterator dirIter=m_impp->m_incDirUsers.begin(); dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) { string exists = filePathCheckOneDir(modname, *dirIter); if (exists!="") return exists; } for (list::iterator dirIter=m_impp->m_incDirFallbacks.begin(); dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) { string exists = filePathCheckOneDir(modname, *dirIter); if (exists!="") return exists; } // Warn and return not found if (errmsg != "") { fl->v3error(errmsg+modname); filePathLookedMsg(fl, modname); } return ""; } void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) { static bool shown_notfound_msg = false; if (!shown_notfound_msg) { shown_notfound_msg = true; if (m_impp->m_incDirUsers.empty()) { fl->v3error("This may be because there's no search path specified with -I."<v3error("Looked in:"<::iterator dirIter=m_impp->m_incDirUsers.begin(); dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) { for (list::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) { string fn = V3Os::filenameFromDirBase(*dirIter,modname+*extIter); fl->v3error(" "<::iterator dirIter=m_impp->m_incDirFallbacks.begin(); dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) { for (list::iterator extIter=m_impp->m_libExtVs.begin(); extIter!=m_impp->m_libExtVs.end(); ++extIter) { string fn = V3Os::filenameFromDirBase(*dirIter,modname+*extIter); fl->v3error(" "<::iterator it = m_impp->m_langExts.find(ext); if (it != m_impp->m_langExts.end()) { return it->second; } } return m_defaultLanguage; } //###################################################################### // Environment string V3Options::getenvPERL() { return V3Os::getenvStr("PERL","perl"); } string V3Options::getenvSYSTEMC() { string var = V3Os::getenvStr("SYSTEMC",""); if (var == "" && string(DEFENV_SYSTEMC) != "") { var = DEFENV_SYSTEMC; V3Os::setenvStr("SYSTEMC", var, "Hardcoded at build time"); } return var; } string V3Options::getenvSYSTEMC_ARCH() { string var = V3Os::getenvStr("SYSTEMC_ARCH",""); if (var == "" && string(DEFENV_SYSTEMC_ARCH) != "") { var = DEFENV_SYSTEMC_ARCH; V3Os::setenvStr("SYSTEMC_ARCH", var, "Hardcoded at build time"); } if (var == "") { #if defined (__MINGW32__) // Hardcoded with MINGW current version. Would like a better way. string sysname = "MINGW32_NT-5.0"; var = "mingw32"; #elif defined (_WIN32) string sysname = "WIN32"; var = "win32"; #else struct utsname uts; uname(&uts); string sysname = VString::downcase(uts.sysname); // aka 'uname -s' if (VString::wildmatch(sysname.c_str(), "*solaris*")) { var = "gccsparcOS5"; } else if (VString::wildmatch(sysname.c_str(), "*cygwin*")) { var ="cygwin"; } else { var = "linux"; } #endif V3Os::setenvStr("SYSTEMC_ARCH", var,"From sysname '"+sysname+"'"); } return var; } string V3Options::getenvSYSTEMC_INCLUDE() { string var = V3Os::getenvStr("SYSTEMC_INCLUDE",""); if (var == "" && string(DEFENV_SYSTEMC_INCLUDE) != "") { var = DEFENV_SYSTEMC_INCLUDE; V3Os::setenvStr("SYSTEMC_INCLUDE", var, "Hardcoded at build time"); } if (var == "") { string sc = getenvSYSTEMC(); if (sc != "") var = sc+"/include"; } // Only correct or check it if we really need the value if (v3Global.opt.usingSystemCLibs()) { if (var == "") { v3fatal("Need $SYSTEMC_INCLUDE in environment or when Verilator configured\n" "Probably System-C isn't installed, see http://www.systemc.org\n"); } } return var; } string V3Options::getenvSYSTEMC_LIBDIR() { string var = V3Os::getenvStr("SYSTEMC_LIBDIR",""); if (var == "" && string(DEFENV_SYSTEMC_LIBDIR) != "") { var = DEFENV_SYSTEMC_LIBDIR; V3Os::setenvStr("SYSTEMC_LIBDIR", var, "Hardcoded at build time"); } if (var == "") { string sc = getenvSYSTEMC(); string arch = getenvSYSTEMC_ARCH(); if (sc != "" && arch != "") var = sc+"/lib-"+arch; } // Only correct or check it if we really need the value if (v3Global.opt.usingSystemCLibs()) { if (var == "") { v3fatal("Need $SYSTEMC_LIBDIR in environment or when Verilator configured\n" "Probably System-C isn't installed, see http://www.systemc.org\n"); } } return var; } string V3Options::getenvSYSTEMPERL() { // Must be careful to set SYSTEMPERL_INCLUDE first else we'd setenv // SYSTEMPERL which would override a DEFENVed SYSTEMPERL_INCLUDE. V3Options::getenvSYSTEMPERL_INCLUDE(); return V3Options::getenvSYSTEMPERLGuts(); } string V3Options::getenvSYSTEMPERLGuts() { // Get SYSTEMPERL when SYSTEMPERL_INCLUDE has already been tested string var = V3Os::getenvStr("SYSTEMPERL",""); if (var == "" && string(DEFENV_SYSTEMPERL) != "") { var = DEFENV_SYSTEMPERL; V3Os::setenvStr("SYSTEMPERL", var, "Hardcoded at build time"); } return var; } string V3Options::getenvSYSTEMPERL_INCLUDE() { string var = V3Os::getenvStr("SYSTEMPERL_INCLUDE",""); if (var == "") { string sp_src = V3Options::getenvSYSTEMPERLGuts()+"/src"; if (V3Options::fileStatNormal(sp_src+"/systemperl.h")) { var = sp_src; V3Os::setenvStr ("SYSTEMPERL_INCLUDE", var, "From $SYSTEMPERL/src"); } else if (string(DEFENV_SYSTEMPERL_INCLUDE) != "") { // Note if SYSTEMPERL is DEFENVed, then SYSTEMPERL_INCLUDE is also DEFENVed // So we don't need to sweat testing DEFENV_SYSTEMPERL also var = DEFENV_SYSTEMPERL_INCLUDE; V3Os::setenvStr("SYSTEMPERL_INCLUDE", var, "Hardcoded at build time"); } } // Only correct or check it if we really need the value if (v3Global.opt.usingSystemPerlLibs()) { // We warn about $SYSTEMPERL instead of _INCLUDE since that's more likely // what users will want to set. if (var == "") { v3fatal("Need $SYSTEMPERL and $SYSTEMPERL_INCLUDE in environment for --sp or --coverage\n" "Probably System-Perl isn't installed, see http://www.veripool.org/systemperl\n"); } else if (var != "" && !V3Options::fileStatNormal(var+"/systemperl.h")) { v3fatal("Neither $SYSTEMPERL nor $SYSTEMPERL_INCLUDE environment vars to point to System-Perl kit: "<=1) m_prefix = string("V")+V3Os::filenameNonExt(*(vFilesList.begin())); if (modPrefix()=="") m_modPrefix = prefix(); // Find files in makedir addIncDirFallback(makeDir()); } //====================================================================== bool V3Options::onoff(const char* sw, const char* arg, bool& flag) { // if sw==arg, then return true (found it), and flag=true // if sw=="-no-arg", then return true (found it), and flag=false // if sw=="-noarg", then return true (found it), and flag=false // else return false if (arg[0]!='-') v3fatalSrc("OnOff switches must have leading dash.\n"); if (0==strcmp(sw,arg)) { flag=true; return true; } else if (0==strncmp(sw,"-no",3) && (0==strcmp(sw+3,arg+1))) { flag=false; return true; } else if (0==strncmp(sw,"-no-",4) && (0==strcmp(sw+4,arg+1))) { flag=false; return true; } return false; } bool V3Options::suffixed(const char* sw, const char* arg) { if (strlen(arg) > strlen(sw)) return false; return (0==strcmp(sw+strlen(sw)-strlen(arg), arg)); } void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char** argv) { // Parse parameters // Note argc and argv DO NOT INCLUDE the filename in [0]!!! // May be called recursively when there are -f files. for (int i=0; iv3fatal ("Invalid Option: "<v3fatal("Unknown language specified: "<m_outputSplitCFuncs)) { m_outputSplitCTrace = m_outputSplitCFuncs; } } else if ( !strcmp (sw, "-output-split-ctrace") ) { // Undocumented optimization tweak shift; m_outputSplitCTrace = atoi(argv[i]); } else if ( !strcmp (sw, "-trace-depth") && (i+1)v3fatal("Unknown warning specified: "<v3fatal("Unknown warning specified: "<v3fatal("Unknown warning specified: "<v3fatal("Unknown setting for --compiler: "<v3fatal("Unknown setting for --x-assign: "<v3fatal ("Invalid Option: "< ifp (V3File::new_ifstream(filename)); if (ifp->fail()) { fl->v3error("Cannot open -f command file: "+filename); return; } string whole_file; bool inCmt = false; while (!ifp->eof()) { string line; getline(*ifp, line); // Strip simple comments string oline; for (string::const_iterator pos = line.begin(); pos != line.end(); ++pos) { if (inCmt) { if (*pos=='*' && *(pos+1)=='/') { inCmt = false; ++pos; } } else if (*pos=='/' && *(pos+1)=='/') { break; // Ignore to EOL } else if (*pos=='/' && *(pos+1)=='*') { inCmt = true; // cppcheck-suppress StlMissingComparison ++pos; } else { oline += *pos; } } whole_file += oline + " "; } whole_file += "\n"; // So string match below is simplified if (inCmt) fl->v3error("Unterminated /* comment inside -f file."); fl = new FileLine(filename, 0); // Split into argument list and process // Note we don't respect quotes. It seems most simulators dont. // Woez those that expect it; we'll at least complain. if (whole_file.find("\"") != string::npos) { fl->v3error("Double quotes in -f files cause unspecified behavior."); } // Strip off arguments and parse into words vector args; string::size_type startpos = 0; while (startpos < whole_file.length()) { while (isspace(whole_file[startpos])) ++startpos; string::size_type endpos = startpos; while (endpos < whole_file.length() && !isspace(whole_file[endpos])) ++endpos; if (startpos != endpos) { string arg (whole_file, startpos, endpos-startpos); args.reserve(args.size()+1); args.push_back(arg); } startpos = endpos; } // Path string optdir = (rel ? V3Os::filenameDir(filename) : "."); // Convert to argv style arg list and parse them char* argv [args.size()+1]; for (unsigned i=0; isecond = level; } else { m_debugSrcs.insert(make_pair(srcfile,level)); } } int V3Options::debugSrcLevel(const string& srcfile_path, int default_level) { // For simplicity, calling functions can just use __FILE__ for srcfile. // That means though we need to cleanup the filename from ../Foo.cpp -> Foo string srcfile = V3Os::filenameNonDirExt(srcfile_path); DebugSrcMap::iterator iter = m_debugSrcs.find(srcfile); if (iter!=m_debugSrcs.end()) { return iter->second; } else { return default_level; } } void V3Options::setDumpTreeLevel(const string& srcfile, int level) { DebugSrcMap::iterator iter = m_dumpTrees.find(srcfile); if (iter!=m_dumpTrees.end()) { iter->second = level; } else { m_dumpTrees.insert(make_pair(srcfile,level)); } } int V3Options::dumpTreeLevel(const string& srcfile_path) { // For simplicity, calling functions can just use __FILE__ for srcfile. // That means though we need to cleanup the filename from ../Foo.cpp -> Foo string srcfile = V3Os::filenameNonDirExt(srcfile_path); DebugSrcMap::iterator iter = m_dumpTrees.find(srcfile); if (iter!=m_dumpTrees.end()) { return iter->second; } else { return m_dumpTree; } } void V3Options::optimize(int level) { // Set all optimizations to on/off bool flag = level > 0; m_oAcycSimp = flag; m_oCase = flag; m_oCombine = flag; m_oConst = flag; m_oExpand = flag; m_oFlopGater = flag; m_oGate = flag; m_oInline = flag; m_oLife = flag; m_oLifePost = flag; m_oLocalize = flag; m_oReorder = flag; m_oSplit = flag; m_oSubst = flag; m_oSubstConst = flag; m_oTable = flag; m_oDedupe = flag; m_oAssemble = flag; // And set specific optimization levels if (level >= 3) { m_inlineMult = -1; // Maximum inlining } } verilator-3.874/src/V3GraphAlg.h0000664000177100017500000000322712525171733016373 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph algorithm base class // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3GRAPHALG_H_ #define _V3GRAPHALG_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Global.h" #include "V3Graph.h" //============================================================================= // Algorithms - common class // For internal use, most graph algorithms use this as a base class class GraphAlg { protected: V3Graph* m_graphp; // Graph we're operating upon V3EdgeFuncP m_edgeFuncp; // Function that says we follow this edge inline bool followEdge(V3GraphEdge* edgep) { return (edgep->weight() && (m_edgeFuncp)(edgep)); } GraphAlg(V3Graph* graphp, V3EdgeFuncP edgeFuncp) : m_graphp(graphp), m_edgeFuncp(edgeFuncp) {} ~GraphAlg() {} }; //============================================================================ #endif // Guard verilator-3.874/src/V3WidthCommit.h0000664000177100017500000001336312525171734017141 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Cleanup stage in V3Width // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3WIDTHCOMMIT_H_ #define _V3WIDTHCOMMIT_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" #ifndef _V3WIDTH_CPP_ # error "V3WidthCommit for V3Width internal use only" #endif //###################################################################### /// Remove all $signed, $unsigned, we're done with them. class WidthRemoveVisitor : public AstNVisitor { private: // VISITORS virtual void visit(AstSigned* nodep, AstNUser*) { replaceWithSignedVersion(nodep, nodep->lhsp()->unlinkFrBack()); nodep=NULL; } virtual void visit(AstUnsigned* nodep, AstNUser*) { replaceWithSignedVersion(nodep, nodep->lhsp()->unlinkFrBack()); nodep=NULL; } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } void replaceWithSignedVersion(AstNode* nodep, AstNode* newp) { UINFO(6," Replace "<replaceWith(newp); newp->dtypeFrom(nodep); pushDeletep(nodep); nodep=NULL; } public: // CONSTRUCTORS WidthRemoveVisitor() {} virtual ~WidthRemoveVisitor() {} AstNode* mainAcceptEdit(AstNode* nodep) { return nodep->acceptSubtreeReturnEdits(*this); } }; //###################################################################### // Now that all widthing is complete, // Copy all width() to widthMin(). V3Const expects this class WidthCommitVisitor : public AstNVisitor { // NODE STATE // AstVar::user1p -> bool, processed AstUser1InUse m_inuser1; public: // METHODS static AstConst* newIfConstCommitSize (AstConst* nodep) { if (((nodep->dtypep()->width() != nodep->num().width()) || !nodep->num().sized()) && !nodep->num().isString()) { // Need to force the number from unsized to sized V3Number num (nodep->fileline(), nodep->dtypep()->width()); num.opAssign(nodep->num()); num.isSigned(nodep->isSigned()); AstConst* newp = new AstConst(nodep->fileline(), num); newp->dtypeFrom(nodep); return newp; } else { return NULL; } } private: // METHODS void editDType(AstNode* nodep) { // Edit dtypes for this node nodep->dtypep(editOneDType(nodep->dtypep())); } AstNodeDType* editOneDType(AstNodeDType* nodep) { // See if the dtype/refDType can be converted to a standard one // This reduces the number of dtypes in the system, and since // dtypep() figures into sameTree() results in better optimizations if (!nodep) return NULL; // Recurse to handle the data type, as may change the size etc of this type if (!nodep->user1()) nodep->accept(*this,NULL); // Look for duplicate if (AstBasicDType* bdtypep = nodep->castBasicDType()) { AstBasicDType* newp = nodep->findInsertSameDType(bdtypep); if (newp != bdtypep && debug()>=9) { UINFO(9,"dtype replacement "); nodep->dumpSmall(cout); cout<<" ----> "; newp->dumpSmall(cout); cout<dtypep()) nodep->v3fatalSrc("No dtype"); nodep->dtypep()->accept(*this); // Do datatype first if (AstConst* newp = newIfConstCommitSize(nodep)) { nodep->replaceWith(newp); AstNode* oldp = nodep; nodep = newp; //if (debug()>4) oldp->dumpTree(cout," fixConstSize_old: "); //if (debug()>4) newp->dumpTree(cout," _new: "); pushDeletep(oldp); oldp=NULL; } editDType(nodep); } virtual void visit(AstNodeDType* nodep, AstNUser*) { visitIterateNodeDType(nodep); } virtual void visit(AstNodeClassDType* nodep, AstNUser*) { visitIterateNodeDType(nodep); nodep->clearCache(); } void visitIterateNodeDType(AstNodeDType* nodep) { // Rather than use dtypeChg which may make new nodes, we simply edit in place, // as we don't need to preserve any widthMin's, and every dtype with the same width // gets an identical edit. if (nodep->user1SetOnce()) return; // Process once nodep->widthMinFromWidth(); // Too late to any unspecified sign to be anything but unsigned if (nodep->numeric().isNosign()) nodep->numeric(AstNumeric::UNSIGNED); nodep->iterateChildren(*this); nodep->virtRefDTypep(editOneDType(nodep->virtRefDTypep())); } virtual void visit(AstNodePreSel* nodep, AstNUser*) { // This check could go anywhere after V3Param nodep->v3fatalSrc("Presels should have been removed before this point"); } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); editDType(nodep); } public: // CONSTUCTORS WidthCommitVisitor(AstNetlist* nodep) { // Were changing widthMin's, so the table is now somewhat trashed nodep->typeTablep()->clearCache(); nodep->accept(*this); // Don't want to repairCache, as all needed nodes have been added back in // a repair would prevent dead nodes from being detected } virtual ~WidthCommitVisitor() {} }; //###################################################################### #endif // Guard verilator-3.874/src/V3Gate.h0000664000177100017500000000226112525171733015563 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity block domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3GATE_H_ #define _V3GATE_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Gate { public: static void gateAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Delayed.cpp0000664000177100017500000004637312525171733016621 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add temporaries, such as for delayed nodes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Delayed's Transformations: // // Each module: // Replace ASSIGNDLY var, exp // With ASSIGNDLY newvar, exp // At top of block: VAR newvar // At bottom of block: ASSIGNW var newvar // Need _x_dly = x at top of active if "x" is not always set // For now we'll say it's set if at top of block (not under IF, etc) // Need x = _x_dly at bottom of active if "x" is never referenced on LHS // in the active, and above rule applies too. (If so, use x on LHS, not _x_dly.) // // If a signal is set in multiple always blocks, we need a dly read & set with // multiple clock sensitivities. We have 3 options: // 1. When detected, make a new ACTIVE and move earlier created delayed assignment there // 2. Form unique ACTIVE for every multiple clocked assignment // 3. Predetect signals from multiple always blocks and do #2 on them // Since all 3 require a top activation cleanup, we do #2 which is easiest. // // ASSIGNDLY (BITSEL(ARRAYSEL (VARREF(v), bits), selbits), rhs) // -> VAR __Vdlyvset_x // VAR __Vdlyvval_x // VAR __Vdlyvdim_x // VAR __Vdlyvlsb_x // ASSIGNW (__Vdlyvset_x,0) // ... // ASSIGNW (VARREF(__Vdlyvval_x), rhs) // ASSIGNW (__Vdlyvdim_x, dimension_number) // ASSIGNW (__Vdlyvset_x, 1) // ... // ASSIGNW (BITSEL(ARRAYSEL(VARREF(x), __Vdlyvdim_x), __Vdlyvlsb_x), __Vdlyvval_x) // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3Delayed.h" #include "V3Ast.h" #include "V3Stats.h" //###################################################################### // Delayed state, as a visitor of each AstNode class DelayedVisitor : public AstNVisitor { private: // NODE STATE // Cleared each module: // AstVarScope::user1p() -> AstVarScope*. Points to temp var created. // AstVarScope::user2p() -> AstActive*. Points to activity block of signal (valid when AstVarScope::user1p is valid) // AstVarScope::user4p() -> AstAlwaysPost*. Post block for this variable // AstVarScope::user5() -> VarUsage. Tracks delayed vs non-delayed usage // AstVar::user2() -> bool. Set true if already made warning // AstVar::user4() -> int. Vector number, for assignment creation // AstVarRef::user2() -> bool. Set true if already processed // AstAlwaysPost::user2() -> ActActive*. Points to activity block of signal (valid when AstAlwaysPost::user4p is valid) // AstAlwaysPost::user4() -> AstIf*. Last IF (__Vdlyvset__) created under this AlwaysPost // Cleared each scope/active: // AstAssignDly::user3() -> AstVarScope*. __Vdlyvset__ created for this assign // AstAlwaysPost::user3() -> AstVarScope*. __Vdlyvset__ last referenced in IF AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; AstUser4InUse m_inuser4; AstUser5InUse m_inuser5; enum VarUsage { VU_NONE=0, VU_DLY=1, VU_NONDLY=2 }; // STATE AstActive* m_activep; // Current activate AstCFunc* m_cfuncp; // Current public C Function AstAssignDly* m_nextDlyp; // Next delayed assignment in a list of assignments bool m_inDly; // True in delayed assignments bool m_inLoop; // True in for loops bool m_inInitial; // True in intial blocks typedef std::map,AstVar*> VarMap; VarMap m_modVarMap; // Table of new var names created under module V3Double0 m_statSharedSet;// Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void markVarUsage(AstVarScope* nodep, uint32_t flags) { //UINFO(4," MVU "<user5( nodep->user5() | flags ); if ((nodep->user5() & VU_DLY) && (nodep->user5() & VU_NONDLY)) { nodep->v3warn(BLKANDNBLK,"Unsupported: Blocked and non-blocking assignments to same variable: "<varp()->prettyName()); } } AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/, AstNodeDType* newdtypep) { // Because we've already scoped it, we may need to add both the AstVar and the AstVarScope if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped"); AstVar* varp; AstNodeModule* addmodp = oldvarscp->scopep()->modp(); // We need a new AstVar, but only one for all scopes, to match the new AstVarScope VarMap::iterator it = m_modVarMap.find(make_pair(addmodp,name)); if (it != m_modVarMap.end()) { // Created module's AstVar earlier under some other scope varp = it->second; } else { if (newdtypep) { varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, newdtypep); } else if (width==0) { varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp()); varp->dtypeFrom(oldvarscp); } else { // Used for vset and dimensions, so can zero init varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, VFlagBitPacked(), width); } addmodp->addStmtp(varp); m_modVarMap.insert(make_pair(make_pair(addmodp, name), varp)); } AstVarScope* varscp = new AstVarScope (oldvarscp->fileline(), oldvarscp->scopep(), varp); oldvarscp->scopep()->addVarp(varscp); return varscp; } AstActive* createActivePost(AstVarRef* varrefp) { AstActive* newactp = new AstActive (varrefp->fileline(), "sequentdly", m_activep->sensesp()); m_activep->addNext(newactp); return newactp; } void checkActivePost(AstVarRef* varrefp, AstActive* oldactivep) { // Check for MULTIDRIVEN, and if so make new sentree that joins old & new sentree if (!oldactivep) varrefp->v3fatalSrc("<= old dly assignment not put under sensitivity block"); if (oldactivep->sensesp() != m_activep->sensesp()) { if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN) && !varrefp->varp()->user2()) { varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks: "<varp()->prettyName()<warnMore()<<"... Location of first driving block"<warnMore()<<"... Location of other driving block"); varrefp->varp()->user2(true); } UINFO(4,"AssignDupDlyVar: "<sensesp()->sensesp()->cloneTree(true); AstNodeSenItem* senb = oldactivep->sensesp()->sensesp()->cloneTree(true); AstSenTree* treep = new AstSenTree(m_activep->fileline(), sena); if (senb) treep->addSensesp(senb); if (AstSenTree* storep = oldactivep->sensesStorep()) { storep->unlinkFrBack(); pushDeletep(storep); } oldactivep->sensesStorep(treep); oldactivep->sensesp(treep); } } AstNode* createDlyArray(AstAssignDly* nodep, AstNode* lhsp) { // Create delayed assignment // See top of this file for transformation // Return the new LHS for the assignment, Null = unlink // Find selects AstNode* newlhsp = NULL; // NULL = unlink old assign AstSel* bitselp = NULL; AstArraySel* arrayselp = NULL; if (lhsp->castSel()) { bitselp = lhsp->castSel(); arrayselp = bitselp->fromp()->castArraySel(); } else { arrayselp = lhsp->castArraySel(); } if (!arrayselp) nodep->v3fatalSrc("No arraysel under bitsel?"); if (arrayselp->length()!=1) nodep->v3fatalSrc("ArraySel with length!=1 should have been removed in V3Slice"); UINFO(4,"AssignDlyArray: "< dimvalp; // Assignment value for each dimension of assignment AstNode* dimselp=arrayselp; for (; dimselp->castArraySel(); dimselp=dimselp->castArraySel()->fromp()) { AstNode* valp = dimselp->castArraySel()->bitp()->unlinkFrBack(); dimvalp.push_front(valp); } AstVarRef* varrefp = dimselp->castVarRef(); if (!varrefp) nodep->v3fatalSrc("No var underneath arraysels\n"); if (!varrefp->varScopep()) varrefp->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n"); varrefp->unlinkFrBack(); AstVar* oldvarp = varrefp->varp(); int modVecNum = oldvarp->user4(); oldvarp->user4(modVecNum+1); // deque dimreadps; // Read value for each dimension of assignment for (unsigned dimension=0; dimensioncastConst()) { // bit = const, can just use it dimreadps.push_front(dimp); } else { string bitvarname = (string("__Vdlyvdim")+cvtToStr(dimension) +"__"+oldvarp->shortName()+"__v"+cvtToStr(modVecNum)); AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, dimp->width(), NULL); AstAssign* bitassignp = new AstAssign (nodep->fileline(), new AstVarRef(nodep->fileline(), bitvscp, true), dimp); nodep->addNextHere(bitassignp); dimreadps.push_front(new AstVarRef(nodep->fileline(), bitvscp, false)); } } // //=== Bitselect: __Vdlyvlsb__ AstNode* bitreadp=NULL; // Code to read Vdlyvlsb if (bitselp) { AstNode* lsbvaluep = bitselp->lsbp()->unlinkFrBack(); if (bitselp->fromp()->castConst()) {// vlsb = constant, can just push constant into where we use it bitreadp = lsbvaluep; } else { string bitvarname = (string("__Vdlyvlsb__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum)); AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, lsbvaluep->width(), NULL); AstAssign* bitassignp = new AstAssign (nodep->fileline(), new AstVarRef(nodep->fileline(), bitvscp, true), lsbvaluep); nodep->addNextHere(bitassignp); bitreadp = new AstVarRef(nodep->fileline(), bitvscp, false); } } // //=== Value: __Vdlyvval__ AstNode* valreadp; // Code to read Vdlyvval if (nodep->rhsp()->castConst()) { // vval = constant, can just push constant into where we use it valreadp = nodep->rhsp()->unlinkFrBack(); } else { string valvarname = (string("__Vdlyvval__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum)); AstVarScope* valvscp = createVarSc(varrefp->varScopep(), valvarname, 0, nodep->rhsp()->dtypep()); newlhsp = new AstVarRef(nodep->fileline(), valvscp, true); valreadp = new AstVarRef(nodep->fileline(), valvscp, false); } // //=== Setting/not setting boolean: __Vdlyvset__ AstVarScope* setvscp; AstAssignPre* setinitp = NULL; if (nodep->user3p()) { // Simplistic optimization. If the previous statement in same scope was also a =>, // then we told this nodep->user3 we can use its Vdlyvset rather than making a new one. // This is good for code like: // for (i=0; i<5; i++) vector[i] <= something; setvscp = nodep->user3p()->castNode()->castVarScope(); ++m_statSharedSet; } else { // Create new one string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum)); setvscp = createVarSc(varrefp->varScopep(), setvarname, 1, NULL); setinitp = new AstAssignPre (nodep->fileline(), new AstVarRef(nodep->fileline(), setvscp, true), new AstConst(nodep->fileline(), 0)); AstAssign* setassignp = new AstAssign (nodep->fileline(), new AstVarRef(nodep->fileline(), setvscp, true), new AstConst(nodep->fileline(), V3Number(nodep->fileline(),1,true))); nodep->addNextHere(setassignp); } if (m_nextDlyp) { // Tell next assigndly it can share the variable m_nextDlyp->user3p(setvscp); } // // Create ALWAYSPOST for delayed variable // We add all logic to the same block if it's for the same memory // This insures that multiple assignments to the same memory will result // in correctly ordered code - the last assignment must be last. // It also has the nice side effect of assisting cache locality. AstNode* selectsp = varrefp; for (int dimension=int(dimreadps.size())-1; dimension>=0; --dimension) { selectsp = new AstArraySel(nodep->fileline(), selectsp, dimreadps[dimension]); } if (bitselp) { selectsp = new AstSel(nodep->fileline(), selectsp, bitreadp, bitselp->widthp()->cloneTree(false)); } // Build "IF (changeit) ... UINFO(9," For "<varScopep()->user4p()->castNode()->castAlwaysPost(); if (finalp) { AstActive* oldactivep = finalp->user2p()->castNode()->castActive(); checkActivePost(varrefp, oldactivep); if (setinitp) oldactivep->addStmtsp(setinitp); } else { // first time we've dealt with this memory finalp = new AstAlwaysPost(nodep->fileline(), NULL/*sens*/, NULL/*body*/); UINFO(9," Created "<addStmtsp(finalp); varrefp->varScopep()->user4p(finalp); finalp->user2p(newactp); if (setinitp) newactp->addStmtsp(setinitp); } AstIf* postLogicp; if (finalp->user3p()->castNode() == setvscp) { // Optimize as above; if sharing Vdlyvset *ON SAME VARIABLE*, // we can share the IF statement too postLogicp = finalp->user4p()->castNode()->castIf(); if (!postLogicp) nodep->v3fatalSrc("Delayed assignment misoptimized; prev var found w/o associated IF"); } else { postLogicp = new AstIf (nodep->fileline(), new AstVarRef(nodep->fileline(), setvscp, false), NULL, NULL); UINFO(9," Created "<addBodysp(postLogicp); finalp->user3p(setvscp); // Remember IF's vset variable finalp->user4p(postLogicp); // and the associated IF, as we may be able to reuse it } postLogicp->addIfsp(new AstAssign(nodep->fileline(), selectsp, valreadp)); return newlhsp; } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { //VV***** We reset all userp() on the netlist m_modVarMap.clear(); nodep->iterateChildren(*this); } virtual void visit(AstScope* nodep, AstNUser*) { UINFO(4," MOD "<iterateChildren(*this); } virtual void visit(AstCFunc* nodep, AstNUser*) { m_cfuncp = nodep; nodep->iterateChildren(*this); m_cfuncp = NULL; } virtual void visit(AstActive* nodep, AstNUser*) { m_activep = nodep; bool oldinit = m_inInitial; m_inInitial = nodep->hasInitial(); AstNode::user3ClearTree(); // Two sets to same variable in different actives must use different vars. nodep->iterateChildren(*this); m_inInitial = oldinit; } virtual void visit(AstAssignDly* nodep, AstNUser*) { m_inDly = true; m_nextDlyp = nodep->nextp()->castAssignDly(); // Next assignment in same block, maybe NULL. if (m_cfuncp) nodep->v3error("Unsupported: Delayed assignment inside public function/task"); if (nodep->lhsp()->castArraySel() || (nodep->lhsp()->castSel() && nodep->lhsp()->castSel()->fromp()->castArraySel())) { AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* newlhsp = createDlyArray(nodep, lhsp); if (m_inLoop) nodep->v3warn(E_BLKLOOPINIT,"Unsupported: Delayed assignment to array inside for loops (non-delayed is ok - see docs)"); if (newlhsp) { nodep->lhsp(newlhsp); } else { nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } lhsp->deleteTree(); lhsp=NULL; } else { nodep->iterateChildren(*this); } m_inDly = false; m_nextDlyp = NULL; } virtual void visit(AstVarRef* nodep, AstNUser*) { if (!nodep->user2Inc()) { // Not done yet if (m_inDly && nodep->lvalue()) { UINFO(4,"AssignDlyVar: "<varScopep(), VU_DLY); if (!m_activep) nodep->v3fatalSrc("<= not under sensitivity block"); if (!m_activep->hasClocked()) nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should have converted in V3Active"); AstVarScope* oldvscp = nodep->varScopep(); if (!oldvscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n"); AstVarScope* dlyvscp = oldvscp->user1p()->castNode()->castVarScope(); if (dlyvscp) { // Multiple use of delayed variable AstActive* oldactivep = dlyvscp->user2p()->castNode()->castActive(); checkActivePost(nodep, oldactivep); } if (!dlyvscp) { // First use of this delayed variable string newvarname = (string("__Vdly__")+nodep->varp()->shortName()); dlyvscp = createVarSc(oldvscp, newvarname, 0, NULL); AstNodeAssign* prep = new AstAssignPre (nodep->fileline(), new AstVarRef(nodep->fileline(), dlyvscp, true), new AstVarRef(nodep->fileline(), oldvscp, false)); AstNodeAssign* postp = new AstAssignPost (nodep->fileline(), new AstVarRef(nodep->fileline(), oldvscp, true), new AstVarRef(nodep->fileline(), dlyvscp, false)); postp->lhsp()->user2(true); // Don't detect this assignment oldvscp->user1p(dlyvscp); // So we can find it later // Make new ACTIVE with identical sensitivity tree AstActive* newactp = createActivePost(nodep); dlyvscp->user2p(newactp); newactp->addStmtsp(prep); // Add to FRONT of statements newactp->addStmtsp(postp); } AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, true); newrefp->user2(true); // No reason to do it again nodep->replaceWith(newrefp); nodep->deleteTree(); nodep=NULL; } else if (!m_inDly && nodep->lvalue()) { //UINFO(9,"NBA "<varScopep(), VU_NONDLY); } } } } virtual void visit(AstNodeFor* nodep, AstNUser*) { nodep->v3fatalSrc("For statements should have been converted to while statements in V3Begin\n"); } virtual void visit(AstWhile* nodep, AstNUser*) { bool oldloop = m_inLoop; m_inLoop = true; nodep->iterateChildren(*this); m_inLoop = oldloop; } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS DelayedVisitor(AstNetlist* nodep) { m_inDly = false; m_activep=NULL; m_cfuncp=NULL; m_nextDlyp=NULL; m_inLoop = false; m_inInitial = false; nodep->accept(*this); } virtual ~DelayedVisitor() { V3Stats::addStat("Optimizations, Delayed shared-sets", m_statSharedSet); } }; //###################################################################### // Delayed class functions void V3Delayed::delayedAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3EmitCSyms.cpp0000664000177100017500000005537312525172036017124 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Emit C++ for tree // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include #include #include "V3Global.h" #include "V3EmitC.h" #include "V3EmitCBase.h" #include "V3LanguageWords.h" //###################################################################### // Symbol table emitting class EmitCSyms : EmitCBaseVisitor { // NODE STATE // Cleared on Netlist // AstNodeModule::user1() -> bool. Set true __Vconfigure called AstUser1InUse m_inuser1; // TYPES struct ScopeNameData { string m_symName; string m_prettyName; ScopeNameData(const string& symName, const string& prettyName) : m_symName(symName), m_prettyName(prettyName) {} }; struct ScopeFuncData { AstScopeName* m_scopep; AstCFunc* m_funcp; AstNodeModule* m_modp; ScopeFuncData(AstScopeName* scopep, AstCFunc* funcp, AstNodeModule* modp) : m_scopep(scopep), m_funcp(funcp), m_modp(modp) {} }; struct ScopeVarData { string m_scopeName; string m_varBasePretty; AstVar* m_varp; AstNodeModule* m_modp; AstScope* m_scopep; ScopeVarData(const string& scopeName, const string& varBasePretty, AstVar* varp, AstNodeModule* modp, AstScope* scopep) : m_scopeName(scopeName), m_varBasePretty(varBasePretty), m_varp(varp), m_modp(modp), m_scopep(scopep) {} }; typedef map ScopeFuncs; typedef map ScopeVars; typedef map ScopeNames; typedef pair ScopeModPair; typedef pair ModVarPair; struct CmpName { inline bool operator () (const ScopeModPair& lhsp, const ScopeModPair& rhsp) const { return lhsp.first->name() < rhsp.first->name(); } }; struct CmpDpi { inline bool operator () (const AstCFunc* lhsp, const AstCFunc* rhsp) const { if (lhsp->dpiImport() != rhsp->dpiImport()) { // cppcheck-suppress comparisonOfFuncReturningBoolError return lhsp->dpiImport() < rhsp->dpiImport(); } return lhsp->name() < rhsp->name(); } }; // STATE AstCFunc* m_funcp; // Current function AstNodeModule* m_modp; // Current module vector m_scopes; // Every scope by module vector m_dpis; // DPI functions vector m_modVars; // Each public {mod,var} ScopeNames m_scopeNames; // Each unique AstScopeName ScopeFuncs m_scopeFuncs; // Each {scope,dpi-export-func} ScopeVars m_scopeVars; // Each {scope,public-var} V3LanguageWords m_words; // Reserved word detector int m_coverBins; // Coverage bin number int m_labelNum; // Next label number // METHODS void emitSymHdr(); void emitSymImp(); void emitDpiHdr(); void emitDpiImp(); void nameCheck(AstNode* nodep) { // Prevent GCC compile time error; name check all things that reach C++ code if (nodep->name() != "") { string rsvd = m_words.isKeyword(nodep->name()); if (rsvd != "") { // Generally V3Name should find all of these and throw SYMRSVDWORD. // We'll still check here because the compiler errors resulting if we miss this warning are SO nasty nodep->v3error("Symbol matching "+rsvd+" reserved word reached emitter, should have hit SYMRSVDWORD: '"<prettyName()<<"'"); } } } void varsExpand() { // We didn'e have all m_scopes loaded when we encountered variables, so expand them now // It would be less code if each module inserted its own variables. // Someday. For now public isn't common. for (vector::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) { AstScope* scopep = it->first; AstNodeModule* smodp = it->second; for (vector::iterator it = m_modVars.begin(); it != m_modVars.end(); ++it) { AstNodeModule* modp = it->first; AstVar* varp = it->second; if (modp == smodp) { // Need to split the module + var name into the original-ish full scope and variable name under that scope. // The module instance name is included later, when we know the scopes this module is under string whole = scopep->name()+"__DOT__"+varp->name(); string scpName; string varBase; if (whole.substr(0,10) == "__DOT__TOP") whole.replace(0,10,""); string::size_type pos = whole.rfind("__DOT__"); if (pos != string::npos) { scpName = whole.substr(0,pos); varBase = whole.substr(pos+strlen("__DOT__")); } else { varBase = whole; } //UINFO(9,"For "<name()<<" - "<name()<<" Scp "<name(), ScopeVarData(scpSym, varBasePretty, varp, modp, scopep))); } } } } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { // Collect list of scopes nodep->iterateChildren(*this); varsExpand(); // Sort by names, so line/process order matters less stable_sort(m_scopes.begin(), m_scopes.end(), CmpName()); stable_sort(m_dpis.begin(), m_dpis.end(), CmpDpi()); // Output emitSymHdr(); emitSymImp(); if (v3Global.dpi()) { emitDpiHdr(); emitDpiImp(); } } virtual void visit(AstNodeModule* nodep, AstNUser*) { nameCheck(nodep); m_modp = nodep; m_labelNum = 0; nodep->iterateChildren(*this); m_modp = NULL; } virtual void visit(AstScope* nodep, AstNUser*) { nameCheck(nodep); m_scopes.push_back(make_pair(nodep, m_modp)); } virtual void visit(AstScopeName* nodep, AstNUser*) { string name = nodep->scopeSymName(); //UINFO(9,"scnameins sp "<name()<<" sp "<scopePrettyName()<<" ss "<scopePrettyName()))); } if (nodep->dpiExport()) { if (!m_funcp) nodep->v3fatalSrc("ScopeName not under DPI function"); m_scopeFuncs.insert(make_pair(name + " " + m_funcp->name(), ScopeFuncData(nodep, m_funcp, m_modp))); } } virtual void visit(AstVar* nodep, AstNUser*) { nameCheck(nodep); nodep->iterateChildren(*this); if (nodep->isSigUserRdPublic() && !nodep->isParam()) { // The VPI functions require a pointer to allow modification, but parameters are constants m_modVars.push_back(make_pair(m_modp, nodep)); } } virtual void visit(AstCoverDecl* nodep, AstNUser*) { // Assign numbers to all bins, so we know how big of an array to use if (!nodep->dataDeclNullp()) { // else duplicate we don't need code for nodep->binNum(m_coverBins++); } } virtual void visit(AstJumpLabel* nodep, AstNUser*) { nodep->labelNum(++m_labelNum); nodep->iterateChildren(*this); } virtual void visit(AstCFunc* nodep, AstNUser*) { nameCheck(nodep); if (nodep->dpiImport() || nodep->dpiExportWrapper()) { m_dpis.push_back(nodep); } m_funcp = nodep; nodep->iterateChildren(*this); m_funcp = NULL; } // NOPs virtual void visit(AstConst*, AstNUser*) {} // Default virtual void visit(AstNode* nodep, AstNUser*) { nameCheck(nodep); nodep->iterateChildren(*this); } //--------------------------------------- // ACCESSORS public: EmitCSyms(AstNetlist* nodep) { m_funcp = NULL; m_modp = NULL; m_coverBins = 0; m_labelNum = 0; nodep->accept(*this); } }; void EmitCSyms::emitSymHdr() { UINFO(6,__FUNCTION__<<": "<putsHeader(); puts("// DESCR" "IPTION: Verilator output: Symbol table internal header\n"); puts("//\n"); puts("// Internal details; most calling programs do not need this header\n"); puts("\n"); puts("#ifndef _"+symClassName()+"_H_\n"); puts("#define _"+symClassName()+"_H_\n"); puts("\n"); if (optSystemPerl()) puts("#include \"systemperl.h\"\n"); else if (optSystemC()) puts("#include \"systemc.h\"\n"); if (optSystemPerl() || optSystemC()) { puts("#include \"verilated_sc.h\"\n"); } if (v3Global.needHeavy()) { puts("#include \"verilated_heavy.h\"\n"); } else { puts("#include \"verilated.h\"\n"); } // for puts("\n// INCLUDE MODULE CLASSES\n"); for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) { puts("#include \""+modClassName(nodep)+".h\"\n"); } if (v3Global.dpi()) { puts ("\n// DPI TYPES for DPI Export callbacks (Internal use)\n"); map types; // Remove duplicates and sort for (ScopeFuncs::iterator it = m_scopeFuncs.begin(); it != m_scopeFuncs.end(); ++it) { AstCFunc* funcp = it->second.m_funcp; if (funcp->dpiExport()) { string cbtype = v3Global.opt.prefix()+"__Vcb_"+funcp->cname()+"_t"; types["typedef void (*"+cbtype+") ("+cFuncArgs(funcp)+");\n"] = 1; } } for (map::iterator it = types.begin(); it != types.end(); ++it) { puts(it->first); } } puts("\n// SYMS CLASS\n"); puts((string)"class "+symClassName()+" : public VerilatedSyms {\n"); ofp()->putsPrivate(false); // public: puts("\n// LOCAL STATE\n"); ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t)); puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert. ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool)); puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n"); ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool)); puts("bool\t__Vm_didInit;\n"); ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t)); puts("\n// SUBCELL STATE\n"); for (vector::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) { AstScope* scopep = it->first; AstNodeModule* modp = it->second; if (modp->isTop()) { ofp()->printf("%-30s ", (modClassName(modp)+"*").c_str()); puts(scopep->nameDotless()+"p;\n"); } else { ofp()->printf("%-30s ", (modClassName(modp)+"").c_str()); puts(scopep->nameDotless()+";\n"); } } puts("\n// COVERAGE\n"); if (m_coverBins) { ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint32_t)); puts("uint32_t\t__Vcoverage["); puts(cvtToStr(m_coverBins)); puts("];\n"); } puts("\n// SCOPE NAMES\n"); for (ScopeNames::iterator it = m_scopeNames.begin(); it != m_scopeNames.end(); ++it) { puts("VerilatedScope __Vscope_"+it->second.m_symName+";\n"); } puts("\n// CREATORS\n"); puts(symClassName()+"("+topClassName()+"* topp, const char* namep);\n"); puts((string)"~"+symClassName()+"() {};\n"); puts("\n// METHODS\n"); puts("inline const char* name() { return __Vm_namep; }\n"); puts("inline bool getClearActivity() { bool r=__Vm_activity; __Vm_activity=false; return r;}\n"); if (v3Global.opt.savable() ) { puts("void __Vserialize(VerilatedSerialize& os);\n"); puts("void __Vdeserialize(VerilatedDeserialize& os);\n"); } puts("\n"); puts("} VL_ATTR_ALIGNED(64);\n"); puts("\n"); puts("#endif /*guard*/\n"); } void EmitCSyms::emitSymImp() { UINFO(6,__FUNCTION__<<": "<support(true); V3OutCFile cf (filename); m_ofp = &cf; ofp()->putsHeader(); puts("// DESCR" "IPTION: Verilator output: Symbol table implementation internals\n"); puts("\n"); // Includes puts("#include \""+symClassName()+".h\"\n"); for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) { puts("#include \""+modClassName(nodep)+".h\"\n"); } //puts("\n// GLOBALS\n"); puts("\n// FUNCTIONS\n"); puts(symClassName()+"::"+symClassName()+"("+topClassName()+"* topp, const char* namep)\n"); puts("\t// Setup locals\n"); puts("\t: __Vm_namep(namep)\n"); // No leak, as we get destroyed when the top is destroyed puts("\t, __Vm_activity(false)\n"); puts("\t, __Vm_didInit(false)\n"); puts("\t// Setup submodule names\n"); char comma=','; for (vector::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) { AstScope* scopep = it->first; AstNodeModule* modp = it->second; if (modp->isTop()) { } else { string nameDl = scopep->nameDotless(); ofp()->printf("\t%c %-30s ", comma, nameDl.c_str()); puts("(Verilated::catName(topp->name(),"); // The "." is added by catName putsQuoted(scopep->prettyName()); puts("))\n"); comma=','; } } puts("{\n"); puts("// Pointer to top level\n"); puts("TOPp = topp;\n"); puts("// Setup each module's pointers to their submodules\n"); for (vector::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) { AstScope* scopep = it->first; AstNodeModule* modp = it->second; if (!modp->isTop()) { string arrow = scopep->name(); string::size_type pos; while ((pos=arrow.find(".")) != string::npos) { arrow.replace(pos, 1, "->"); } if (arrow.substr(0,5) == "TOP->") arrow.replace(0,5,"TOPp->"); ofp()->printf("%-30s ", arrow.c_str()); puts(" = &"); puts(scopep->nameDotless()+";\n"); } } puts("// Setup each module's pointer back to symbol table (for public functions)\n"); puts("TOPp->__Vconfigure(this, true);\n"); for (vector::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) { AstScope* scopep = it->first; AstNodeModule* modp = it->second; if (!modp->isTop()) { // first is used by AstCoverDecl's call to __vlCoverInsert bool first = !modp->user1(); modp->user1(true); puts(scopep->nameDotless()+".__Vconfigure(this, " +(first?"true":"false") +");\n"); } } puts("// Setup scope names\n"); for (ScopeNames::iterator it = m_scopeNames.begin(); it != m_scopeNames.end(); ++it) { puts("__Vscope_"+it->second.m_symName+".configure(this,name(),"); putsQuoted(it->second.m_prettyName); puts(");\n"); } if (v3Global.dpi()) { puts("// Setup export functions\n"); puts("for (int __Vfinal=0; __Vfinal<2; __Vfinal++) {\n"); for (ScopeFuncs::iterator it = m_scopeFuncs.begin(); it != m_scopeFuncs.end(); ++it) { AstScopeName* scopep = it->second.m_scopep; AstCFunc* funcp = it->second.m_funcp; AstNodeModule* modp = it->second.m_modp; if (funcp->dpiExport()) { puts("__Vscope_"+scopep->scopeSymName()+".exportInsert(__Vfinal,"); putsQuoted(funcp->cname()); puts(", (void*)(&"); puts(modClassName(modp)); puts("::"); puts(funcp->name()); puts("));\n"); } } // It would be less code if each module inserted its own variables. // Someday. For now public isn't common. for (ScopeVars::iterator it = m_scopeVars.begin(); it != m_scopeVars.end(); ++it) { AstNodeModule* modp = it->second.m_modp; AstScope* scopep = it->second.m_scopep; AstVar* varp = it->second.m_varp; // int pdim=0; int udim=0; string bounds; if (AstBasicDType* basicp = varp->basicp()) { // Range is always first, it's not in "C" order if (basicp->isRanged()) { bounds += " ,"; bounds += cvtToStr(basicp->msb()); bounds += ","; bounds += cvtToStr(basicp->lsb()); pdim++; } for (AstNodeDType* dtypep=varp->dtypep(); dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { bounds += " ,"; bounds += cvtToStr(adtypep->msb()); bounds += ","; bounds += cvtToStr(adtypep->lsb()); if (dtypep->castPackArrayDType()) pdim++; else udim++; dtypep = adtypep->subDTypep(); } else break; // AstBasicDType - nothing below, 1 } } // if (pdim>1 || udim>1) { puts("//UNSUP "); // VerilatedImp can't deal with >2d or packed arrays } puts("__Vscope_"+it->second.m_scopeName+".varInsert(__Vfinal,"); putsQuoted(it->second.m_varBasePretty); puts(", &("); if (modp->isTop()) { puts(scopep->nameDotless()); puts("p->"); } else { puts(scopep->nameDotless()); puts("."); } puts(varp->name()); puts("), "); puts(varp->vlEnumType()); // VLVT_UINT32 etc puts(","); puts(varp->vlEnumDir()); // VLVD_IN etc if (varp->isSigUserRWPublic()) puts("|VLVF_PUB_RW"); else if (varp->isSigUserRdPublic()) puts("|VLVF_PUB_RD"); puts(","); puts(cvtToStr(pdim+udim)); puts(bounds); puts(");\n"); } puts("}\n"); } puts("}\n"); if (v3Global.opt.savable() ) { puts("\n"); for (int de=0; de<2; ++de) { string classname = de ? "VerilatedDeserialize" : "VerilatedSerialize"; string funcname = de ? "__Vdeserialize" : "__Vserialize"; string op = de ? ">>" : "<<"; puts("void "+symClassName()+"::"+funcname+"("+classname+"& os) {\n"); puts( "// LOCAL STATE\n"); // __Vm_namep presumably already correct puts( "os"+op+"__Vm_activity;\n"); puts( "os"+op+"__Vm_didInit;\n"); puts( "// SUBCELL STATE\n"); for (vector::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) { AstScope* scopep = it->first; AstNodeModule* modp = it->second; if (!modp->isTop()) { puts( scopep->nameDotless()+"."+funcname+"(os);\n"); } } puts("}\n"); } } } //###################################################################### void EmitCSyms::emitDpiHdr() { UINFO(6,__FUNCTION__<<": "<support(true); V3OutCFile hf (filename); m_ofp = &hf; m_ofp->putsHeader(); puts("// DESCR" "IPTION: Verilator output: Prototypes for DPI import and export functions.\n"); puts("//\n"); puts("// Verilator includes this file in all generated .cpp files that use DPI functions.\n"); puts("// Manually include this file where DPI .c import functions are declared to insure\n"); puts("// the C functions match the expectations of the DPI imports.\n"); puts("\n"); puts("#include \"svdpi.h\"\n"); puts("\n"); puts("#ifdef __cplusplus\n"); puts("extern \"C\" {\n"); puts("#endif\n"); puts("\n"); int firstExp = 0; int firstImp = 0; for (vector::iterator it = m_dpis.begin(); it != m_dpis.end(); ++it) { AstCFunc* nodep = *it; if (nodep->dpiExportWrapper()) { if (!firstExp++) puts("\n// DPI EXPORTS\n"); puts("// DPI Export at "+nodep->fileline()->ascii()+"\n"); puts("extern "+nodep->rtnTypeVoid()+" "+nodep->name()+" ("+cFuncArgs(nodep)+");\n"); } else if (nodep->dpiImport()) { if (!firstImp++) puts("\n// DPI IMPORTS\n"); puts("// DPI Import at "+nodep->fileline()->ascii()+"\n"); puts("extern "+nodep->rtnTypeVoid()+" "+nodep->name()+" ("+cFuncArgs(nodep)+");\n"); } } puts("\n"); puts("#ifdef __cplusplus\n"); puts("}\n"); puts("#endif\n"); } //###################################################################### void EmitCSyms::emitDpiImp() { UINFO(6,__FUNCTION__<<": "<support(true); V3OutCFile hf (filename); m_ofp = &hf; m_ofp->putsHeader(); puts("// DESCR" "IPTION: Verilator output: Implementation of DPI export functions.\n"); puts("//\n"); puts("// Verilator compiles this file in when DPI functions are used.\n"); puts("// If you have multiple Verilated designs with the same DPI exported\n"); puts("// function names, you will get multiple definition link errors from here.\n"); puts("// This is an unfortunate result of the DPI specification.\n"); puts("// To solve this, either\n"); puts("// 1. Call "+topClassName()+"::{export_function} instead,\n"); puts("// and do not even bother to compile this file\n"); puts("// or 2. Compile all __Dpi.cpp files in the same compiler run,\n"); puts("// and #ifdefs already inserted here will sort everything out.\n"); puts("\n"); puts("#include \""+topClassName()+"__Dpi.h\"\n"); puts("#include \""+topClassName()+".h\"\n"); puts("\n"); for (vector::iterator it = m_dpis.begin(); it != m_dpis.end(); ++it) { AstCFunc* nodep = *it; if (nodep->dpiExportWrapper()) { puts("#ifndef _VL_DPIDECL_"+nodep->name()+"\n"); puts("#define _VL_DPIDECL_"+nodep->name()+"\n"); puts(nodep->rtnTypeVoid()+" "+nodep->name()+" ("+cFuncArgs(nodep)+") {\n"); puts("// DPI Export at "+nodep->fileline()->ascii()+"\n"); puts("return "+topClassName()+"::"+nodep->name()+"("); string args; for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) { if (AstVar* portp = stmtp->castVar()) { if (portp->isIO() && !portp->isFuncReturn()) { if (args != "") args+= ", "; args += portp->name(); } } } puts(args+");\n"); puts("}\n"); puts("#endif\n"); puts("\n"); } } } //###################################################################### // EmitC class functions void V3EmitC::emitcSyms() { UINFO(2,__FUNCTION__<<": "< class V3Lexer; // IMPORTANT: Don't include this file other than in the bison and flex, // as it's definitions will confuse other parsers //====================================================================== // Types (between parser & lexer) typedef enum { uniq_NONE, uniq_UNIQUE, uniq_UNIQUE0, uniq_PRIORITY } V3UniqState; typedef enum { iprop_NONE, iprop_CONTEXT, iprop_PURE } V3ImportProperty; //============================================================================ // We can't use bison's %union as we want to pass the fileline with all tokens struct V3ParseBisonYYSType { FileLine* fl; AstNode* scp; // Symbol table scope for future lookups union { V3Number* nump; string* strp; int cint; double cdouble; bool cbool; V3UniqState uniqstate; VSignedState signstate; V3ImportProperty iprop; V3ErrorCode::en errcodeen; AstNode* nodep; AstBasicDType* bdtypep; AstBegin* beginp; AstCase* casep; AstCaseItem* caseitemp; AstCell* cellp; AstConst* constp; AstMemberDType* memberp; AstNodeModule* modulep; AstNodeClassDType* classp; AstNodeDType* dtypep; AstNodeFTask* ftaskp; AstNodeFTaskRef* ftaskrefp; AstNodeSenItem* senitemp; AstNodeVarRef* varnodep; AstPackage* packagep; AstPackageRef* packagerefp; AstParseRef* parserefp; AstPatMember* patmemberp; AstPattern* patternp; AstPin* pinp; AstRange* rangep; AstSenTree* sentreep; AstVar* varp; AstVarRef* varrefp; }; }; #define YYSTYPE V3ParseBisonYYSType //###################################################################### class V3ParseImp { // MEMBERS AstNetlist* m_rootp; // Root of the design V3InFilter* m_filterp; // Reading filter V3ParseSym* m_symp; // Symbol table V3Lexer* m_lexerp; // Current FlexLexer static V3ParseImp* s_parsep; // Current THIS, bison() isn't class based FileLine* m_fileline; // Filename/linenumber currently active bool m_inCellDefine; // Inside a `celldefine bool m_inLibrary; // Currently reading a library vs. regular file int m_inBeginKwd; // Inside a `begin_keywords int m_lastVerilogState; // Last LEX state in `begin_keywords int m_prevLexToken; // previous parsed token (for lexer) bool m_ahead; // aheadToken is valid int m_aheadToken; // Token we read ahead V3ParseBisonYYSType m_aheadVal; // aheadToken's value deque m_stringps; // Created strings for later cleanup deque m_numberps; // Created numbers for later cleanup deque m_lintState; // Current lint state for save/restore deque m_ppBuffers; // Preprocessor->lex buffer of characters to process public: // Note these are an exception to using the filename as the debug type static int debugBison() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel("bison"); return level; } static int debugFlex() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel("flex"); return level; } static int debug() { return debugBison() ? debugFlex() : 0; } // Functions called by lex rules: int yylexThis(); static bool optFuture(const string& flag) { return v3Global.opt.isFuture(flag); } void ppline (const char* text); void linenoInc() { fileline()->linenoInc(); } void verilatorCmtLint(const char* text, bool on); void verilatorCmtLintSave(); void verilatorCmtLintRestore(); void verilatorCmtBad(const char* text); double parseDouble(const char* text, size_t length); void pushBeginKeywords(int state) { m_inBeginKwd++; m_lastVerilogState=state; } bool popBeginKeywords() { if (m_inBeginKwd) { m_inBeginKwd--; return true; } else return false; } int lastVerilogState() const { return m_lastVerilogState; } static const char* tokenName(int tok); void ppPushText(const string& text) { m_ppBuffers.push_back(text); } size_t ppInputToLex(char* buf, size_t max_size); static V3ParseImp* parsep() { return s_parsep; } // TODO: Many of these functions are the old interface; they'd be better as non-static // and called as READP->newString(...) etc. string* newString(const string& text) { // Allocate a string, remembering it so we can reclaim storage at lex end string* strp = new string (text); m_stringps.push_back(strp); return strp; } string* newString(const char* text) { // Allocate a string, remembering it so we can reclaim storage at lex end string* strp = new string (text); m_stringps.push_back(strp); return strp; } string* newString(const char* text, size_t length) { string* strp = new string (text, length); m_stringps.push_back(strp); return strp; } V3Number* newNumber(FileLine* fl, const char* text) { V3Number* nump = new V3Number (fl, text); m_numberps.push_back(nump); return nump; } // Return next token, for bison, since bison isn't class based, use a global THIS FileLine* fileline() const { return m_fileline; } AstNetlist* rootp() const { return m_rootp; } FileLine* copyOrSameFileLine() { return fileline()->copyOrSameFileLine(); } bool inCellDefine() const { return m_inCellDefine; } void inCellDefine(bool flag) { m_inCellDefine = flag; } bool inLibrary() const { return m_inLibrary; } // Interactions with parser int bisonParse(); // Interactions with lexer void lexNew(int debug); void lexDestroy(); void statePop(); // Parser -> lexer communication static int stateVerilogRecent(); // Parser -> lexer communication int prevLexToken() { return m_prevLexToken; } // Parser -> lexer communication size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf,max_size); } //==== Symbol tables V3ParseSym* symp() { return m_symp; } public: // CREATORS V3ParseImp(AstNetlist* rootp, V3InFilter* filterp, V3ParseSym* parserSymp) : m_rootp(rootp), m_filterp(filterp), m_symp(parserSymp) { m_fileline = NULL; m_lexerp = NULL; m_inCellDefine = false; m_inLibrary = false; m_inBeginKwd = 0; m_lastVerilogState = stateVerilogRecent(); m_prevLexToken = 0; m_ahead = false; m_aheadToken = 0; // m_aheadVal not used as m_ahead = false } ~V3ParseImp(); void parserClear(); void unputString(const char* textp, size_t length); // METHODS // Preprocess and read the Verilog file specified into the netlist database int lexToBison(); // Pass token to bison void parseFile(FileLine* fileline, const string& modfilename, bool inLibrary, const string& errmsg); private: void lexFile(const string& modname); int yylexReadTok(); int lexToken(); // Internal; called from lexToBison }; #endif // Guard verilator-3.874/src/V3Changed.cpp0000664000177100017500000002163512525171733016575 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add temporaries, such as for changed nodes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Changed's Transformations: // // Each module: // Each combo block // For each variable that comes from combo block and is generated AFTER a usage // Add __Vlast_{var} to local section, init to current value (just use array?) // Change = if any var != last. // If a signal is used as a clock in this module or any // module *below*, and it isn't a input to this module, // we need to indicate a new clock has been created. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Ast.h" #include "V3Changed.h" #include "V3EmitCBase.h" //###################################################################### class ChangedState { public: // STATE AstNodeModule* m_topModp; // Top module AstScope* m_scopetopp; // Scope under TOPSCOPE AstCFunc* m_chgFuncp; // Change function we're building ChangedState() { m_topModp = NULL; m_chgFuncp = NULL; m_scopetopp = NULL; } ~ChangedState() {} }; //###################################################################### // Utility visitor to find elements to be compared class ChangedInsertVisitor : public AstNVisitor { private: // STATE ChangedState* m_statep; // Shared state across visitors AstVarScope* m_vscp; // Original (non-change) variable we're change-detecting AstVarScope* m_newvscp; // New (change detect) variable we're change-detecting AstNode* m_varEqnp; // Original var's equation to get var value AstNode* m_newLvEqnp; // New var's equation to read value AstNode* m_newRvEqnp; // New var's equation to set value uint32_t m_detects; // # detects created // CONSTANTS enum MiscConsts { DETECTARRAY_MAX_INDEXES = 256 // How many indexes before error // Ok to increase this, but may result in much slower model }; void newChangeDet() { if (++m_detects > DETECTARRAY_MAX_INDEXES) { m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect more than "<prettyName()<warnMore() <<"... Could recompile with DETECTARRAY_MAX_INDEXES increased"<fileline(), m_varEqnp->cloneTree(true), m_newRvEqnp->cloneTree(true), false); m_statep->m_chgFuncp->addStmtsp(changep); AstAssign* initp = new AstAssign (m_vscp->fileline(), m_newLvEqnp->cloneTree(true), m_varEqnp->cloneTree(true)); m_statep->m_chgFuncp->addFinalsp(initp); } virtual void visit(AstBasicDType* nodep, AstNUser*) { newChangeDet(); } virtual void visit(AstPackArrayDType* nodep, AstNUser*) { newChangeDet(); } virtual void visit(AstUnpackArrayDType* nodep, AstNUser*) { for (int index=0; index < nodep->elementsConst(); ++index) { AstNode* origVEp = m_varEqnp; AstNode* origNLEp = m_newLvEqnp; AstNode* origNREp = m_newRvEqnp; m_varEqnp = new AstArraySel(nodep->fileline(), m_varEqnp->cloneTree(true), index); m_newLvEqnp = new AstArraySel(nodep->fileline(), m_newLvEqnp->cloneTree(true), index); m_newRvEqnp = new AstArraySel(nodep->fileline(), m_newRvEqnp->cloneTree(true), index); nodep->subDTypep()->skipRefp()->accept(*this); m_varEqnp->deleteTree(); m_newLvEqnp->deleteTree(); m_newRvEqnp->deleteTree(); m_varEqnp = origVEp; m_newLvEqnp = origNLEp; m_newRvEqnp = origNREp; } } virtual void visit(AstNodeClassDType* nodep, AstNUser*) { if (nodep->packedUnsup()) { newChangeDet(); } else { if (debug()) nodep->dumpTree(cout,"-DETECTARRAY-class-"); m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<varp()->prettyName()); } } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); if (debug()) nodep->dumpTree(cout,"-DETECTARRAY-general-"); m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<varp()->prettyName()); } public: // CONSTUCTORS ChangedInsertVisitor(AstVarScope* vscp, ChangedState* statep) { m_statep = statep; m_vscp = vscp; m_detects = 0; { AstVar* varp = m_vscp->varp(); string newvarname = "__Vchglast__"+m_vscp->scopep()->nameDotless()+"__"+varp->shortName(); // Create: VARREF(_last) // ASSIGN(VARREF(_last), VARREF(var)) // ... // CHANGEDET(VARREF(_last), VARREF(var)) AstVar* newvarp = new AstVar (varp->fileline(), AstVarType::MODULETEMP, newvarname, varp); m_statep->m_topModp->addStmtp(newvarp); m_newvscp = new AstVarScope(m_vscp->fileline(), m_statep->m_scopetopp, newvarp); m_statep->m_scopetopp->addVarp(m_newvscp); m_varEqnp = new AstVarRef(m_vscp->fileline(), m_vscp, false); m_newLvEqnp = new AstVarRef(m_vscp->fileline(), m_newvscp, true); m_newRvEqnp = new AstVarRef(m_vscp->fileline(), m_newvscp, false); } vscp->dtypep()->skipRefp()->accept(*this); m_varEqnp->deleteTree(); m_newLvEqnp->deleteTree(); m_newRvEqnp->deleteTree(); } virtual ~ChangedInsertVisitor() {} }; //###################################################################### // Changed state, as a visitor of each AstNode class ChangedVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstVarScope::user1() -> bool. True indicates processed AstUser1InUse m_inuser1; // STATE ChangedState* m_statep; // Shared state across visitors // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void genChangeDet(AstVarScope* vscp) { vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<isTop()) { m_statep->m_topModp = nodep; } nodep->iterateChildren(*this); } virtual void visit(AstTopScope* nodep, AstNUser*) { UINFO(4," TS "<scopep(); if (!scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?\n"); m_statep->m_scopetopp = scopep; // Create change detection function m_statep->m_chgFuncp = new AstCFunc(nodep->fileline(), "_change_request", scopep, "QData"); m_statep->m_chgFuncp->argTypes(EmitCBaseVisitor::symClassVar()); m_statep->m_chgFuncp->symProlog(true); m_statep->m_chgFuncp->declPrivate(true); m_statep->m_scopetopp->addActivep(m_statep->m_chgFuncp); // We need at least one change detect so we know to emit the correct code m_statep->m_chgFuncp->addStmtsp(new AstChangeDet(nodep->fileline(), NULL, NULL, false)); // nodep->iterateChildren(*this); } virtual void visit(AstVarScope* nodep, AstNUser*) { if (nodep->isCircular()) { UINFO(8," CIRC "<user1SetOnce()) { genChangeDet(nodep); } } } virtual void visit(AstNodeMath* nodep, AstNUser*) { // Short-circuit } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ChangedVisitor(AstNetlist* nodep, ChangedState* statep) { m_statep = statep; nodep->accept(*this); } virtual ~ChangedVisitor() {} }; //###################################################################### // Changed class functions void V3Changed::changedAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3PreLex.l0000664000177100017500000005216012525172076016112 0ustar wsnyderwsnyder%option noyywrap align interactive %option stack %option noc++ %option prefix="V3PreLex" %{ /************************************************************************** * DESCRIPTION: Verilator: Flex verilog preprocessor * * Code available from: http://www.veripool.org/verilator * ************************************************************************** * * Copyright 2003-2015 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. * * Verilator is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * ************************************************************************** * Do not use Flex in C++ mode. It has bugs with yyunput() which result in * lost characters. **************************************************************************/ #include "V3PreProc.h" #include "V3PreLex.h" V3PreLex* V3PreLex::s_currentLexp = NULL; // Current lexing point #define LEXP V3PreLex::s_currentLexp #define YY_INPUT(buf,result,max_size) \ result = LEXP->inputToLex(buf,max_size); // Accessors, because flex keeps changing the type of yyleng char* yyourtext() { return yytext; } size_t yyourleng() { return yyleng; } void yyourtext(const char* textp, size_t size) { yytext=(char*)textp; yyleng=size; } // Prevent conflicts from perl version static void linenoInc() {LEXP->linenoInc();} static bool pedantic() { return LEXP->m_pedantic; } static void yyerror(char* msg) { LEXP->curFilelinep()->v3error(msg); } static void yyerrorf(const char* msg) { LEXP->curFilelinep()->v3error(msg); } static void appendDefValue(const char* t, size_t l) { LEXP->appendDefValue(t,l); } /**********************************************************************/ %} %x CMTONEM %x CMTBEGM %x CMTMODE %x STRMODE %x DEFFPAR %x DEFFORM %x DEFVAL %x DEFCMT %x STRIFY %x ARGMODE %x INCMODE %x PRTMODE /* drop: Drop Ctrl-Z - can't pass thru or may EOF the output too soon */ ws [ \t\f\r] wsn [ \t\f] crnl [\r]*[\n] quote [\"] tickquote [`][\"] backslash [\\] /* Where we use symb/symbdef, we must also look for a `` join */ /* Note in the preprocessor \ESCaped is *not* always special; mantis1537/bug441 */ symb ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n]+) symbdef ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n`]+) word [a-zA-Z0-9_]+ drop [\032] /**************************************************************/ %% ^{ws}*"`line"{ws}+.*{crnl} { LEXP->lineDirective(yytext); return(VP_LINE); } /* Special directives we recognize */ "`define" { return(VP_DEFINE); } "`else" { return(VP_ELSE); } "`elsif" { return(VP_ELSIF); } "`endif" { return(VP_ENDIF); } "`ifdef" { return(VP_IFDEF); } "`ifndef" { return(VP_IFNDEF); } "`include" { return(VP_INCLUDE); } "`undef" { return(VP_UNDEF); } "`undefineall" { return(VP_UNDEFINEALL); } "`error" { if (!pedantic()) return (VP_ERROR); else return(VP_DEFREF); } "`__FILE__" { static string rtnfile; rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename(); rtnfile += '"'; yytext=(char*)rtnfile.c_str(); yyleng = rtnfile.length(); return (VP_STRING); } "`__LINE__" { static char buf[10]; sprintf(buf, "%d",LEXP->curFilelinep()->lineno()); yytext = buf; yyleng = strlen(yytext); return (VP_TEXT); } /* Pass-through strings */ {quote} { yy_push_state(STRMODE); yymore(); } <> { linenoInc(); yyerrorf("EOF in unterminated string"); yyleng=0; yyterminate(); } {crnl} { linenoInc(); yyerrorf("Unterminated string"); BEGIN(INITIAL); } {word} { yymore(); } [^\"\\] { yymore(); } {backslash}{crnl} { linenoInc(); yymore(); } {backslash}. { yymore(); } {quote} { yy_pop_state(); if (LEXP->m_parenLevel || LEXP->m_defQuote) { LEXP->m_defQuote=false; appendDefValue(yytext,yyleng); yyleng=0; } else return (VP_STRING); } /* Stringification */ {tickquote} { yy_push_state(STRIFY); return VP_STRIFY; } <> { linenoInc(); yyerrorf("EOF in unterminated '\""); yyleng=0; yyterminate(); } "`\\`\"" { return VP_BACKQUOTE; } {quote} { yy_push_state(STRMODE); yymore(); } {tickquote} { yy_pop_state(); return VP_STRIFY; } {symbdef} { return (VP_SYMBOL); } {symbdef}`` { yyleng-=2; return (VP_SYMBOL_JOIN); } "`"{symbdef} { return (VP_DEFREF); } "`"{symbdef}`` { yyleng-=2; return (VP_DEFREF_JOIN); } {crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); } {wsn}+ { return (VP_WHITE); } {drop} { } [\r] { } . { return (VP_TEXT); } /* Protected blocks */ "`protected" { yy_push_state(PRTMODE); yymore(); } <> { linenoInc(); yyerrorf("EOF in `protected"); yyleng=0; yyterminate(); } {crnl} { linenoInc(); return VP_TEXT; } . { yymore(); } "`endprotected" { yy_pop_state(); return VP_TEXT; } /* Pass-through include <> filenames */ <> { linenoInc(); yyerrorf("EOF in unterminated include filename"); yyleng=0; yyterminate(); } {crnl} { linenoInc(); yyerrorf("Unterminated include filename"); BEGIN(INITIAL); } [^\>\\] { yymore(); } {backslash}. { yymore(); } [\>] { yy_pop_state(); return VP_STRING; } /* Reading definition formal parenthesis (or not) to begin formal arguments */ /* Note '(' must IMMEDIATELY follow definition name */ [(] { appendDefValue("(",1); LEXP->m_formalLevel=1; BEGIN(DEFFORM); } {crnl} { yy_pop_state(); unput('\n'); yyleng=0; return VP_DEFFORM; } /* DEFVAL will later grab the return */ <> { yy_pop_state(); return VP_DEFFORM; } /* empty formals */ . { yy_pop_state(); unput(yytext[yyleng-1]); yyleng=0; return VP_DEFFORM; } /* empty formals */ /* Reading definition formals (declaration of a define) */ [(] { appendDefValue(yytext,yyleng); yyleng=0; ++LEXP->m_formalLevel; } [)] { appendDefValue(yytext,yyleng); yyleng=0; if ((--LEXP->m_formalLevel)==0) { yy_pop_state(); return VP_DEFFORM; } } "/*" { yy_push_state(CMTMODE); yymore(); } "//"[^\n\r]* { return (VP_COMMENT);} {drop} { } <> { linenoInc(); yy_pop_state(); yyerrorf("Unterminated ( in define formal arguments."); yyleng=0; return VP_DEFFORM; } {crnl} { linenoInc(); appendDefValue((char*)"\n",1); } /* Include return so can maintain output line count */ [\\]{crnl} { linenoInc(); appendDefValue((char*)"\\\n",2); } /* Include return so can maintain output line count */ {quote} { LEXP->m_defQuote=true; yy_push_state(STRMODE); yymore(); } /* Legal only in default values */ "`\\`\"" { appendDefValue(yytext,yyleng); } /* Maybe illegal, otherwise in default value */ {tickquote} { appendDefValue(yytext,yyleng); } /* Maybe illegal, otherwise in default value */ [{\[] { LEXP->m_formalLevel++; appendDefValue(yytext,yyleng); } [}\]] { LEXP->m_formalLevel--; appendDefValue(yytext,yyleng); } [^\/\*\n\r\\(){}\[\]\"]+ | [\\][^\n\r] | . { appendDefValue(yytext,yyleng); } /* Reading definition value (declaration of a define's text) */ "/*" { LEXP->m_defCmtSlash=false; yy_push_state(DEFCMT); yymore(); } /* Special comment parser */ "//"[^\n\r]*[\\]{crnl} { linenoInc(); appendDefValue((char*)"\n",1); } /* Spec says // not part of define value */ "//"[^\n\r]* { return (VP_COMMENT);} {drop} { } <> { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return (VP_DEFVALUE); } /* Technically illegal, but people complained */ {crnl} { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return (VP_DEFVALUE); } [\\]{crnl} { linenoInc(); appendDefValue((char*)"\\\n",2); } /* Return, AND \ is part of define value */ {quote} { LEXP->m_defQuote=true; yy_push_state(STRMODE); yymore(); } [^\/\*\n\r\\\"]+ | [\\][^\n\r] | . { appendDefValue(yytext,yyleng); } /* Comments inside define values - if embedded get added to define value per spec */ /* - if no \{crnl} ending then the comment belongs to the next line, as a non-embedded comment */ /* - if all but (say) 3rd line is missing \ then it's indeterminate */ "*/" { yy_pop_state(); appendDefValue(yytext,yyleng); } [\\]{crnl} { linenoInc(); LEXP->m_defCmtSlash=true; appendDefValue(yytext,yyleng-2); appendDefValue((char*)"\n",1); } /* Return but not \ */ {crnl} { linenoInc(); yymore(); if (LEXP->m_defCmtSlash) yyerrorf("One line of /* ... */ is missing \\ before newline"); BEGIN(CMTMODE); } {word} { yymore(); } . { yymore(); } <> { yyerrorf("EOF in '/* ... */' block comment\n"); yyleng=0; yyterminate(); } /* Define arguments (use of a define) */ "/*" { yy_push_state(CMTMODE); yymore(); } "//"[^\n\r]* { return (VP_COMMENT);} {drop} { } <> { yyerrorf("EOF in define argument list\n"); yyleng = 0; yyterminate(); } {crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); } {quote} { yy_push_state(STRMODE); yymore(); } "`\\`\"" { appendDefValue(yytext,yyleng); } /* Literal text */ {tickquote} { return(VP_STRIFY); } [{\[] { LEXP->m_parenLevel++; appendDefValue(yytext,yyleng); } [}\]] { LEXP->m_parenLevel--; appendDefValue(yytext,yyleng); } [(] { LEXP->m_parenLevel++; // Note paren level 0 means before "(" of starting args // Level 1 means "," between arguments // Level 2+ means one argument's internal () if (LEXP->m_parenLevel>1) { appendDefValue(yytext,yyleng); } else { return (VP_TEXT); }} [)] { LEXP->m_parenLevel--; if (LEXP->m_parenLevel>0) { appendDefValue(yytext,yyleng); } else { yy_pop_state(); return (VP_DEFARG); }} [,] { if (LEXP->m_parenLevel>1) { appendDefValue(yytext,yyleng); } else { yy_pop_state(); return (VP_DEFARG); }} "`"{symbdef} { appendDefValue(yytext,yyleng); } /* defref in defref - outer macro expands first */ "`"{symbdef}`` { appendDefValue(yytext,yyleng); } /* defref in defref - outer macro expands first */ [^\/\*\n\r\\(,){}\[\]\"`]+ | . { appendDefValue(yytext,yyleng); } /* One line comments. */ "//"{ws}*{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return (VP_WHITE); } "//" { yy_push_state(CMTONEM); yymore(); } [^\n\r]* { yy_pop_state(); return (VP_COMMENT); } /* C-style comments. */ /**** See also DEFCMT */ /* We distinguish between the start of a comment, and later, to look for prefix comments (deprecated) */ "/*" { yy_push_state(CMTMODE); yymore(); } {ws}+ { yymore(); } "*/" { yy_pop_state(); return(VP_COMMENT); } {crnl} { linenoInc(); yymore(); } <> { yyerrorf("EOF in '/* ... */' block comment\n"); yyleng=0; yyterminate(); } {word} { yymore(); } . { BEGIN CMTMODE; yymore(); } /* beginning in comment */ . { yymore(); } /* Define calls */ /* symbdef prevents normal lex rules from making `\`"foo a symbol {`"foo} instead of a BACKQUOTE */ "`"{symbdef} { return (VP_DEFREF); } "`"{symbdef}`` { yyleng-=2; return (VP_DEFREF_JOIN); } /* Generics */ {crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); } <> { yyterminate(); } /* A "normal" EOF */ {symb} { return (VP_SYMBOL); } {symb}`` { yyleng-=2; return (VP_SYMBOL_JOIN); } {wsn}+ { return (VP_WHITE); } {drop} { } [\r] { } . { return (VP_TEXT); } %% void V3PreLex::pushStateDefArg(int level) { // Enter define substitution argument state yy_push_state(ARGMODE); m_parenLevel = level; m_defValue = ""; } void V3PreLex::pushStateDefForm() { // Enter define formal arguments state yy_push_state(DEFFPAR); // First is an optional ( to begin args m_parenLevel = 0; m_defValue = ""; } void V3PreLex::pushStateDefValue() { // Enter define value state yy_push_state(DEFVAL); m_parenLevel = 0; m_defValue = ""; } void V3PreLex::pushStateIncFilename() { // Enter include <> filename state yy_push_state(INCMODE); yymore(); } void V3PreLex::debug(int level) { yy_flex_debug=level; } int V3PreLex::debug() { return yy_flex_debug; } int V3PreLex::lex() { V3PreLex::s_currentLexp = this; // Tell parser where to get/put data m_tokFilelinep = curFilelinep(); // Remember token start location, may be updated by the lexer later return yylex(); } size_t V3PreLex::inputToLex(char* buf, size_t max_size) { // We need a custom YY_INPUT because we can't use flex buffers. // Flex buffers are limited to 2GB, and we can't chop into 2G pieces // because buffers can't end in the middle of tokens. // Note if we switched streams here (which we don't) "buf" would be // become a stale invalid pointer. // VPreStream* streamp = curStreamp(); if (debug()>=10) { cout<<"- pp:inputToLex ITL s="< max_size) { yyerrorf("Output buffer too small for a `line"); } else { got = forceOut.length(); strncpy(buf, forceOut.c_str(), got); } } else { if (streamp->m_eof) { if (yy_flex_debug) cout<<"- EOF\n"; } got = 0; // 0=EOF/EOS - although got was already 0. if (again) goto again; } } if (debug()>=10) { cout<<"- pp::inputToLex got="<m_eof) return ""; // Don't delete the final "EOF" stream bool exited_file = curStreamp()->m_file; if (!exited_file) { // Midpoint of stream, just change buffers delete curStreamp(); m_streampStack.pop(); // Must work as size>1; EOF is entry 0 againr = true; return ""; } // Multiple steps because we need FLEX to see ending \n and EOS to end // any illegal states, like an unterminated `protected region else if (!curStreamp()->m_termState) { // First shutdown phase for a file // Terminate all files with a newline. This prevents problems if // the user had a define without a terminating newline, // otherwise the resumed file's next line would get tacked on. // Also makes it likely the `line that changes files comes out // immediately. curStreamp()->m_termState = 1; return "\n"; // Exit old file } else if (curStreamp()->m_termState == 1) { // Now the EOF - can't be sent with other characters curStreamp()->m_termState = 2; return ""; // End of file } else if (curStreamp()->m_termState == 2) { // Now ending `line curStreamp()->m_termState = 3; return curFilelinep()->lineDirectiveStrg(2); // Exit old file } else { // Final shutdown phase for a stream, we can finally change the // current fileline to the new stream curStreamp()->m_termState = 0; FileLine* filelinep = curFilelinep(); delete curStreamp(); m_streampStack.pop(); // Must work as size>1; EOF is entry 0 if (curStreamp()->m_eof) { // EOF doesn't have a "real" fileline, but a linenumber of 0 from init time // Inherit whatever we last parsed so it's more obvious. curFilelinep(filelinep); } // The caller parser remembered the start location for the text we are parsing, // but we've discovered there was a file switch along the way, so update it. m_tokFilelinep = curFilelinep(); // if (curStreamp()->m_eof) { return ""; } else { return curFilelinep()->lineDirectiveStrg(0); // Reenter resumed file } } } void V3PreLex::initFirstBuffer(FileLine* filelinep) { // Called from constructor to make first buffer // yy_create_buffer also sets yy_fill_buffer=1 so reads from YY_INPUT VPreStream* streamp = new VPreStream(filelinep, this); streamp->m_eof = true; m_streampStack.push(streamp); // m_bufferState = yy_create_buffer(NULL, YY_BUF_SIZE); yy_switch_to_buffer(m_bufferState); yyrestart(NULL); } void V3PreLex::scanNewFile(FileLine* filelinep) { // Called on new open file. scanBytesBack will be called next. if (streamDepth() > V3PreProc::DEFINE_RECURSION_LEVEL_MAX) { // The recursive `include in VPreProcImp should trigger first yyerrorf("Recursive `define or other nested inclusion"); curStreamp()->m_eof = true; // Fake it to stop recursion } else { VPreStream* streamp = new VPreStream(filelinep, this); m_tokFilelinep = curFilelinep(); streamp->m_file = true; scanSwitchStream(streamp); } } void V3PreLex::scanBytes(const string& str) { // Note buffers also appended in ::scanBytesBack // Not "m_buffers.push_front(string(strp,len))" as we need a `define // to take effect immediately, in the middle of the current buffer // Also we don't use scan_bytes that would set yy_fill_buffer // which would force Flex to bypass our YY_INPUT routine. if (streamDepth() > V3PreProc::DEFINE_RECURSION_LEVEL_MAX) { // More streams if recursive `define with complex insertion // More buffers mostly if something internal goes funky yyerrorf("Recursive `define or other nested inclusion"); curStreamp()->m_eof = true; // Fake it to stop recursion } else { VPreStream* streamp = new VPreStream(curFilelinep(), this); streamp->m_buffers.push_front(str); scanSwitchStream(streamp); } } void V3PreLex::scanSwitchStream(VPreStream* streamp) { curStreamp()->m_buffers.push_front(currentUnreadChars()); m_streampStack.push(streamp); yyrestart(NULL); } void V3PreLex::scanBytesBack(const string& str) { // Initial creation, that will pull from YY_INPUT==inputToLex // Note buffers also appended in ::scanBytes if (curStreamp()->m_eof) yyerrorf("scanBytesBack without being under scanNewFile"); curStreamp()->m_buffers.push_back(str); } string V3PreLex::currentUnreadChars() { // WARNING - Peeking at internals ssize_t left = (yy_n_chars - (yy_c_buf_p -currentBuffer()->yy_ch_buf)); if (left > 0) { // left may be -1 at EOS *(yy_c_buf_p) = (yy_hold_char); return string(yy_c_buf_p, left); } else { return ""; } } YY_BUFFER_STATE V3PreLex::currentBuffer() { return YY_CURRENT_BUFFER; } int V3PreLex::currentStartState() const { return YY_START; } void V3PreLex::lineDirective(const char* textp) { curFilelinep()->lineDirective(textp, m_enterExit/*ref*/); // Make sure we have a dependency on whatever file was specified V3File::addSrcDepend(curFilelinep()->filename()); } void V3PreLex::dumpSummary() { cout<<"- pp::dumpSummary curBuf="<<(void*)(currentBuffer()); #ifdef FLEX_DEBUG // Else peeking at internals may cause portability issues ssize_t left = (yy_n_chars - (yy_c_buf_p -currentBuffer()->yy_ch_buf)); cout<<" left="< tmpstack = LEXP->m_streampStack; while (!tmpstack.empty()) { VPreStream* streamp = tmpstack.top(); cout<<"- bufferStack["<<(void*)(streamp)<<"]: " <<" at="<m_curFilelinep <<" nBuf="<m_buffers.size() <<" size0="<<(streamp->m_buffers.empty() ? 0 : streamp->m_buffers.front().length()) <<(streamp->m_eof?" [EOF]":"") <<(streamp->m_file?" [FILE]":""); cout< #include #include #include #include #include #include //###################################################################### class V3ErrorCode { public: enum en { EC_MIN=0, // Keep first // EC_INFO, // General information out EC_FATAL, // Kill the program EC_FATALSRC, // Kill the program, for internal source errors EC_ERROR, // General error out, can't suppress // Boolean information we track per-line, but aren't errors I_COVERAGE, // Coverage is on/off from /*verilator coverage_on/off*/ I_TRACING, // Tracing is on/off from /*verilator tracing_on/off*/ I_LINT, // All lint messages I_DEF_NETTYPE_WIRE, // `default_nettype is WIRE (false=NONE) // Error codes: E_BLKLOOPINIT, // Error: Delayed assignment to array inside for loops E_DETECTARRAY, // Error: Unsupported: Can't detect changes on arrayed variable E_MULTITOP, // Error: Multiple top level modules E_TASKNSVAR, // Error: Task I/O not simple // // Warning codes: EC_FIRST_WARN, // Just a code so the program knows where to start warnings // ALWCOMBORDER, // Always_comb with unordered statements ASSIGNDLY, // Assignment delays ASSIGNIN, // Assigning to input BLKANDNBLK, // Blocked and non-blocking assignments to same variable BLKSEQ, // Blocking assignments in sequential block CASEINCOMPLETE, // Case statement has missing values CASEOVERLAP, // Case statements overlap CASEWITHX, // Case with X values CASEX, // Casex CDCRSTLOGIC, // Logic in async reset path CLKDATA, // Clock used as data CMPCONST, // Comparison is constant due to limited range COMBDLY, // Combinatorial delayed assignment DEFPARAM, // Style: Defparam DECLFILENAME, // Declaration doesn't match filename ENDLABEL, // End lable name mismatch GENCLK, // Generated Clock IFDEPTH, // If statements too deep IMPERFECTSCH, // Imperfect schedule (disabled by default) IMPLICIT, // Implicit wire IMPURE, // Impure function not being inlined INCABSPATH, // Include has absolute path INITIALDLY, // Initial delayed statement LITENDIAN, // Little bit endian vector MODDUP, // Duplicate module MULTIDRIVEN, // Driven from multiple blocks PINMISSING, // Cell pin not specified PINNOCONNECT, // Cell pin not connected PINCONNECTEMPTY,// Cell pin connected by name with empty reference: ".name()" (can be used to mark unused pins) REALCVT, // Real conversion REDEFMACRO, // Redefining existing define macro SELRANGE, // Selection index out of range STMTDLY, // Delayed statement SYMRSVDWORD, // Symbol is Reserved Word SYNCASYNCNET, // Mixed sync + async reset UNDRIVEN, // No drivers UNOPT, // Unoptimizable block UNOPTFLAT, // Unoptimizable block after flattening UNPACKED, // Unsupported unpacked UNSIGNED, // Comparison is constant due to unsigned arithmetic UNUSED, // No receivers VARHIDDEN, // Hiding variable WIDTH, // Width mismatch WIDTHCONCAT, // Unsized numbers/parameters in concatenations _ENUM_MAX // ***Add new elements below also*** }; enum en m_e; inline V3ErrorCode () : m_e(EC_MIN) {} inline V3ErrorCode (en _e) : m_e(_e) {} V3ErrorCode (const char* msgp); // Matching code or ERROR explicit inline V3ErrorCode (int _e) : m_e(static_cast(_e)) {} operator en () const { return m_e; } const char* ascii() const { const char* names[] = { // Leading spaces indicate it can't be disabled. " MIN", " INFO", " FATAL", " FATALSRC", " ERROR", // Boolean " I_COVERAGE", " I_TRACING", " I_LINT", " I_DEF_NETTYPE_WIRE", // Errors "BLKLOOPINIT", "DETECTARRAY", "MULTITOP", "TASKNSVAR", // Warnings " EC_FIRST_WARN", "ALWCOMBORDER", "ASSIGNDLY", "ASSIGNIN", "BLKANDNBLK", "BLKSEQ", "CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CLKDATA", "CMPCONST", "COMBDLY", "DEFPARAM", "DECLFILENAME", "ENDLABEL", "GENCLK", "IFDEPTH", "IMPERFECTSCH", "IMPLICIT", "IMPURE", "INCABSPATH", "INITIALDLY", "LITENDIAN", "MODDUP", "MULTIDRIVEN", "PINMISSING", "PINNOCONNECT", "PINCONNECTEMPTY", "REALCVT", "REDEFMACRO", "SELRANGE", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNPACKED", "UNSIGNED", "UNUSED", "VARHIDDEN", "WIDTH", "WIDTHCONCAT", " MAX" }; return names[m_e]; } // Warnings that default to off bool defaultsOff() const { return ( m_e==IMPERFECTSCH || styleError()); } // Warnings that warn about nasty side effects bool dangerous() const { return ( m_e==COMBDLY ); } // Warnings we'll present to the user as errors // Later -Werror- options may make more of these. bool pretendError() const { return ( m_e==ASSIGNIN || m_e==BLKANDNBLK || m_e==IMPURE || m_e==MODDUP); } // Warnings to mention manual bool mentionManual() const { return ( m_e==EC_FATALSRC || m_e==SYMRSVDWORD || pretendError() ); } // Warnings that are lint only bool lintError() const { return ( m_e==ALWCOMBORDER || m_e==CASEINCOMPLETE || m_e==CASEOVERLAP || m_e==CASEWITHX || m_e==CASEX || m_e==CMPCONST || m_e==ENDLABEL || m_e==IMPLICIT || m_e==LITENDIAN || m_e==PINMISSING || m_e==REALCVT || m_e==UNSIGNED || m_e==WIDTH); } // Warnings that are style only bool styleError() const { return ( m_e==ASSIGNDLY // More than style, but for backward compatibility || m_e==BLKSEQ || m_e==DEFPARAM || m_e==DECLFILENAME || m_e==INCABSPATH || m_e==PINCONNECTEMPTY || m_e==PINNOCONNECT || m_e==SYNCASYNCNET || m_e==UNDRIVEN || m_e==UNUSED || m_e==VARHIDDEN ); } }; inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (V3ErrorCode::en lhs, V3ErrorCode rhs) { return (lhs == rhs.m_e); } inline ostream& operator<<(ostream& os, V3ErrorCode rhs) { return os< MessagesSet; typedef void (*ErrorExitCb)(void); private: static bool s_describedWarnings; // Told user how to disable warns static bool s_describedEachWarn[V3ErrorCode::_ENUM_MAX]; // Told user specifics about this warning static bool s_pretendError[V3ErrorCode::_ENUM_MAX]; // Pretend this warning is an error static int s_debugDefault; // Option: --debugi Default debugging level static int s_errorLimit; // Option: --error-limit Number of errors before exit static bool s_warnFatal; // Option: --warnFatal Warnings are fatal static int s_errCount; // Error count static int s_warnCount; // Warning count static int s_tellManual; // Tell user to see manual, 0=not yet, 1=doit, 2=disable static ostringstream s_errorStr; // Error string being formed static V3ErrorCode s_errorCode; // Error string being formed will abort static bool s_errorSuppressed; // Error being formed should be suppressed static MessagesSet s_messages; // What errors we've outputted static ErrorExitCb s_errorExitCb; // Callback when error occurs for dumping enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors V3Error() { cerr<<("Static class"); abort(); } public: // CREATORS // ACCESSORS static void debugDefault(int level) { s_debugDefault = level; } static int debugDefault() { return s_debugDefault; } static void errorLimit(int level) { s_errorLimit = level; } static int errorLimit() { return s_errorLimit; } static void warnFatal(bool flag) { s_warnFatal = flag; } static bool warnFatal() { return s_warnFatal; } static string msgPrefix(); // returns %Error/%Warn static int errorCount() { return s_errCount; } static int warnCount() { return s_warnCount; } static int errorOrWarnCount() { return errorCount()+warnCount(); } // METHODS static void incErrors(); static void incWarnings() { s_warnCount++; } static void init(); static void abortIfErrors() { if (errorCount()) abortIfWarnings(); } static void abortIfWarnings(); static void suppressThisWarning(); // Suppress next %Warn if user has it off static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; } static bool isError(V3ErrorCode code, bool supp); static string lineStr (const char* filename, int lineno); static V3ErrorCode errorCode() { return s_errorCode; } static void errorExitCb(ErrorExitCb cb) { s_errorExitCb = cb; } // When printing an error/warning, print prefix for multiline message static string warnMore(); // Internals for v3error()/v3fatal() macros only // Error end takes the string stream to output, be careful to seek() as needed static void v3errorPrep(V3ErrorCode code) { s_errorStr.str(""); s_errorCode=code; s_errorSuppressed=false; } static ostringstream& v3errorStr() { return s_errorStr; } static void vlAbort(); static void v3errorEnd(ostringstream& sstr); // static, but often overridden in classes. }; // Global versions, so that if the class doesn't define a operator, we get the functions anyways. inline int debug() { return V3Error::debugDefault(); } inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); } // Theses allow errors using << operators: v3error("foo"<<"bar"); // Careful, you can't put () around msg, as you would in most macro definitions // Note the commas are the comma operator, not separating arguments. These are needed to insure // evaluation order as otherwise we couldn't insure v3errorPrep is called first. #define v3warnCode(code,msg) v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<=(level))) { cout<<"- "<=(level))) { cout< std::string cvtToStr (const T& t) { ostringstream os; os< //###################################################################### // Symbol table for parsing class V3ParseSym { // TYPES typedef vector SymStack; private: // MEMBERS static int s_anonNum; // Number of next anonymous object (parser use only) VSymGraph m_syms; // Graph of symbol tree VSymEnt* m_symTableNextId; // Symbol table for next lexer lookup (parser use only) VSymEnt* m_symCurrentp; // Active symbol table for additions/lookups SymStack m_sympStack; // Stack of upper nodes with pending symbol tables private: // METHODS static VSymEnt* getTable(AstNode* nodep) { if (!nodep->user4p()) nodep->v3fatalSrc("Current symtable not found"); return nodep->user4p()->castSymEnt(); } public: VSymEnt* nextId() const { return m_symTableNextId; } VSymEnt* symCurrentp() const { return m_symCurrentp; } VSymEnt* symRootp() const { return m_syms.rootp(); } VSymEnt* findNewTable(AstNode* nodep) { if (!nodep->user4p()) { VSymEnt* symsp = new VSymEnt(&m_syms, nodep); nodep->user4p(symsp); } return getTable(nodep); } void nextId(AstNode* entp) { if (entp) { UINFO(9,"symTableNextId under "<type().ascii()<name()); } void reinsert(AstNode* nodep, VSymEnt* parentp, string name) { if (!parentp) parentp = symCurrentp(); if (name == "") { // New name with space in name so can't collide with users name = string(" anon") + nodep->type().ascii() + cvtToStr(++s_anonNum); } parentp->reinsert(name, findNewTable(nodep)); } void pushNew(AstNode* nodep) { pushNewUnder(nodep, NULL); } void pushNewUnder(AstNode* nodep, VSymEnt* parentp) { if (!parentp) parentp = symCurrentp(); VSymEnt* symp = findNewTable(nodep); // Will set user4p, which is how we connect table to node symp->fallbackp(parentp); reinsert(nodep, parentp); pushScope(symp); } void pushScope(VSymEnt* symp) { m_sympStack.push_back(symp); m_symCurrentp = symp; } void popScope(AstNode* nodep) { if (symCurrentp()->nodep() != nodep) { if (debug()) { showUpward(); dump(cout,"-mism: "); } nodep->v3fatalSrc("Symbols suggest ending "<nodep()->prettyTypeName() <<" but parser thinks ending "<prettyTypeName()); return; } m_sympStack.pop_back(); if (m_sympStack.empty()) { nodep->v3fatalSrc("symbol stack underflow"); return; } m_symCurrentp = m_sympStack.back(); } void showUpward () { UINFO(1,"ParseSym Stack:\n"); for (SymStack::reverse_iterator it=m_sympStack.rbegin(); it!=m_sympStack.rend(); ++it) { VSymEnt* symp = *it; UINFO(1,"\t"<nodep()<nodep()<findIdFallback(name)->nodep(); } void import(AstNode* packagep, const string& id_or_star) { // Import from package::id_or_star to this VSymEnt* symp = getTable(packagep); if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE packagep->v3fatalSrc("Import package not found"); return; } // Walk old sym table and reinsert into current table // We let V3LinkDot report the error instead of us symCurrentp()->importFromPackage(&m_syms, symp, id_or_star); } public: // CREATORS V3ParseSym(AstNetlist* rootp) : m_syms(rootp) { s_anonNum = 0; // Number of next anonymous object pushScope(findNewTable(rootp)); m_symTableNextId = NULL; m_symCurrentp = symCurrentp(); } ~V3ParseSym() {} }; #endif // Guard verilator-3.874/src/V3LinkCells.cpp0000664000177100017500000004027612525171733017126 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Resolve module/signal name references // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // NO EDITS: Don't replace or delete nodes, as the parser symbol table // has pointers into the ast tree. // // LINK TRANSFORMATIONS: // Top-down traversal // Cells: // Read module if needed // Link to module that instantiates it //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3LinkCells.h" #include "V3SymTable.h" #include "V3Parse.h" #include "V3Ast.h" #include "V3Graph.h" //###################################################################### // Graph subclasses class LinkCellsGraph : public V3Graph { public: LinkCellsGraph() {} virtual ~LinkCellsGraph() {} virtual void loopsMessageCb(V3GraphVertex* vertexp); }; class LinkCellsVertex : public V3GraphVertex { AstNodeModule* m_modp; public: LinkCellsVertex(V3Graph* graphp, AstNodeModule* modp) : V3GraphVertex(graphp), m_modp(modp) {} virtual ~LinkCellsVertex() {} AstNodeModule* modp() const { return m_modp; } virtual string name() const { return modp()->name(); } }; class LibraryVertex : public V3GraphVertex { public: LibraryVertex(V3Graph* graphp) : V3GraphVertex(graphp) {} virtual ~LibraryVertex() {} virtual string name() const { return "*LIBRARY*"; } }; void LinkCellsGraph::loopsMessageCb(V3GraphVertex* vertexp) { if (LinkCellsVertex* vvertexp = dynamic_cast(vertexp)) { vvertexp->modp()->v3error("Recursive module (module instantiates itself): " <modp()->prettyName()); V3Error::abortIfErrors(); } else { // Everything should match above, but... v3fatalSrc("Recursive instantiations"); } } //###################################################################### // Link state, as a visitor of each AstNode class LinkCellsVisitor : public AstNVisitor { private: // NODE STATE // Entire netlist: // AstNodeModule::user1p() // V3GraphVertex* Vertex describing this module // AstCell::user1() // bool Did it. // Allocated across all readFiles in V3Global::readFiles: // AstNode::user4p() // VSymEnt* Package and typedef symbol names AstUser1InUse m_inuser1; // STATE V3InFilter* m_filterp; // Parser filter V3ParseSym* m_parseSymp; // Parser symbol table // Below state needs to be preserved between each module call. AstNodeModule* m_modp; // Current module VSymGraph m_mods; // Symbol table of all module names LinkCellsGraph m_graph; // Linked graph of all cell interconnects LibraryVertex* m_libVertexp; // Vertex at root of all libraries V3GraphVertex* m_topVertexp; // Vertex of top module set m_declfnWarned; // Files we issued DECLFILENAME on static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // METHODS V3GraphVertex* vertex(AstNodeModule* nodep) { // Return corresponding vertex for this module if (!nodep->user1p()) { nodep->user1p(new LinkCellsVertex(&m_graph, nodep)); } return (nodep->user1p()->castGraphVertex()); } AstNodeModule* resolveModule(AstNode* nodep, const string& modName) { AstNodeModule* modp = m_mods.rootp()->findIdFallback(modName)->nodep()->castNodeModule(); if (!modp) { // Read-subfile // If file not found, make AstNotFoundModule, rather than error out. // We'll throw the error when we know the module will really be needed. string prettyName = AstNode::prettyName(modName); V3Parse parser (v3Global.rootp(), m_filterp, m_parseSymp); parser.parseFile(nodep->fileline(), prettyName, false, ""); V3Error::abortIfErrors(); // We've read new modules, grab new pointers to their names readModNames(); // Check again modp = m_mods.rootp()->findIdFallback(modName)->nodep()->castNodeModule(); if (!modp) { // This shouldn't throw a message as parseFile will create a AstNotFoundModule for us nodep->v3error("Can't resolve module reference: "<iterateChildren(*this); // Find levels in graph m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); m_graph.dumpDotFilePrefixed("linkcells"); m_graph.rank(); for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) { if (LinkCellsVertex* vvertexp = dynamic_cast(itp)) { // +1 so we leave level 1 for the new wrapper we'll make in a moment AstNodeModule* modp = vvertexp->modp(); modp->level(vvertexp->rank()+1); if (vvertexp == m_topVertexp && modp->level() != 2) { AstNodeModule* abovep = NULL; if (V3GraphEdge* edgep = vvertexp->inBeginp()) { if (LinkCellsVertex* eFromVertexp = dynamic_cast(edgep->fromp())) { abovep = eFromVertexp->modp(); } } v3error("Specified --top-module '"<prettyName() : "UNKNOWN")<<"'"); } } } if (v3Global.opt.topModule()!="" && !m_topVertexp) { v3error("Specified --top-module '"<fileline()->filebasenameNoExt() != nodep->prettyName() && !v3Global.opt.isLibraryFile(nodep->fileline()->filename()) && !nodep->internal()) { // We only complain once per file, otherwise library-like files have a huge mess of warnings if (m_declfnWarned.find(nodep->fileline()->filename()) == m_declfnWarned.end()) { m_declfnWarned.insert(nodep->fileline()->filename()); nodep->v3warn(DECLFILENAME, "Filename '"<fileline()->filebasenameNoExt() <<"' does not match "<typeName()<<" name: "<prettyName()); } } if (nodep->castIface() || nodep->castPackage()) nodep->inLibrary(true); // Interfaces can't be at top, unless asked bool topMatch = (v3Global.opt.topModule()==nodep->prettyName()); if (topMatch) { m_topVertexp = vertex(nodep); UINFO(2,"Link --top-module: "<inLibrary(false); // Safer to make sure it doesn't disappear } if (v3Global.opt.topModule()=="" ? nodep->inLibrary() // Library cells are lower : !topMatch) { // Any non-specified module is lower // Put under a fake vertex so that the graph ranking won't indicate // this is a top level module if (!m_libVertexp) m_libVertexp = new LibraryVertex(&m_graph); new V3GraphEdge(&m_graph, m_libVertexp, vertex(nodep), 1, false); } // Note AstBind also has iteration on cells nodep->iterateChildren(*this); nodep->checkTree(); m_modp = NULL; } virtual void visit(AstIfaceRefDType* nodep, AstNUser*) { // Cell: Resolve its filename. If necessary, parse it. UINFO(4,"Link IfaceRef: "<ifaceName()); if (modp) { if (modp->castIface()) { // Track module depths, so can sort list from parent down to children new V3GraphEdge(&m_graph, vertex(m_modp), vertex(modp), 1, false); if (!nodep->cellp()) nodep->ifacep(modp->castIface()); } else if (modp->castNotFoundModule()) { // Will error out later } else { nodep->v3error("Non-interface used as an interface: "<prettyName()); } } // Note cannot do modport resolution here; modports are allowed underneath generates } virtual void visit(AstPackageImport* nodep, AstNUser*) { // Package Import: We need to do the package before the use of a package nodep->iterateChildren(*this); if (!nodep->packagep()) nodep->v3fatalSrc("Unlinked package"); // Parser should set packagep new V3GraphEdge(&m_graph, vertex(m_modp), vertex(nodep->packagep()), 1, false); } virtual void visit(AstBind* nodep, AstNUser*) { // Bind: Has cells underneath that need to be put into the new module, and cells which need resolution // TODO this doesn't allow bind to dotted hier names, that would require // this move to post param, which would mean we do not auto-read modules // and means we cannot compute module levels until later. UINFO(4,"Link Bind: "<name()); if (modp) { AstNode* cellsp = nodep->cellsp()->unlinkFrBackWithNext(); // Module may have already linked, so need to pick up these new cells AstNodeModule* oldModp = m_modp; { m_modp = modp; modp->addStmtp(cellsp); // Important that this adds to end, as next iterate assumes does all cells cellsp->iterateAndNext(*this); } m_modp = oldModp; } pushDeletep(nodep->unlinkFrBack()); } virtual void visit(AstCell* nodep, AstNUser*) { // Cell: Resolve its filename. If necessary, parse it. if (nodep->user1SetOnce()) return; // AstBind and AstNodeModule may call a cell twice if (!nodep->modp()) { UINFO(4,"Link Cell: "<modName()); if (modp) { nodep->modp(modp); // Track module depths, so can sort list from parent down to children new V3GraphEdge(&m_graph, vertex(m_modp), vertex(modp), 1, false); } } // Remove AstCell(AstPin("",NULL)), it's a side effect of how we parse "()" // the empty middle is identical to the empty rule that must find pins in "(,)". if (nodep->pinsp() && !nodep->pinsp()->nextp() && nodep->pinsp()->name() == "" && !nodep->pinsp()->exprp()) { pushDeletep(nodep->pinsp()->unlinkFrBackWithNext()); } if (nodep->paramsp() && !nodep->paramsp()->nextp() && nodep->paramsp()->name() == "" && !nodep->paramsp()->exprp()) { pushDeletep(nodep->paramsp()->unlinkFrBackWithNext()); } // Convert .* to list of pins 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; } } // Convert unnamed pins to pin number based assignments for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { if (pinp->name()=="") pinp->name("__pinNumber"+cvtToStr(pinp->pinNum())); } for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) { pinp->param(true); if (pinp->name()=="") pinp->name("__paramNumber"+cvtToStr(pinp->pinNum())); } if (nodep->modp()) { // Note what pins exist set ports; // Symbol table of all connected port names for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells"); if (!pinp->exprp()) { if (pinp->name().substr(0, 11) == "__pinNumber") { pinp->v3warn(PINNOCONNECT,"Cell pin is not connected: "<prettyName()); } else { pinp->v3warn(PINCONNECTEMPTY,"Cell pin connected by name with empty reference: "<prettyName()); } } if (ports.find(pinp->name()) == ports.end()) { ports.insert(pinp->name()); } } // We search ports, rather than in/out declarations as they aren't resolved yet, // and it's easier to do it now than in V3LinkDot when we'd need to repeat steps. for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) { if (AstPort* portp = portnodep->castPort()) { if (ports.find(portp->name()) == ports.end() && ports.find("__pinNumber"+cvtToStr(portp->pinNum())) == ports.end()) { if (pinStar) { UINFO(9," need .* PORT "<fileline(),0,portp->name(), new AstVarRef(nodep->fileline(),portp->name(),false)); newp->svImplicit(true); nodep->addPinsp(newp); } else { // warn on the CELL that needs it, not the port nodep->v3warn(PINMISSING, "Cell has missing pin: "<prettyName()); AstPin* newp = new AstPin(nodep->fileline(),0,portp->name(),NULL); nodep->addPinsp(newp); } } } } } if (nodep->modp()->castIface()) { // Cell really is the parent's instantiation of an interface, not a normal module // Make sure we have a variable to refer to this cell, so can . // in the same way that a child does. Rename though to avoid conflict with cell. // This is quite similar to how classes work; when unpacked classes are better supported // may remap interfaces to be more like a class. if (!nodep->hasIfaceVar()) { string varName = nodep->name()+"__Viftop"; // V3LinkDot looks for this naming AstIfaceRefDType* idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(), nodep->modp()->name()); idtypep->cellp(nodep); // Only set when real parent cell known idtypep->ifacep(NULL); // cellp overrides AstVar* varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName, VFlagChildDType(), idtypep); varp->isIfaceParent(true); nodep->addNextHere(varp); nodep->hasIfaceVar(true); } } if (nodep->modp()) { nodep->iterateChildren(*this); } UINFO(4," Link Cell done: "<iterateChildren(*this); } // METHODS void readModNames() { // Look at all modules, and store pointers to all module names for (AstNodeModule* nextp,* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nextp) { nextp = nodep->nextp()->castNodeModule(); AstNode* foundp = m_mods.rootp()->findIdFallback(nodep->name())->nodep(); if (foundp && foundp != nodep) { if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP) || nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP))) { nodep->v3warn(MODDUP,"Duplicate declaration of module: "<prettyName()<warnMore()<<"... Location of original declaration"); } nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } else if (!foundp) { m_mods.rootp()->insert(nodep->name(), new VSymEnt(&m_mods, nodep)); } } //if (debug()>=9) m_mods.dump(cout, "-syms: "); } public: // CONSTUCTORS LinkCellsVisitor(AstNetlist* rootp, V3InFilter* filterp, V3ParseSym* parseSymp) : m_mods(rootp) { m_filterp = filterp; m_parseSymp = parseSymp; m_modp = NULL; m_libVertexp = NULL; m_topVertexp = NULL; rootp->accept(*this); } virtual ~LinkCellsVisitor() {} }; //###################################################################### // Link class functions void V3LinkCells::link(AstNetlist* rootp, V3InFilter* filterp, V3ParseSym* parseSymp) { UINFO(4,__FUNCTION__<<": "<) { $line =~ s/(\\begin{document})/${header}$1/; $line =~ s/(\\tableofcontents)/\\begin{titlepage} \\maketitle \\end{titlepage}\n$1/; print "$line"; } verilator-3.874/src/V3Clean.h0000664000177100017500000000224212525171733015724 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Pre C-Emit stage changes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3CLEAN_H_ #define _V3CLEAN_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3Clean { public: static void cleanAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Expand.cpp0000664000177100017500000010511012525171733016452 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add temporaries, such as for expand nodes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2004-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Expand's Transformations: // // Each module: // Expand verilated.h macros into internal micro optimizations (RTL) // this will enable later optimizations. // Wide operands become assignments to each word of the vector, (WORDSELs) // Note in this case that the widthMin is not correct for the MSW of // the vector. This must be accounted for if doing later constant // propagation across signals. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Expand.h" #include "V3Ast.h" //###################################################################### // Expand state, as a visitor of each AstNode class ExpandVisitor : public AstNVisitor { private: // NODE STATE // AstNode::user1() -> bool. Processed AstUser1InUse m_inuser1; // STATE AstNode* m_stmtp; // Current statement // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } int longOrQuadWidth (AstNode* nodep) { // Return 32 or 64... return (nodep->width()+(VL_WORDSIZE-1)) & ~(VL_WORDSIZE-1); } V3Number notWideMask (AstNode* nodep) { return V3Number (nodep->fileline(), VL_WORDSIZE, ~VL_MASK_I(nodep->widthMin())); } V3Number wordMask (AstNode* nodep) { if (nodep->isWide()) { return V3Number (nodep->fileline(), VL_WORDSIZE, VL_MASK_I(nodep->widthMin())); } else { V3Number mask (nodep->fileline(), longOrQuadWidth(nodep)); mask.setMask(nodep->widthMin()); return mask; } } void insertBefore (AstNode* placep, AstNode* newp) { newp->user1(1); // Already processed, don't need to re-iterate AstNRelinker linker; placep->unlinkFrBack(&linker); newp->addNext(placep); linker.relink(newp); } void replaceWithDelete (AstNode* nodep, AstNode* newp) { newp->user1(1); // Already processed, don't need to re-iterate nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } AstNode* newWordAssign (AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) { AstAssign* newp = new AstAssign (placep->fileline(), new AstWordSel (placep->fileline(), lhsp->cloneTree(true), new AstConst (placep->fileline(), word)), rhsp); return newp; } void addWordAssign (AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) { insertBefore (placep, newWordAssign(placep, word, lhsp, rhsp)); } void addWordAssign (AstNodeAssign* placep, int word, AstNode* rhsp) { addWordAssign (placep, word, placep->lhsp(), rhsp); } void fixCloneLvalue (AstNode* nodep) { // In AstSel transforms, we call clone() on VarRefs that were lvalues, // but are now being used on the RHS of the assignment if (nodep->castVarRef()) nodep->castVarRef()->lvalue(false); // Iterate if (nodep->op1p()) fixCloneLvalue(nodep->op1p()); if (nodep->op2p()) fixCloneLvalue(nodep->op2p()); if (nodep->op3p()) fixCloneLvalue(nodep->op3p()); if (nodep->op4p()) fixCloneLvalue(nodep->op4p()); } AstNode* newAstWordSelClone (AstNode* nodep, int word) { // Get the specified word number from a wide array // Or, if it's a long/quad, do appropriate conversion to wide // Concat may pass negative word numbers, that means it wants a zero if (nodep->isWide() && word>=0 && wordwidthWords()) { return new AstWordSel (nodep->fileline(), nodep->cloneTree(true), new AstConst(nodep->fileline(), word)); } else if (nodep->isQuad() && word==0) { AstNode* quadfromp = nodep->cloneTree(true); quadfromp->dtypeSetBitSized(VL_QUADSIZE,quadfromp->widthMin(),AstNumeric::UNSIGNED); return new AstCCast (nodep->fileline(), quadfromp, VL_WORDSIZE); } else if (nodep->isQuad() && word==1) { AstNode* quadfromp = nodep->cloneTree(true); quadfromp->dtypeSetBitSized(VL_QUADSIZE,quadfromp->widthMin(),AstNumeric::UNSIGNED); return new AstCCast (nodep->fileline(), new AstShiftR (nodep->fileline(), quadfromp, new AstConst (nodep->fileline(), VL_WORDSIZE), VL_WORDSIZE), VL_WORDSIZE); } else if (!nodep->isWide() && !nodep->isQuad() && word==0) { return nodep->cloneTree(true); } else { // Out of bounds return new AstConst (nodep->fileline(), 0); } } AstNode* newWordGrabShift (FileLine* fl, int word, AstNode* lhsp, int shift) { // Extract the expression to grab the value for the specified word, if it's the shift // of shift bits from lhsp AstNode* newp; // Negative word numbers requested for lhs when it's "before" what we want. // We get a 0 then. int othword = word - shift/VL_WORDSIZE; AstNode* llowp = newAstWordSelClone (lhsp, othword); if (int loffset = VL_BITBIT_I(shift)) { AstNode* lhip = newAstWordSelClone (lhsp, othword-1); int nbitsonright = VL_WORDSIZE-loffset; // bits that end up in lword newp = new AstOr (fl, new AstAnd(fl, new AstConst (fl, VL_MASK_I(loffset)), new AstShiftR (fl, lhip, new AstConst(fl, nbitsonright), VL_WORDSIZE)), new AstAnd(fl, new AstConst (fl, ~VL_MASK_I(loffset)), new AstShiftL(fl, llowp, new AstConst(fl, loffset), VL_WORDSIZE))); } else { newp = llowp; } return newp; } AstNode* newSelBitWord(AstNode* lsbp, int wordAdder) { // Return equation to get the VL_BITWORD of a constant or non-constant if (lsbp->castConst()) { return new AstConst (lsbp->fileline(), wordAdder + VL_BITWORD_I(lsbp->castConst()->toUInt())); } else { AstNode* shiftp = new AstShiftR (lsbp->fileline(), lsbp->cloneTree(true), new AstConst(lsbp->fileline(), VL_WORDSIZE_LOG2), VL_WORDSIZE); if (wordAdder != 0) { shiftp = new AstAdd (lsbp->fileline(), // This is indexing a arraysel, so a 32 bit constant is fine new AstConst (lsbp->fileline(), wordAdder), shiftp); } return shiftp; } } AstNode* dropCondBound(AstNode* nodep) { // Experimental only... // If there's a CONDBOUND safety to keep arrays in bounds, // we're going to AND it to a value that always fits inside a // word, so we don't need it. //if (nodep->castCondBound() && nodep->castCondBound()->lhsp()->castLte()) { // nodep = nodep->castCondBound()->rhsp(); //} return nodep; } AstNode* newSelBitBit(AstNode* lsbp) { // Return equation to get the VL_BITBIT of a constant or non-constant if (lsbp->castConst()) { return new AstConst (lsbp->fileline(), VL_BITBIT_I(lsbp->castConst()->toUInt())); } else { return new AstAnd (lsbp->fileline(), new AstConst(lsbp->fileline(), VL_WORDSIZE-1), dropCondBound(lsbp)->cloneTree(true)); } } //==================== bool expandWide (AstNodeAssign* nodep, AstConst* rhsp) { UINFO(8," Wordize ASSIGN(CONST) "< {for each_word{ ASSIGN(WORDSEL(wide,#),WORDSEL(CONST,#))}} if (rhsp->num().isFourState()) { rhsp->v3error("Unsupported: 4-state numbers in this context"); } for (int w=0; wwidthWords(); w++) { V3Number num (nodep->fileline(), VL_WORDSIZE, rhsp->num().dataWord(w)); addWordAssign(nodep, w, new AstConst (nodep->fileline(), num)); } return true; } //-------- Uniops bool expandWide (AstNodeAssign* nodep, AstVarRef* rhsp) { UINFO(8," Wordize ASSIGN(VARREF) "<widthWords(); w++) { addWordAssign(nodep, w, newAstWordSelClone (rhsp, w)); } return true; } bool expandWide (AstNodeAssign* nodep, AstArraySel* rhsp) { UINFO(8," Wordize ASSIGN(ARRAYSEL) "<length()!=1) nodep->v3fatalSrc("ArraySel with length!=1 should have been removed in V3Slice"); for (int w=0; wwidthWords(); w++) { addWordAssign(nodep, w, newAstWordSelClone (rhsp, w)); } return true; } bool expandWide (AstNodeAssign* nodep, AstNot* rhsp) { UINFO(8," Wordize ASSIGN(NOT) "< {for each_word{ ASSIGN(WORDSEL(wide,#),NOT(WORDSEL(lhs,#))) }} for (int w=0; wwidthWords(); w++) { addWordAssign(nodep, w, new AstNot (rhsp->fileline(), newAstWordSelClone (rhsp->lhsp(), w))); } return true; } //-------- Biops bool expandWide (AstNodeAssign* nodep, AstAnd* rhsp) { UINFO(8," Wordize ASSIGN(AND) "<widthWords(); w++) { addWordAssign(nodep, w, new AstAnd (nodep->fileline(), newAstWordSelClone (rhsp->lhsp(), w), newAstWordSelClone (rhsp->rhsp(), w))); } return true; } bool expandWide (AstNodeAssign* nodep, AstOr* rhsp) { UINFO(8," Wordize ASSIGN(OR) "<widthWords(); w++) { addWordAssign(nodep, w, new AstOr (nodep->fileline(), newAstWordSelClone (rhsp->lhsp(), w), newAstWordSelClone (rhsp->rhsp(), w))); } return true; } bool expandWide (AstNodeAssign* nodep, AstXor* rhsp) { UINFO(8," Wordize ASSIGN(XOR) "<widthWords(); w++) { addWordAssign(nodep, w, new AstXor (nodep->fileline(), newAstWordSelClone (rhsp->lhsp(), w), newAstWordSelClone (rhsp->rhsp(), w))); } return true; } bool expandWide (AstNodeAssign* nodep, AstXnor* rhsp) { UINFO(8," Wordize ASSIGN(XNOR) "<widthWords(); w++) { addWordAssign(nodep, w, new AstXnor (nodep->fileline(), newAstWordSelClone (rhsp->lhsp(), w), newAstWordSelClone (rhsp->rhsp(), w))); } return true; } //-------- Triops bool expandWide (AstNodeAssign* nodep, AstNodeCond* rhsp) { UINFO(8," Wordize ASSIGN(COND) "<widthWords(); w++) { addWordAssign(nodep, w, new AstCond (nodep->fileline(), rhsp->condp()->cloneTree(true), newAstWordSelClone (rhsp->expr1p(), w), newAstWordSelClone (rhsp->expr2p(), w))); } return true; } // VISITORS virtual void visit(AstExtend* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; // Process once nodep->iterateChildren(*this); if (nodep->isWide()) { // See under ASSIGN(EXTEND) } else { AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* newp = lhsp; if (nodep->isQuad()) { if (lhsp->isQuad()) { lhsp->dtypeFrom(nodep); // Just mark it, else nop } else if (lhsp->isWide()) { nodep->v3fatalSrc("extending larger thing into smaller?"); } else { UINFO(8," EXTEND(q<-l) "<fileline(), lhsp, nodep); } } else { // Long if (lhsp->isQuad() || lhsp->isWide()) { nodep->v3fatalSrc("extending larger thing into smaller?"); } else { lhsp->dtypeFrom(nodep); // Just mark it, else nop } } replaceWithDelete(nodep,newp); nodep=NULL; } } bool expandWide (AstNodeAssign* nodep, AstExtend* rhsp) { UINFO(8," Wordize ASSIGN(EXTEND) "<lhsp()->widthWords(); w++) { addWordAssign(nodep, w, newAstWordSelClone (rhsp->lhsp(), w)); } for (; wwidthWords(); w++) { addWordAssign(nodep, w, new AstConst (rhsp->fileline(), 0)); } return true; } virtual void visit(AstSel* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; // Process once nodep->iterateChildren(*this); // Remember, Sel's may have non-integer rhs, so need to optimize for that! if (nodep->widthMin()!=(int)nodep->widthConst()) nodep->v3fatalSrc("Width mismatch"); if (nodep->backp()->castNodeAssign() && nodep==nodep->backp()->castNodeAssign()->lhsp()) { // Sel is an LHS assignment select } else if (nodep->isWide()) { // See under ASSIGN(WIDE) } else if (nodep->fromp()->isWide()) { UINFO(8," SEL(wide) "<fromp()->fileline(), nodep->fromp()->cloneTree(true), newSelBitWord(nodep->lsbp(), 0)); if (nodep->isQuad() && !lowwordp->isQuad()) lowwordp = new AstCCast(nodep->fileline(), lowwordp, nodep); AstNode* lowp = new AstShiftR (nodep->fileline(), lowwordp, newSelBitBit(nodep->lsbp()), nodep->width()); // If > 1 bit, we might be crossing the word boundary AstNode* midp=NULL; V3Number zero (nodep->fileline(), longOrQuadWidth(nodep)); if (nodep->widthConst() > 1) { AstNode* midwordp = // SEL(from,[1+wordnum]) new AstWordSel (nodep->fromp()->fileline(), nodep->fromp()->cloneTree(true), newSelBitWord(nodep->lsbp(), 1)); if (nodep->isQuad() && !midwordp->isQuad()) midwordp = new AstCCast(nodep->fileline(), midwordp, nodep); // If we're selecting bit zero, then all 32 bits in word 1 get shifted << by 32 bits // else we need to form the lower word, so we << by 31 or less // nbitsfromlow <= (lsb==0) ? 64-bitbit(lsb) : 32-bitbit(lsb) AstNode* midshiftp = new AstSub (nodep->lsbp()->fileline(), new AstConst(nodep->lsbp()->fileline(), VL_WORDSIZE), newSelBitBit(nodep->lsbp())); if (nodep->isQuad()) { midshiftp = new AstCond (nodep->fileline(), new AstEq (nodep->fileline(), new AstConst(nodep->fileline(), 0), newSelBitBit(nodep->lsbp())), new AstConst(nodep->lsbp()->fileline(), VL_WORDSIZE), midshiftp); } AstNode* midmayp = new AstShiftL (nodep->fileline(), midwordp, midshiftp, nodep->width()); if (nodep->isQuad()) { midp = midmayp; // Always grab from two words } else { midp = new AstCond (nodep->fileline(), new AstEq (nodep->fileline(), new AstConst(nodep->fileline(), 0), newSelBitBit(nodep->lsbp())), new AstConst(nodep->fileline(), zero), midmayp); } } // If > 32 bits, we might be crossing the second word boundary AstNode* hip=NULL; if (nodep->widthConst() > VL_WORDSIZE) { AstNode* hiwordp = // SEL(from,[2+wordnum]) new AstWordSel (nodep->fromp()->fileline(), nodep->fromp()->cloneTree(true), newSelBitWord(nodep->lsbp(), 2)); if (nodep->isQuad() && !hiwordp->isQuad()) hiwordp = new AstCCast(nodep->fileline(), hiwordp, nodep); AstNode* himayp = new AstShiftL (nodep->fileline(), hiwordp, // nbitsfromlow_and_mid <= 64-bitbit(lsb) new AstSub (nodep->lsbp()->fileline(), new AstConst(nodep->lsbp()->fileline(), 64), newSelBitBit(nodep->lsbp())), nodep->width()); // if (frombit==0) then ignore, else use it hip = new AstCond (nodep->fileline(), new AstEq (nodep->fileline(), new AstConst(nodep->fileline(), 0), newSelBitBit(nodep->lsbp())), new AstConst(nodep->fileline(), zero), himayp); } AstNode* newp = lowp; if (midp) newp = new AstOr (nodep->fileline(), midp, newp); if (hip) newp = new AstOr (nodep->fileline(), hip, newp); newp->dtypeFrom(nodep); replaceWithDelete(nodep,newp); nodep=NULL; } else { // Long/Quad from Long/Quad UINFO(8," SEL->SHIFT "<fromp()->unlinkFrBack(); AstNode* lsbp = nodep->lsbp()->unlinkFrBack(); if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCCast(nodep->fileline(), fromp, nodep); AstNode* newp = new AstShiftR (nodep->fileline(), fromp, dropCondBound(lsbp), fromp->width()); // {large}>>32 requires 64-bit shift operation; then cast newp->dtypeFrom(fromp); if (!nodep->isQuad() && fromp->isQuad()) { newp = new AstCCast (newp->fileline(), newp, nodep); } newp->dtypeFrom(nodep); replaceWithDelete(nodep,newp); nodep=NULL; } } bool expandWide (AstNodeAssign* nodep, AstSel* rhsp) { if (nodep->widthMin()!=(int)rhsp->widthConst()) nodep->v3fatalSrc("Width mismatch"); if (rhsp->lsbp()->castConst() && VL_BITBIT_I(rhsp->lsbConst())==0) { int lsb = rhsp->lsbConst(); UINFO(8," Wordize ASSIGN(SEL,align) "<widthWords(); w++) { addWordAssign(nodep, w, newAstWordSelClone (rhsp->fromp(), w + VL_BITWORD_I(lsb))); } return true; } else { UINFO(8," Wordize ASSIGN(EXTRACT,misalign) "<widthWords(); w++) { // Grab lowest bits AstNode* lowwordp = new AstWordSel (rhsp->fileline(), rhsp->fromp()->cloneTree(true), newSelBitWord(rhsp->lsbp(), w)); AstNode* lowp = new AstShiftR (rhsp->fileline(), lowwordp, newSelBitBit(rhsp->lsbp()), VL_WORDSIZE); // Upper bits V3Number zero (nodep->fileline(), VL_WORDSIZE, 0); AstNode* midwordp = // SEL(from,[1+wordnum]) new AstWordSel (rhsp->fromp()->fileline(), rhsp->fromp()->cloneTree(true), newSelBitWord(rhsp->lsbp(), w+1)); AstNode* midshiftp = new AstSub (rhsp->lsbp()->fileline(), new AstConst(rhsp->lsbp()->fileline(), VL_WORDSIZE), newSelBitBit(rhsp->lsbp())); AstNode* midmayp = new AstShiftL (rhsp->fileline(), midwordp, midshiftp, VL_WORDSIZE); AstNode* midp = new AstCond (rhsp->fileline(), new AstEq (rhsp->fileline(), new AstConst(rhsp->fileline(), 0), newSelBitBit(rhsp->lsbp())), new AstConst(rhsp->fileline(), zero), midmayp); AstNode* newp = new AstOr (nodep->fileline(), midp, lowp); addWordAssign(nodep, w, newp); } return true; } } bool expandLhs(AstNodeAssign* nodep, AstSel* lhsp) { // Possibilities // destp: wide or narrow // rhsp: wide (destp must be wide), narrow, or 1 bit wide // rhsp: may be allones and can remove AND NOT gate // lsbp: constant or variable // Yuk. bool destwide = lhsp->fromp()->isWide(); bool ones = nodep->rhsp()->isAllOnesV(); if (lhsp->lsbp()->castConst()) { // The code should work without this constant test, but it won't // constify as nicely as we'd like. AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* destp = lhsp->fromp()->unlinkFrBack(); int lsb = lhsp->lsbConst(); int msb = lhsp->msbConst(); V3Number maskset (nodep->fileline(), destp->widthMin()); for (int bit=lsb; bit<(msb+1); bit++) maskset.setBit(bit,1); V3Number maskold (nodep->fileline(), destp->widthMin()); maskold.opNot(maskset); if (destwide) { UINFO(8," ASSIGNSEL(const,wide) "<widthWords(); w++) { if (w>=VL_BITWORD_I(lsb) && w<=VL_BITWORD_I(msb)) { // else we would just be setting it to the same exact value AstNode* oldvalp = newAstWordSelClone (destp, w); fixCloneLvalue(oldvalp); if (!ones) oldvalp = new AstAnd (lhsp->fileline(), new AstConst (lhsp->fileline(), maskold.dataWord(w)), oldvalp); addWordAssign(nodep, w, destp, new AstOr (lhsp->fileline(), oldvalp, newWordGrabShift(lhsp->fileline(), w, rhsp, lsb))); } } rhsp->deleteTree(); rhsp=NULL; destp->deleteTree(); destp=NULL; } else { UINFO(8," ASSIGNSEL(const,narrow) "<isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep); AstNode* oldvalp = destp->cloneTree(true); fixCloneLvalue(oldvalp); if (!ones) oldvalp = new AstAnd (lhsp->fileline(), new AstConst (lhsp->fileline(), maskold), oldvalp); AstNode* newp = new AstOr (lhsp->fileline(), oldvalp, new AstShiftL (lhsp->fileline(), rhsp, new AstConst (lhsp->fileline(), lsb), destp->width())); newp = new AstAssign (nodep->fileline(), destp, newp); insertBefore(nodep,newp); } return true; } else { // non-const RHS if (destwide && lhsp->widthConst()==1) { UINFO(8," ASSIGNSEL(varlsb,wide,1bit) "<rhsp()->unlinkFrBack(); AstNode* destp = lhsp->fromp()->unlinkFrBack(); AstNode* oldvalp = new AstWordSel (lhsp->fileline(), destp->cloneTree(true), newSelBitWord(lhsp->lsbp(), 0)); fixCloneLvalue(oldvalp); if (!ones) oldvalp = new AstAnd (lhsp->fileline(), new AstNot (lhsp->fileline(), new AstShiftL (lhsp->fileline(), new AstConst (nodep->fileline(),1), // newSelBitBit may exceed the MSB of this variable. // That's ok as we'd just AND with a larger value, // but oldval would clip the upper bits to sanity newSelBitBit(lhsp->lsbp()), VL_WORDSIZE)), oldvalp); // Restrict the shift amount to 0-31, see bug804. AstNode* shiftp = new AstAnd(nodep->fileline(), lhsp->lsbp()->cloneTree(true), new AstConst(nodep->fileline(), VL_WORDSIZE-1)); AstNode* newp = new AstOr (lhsp->fileline(), oldvalp, new AstShiftL (lhsp->fileline(), rhsp, shiftp, VL_WORDSIZE)); newp = new AstAssign (nodep->fileline(), new AstWordSel (nodep->fileline(), destp, newSelBitWord(lhsp->lsbp(), 0)), newp); insertBefore(nodep,newp); return true; } else if (destwide) { UINFO(8," ASSIGNSEL(varlsb,wide) -- NoOp -- "<dumpTree(cout,"- old: "); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* destp = lhsp->fromp()->unlinkFrBack(); AstNode* oldvalp = destp->cloneTree(true); fixCloneLvalue(oldvalp); V3Number maskwidth (nodep->fileline(), destp->widthMin()); for (int bit=0; bit<(int)lhsp->widthConst(); bit++) maskwidth.setBit(bit,1); if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep); if (!ones) oldvalp = new AstAnd (lhsp->fileline(), new AstNot (lhsp->fileline(), new AstShiftL (lhsp->fileline(), new AstConst (nodep->fileline(), maskwidth), lhsp->lsbp()->cloneTree(true), destp->width())), oldvalp); AstNode* newp = new AstOr (lhsp->fileline(), oldvalp, new AstShiftL (lhsp->fileline(), rhsp, lhsp->lsbp()->cloneTree(true), destp->width())); newp = new AstAssign (nodep->fileline(), destp, newp); //newp->dumpTree(cout,"- new: "); insertBefore(nodep,newp); return true; } } } virtual void visit(AstConcat* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; // Process once nodep->iterateChildren(*this); if (nodep->isWide()) { // See under ASSIGN(WIDE) } else { UINFO(8," CONCAT "<lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); int rhsshift = rhsp->widthMin(); if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCCast(nodep->fileline(), lhsp, nodep); if (nodep->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep); AstNode* newp = new AstOr (nodep->fileline(), new AstShiftL (nodep->fileline(), lhsp, new AstConst (nodep->fileline(), rhsshift), nodep->width()), rhsp); newp->dtypeFrom(nodep); // Unsigned replaceWithDelete(nodep,newp); nodep=NULL; } } bool expandWide (AstNodeAssign* nodep, AstConcat* rhsp) { UINFO(8," Wordize ASSIGN(CONCAT) "<rhsp()->widthMin(); // Sometimes doing the words backwards is preferrable. // When we have x={x,foo} backwards is better, when x={foo,x} forward is better // However V3Subst tends to rip this up, so not worth optimizing now. for (int w=0; wwidthWords(); w++) { addWordAssign(nodep, w, new AstOr (rhsp->fileline(), newWordGrabShift(rhsp->fileline(), w, rhsp->lhsp(), rhsshift), newAstWordSelClone (rhsp->rhsp(), w))); } return true; } virtual void visit(AstReplicate* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; // Process once nodep->iterateChildren(*this); if (nodep->isWide()) { // See under ASSIGN(WIDE) } else { AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* newp; int lhswidth = lhsp->widthMin(); if (lhswidth==1) { UINFO(8," REPLICATE(w1) "<fileline(), lhsp); } else { UINFO(8," REPLICATE "<rhsp()->castConst(); if (!constp) nodep->v3fatalSrc("Replication value isn't a constant. Checked earlier!"); uint32_t times = constp->toUInt(); if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCCast(nodep->fileline(), lhsp, nodep); newp = lhsp->cloneTree(true); for (unsigned repnum=1; repnumfileline(), new AstShiftL (nodep->fileline(), lhsp->cloneTree(true), new AstConst (nodep->fileline(), rhsshift), nodep->width()), newp); newp->dtypeFrom(nodep); // Unsigned } lhsp->deleteTree(); // Never used } newp->dtypeFrom(nodep); // Unsigned replaceWithDelete(nodep,newp); nodep=NULL; } } bool expandWide (AstNodeAssign* nodep, AstReplicate* rhsp) { UINFO(8," Wordize ASSIGN(REPLICATE) "<lhsp(); int lhswidth = lhsp->widthMin(); AstConst* constp = rhsp->rhsp()->castConst(); if (!constp) rhsp->v3fatalSrc("Replication value isn't a constant. Checked earlier!"); uint32_t times = constp->toUInt(); for (int w=0; wwidthWords(); w++) { AstNode* newp; if (lhswidth==1) { newp = new AstNegate (nodep->fileline(), lhsp->cloneTree(true)); newp->dtypeSetLogicSized(VL_WORDSIZE,VL_WORDSIZE,AstNumeric::UNSIGNED); // Replicate always unsigned } else { newp = newAstWordSelClone (lhsp, w); for (unsigned repnum=1; repnumfileline(), newWordGrabShift(rhsp->fileline(), w, lhsp, lhswidth*repnum), newp); } } addWordAssign(nodep, w, newp); } return true; } virtual void visit(AstChangeXor* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; // Process once nodep->iterateChildren(*this); UINFO(8," Wordize ChangeXor "< (0=={or{for each_word{WORDSEL(lhs,#)^WORDSEL(rhs,#)}}} AstNode* newp = NULL; for (int w=0; wlhsp()->widthWords(); w++) { AstNode* eqp = new AstXor (nodep->fileline(), newAstWordSelClone (nodep->lhsp(), w), newAstWordSelClone (nodep->rhsp(), w)); newp = (newp==NULL) ? eqp : (new AstOr (nodep->fileline(), newp, eqp)); } replaceWithDelete(nodep,newp); nodep=NULL; } void visitEqNeq(AstNodeBiop* nodep) { if (nodep->user1SetOnce()) return; // Process once nodep->iterateChildren(*this); if (nodep->lhsp()->isWide()) { UINFO(8," Wordize EQ/NEQ "< (0=={or{for each_word{WORDSEL(lhs,#)^WORDSEL(rhs,#)}}} AstNode* newp = NULL; for (int w=0; wlhsp()->widthWords(); w++) { AstNode* eqp = new AstXor (nodep->fileline(), newAstWordSelClone (nodep->lhsp(), w), newAstWordSelClone (nodep->rhsp(), w)); newp = (newp==NULL) ? eqp : (new AstOr (nodep->fileline(), newp, eqp)); } if (nodep->castNeq()) { newp = new AstNeq (nodep->fileline(), new AstConst (nodep->fileline(), 0), newp); } else { newp = new AstEq (nodep->fileline(), new AstConst (nodep->fileline(), 0), newp); } replaceWithDelete(nodep,newp); nodep=NULL; } } virtual void visit(AstEq* nodep, AstNUser*) { visitEqNeq (nodep); } virtual void visit(AstNeq* nodep, AstNUser*) { visitEqNeq (nodep); } virtual void visit(AstRedOr* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; // Process once nodep->iterateChildren(*this); if (nodep->lhsp()->isWide()) { UINFO(8," Wordize REDOR "< (0!={or{for each_word{WORDSEL(lhs,#)}}} AstNode* newp = NULL; for (int w=0; wlhsp()->widthWords(); w++) { AstNode* eqp = newAstWordSelClone (nodep->lhsp(), w); newp = (newp==NULL) ? eqp : (new AstOr (nodep->fileline(), newp, eqp)); } newp = new AstNeq (nodep->fileline(), new AstConst (nodep->fileline(), 0), newp); replaceWithDelete(nodep,newp); nodep=NULL; } else { UINFO(8," REDOR->EQ "<lhsp()->unlinkFrBack(); V3Number zero (nodep->fileline(), longOrQuadWidth(nodep)); AstNode* newp = new AstNeq (nodep->fileline(), new AstConst (nodep->fileline(), zero), lhsp); replaceWithDelete(nodep,newp); nodep=NULL; } } virtual void visit(AstRedAnd* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; // Process once nodep->iterateChildren(*this); if (nodep->lhsp()->isWide()) { UINFO(8," Wordize REDAND "< (0!={and{for each_word{WORDSEL(lhs,#)}}} AstNode* newp = NULL; for (int w=0; wlhsp()->widthWords(); w++) { AstNode* eqp = newAstWordSelClone (nodep->lhsp(), w); if (w==nodep->lhsp()->widthWords()-1) { // Rather than doing a (slowish) ==##, we OR in the bits that aren't part of the mask eqp = new AstOr (nodep->fileline(), new AstConst (nodep->fileline(), notWideMask(nodep->lhsp())), eqp); } newp = (newp==NULL) ? eqp : (new AstAnd (nodep->fileline(), newp, eqp)); } newp = new AstEq (nodep->fileline(), new AstConst (nodep->fileline(), ~0), newp); replaceWithDelete(nodep, newp); nodep=NULL; } else { UINFO(8," REDAND->EQ "<lhsp()->unlinkFrBack(); AstNode* newp = new AstEq (nodep->fileline(), new AstConst (nodep->fileline(), wordMask(lhsp)), lhsp); replaceWithDelete(nodep,newp); nodep=NULL; } } virtual void visit(AstRedXor* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; // Process once nodep->iterateChildren(*this); if (nodep->lhsp()->isWide()) { UINFO(8," Wordize REDXOR "< (0!={redxor{for each_word{XOR(WORDSEL(lhs,#))}}} AstNode* newp = NULL; for (int w=0; wlhsp()->widthWords(); w++) { AstNode* eqp = newAstWordSelClone (nodep->lhsp(), w); newp = (newp==NULL) ? eqp : (new AstXor (nodep->fileline(), newp, eqp)); } newp = new AstRedXor (nodep->fileline(), newp); UINFO(8," Wordize REDXORnew "<user1SetOnce()) return; // Process once m_stmtp = nodep; nodep->iterateChildren(*this); m_stmtp = NULL; } virtual void visit(AstNodeAssign* nodep, AstNUser*) { if (nodep->user1SetOnce()) return; // Process once m_stmtp = nodep; nodep->iterateChildren(*this); bool did = false; if (nodep->isWide() && ((nodep->lhsp()->castVarRef() || nodep->lhsp()->castArraySel())) && !AstVar::scVarRecurse(nodep->lhsp()) // Need special function for SC && !AstVar::scVarRecurse(nodep->rhsp())) { if (AstConst* rhsp = nodep->rhsp()->castConst()) { did = expandWide(nodep,rhsp); } else if (AstVarRef* rhsp = nodep->rhsp()->castVarRef()) { did = expandWide(nodep,rhsp); } else if (AstSel* rhsp = nodep->rhsp()->castSel()) { did = expandWide(nodep,rhsp); } else if (AstArraySel* rhsp = nodep->rhsp()->castArraySel()) { did = expandWide(nodep,rhsp); } else if (AstConcat* rhsp = nodep->rhsp()->castConcat()) { did = expandWide(nodep,rhsp); } else if (AstReplicate* rhsp = nodep->rhsp()->castReplicate()) { did = expandWide(nodep,rhsp); } else if (AstAnd* rhsp = nodep->rhsp()->castAnd()) { did = expandWide(nodep,rhsp); } else if (AstOr* rhsp = nodep->rhsp()->castOr()) { did = expandWide(nodep,rhsp); } else if (AstNot* rhsp = nodep->rhsp()->castNot()) { did = expandWide(nodep,rhsp); } else if (AstXor* rhsp = nodep->rhsp()->castXor()) { did = expandWide(nodep,rhsp); } else if (AstXnor* rhsp = nodep->rhsp()->castXnor()) { did = expandWide(nodep,rhsp); } else if (AstNodeCond* rhsp = nodep->rhsp()->castNodeCond()) { did = expandWide(nodep,rhsp); } } else if (AstSel* lhsp = nodep->lhsp()->castSel()) { did = expandLhs(nodep,lhsp); } // Cleanup common code if (did) { nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } m_stmtp = NULL; } //-------------------- // Default: Just iterate virtual void visit(AstVar*, AstNUser*) {} // Don't hit varrefs under vars virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS ExpandVisitor(AstNetlist* nodep) { m_stmtp=NULL; nodep->accept(*this); } virtual ~ExpandVisitor() {} }; //---------------------------------------------------------------------- // Top loop //###################################################################### // Expand class functions void V3Expand::expandAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3Inline.cpp0000664000177100017500000005121712525171733016461 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add temporaries, such as for inline nodes // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Inline's Transformations: // // Each module: // Look for CELL... PRAGMA INLINE_MODULE // Replicate the cell's module // Convert pins to wires that make assignments // Rename vars to include cell name // Insert cell's module statements into the upper module // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include "V3Global.h" #include "V3Inline.h" #include "V3Inst.h" #include "V3Stats.h" #include "V3Ast.h" // CONFIG static const int INLINE_MODS_SMALLER = 100; // If a mod is < this # nodes, can always inline it //###################################################################### // Inline state, as a visitor of each AstNode class InlineMarkVisitor : public AstNVisitor { private: // NODE STATE // Output // AstNodeModule::user1() // OUTPUT: bool. User request to inline this module // Entire netlist (can be cleared after this visit completes) // AstNodeModule::user2() // CIL_*. Allowed to automatically inline module // AstNodeModule::user3() // int. Number of cells referencing this module AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser3InUse m_inuser3; enum {CIL_NOTHARD=0, // For user2, inline not supported CIL_NOTSOFT, // For user2, don't inline unless user overrides CIL_MAYBE}; // For user2, might inline // STATE AstNodeModule* m_modp; // Flattened cell's containing module int m_stmtCnt; // Statements in module V3Double0 m_statUnsup; // Statistic tracking // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void cantInline(const char* reason, bool hard) { if (hard) { if (m_modp->user2() != CIL_NOTHARD) { UINFO(4," No inline hard: "<user2(CIL_NOTHARD); ++m_statUnsup; } } else { if (m_modp->user2() == CIL_MAYBE) { UINFO(4," No inline soft: "<user2(CIL_NOTSOFT); } } } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { m_stmtCnt = 0; m_modp = nodep; m_modp->user2(CIL_MAYBE); if (m_modp->castIface()) { // Inlining an interface means we no longer have a cell handle to resolve to. // If inlining moves post-scope this can perhaps be relaxed. cantInline("modIface",true); } if (m_modp->modPublic()) cantInline("modPublic",false); // nodep->iterateChildren(*this); // bool userinline = nodep->user1(); int allowed = nodep->user2(); int refs = nodep->user3(); // Should we automatically inline this module? // inlineMult = 2000 by default. If a mod*#instances is < this # nodes, can inline it bool doit = ((allowed == CIL_NOTSOFT || allowed == CIL_MAYBE) && (userinline || ((allowed == CIL_MAYBE) && (refs==1 || m_stmtCnt < INLINE_MODS_SMALLER || v3Global.opt.inlineMult() < 1 || refs*m_stmtCnt < v3Global.opt.inlineMult())))); // Packages aren't really "under" anything so they confuse this algorithm if (nodep->castPackage()) doit = false; UINFO(4, " Inline="<user1(doit); m_modp = NULL; } virtual void visit(AstCell* nodep, AstNUser*) { nodep->modp()->user3Inc(); nodep->iterateChildren(*this); } virtual void visit(AstPragma* nodep, AstNUser*) { if (nodep->pragType() == AstPragmaType::INLINE_MODULE) { //UINFO(0,"PRAG MARK "<v3error("Inline pragma not under a module"); } else { m_modp->user1(1); } nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell... } else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) { if (!m_modp) { nodep->v3error("Inline pragma not under a module"); } else { cantInline("Pragma NO_INLINE_MODULE",false); } nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell... } else { nodep->iterateChildren(*this); } } virtual void visit(AstVarXRef* nodep, AstNUser*) { // Cleanup link until V3LinkDot can correct it nodep->varp(NULL); } virtual void visit(AstVar* nodep, AstNUser*) { // Can't look at AstIfaceRefDType directly as it is no longer underneath the module if (nodep->isIfaceRef()) { // Unsupported: Inlining of modules with ifaces (see AstIface comment above) if (m_modp) cantInline("Interfaced",true); } nodep->iterateChildren(*this); } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { // Cleanup link until V3LinkDot can correct it if (!nodep->packagep()) nodep->taskp(NULL); nodep->iterateChildren(*this); } // Nop's to speed up the loop virtual void visit(AstAlways* nodep, AstNUser*) { nodep->iterateChildren(*this); m_stmtCnt++; } virtual void visit(AstNodeAssign* nodep, AstNUser*) { // Don't count assignments, as they'll likely flatten out // Still need to iterate though to nullify VarXRefs int oldcnt = m_stmtCnt; nodep->iterateChildren(*this); m_stmtCnt = oldcnt; } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); m_stmtCnt++; } public: // CONSTUCTORS InlineMarkVisitor(AstNode* nodep) { m_modp = NULL; m_stmtCnt = 0; nodep->accept(*this); } virtual ~InlineMarkVisitor() { V3Stats::addStat("Optimizations, Inline unsupported", m_statUnsup); // Done with these, are not outputs AstNode::user2ClearTree(); AstNode::user3ClearTree(); } }; //###################################################################### // Using clonep(), find cell cross references. // clone() must not be called inside this visitor class InlineCollectVisitor : public AstNVisitor { private: // NODE STATE // Output: // AstCell::user4p() // AstCell* of the created clone static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstCell* nodep, AstNUser*) { nodep->user4p(nodep->clonep()); } // Accelerate virtual void visit(AstNodeStmt* nodep, AstNUser*) {} virtual void visit(AstNodeMath* nodep, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS InlineCollectVisitor(AstNodeModule* nodep) { // passed OLD module, not new one nodep->accept(*this); } virtual ~InlineCollectVisitor() {} }; //###################################################################### // After cell is cloned, relink the new module's contents class InlineRelinkVisitor : public AstNVisitor { private: // NODE STATE // Input: // See InlineVisitor // STATE AstNodeModule* m_modp; // Current module AstCell* m_cellp; // Cell being cloned static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstCellInline* nodep, AstNUser*) { // Inlined cell under the inline cell, need to move to avoid conflicts nodep->unlinkFrBack(); m_modp->addInlinesp(nodep); // Rename string name = m_cellp->name() + "__DOT__" + nodep->name(); nodep->name(name); UINFO(6, " Inline "<iterateChildren(*this); } virtual void visit(AstCell* nodep, AstNUser*) { // Cell under the inline cell, need to rename to avoid conflicts string name = m_cellp->name() + "__DOT__" + nodep->name(); nodep->name(name); nodep->iterateChildren(*this); } virtual void visit(AstVar* nodep, AstNUser*) { if (nodep->user2p()) { // Make an assignment, so we'll trace it properly // user2p is either a const or a var. AstConst* exprconstp = nodep->user2p()->castNode()->castConst(); AstVarRef* exprvarrefp = nodep->user2p()->castNode()->castVarRef(); UINFO(8,"connectto: "<user2p()->castNode()<v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up\n"); } if (exprconstp) { m_modp->addStmtp(new AstAssignW(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, true), exprconstp->cloneTree(true))); } else if (nodep->user3()) { // Public variable at the lower module end - we need to make sure we propagate // the logic changes up and down; if we aliased, we might remove the change detection // on the output variable. UINFO(9,"public pin assign: "<isInput()) nodep->v3fatalSrc("Outputs only - inputs use AssignAlias"); m_modp->addStmtp(new AstAssignW(nodep->fileline(), new AstVarRef(nodep->fileline(), exprvarrefp->varp(), true), new AstVarRef(nodep->fileline(), nodep, false))); } else if (nodep->isIfaceRef()) { m_modp->addStmtp(new AstAssignVarScope(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, true), new AstVarRef(nodep->fileline(), exprvarrefp->varp(), false))); AstNode* nodebp=exprvarrefp->varp(); nodep ->fileline()->modifyStateInherit(nodebp->fileline()); nodebp->fileline()->modifyStateInherit(nodep ->fileline()); } else { // Do to inlining child's variable now within the same module, so a AstVarRef not AstVarXRef below m_modp->addStmtp(new AstAssignAlias(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, true), new AstVarRef(nodep->fileline(), exprvarrefp->varp(), false))); AstNode* nodebp=exprvarrefp->varp(); nodep ->fileline()->modifyStateInherit(nodebp->fileline()); nodebp->fileline()->modifyStateInherit(nodep ->fileline()); } } // Variable under the inline cell, need to rename to avoid conflicts // Also clear I/O bits, as it is now local. string name = m_cellp->name() + "__DOT__" + nodep->name(); if (!nodep->isFuncLocal()) nodep->inlineAttrReset(name); if (!m_cellp->isTrace()) nodep->trace(false); if (debug()>=9) { nodep->dumpTree(cout,"varchanged:"); } if (debug()>=9) { nodep->valuep()->dumpTree(cout,"varchangei:"); } // Iterate won't hit AstIfaceRefDType directly as it is no longer underneath the module if (AstIfaceRefDType* ifacerefp = nodep->dtypep()->castIfaceRefDType()) { // Relink to point to newly cloned cell if (ifacerefp->cellp()) { if (AstCell* newcellp = ifacerefp->cellp()->user4p()->castNode()->castCell()) { ifacerefp->cellp(newcellp); ifacerefp->cellName(newcellp->name()); } } } nodep->iterateChildren(*this); } virtual void visit(AstNodeFTask* nodep, AstNUser*) { // Function under the inline cell, need to rename to avoid conflicts nodep->name(m_cellp->name() + "__DOT__" + nodep->name()); nodep->iterateChildren(*this); } virtual void visit(AstTypedef* nodep, AstNUser*) { // Typedef under the inline cell, need to rename to avoid conflicts nodep->name(m_cellp->name() + "__DOT__" + nodep->name()); nodep->iterateChildren(*this); } virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->varp()->user2p() // It's being converted to an alias. && !nodep->varp()->user3() && !nodep->backp()->castAssignAlias()) { // Don't constant propagate aliases (we just made) AstConst* exprconstp = nodep->varp()->user2p()->castNode()->castConst(); AstVarRef* exprvarrefp = nodep->varp()->user2p()->castNode()->castVarRef(); if (exprconstp) { nodep->replaceWith(exprconstp->cloneTree(true)); nodep->deleteTree(); nodep=NULL; return; } else if (exprvarrefp) { nodep->varp( exprvarrefp->varp() ); } else { nodep->v3fatalSrc("Null connection?\n"); } } nodep->name(nodep->varp()->name()); nodep->iterateChildren(*this); } virtual void visit(AstVarXRef* nodep, AstNUser*) { // Track what scope it was originally under so V3LinkDot can resolve it string newname = m_cellp->name(); if (nodep->inlinedDots() != "") { newname += "." + nodep->inlinedDots(); } nodep->inlinedDots(newname); UINFO(8," "<iterateChildren(*this); } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { // Track what scope it was originally under so V3LinkDot can resolve it string newname = m_cellp->name(); if (nodep->inlinedDots() != "") { newname += "." + nodep->inlinedDots(); } nodep->inlinedDots(newname); UINFO(8," "<iterateChildren(*this); } // Not needed, as V3LinkDot doesn't care about typedefs //virtual void visit(AstRefDType* nodep, AstNUser*) {} virtual void visit(AstScopeName* nodep, AstNUser*) { // If there's a %m in the display text, we add a special node that will contain the name() // Similar code in V3Begin // To keep correct visual order, must add before other Text's AstNode* afterp = nodep->scopeAttrp(); if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeAttrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name())); if (afterp) nodep->scopeAttrp(afterp); afterp = nodep->scopeEntrp(); if (afterp) afterp->unlinkFrBackWithNext(); nodep->scopeEntrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name())); if (afterp) nodep->scopeEntrp(afterp); nodep->iterateChildren(*this); } virtual void visit(AstCoverDecl* nodep, AstNUser*) { // Fix path in coverage statements nodep->hier(m_cellp->prettyName() + (nodep->hier()!="" ? ".":"") + nodep->hier()); nodep->iterateChildren(*this); } virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS InlineRelinkVisitor(AstNodeModule* cloneModp, AstNodeModule* oldModp, AstCell* cellp) { m_modp = oldModp; m_cellp = cellp; cloneModp->accept(*this); } virtual ~InlineRelinkVisitor() {} }; //###################################################################### // Inline state, as a visitor of each AstNode class InlineVisitor : public AstNVisitor { private: // NODE STATE // Cleared entire netlist // Input: // AstNodeModule::user1p() // bool. True to inline this module (from InlineMarkVisitor) // Cleared each cell // AstVar::user2p() // AstVarRef*/AstConst* Points to signal this is a direct connect to // AstVar::user3() // bool Don't alias the user2, keep it as signal // AstCell::user4 // AstCell* of the created clone AstUser4InUse m_inuser4; // STATE AstNodeModule* m_modp; // Current module V3Double0 m_statCells; // Statistic tracking static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } // VISITORS virtual void visit(AstNetlist* nodep, AstNUser*) { // Iterate modules backwards, in bottom-up order. Required! nodep->iterateChildrenBackwards(*this); } virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; nodep->iterateChildren(*this); } virtual void visit(AstCell* nodep, AstNUser*) { if (nodep->modp()->user1()) { // Marked with inline request UINFO(5," Inline CELL "<pinsp(); pinp; pinp=pinp->nextp()->castPin()) { if (!pinp->exprp()) continue; V3Inst::pinReconnectSimple(pinp, nodep, m_modp, false); } // Clone original module if (debug()>=9) { nodep->dumpTree(cout,"inlcell:"); } //if (debug()>=9) { nodep->modp()->dumpTree(cout,"oldmod:"); } AstNodeModule* newmodp = nodep->modp()->cloneTree(false); if (debug()>=9) { newmodp->dumpTree(cout,"newmod:"); } // Clear var markings and find cell cross references AstNode::user2ClearTree(); AstNode::user4ClearTree(); { InlineCollectVisitor(nodep->modp()); } // {} to destroy visitor immediately // Create data for dotted variable resolution AstCellInline* inlinep = new AstCellInline(nodep->fileline(), nodep->name(), nodep->modp()->origName()); m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells // Create assignments to the pins for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { if (!pinp->exprp()) continue; UINFO(6," Pin change from "<modVarp()<modVarp(); AstVar* pinNewVarp = pinOldVarp->clonep()->castVar(); AstNode* connectRefp = pinp->exprp(); if (!connectRefp->castConst() && !connectRefp->castVarRef()) { pinp->v3fatalSrc("Unknown interconnect type; pinReconnectSimple should have cleared up\n"); } if (pinNewVarp->isOutOnly() && connectRefp->castConst()) { pinp->v3error("Output port is connected to a constant pin, electrical short"); } // Propagate any attributes across the interconnect pinNewVarp->propagateAttrFrom(pinOldVarp); if (connectRefp->castVarRef()) { connectRefp->castVarRef()->varp()->propagateAttrFrom(pinOldVarp); } // One to one interconnect won't make a temporary variable. // This prevents creating a lot of extra wires for clock signals. // It will become a tracing alias. UINFO(6,"One-to-one "<user2p(connectRefp); // Public output inside the cell must go via an assign rather than alias // Else the public logic will set the alias, losing the value to be propagated up // (InOnly isn't a problem as the AssignAlias will create the assignment for us) pinNewVarp->user3(pinNewVarp->isSigUserRWPublic() && pinNewVarp->isOutOnly()); } // Cleanup var names, etc, to not conflict { InlineRelinkVisitor(newmodp, m_modp, nodep); } // Move statements to top module if (debug()>=9) { newmodp->dumpTree(cout,"fixmod:"); } AstNode* stmtsp = newmodp->stmtsp(); if (stmtsp) stmtsp->unlinkFrBackWithNext(); if (stmtsp) m_modp->addStmtp(stmtsp); // Remove the cell newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc nodep->unlinkFrBack(); pushDeletep(nodep); nodep = NULL; if (debug()>=9) { m_modp->dumpTree(cout,"donemod:"); } } } //-------------------- virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate virtual void visit(AstNodeStmt* nodep, AstNUser*) {} // Accelerate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS InlineVisitor(AstNode* nodep) { m_modp = NULL; nodep->accept(*this); } virtual ~InlineVisitor() { V3Stats::addStat("Optimizations, Inlined cells", m_statCells); } }; //###################################################################### // Inline class functions void V3Inline::inlineAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<modulesp(); modp; modp=nextmodp) { nextmodp = modp->nextp()->castNodeModule(); if (modp->user1()) { // Was inlined modp->unlinkFrBack()->deleteTree(); modp=NULL; } } V3Global::dumpCheckGlobalTree("inline.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); } verilator-3.874/src/V3ActiveTop.h0000664000177100017500000000230512525171733016600 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Break always into sensitivity block domains // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3ACTIVETOP_H_ #define _V3ACTIVETOP_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3ActiveTop { public: static void activeTopAll(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/V3Unknown.cpp0000664000177100017500000004372312525171733016705 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Add Unknown assigns // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Unknown's Transformations: // // Each module: // TBD: Eliminate tristates by adding __in, __inen, __en wires in parallel // Need __en in changed list if a signal is on the LHS of a assign // Constants: // RHS, Replace 5'bx_1_x with a module global we init to a random value // CONST(5'bx_1_x) -> VARREF(_{numberedtemp}) // -> VAR(_{numberedtemp}) // -> INITIAL(VARREF(_{numberedtemp}), OR(5'bx_1_x,AND(random,5'b0_1_x)) // OPTIMIZE: Must not collapse this initial back into the equation. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Unknown.h" #include "V3Ast.h" #include "V3Const.h" #include "V3Stats.h" //###################################################################### class UnknownVisitor : public AstNVisitor { private: // NODE STATE // Cleared on Netlist // AstSel::user() -> bool. Set true if already processed // AstArraySel::user() -> bool. Set true if already processed // AstNode::user2p() -> AstIf* Inserted if assignment for conditional AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; // STATE AstNodeModule* m_modp; // Current module bool m_constXCvt; // Convert X's V3Double0 m_statUnkVars; // Statistic tracking AstAssignW* m_assignwp; // Current assignment AstAssignDly* m_assigndlyp; // Current assignment // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void replaceBoundLvalue(AstNode* nodep, AstNode* condp) { // Spec says a out-of-range LHS SEL results in a NOP. // This is a PITA. We could: // 1. IF(...) around an ASSIGN, // but that would break a "foo[TOO_BIG]=$fopen(...)". // 2. Hack to extend the size of the output structure // by one bit, and write to that temporary, but never read it. // That makes there be two widths() and is likely a bug farm. // 3. Make a special SEL to choose between the real lvalue // and a temporary NOP register. // 4. Assign to a temp, then IF that assignment. // This is suspected to be nicest to later optimizations. // 4 seems best but breaks later optimizations. 3 was tried, // but makes a mess in the emitter as lvalue switching is needed. So 4. // SEL(...) -> temp // if (COND(LTE(bit<=maxlsb))) ASSIGN(SEL(...)),temp) if (m_assignwp) { // Wire assigns must become always statements to deal with insertion // of multiple statements. Perhaps someday make all wassigns into always's? UINFO(5," IM_WireRep "<convertToAlways(); pushDeletep(m_assignwp); m_assignwp=NULL; } bool needDly = (m_assigndlyp != NULL); if (m_assigndlyp) { // Delayed assignments become normal assignments, // then the temp created becomes the delayed assignment AstNode* newp = new AstAssign(m_assigndlyp->fileline(), m_assigndlyp->lhsp()->unlinkFrBackWithNext(), m_assigndlyp->rhsp()->unlinkFrBackWithNext()); m_assigndlyp->replaceWith(newp); pushDeletep(m_assigndlyp); m_assigndlyp=NULL; } AstNode* prep = nodep; // Scan back to put the condlvalue above all selects (IE top of the lvalue) while (prep->backp()->castNodeSel() || prep->backp()->castSel()) { prep=prep->backp(); } FileLine* fl = nodep->fileline(); nodep=NULL; // Zap it so we don't use it by mistake - use prep // Already exists; rather than IF(a,... IF(b... optimize to IF(a&&b, // Saves us teaching V3Const how to optimize, and it won't be needed again. if (AstIf* ifp = prep->user2p()->castNode()->castIf()) { if (needDly) prep->v3fatalSrc("Should have already converted to non-delay"); AstNRelinker replaceHandle; AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle); AstNode* newp = new AstLogAnd (condp->fileline(), condp, earliercondp); UINFO(4, "Edit BOUNDLVALUE "<varNumGetInc())); AstVar* varp = new AstVar(fl, AstVarType::MODULETEMP, name, prep->dtypep()); m_modp->addStmtp(varp); AstNode* abovep = prep->backp(); // Grab above point before lose it w/ next replace prep->replaceWith(new AstVarRef(fl, varp, true)); AstNode* newp = new AstIf(fl, condp, (needDly ? ((new AstAssignDly(fl, prep, new AstVarRef(fl, varp, false)))->castNode()) : ((new AstAssign (fl, prep, new AstVarRef(fl, varp, false)))->castNode())), NULL); if (debug()>=9) newp->dumpTree(cout," _new: "); abovep->addNextStmt(newp,abovep); prep->user2p(newp); // Save so we may LogAnd it next time } } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { UINFO(4," MOD "<iterateChildren(*this); m_modp = NULL; } virtual void visit(AstAssignDly* nodep, AstNUser*) { m_assigndlyp = nodep; nodep->iterateChildren(*this); nodep=NULL; // May delete nodep. m_assigndlyp = NULL; } virtual void visit(AstAssignW* nodep, AstNUser*) { m_assignwp = nodep; nodep->iterateChildren(*this); nodep=NULL; // May delete nodep. m_assignwp = NULL; } virtual void visit(AstCaseItem* nodep, AstNUser*) { m_constXCvt = false; // Avoid losing the X's in casex nodep->condsp()->iterateAndNext(*this); m_constXCvt = true; nodep->bodysp()->iterateAndNext(*this); } virtual void visit(AstNodeDType* nodep, AstNUser*) { m_constXCvt = false; // Avoid losing the X's in casex nodep->iterateChildren(*this); m_constXCvt = true; } void visitEqNeqCase(AstNodeBiop* nodep) { UINFO(4," N/EQCASE->EQ "<lhsp()); // lhsp may change V3Const::constifyEdit(nodep->rhsp()); // rhsp may change if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) { // Both sides are constant, node can be constant V3Const::constifyEdit(nodep); nodep=NULL; return; } else { AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* newp; // If we got ==1'bx it can never be true (but 1'bx==1'bx can be!) if (((lhsp->castConst() && lhsp->castConst()->num().isFourState()) || (rhsp->castConst() && rhsp->castConst()->num().isFourState()))) { V3Number num (nodep->fileline(), 1, (nodep->castEqCase()?0:1)); newp = new AstConst (nodep->fileline(), num); lhsp->deleteTree(); lhsp=NULL; rhsp->deleteTree(); rhsp=NULL; } else { if (nodep->castEqCase()) newp = new AstEq (nodep->fileline(), lhsp, rhsp); else newp = new AstNeq (nodep->fileline(), lhsp, rhsp); } nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; // Iterate tree now that we may have gotten rid of Xs newp->iterateChildren(*this); } } void visitEqNeqWild(AstNodeBiop* nodep) { UINFO(4," N/EQWILD->EQ "<lhsp()); // lhsp may change V3Const::constifyEdit(nodep->rhsp()); // rhsp may change if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) { // Both sides are constant, node can be constant V3Const::constifyEdit(nodep); nodep=NULL; return; } else { AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* newp; if (!rhsp->castConst()) { nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec. // Replace with anything that won't cause more errors newp = new AstEq (nodep->fileline(), lhsp, rhsp); } else { // X or Z's become mask, ala case statements. V3Number nummask (rhsp->fileline(), rhsp->width()); nummask.opBitsNonX(rhsp->castConst()->num()); V3Number numval (rhsp->fileline(), rhsp->width()); numval.opBitsOne (rhsp->castConst()->num()); AstNode* and1p = new AstAnd(nodep->fileline(), lhsp, new AstConst(nodep->fileline(), nummask)); AstNode* and2p = new AstConst(nodep->fileline(), numval); if (nodep->castEqWild()) newp = new AstEq (nodep->fileline(), and1p, and2p); else newp = new AstNeq (nodep->fileline(), and1p, and2p); rhsp->deleteTree(); rhsp=NULL; } nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; // Iterate tree now that we may have gotten rid of the compare newp->iterateChildren(*this); } } virtual void visit(AstEqCase* nodep, AstNUser*) { visitEqNeqCase(nodep); } virtual void visit(AstNeqCase* nodep, AstNUser*) { visitEqNeqCase(nodep); } virtual void visit(AstEqWild* nodep, AstNUser*) { visitEqNeqWild(nodep); } virtual void visit(AstNeqWild* nodep, AstNUser*) { visitEqNeqWild(nodep); } virtual void visit(AstIsUnknown* nodep, AstNUser*) { nodep->iterateChildren(*this); // Ahh, we're two state, so this is easy UINFO(4," ISUNKNOWN->0 "<fileline(), 1, 0); AstConst* newp = new AstConst (nodep->fileline(), zero); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; } virtual void visit(AstConst* nodep, AstNUser*) { if (m_constXCvt && nodep->num().isFourState()) { UINFO(4," CONST4 "<=9) nodep->dumpTree(cout," Const_old: "); // CONST(num) -> VARREF(newvarp) // -> VAR(newvarp) // -> INITIAL(VARREF(newvarp, OR(num_No_Xs,AND(random,num_1s_Where_X)) V3Number numb1 (nodep->fileline(), nodep->width()); numb1.opBitsOne(nodep->num()); V3Number numbx (nodep->fileline(), nodep->width()); numbx.opBitsXZ(nodep->num()); if (v3Global.opt.xAssign()!="unique") { // All X bits just become 0; fastest simulation, but not nice V3Number numnew (nodep->fileline(), numb1.width()); if (v3Global.opt.xAssign()=="1") { numnew.opOr(numb1, numbx); } else { numnew.opAssign(numb1); } AstConst* newp = new AstConst(nodep->fileline(), numnew); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; UINFO(4," -> "<v3fatalSrc("X number not under module"); string newvarname = ((string)"__Vxrand" +cvtToStr(m_modp->varNumGetInc())); AstVar* newvarp = new AstVar (nodep->fileline(), AstVarType::XTEMP, newvarname, VFlagLogicPacked(), nodep->width()); ++m_statUnkVars; AstNRelinker replaceHandle; nodep->unlinkFrBack(&replaceHandle); AstNodeVarRef* newref1p = new AstVarRef(nodep->fileline(), newvarp, false); replaceHandle.relink(newref1p); // Replace const with varref AstInitial* newinitp = new AstInitial( nodep->fileline(), new AstAssign( nodep->fileline(), new AstVarRef(nodep->fileline(), newvarp, true), new AstOr(nodep->fileline(), new AstConst(nodep->fileline(),numb1), new AstAnd(nodep->fileline(), new AstConst(nodep->fileline(),numbx), new AstRand(nodep->fileline(), nodep->dtypep(), true))))); // Add inits in front of other statement. // In the future, we should stuff the initp into the module's constructor. AstNode* afterp = m_modp->stmtsp()->unlinkFrBackWithNext(); m_modp->addStmtp(newvarp); m_modp->addStmtp(newinitp); m_modp->addStmtp(afterp); if (debug()>=9) newref1p->dumpTree(cout," _new: "); if (debug()>=9) newvarp->dumpTree(cout," _new: "); if (debug()>=9) newinitp->dumpTree(cout," _new: "); nodep->deleteTree(); nodep=NULL; } } } void visit(AstSel* nodep, AstNUser*) { nodep->iterateChildren(*this); if (!nodep->user1SetOnce()) { // Guard against reading/writing past end of bit vector array AstNode* basefromp = AstArraySel::baseFromp(nodep); bool lvalue = false; if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { lvalue = varrefp->lvalue(); } // Find range of dtype we are selecting from // Similar code in V3Const::warnSelect int maxmsb = nodep->fromp()->dtypep()->width()-1; if (debug()>=9) nodep->dumpTree(cout,"sel_old: "); V3Number maxmsbnum (nodep->fileline(), nodep->lsbp()->width(), maxmsb); // If (maxmsb >= selected), we're in bound AstNode* condp = new AstGte (nodep->fileline(), new AstConst(nodep->fileline(), maxmsbnum), nodep->lsbp()->cloneTree(false)); // See if the condition is constant true (e.g. always in bound due to constant select) // Note below has null backp(); the Edit function knows how to deal with that. condp = V3Const::constifyEdit(condp); if (condp->isOne()) { // We don't need to add a conditional; we know the existing expression is ok condp->deleteTree(); } else if (!lvalue) { // SEL(...) -> COND(LTE(bit<=maxmsb), ARRAYSEL(...), {width{1'bx}}) AstNRelinker replaceHandle; nodep->unlinkFrBack(&replaceHandle); V3Number xnum (nodep->fileline(), nodep->width()); xnum.setAllBitsX(); AstNode* newp = new AstCondBound (nodep->fileline(), condp, nodep, new AstConst(nodep->fileline(), xnum)); if (debug()>=9) newp->dumpTree(cout," _new: "); // Link in conditional replaceHandle.relink(newp); // Added X's, tristate them too newp->accept(*this); } else { // lvalue replaceBoundLvalue(nodep, condp); } } } virtual void visit(AstArraySel* nodep, AstNUser*) { nodep->iterateChildren(*this); if (!nodep->user1SetOnce()) { if (debug()==9) nodep->dumpTree(cout,"-in: "); // Guard against reading/writing past end of arrays AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp()); bool lvalue = false; if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { lvalue = varrefp->lvalue(); } else if (basefromp->castConst()) { // If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp } else { nodep->v3fatalSrc("No VarRef or Const under ArraySel\n"); } // Find range of dtype we are selecting from int declElements = -1; AstNodeDType* dtypep = nodep->fromp()->dtypep()->skipRefp(); if (!dtypep) nodep->v3fatalSrc("Select of non-selectable type"); if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { declElements = adtypep->elementsConst(); } else { nodep->v3error("Select from non-array "<prettyTypeName()); } if (debug()>=9) nodep->dumpTree(cout,"arraysel_old: "); V3Number widthnum (nodep->fileline(), nodep->bitp()->width(), declElements-1); // See if the condition is constant true AstNode* condp = new AstGte (nodep->fileline(), new AstConst(nodep->fileline(), widthnum), nodep->bitp()->cloneTree(false)); // Note below has null backp(); the Edit function knows how to deal with that. condp = V3Const::constifyEdit(condp); if (condp->isOne()) { // We don't need to add a conditional; we know the existing expression is ok condp->deleteTree(); } else if (!lvalue && !nodep->backp()->castArraySel()) { // Too complicated and slow if mid-multidimension // ARRAYSEL(...) -> COND(LT(bitunlinkFrBack(&replaceHandle); V3Number xnum (nodep->fileline(), nodep->width()); if (nodep->isString()) { xnum = V3Number(V3Number::String(), nodep->fileline(), ""); } else { xnum.setAllBitsX(); } AstNode* newp = new AstCondBound (nodep->fileline(), condp, nodep, new AstConst(nodep->fileline(), xnum)); if (debug()>=9) newp->dumpTree(cout," _new: "); // Link in conditional, can blow away temp xor replaceHandle.relink(newp); // Added X's, tristate them too newp->accept(*this); } else if (!lvalue) { // Mid-multidimension read, just use zero // ARRAYSEL(...) -> ARRAYSEL(COND(LT(bitbitp()->unlinkFrBack(&replaceHandle); V3Number zeronum (nodep->fileline(), bitp->width(), 0); AstNode* newp = new AstCondBound (bitp->fileline(), condp, bitp, new AstConst(bitp->fileline(), zeronum)); // Added X's, tristate them too if (debug()>=9) newp->dumpTree(cout," _new: "); replaceHandle.relink(newp); newp->accept(*this); } else { // lvalue replaceBoundLvalue(nodep, condp); } } } //-------------------- // Default: Just iterate virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS UnknownVisitor(AstNetlist* nodep) { m_modp = NULL; m_assigndlyp = NULL; m_assignwp = NULL; m_constXCvt = false; nodep->accept(*this); } virtual ~UnknownVisitor() { V3Stats::addStat("Unknowns, variables created", m_statUnkVars); } }; //###################################################################### // Unknown class functions void V3Unknown::unknownAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/flexfix0000775000177100017500000000323412525171734015716 0ustar wsnyderwsnyder#!/usr/bin/perl -w ###################################################################### # # Copyright 2002-2015 by Wilson Snyder. Verilator 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ###################################################################### # DESCRIPTION: Edits flex output to get around various broken flex issues. my $Opt_Prefix = $ARGV[0] or die "%Error: No prefix specified,"; foreach my $line () { # Fix flex 2.5.4 namespace omission $line =~ s/^class istream;/\#include \nusing namespace std;\n/; # Fix flex 2.5.31 redefinition $line =~ s!(\#define\s+yyFlexLexer\s+yyFlexLexer)!//flexfix: $1!g; # Fix flex 2.5.1 yytext_ptr undef $line =~ s!(\#undef\s+yytext_ptr)!//flexfix: $1!g; # Fix flex 2.5.4 and GCC 4.1.0 warn_unused_result $line =~ s!\(void\) *fwrite\((.*)\)!if (fwrite($1)) {}!g; # Fix flex 2.5.33 and GCC 4.1.2 "warning: comparison between signed and unsigned integer expressions" in YY_INPUT $line =~ s!for \( n = 0; n < max_size && !for ( n = 0; ((size_t)n < (size_t)max_size) && !g; # Fix flex 2.5.4 and GCC 4.0.2 under FLEX_DEBUG $line =~ s!--accepting rule at line %d !--accepting rule at line %ld !g; # Fix compiler warning filenames $line =~ s!(#line \d+ ".*)_pretmp!$1!; print "$line"; } verilator-3.874/src/V3LinkDot.cpp0000664000177100017500000024732212525171733016613 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Resolve module/signal name references // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // LinkDot TRANSFORMATIONS: // Top-down traversal in LinkDotFindVisitor // Cells: // Make graph of cell hierarchy // Var/Funcs's: // Collect all names into symtable under appropriate cell // Top-down traversal in LinkDotScopeVisitor // Find VarScope versions of signals (well past original link) // Top-down traversal in LinkDotParamVisitor // Create implicit signals // Top-down traversal in LinkDotResolveVisitor // VarXRef/Func's: // Find appropriate named cell and link to var they reference //************************************************************************* // Interfaces: // CELL (.port (ifref) // ^--- cell -> IfaceDTypeRef(iface) // ^--- cell.modport -> IfaceDTypeRef(iface,modport) // ^--- varref(input_ifref) -> IfaceDTypeRef(iface) // ^--- varref(input_ifref).modport -> IfaceDTypeRef(iface,modport) // FindVisitor: // #1: Insert interface Vars // #2: Insert ModPort names // IfaceVisitor: // #3: Update ModPortVarRef to point at interface vars (after #1) // #4: Create ModPortVarRef symbol table entries // FindVisitor-insertIfaceRefs() // #5: Resolve IfaceRefDtype modport names (after #2) // #7: Record sym of IfaceRefDType and aliased interface and/or modport (after #4,#5) // insertAllScopeAliases(): // #8: Insert modport's symbols under IfaceRefDType (after #7) // ResolveVisitor: // #9: Resolve general variables, which may point into the interface or modport (after #8) //************************************************************************* // TOP // {name-of-top-modulename} // a (VSymEnt->AstCell) // {name-of-cell} // {name-of-cell-module} // aa (VSymEnt->AstCell) // var (AstVar) -- no sub symbol table needed // beg (VSymEnt->AstBegin) -- can see "upper" a's symbol table // a__DOT__aa (VSymEnt->AstCellInline) -- points to a.aa's symbol table // b (VSymEnt->AstCell) //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include #include #include "V3Global.h" #include "V3LinkDot.h" #include "V3SymTable.h" #include "V3Graph.h" #include "V3Ast.h" //###################################################################### // LinkDot state, as a visitor of each AstNode class LinkDotState { private: // NODE STATE // Cleared on Netlist // AstNodeModule::user1p() // VSymEnt*. Last symbol created for this node // ... Note maybe more than one, as can be multiple hierarchy places // AstVarScope::user2p() // AstVarScope*. Base alias for AstInline of this signal // AstVar::user2p() // AstFTask*. If a function variable, the task that links to the variable // AstVar::user4() // bool. True if port set for this variable // AstBegin::user4() // bool. Did name processing // AstNodeModule::user4() // bool. Live module AstUser1InUse m_inuser1; AstUser2InUse m_inuser2; AstUser4InUse m_inuser4; public: // ENUMS // In order of priority, compute first ... compute last enum SAMNum { SAMN_MODPORT, SAMN_IFTOP, SAMN__MAX }; // Values for m_scopeAliasMap private: // TYPES typedef multimap NameScopeSymMap; typedef map ScopeAliasMap; typedef set > ImplicitNameSet; typedef vector IfaceVarSyms; typedef vector > IfaceModSyms; static LinkDotState* s_errorThisp; // Last self, for error reporting only // MEMBERS VSymGraph m_syms; // Symbol table VSymEnt* m_dunitEntp; // $unit entry NameScopeSymMap m_nameScopeSymMap; // Map of scope referenced by non-pretty textual name ImplicitNameSet m_implicitNameSet; // For [module][signalname] if we can implicitly create it ScopeAliasMap m_scopeAliasMap[SAMN__MAX]; // Map of aliases IfaceVarSyms m_ifaceVarSyms; // List of AstIfaceRefDType's to be imported IfaceModSyms m_ifaceModSyms; // List of AstIface+Symbols to be processed bool m_forPrimary; // First link bool m_forPrearray; // Compress cell__[array] refs bool m_forScopeCreation; // Remove VarXRefs for V3Scope public: static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void dump(const string& nameComment="linkdot", bool force=false) { if (debug()>=6 || force) { string filename = v3Global.debugFilename(nameComment)+".txt"; const VL_UNIQUE_PTR logp (V3File::new_ofstream(filename)); if (logp->fail()) v3fatalSrc("Can't write "<first<<" ("<first->nodep()->typeName() <<") <- "<second<<" "<second->nodep()<preErrorDump(); } void preErrorDump() { static bool diddump = false; if (!diddump && v3Global.opt.dumpTree()) { diddump = true; dump("linkdot-preerr",true); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("linkdot-preerr.tree")); } } // CONSTRUCTORS LinkDotState(AstNetlist* rootp, VLinkDotStep step) : m_syms(rootp) { UINFO(4,__FUNCTION__<<": "<castVar()) return "variable"; else if (nodep->castCell()) return "cell"; else if (nodep->castTask()) return "task"; else if (nodep->castFunc()) return "function"; else if (nodep->castBegin()) return "block"; else if (nodep->castIface()) return "interface"; else return nodep->prettyTypeName(); } VSymEnt* rootEntp() const { return m_syms.rootp(); } VSymEnt* dunitEntp() const { return m_dunitEntp; } void checkDuplicate(VSymEnt* lookupSymp, AstNode* nodep, const string& name) { // Lookup the given name under current symbol table // Insert if not found // Report error if there's a duplicate // // Note we only check for conflicts at the same level; it's ok if one block hides another // We also wouldn't want to not insert it even though it's lower down VSymEnt* foundp = lookupSymp->findIdFlat(name); AstNode* fnodep = foundp->nodep(); if (!fnodep) { // Not found, will add in a moment. } else if (nodep==fnodep) { // Already inserted. // Good. } else if (foundp->imported()) { // From package // We don't throw VARHIDDEN as if the import is later the symbol table's import wouldn't warn } else if (nodep->castBegin() && fnodep->castBegin() && nodep->castBegin()->generate()) { // Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks // See t_gen_forif.v for an example. } else { UINFO(4,"name "<name UINFO(4,"Var1 "<type() == fnodep->type()) { nodep->v3error("Duplicate declaration of "<prettyName()<warnMore()<<"... Location of original declaration"); } else { nodep->v3error("Unsupported in C: "<prettyName()<warnMore()<<"... Location of original declaration"); } } } void insertDUnit(AstNetlist* nodep) { // $unit on top scope VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTdunit se"<<(void*)symp<parentp(rootEntp()); // Needed so backward search can find name of top module symp->fallbackp(NULL); rootEntp()->insert("$unit ",symp); // Space so can never name conflict with user code // if (m_dunitEntp) nodep->v3fatalSrc("Call insertDUnit only once"); m_dunitEntp = symp; } VSymEnt* insertTopCell(AstNodeModule* nodep, const string& scopename) { // Only called on the module at the very top of the hierarchy VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTtop se"<<(void*)symp<<" "<parentp(rootEntp()); // Needed so backward search can find name of top module symp->fallbackp(dunitEntp()); // Needed so can find $unit stuff nodep->user1p(symp); checkDuplicate(rootEntp(), nodep, nodep->origName()); rootEntp()->insert(nodep->origName(),symp); if (forScopeCreation()) m_nameScopeSymMap.insert(make_pair(scopename, symp)); return symp; } VSymEnt* insertCell(VSymEnt* abovep, VSymEnt* modSymp, AstCell* nodep, const string& scopename) { if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTcel se"<<(void*)symp<<" "<reinsert(nodep->name(), symp); } if (forScopeCreation()) m_nameScopeSymMap.insert(make_pair(scopename, symp)); return symp; } VSymEnt* insertInline(VSymEnt* abovep, VSymEnt* modSymp, AstCellInline* nodep, const string& basename) { // A fake point in the hierarchy, corresponding to an inlined module // This refrences to another Sym, and eventually resolves to a module with a prefix if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTinl se"<<(void*)symp<<" "<user1p(symp); checkDuplicate(abovep, nodep, nodep->name()); abovep->reinsert(basename, symp); if (abovep != modSymp && !modSymp->findIdFlat(nodep->name())) { // If it's foo_DOT_bar, we need to be able to find it under that too. modSymp->reinsert(nodep->name(), symp); } return symp; } VSymEnt* insertBlock(VSymEnt* abovep, const string& name, AstNode* nodep, AstPackage* packagep) { // A fake point in the hierarchy, corresponding to a begin or function/task block // After we remove begins these will go away // Note we fallback to the symbol table of the parent, as we want to find variables there // However, cells walk the graph, so cells will appear under the begin/ftask itself if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTblk se"<<(void*)symp<<" above=se"<<(void*)abovep<<" node="<parentp(abovep); symp->packagep(packagep); symp->fallbackp(abovep); nodep->user1p(symp); if (name != "") { checkDuplicate(abovep, nodep, name); } // Duplicates are possible, as until resolve generates might have 2 same cells under an if abovep->reinsert(name, symp); return symp; } VSymEnt* insertSym(VSymEnt* abovep, const string& name, AstNode* nodep, AstPackage* packagep) { if (!abovep) nodep->v3fatalSrc("Null symbol table inserting node"); VSymEnt* symp = new VSymEnt(&m_syms, nodep); UINFO(9," INSERTsym se"<<(void*)symp<<" name='"<name()); if (it == m_nameScopeSymMap.end()) { nodep->v3fatalSrc("Scope never assigned a symbol entry?"); } return it->second; } void implicitOkAdd(AstNodeModule* nodep, const string& varname) { // Mark the given variable name as being allowed to be implicitly declared if (nodep) { ImplicitNameSet::iterator it = m_implicitNameSet.find(make_pair(nodep,varname)); if (it == m_implicitNameSet.end()) { m_implicitNameSet.insert(make_pair(nodep,varname)); } } } bool implicitOk(AstNodeModule* nodep, const string& varname) { return nodep && (m_implicitNameSet.find(make_pair(nodep,varname)) != m_implicitNameSet.end()); } // Track and later recurse interface modules void insertIfaceModSym(AstIface* nodep, VSymEnt* symp) { m_ifaceModSyms.push_back(make_pair(nodep, symp)); } void computeIfaceModSyms(); // Track and later insert interface references void insertIfaceVarSym(VSymEnt* symp) { // Where sym is for a VAR of dtype IFACEREFDTYPE m_ifaceVarSyms.push_back(symp); } void computeIfaceVarSyms() { for (IfaceVarSyms::iterator it = m_ifaceVarSyms.begin(); it != m_ifaceVarSyms.end(); ++it) { VSymEnt* varSymp = *it; AstVar* varp = varSymp->nodep()->castVar(); UINFO(9, " insAllIface se"<<(void*)varSymp<<" "<subDTypep()->castIfaceRefDType(); if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!"); if (!ifacerefp->ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface"); VSymEnt* ifaceSymp = getNodeSym(ifacerefp->ifaceViaCellp()); VSymEnt* ifOrPortSymp = ifaceSymp; // Link Modport names to the Modport Node under the Interface if (ifacerefp->isModport()) { VSymEnt* foundp = ifaceSymp->findIdFallback(ifacerefp->modportName()); bool ok = false; if (foundp) { if (AstModport* modportp = foundp->nodep()->castModport()) { UINFO(4,"Link Modport: "<modportp(modportp); ifOrPortSymp = foundp; ok = true; } } if (!ok) ifacerefp->v3error("Modport not found under interface '" <prettyName(ifacerefp->ifaceName()) <<"': "<prettyName(ifacerefp->modportName())); } // Alias won't expand until interfaces and modport names are known; see notes at top insertScopeAlias(SAMN_IFTOP, varSymp, ifOrPortSymp); } m_ifaceVarSyms.clear(); } void insertScopeAlias(SAMNum samn, VSymEnt* lhsp, VSymEnt* rhsp) { // Track and later insert scope aliases; an interface referenced by a child cell connecting to that interface // Typically lhsp=VAR w/dtype IFACEREF, rhsp=IFACE cell UINFO(9," insertScopeAlias se"<<(void*)lhsp<<" se"<<(void*)rhsp<first; VSymEnt* srcp = lhsp; while (1) { // Follow chain of aliases up to highest level non-alias ScopeAliasMap::iterator it2 = m_scopeAliasMap[samn].find(srcp); if (it2 != m_scopeAliasMap[samn].end()) { srcp = it2->second; continue; } else break; } UINFO(9," iiasa: Insert alias se"<nodep()->typeName() <<") <- se"<nodep()<importFromIface(symsp(), srcp); } //m_scopeAliasMap[samn].clear(); // Done with it, but put into debug file } } private: VSymEnt* findWithAltFallback(VSymEnt* symp, const string& name, const string& altname) { VSymEnt* findp = symp->findIdFallback(name); if (findp) return findp; if (altname != "") { UINFO(8," alt fallback\n"); findp = symp->findIdFallback(altname); } return findp; } public: VSymEnt* findDotted(VSymEnt* lookupSymp, const string& dotname, string& baddot, VSymEnt*& okSymp) { // Given a dotted hierarchy name, return where in scope it is // Note when dotname=="" we just fall through and return lookupSymp UINFO(8," dottedFind se"<<(void*)lookupSymp<<" '"<nodep()->castCell(); // Replicated below AstCellInline* inlinep = lookupSymp->nodep()->castCellInline(); // Replicated below if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) { lookupSymp = findSymp; } // Check this module - cur modname else if ((cellp && cellp->modp()->origName() == ident) || (inlinep && inlinep->origModName() == ident)) {} // Move up and check cellname + modname else { while (lookupSymp) { lookupSymp = lookupSymp->parentp(); cellp = lookupSymp->nodep()->castCell(); // Replicated above inlinep = lookupSymp->nodep()->castCellInline(); // Replicated above if (lookupSymp) { UINFO(9,"\t\tUp to "<modp()->origName() == ident) || (inlinep && inlinep->origModName() == ident)) { break; } else if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) { lookupSymp = findSymp; break; } } else break; } if (!lookupSymp) return NULL; // Not found } } else { // Searching for middle submodule, must be a cell name if (VSymEnt* findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) { lookupSymp = findSymp; } else { return NULL; // Not found } } firstId = false; } return lookupSymp; } VSymEnt* findSymPrefixed(VSymEnt* lookupSymp, const string& dotname, string& baddot) { // Find symbol in given point in hierarchy, allowing prefix (post-Inline) // For simplicity lookupSymp may be passed NULL result from findDotted if (!lookupSymp) return NULL; UINFO(8,"\t\tfindSymPrefixed "<symPrefix()=="") ? "" : " as ") <<((lookupSymp->symPrefix()=="") ? "" : lookupSymp->symPrefix()+dotname) <<" at se"<findIdFallback(lookupSymp->symPrefix() + dotname); // Might be NULL if (!foundp) baddot = dotname; return foundp; } }; LinkDotState* LinkDotState::s_errorThisp = NULL; //====================================================================== class LinkDotFindVisitor : public AstNVisitor { // STATE LinkDotState* m_statep; // State to pass between visitors, including symbol table AstPackage* m_packagep; // Current package VSymEnt* m_modSymp; // Symbol Entry for current module VSymEnt* m_curSymp; // Symbol Entry for current table, where to lookup/insert string m_scope; // Scope text AstBegin* m_beginp; // Current Begin/end block AstNodeFTask* m_ftaskp; // Current function/task bool m_inGenerate; // Inside a generate int m_paramNum; // Parameter number, for position based connection int m_beginNum; // Begin block number, 0=none seen int m_modBeginNum; // Begin block number in module, 0=none seen // METHODS int debug() { return LinkDotState::debug(); } // VISITs virtual void visit(AstNetlist* nodep, AstNUser*) { // Process $unit or other packages // Not needed - dotted references not allowed from inside packages //for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) { // if (nodep->castPackage()) {}} m_statep->insertDUnit(nodep); // First back iterate, to find all packages. Backward as must do base packages before using packages nodep->iterateChildrenBackwards(*this); // The first module in the list is always the top module (sorted before this is called). // This may not be the module with isTop() set, as early in the steps, // wrapTop may have not been created yet. AstNodeModule* topmodp = nodep->modulesp(); if (!topmodp) { nodep->v3error("No top level module found"); } else { UINFO(8,"Top Module: "<insertTopCell(topmodp, m_scope); { topmodp->accept(*this); } m_scope = ""; m_curSymp = m_modSymp = NULL; } } virtual void visit(AstTypeTable* nodep, AstNUser*) {} virtual void visit(AstNodeModule* nodep, AstNUser*) { // Called on top module from Netlist, other modules from the cell creating them, // and packages UINFO(8," "<forPrearray() && nodep->castPackage()); bool doit = (m_modSymp || standalonePkg); string oldscope = m_scope; VSymEnt* oldModSymp = m_modSymp; VSymEnt* oldCurSymp = m_curSymp; int oldParamNum = m_paramNum; int oldBeginNum = m_beginNum; int oldModBeginNum = m_modBeginNum; if (doit) { UINFO(2," Link Module: "<dead()) nodep->v3fatalSrc("Module in cell tree mislabeled as dead?"); VSymEnt* upperSymp = m_curSymp ? m_curSymp : m_statep->rootEntp(); m_packagep = nodep->castPackage(); if (standalonePkg) { if (m_packagep->isDollarUnit()) { m_curSymp = m_modSymp = m_statep->dunitEntp(); nodep->user1p(m_curSymp); } else { m_scope = nodep->name(); m_curSymp = m_modSymp = m_statep->insertBlock(upperSymp, nodep->name()+"::", nodep, m_packagep); UINFO(9, "New module scope "<iterateChildren(*this); nodep->user4(true); // Interfaces need another pass when signals are resolved if (AstIface* ifacep = nodep->castIface()) { m_statep->insertIfaceModSym(ifacep, m_curSymp); } } else { //!doit // Will be optimized away later // Can't remove now, as our backwards iterator will throw up UINFO(5, "Module not under any CELL or top - dead module: "<forScopeCreation()) v3fatalSrc("Scopes should only exist right after V3Scope"); // Ignored. Processed in next step } virtual void visit(AstCell* nodep, AstNUser*) { UINFO(5," CELL under "<iterateChildren(*this); // Recurse in, preserving state string oldscope = m_scope; AstBegin* oldbeginp = m_beginp; VSymEnt* oldModSymp = m_modSymp; VSymEnt* oldCurSymp = m_curSymp; int oldParamNum = m_paramNum; // Where do we add it? VSymEnt* aboveSymp = m_curSymp; string origname = AstNode::dedotName(nodep->name()); string::size_type pos; if ((pos = origname.rfind(".")) != string::npos) { // Flattened, find what CellInline it should live under string scope = origname.substr(0,pos); string baddot; VSymEnt* okSymp; aboveSymp = m_statep->findDotted(aboveSymp, scope, baddot, okSymp); if (!aboveSymp) { nodep->v3fatalSrc("Can't find cell insertion point at '"<prettyName()); } } { m_scope = m_scope+"."+nodep->name(); m_curSymp = m_modSymp = m_statep->insertCell(aboveSymp, m_modSymp, nodep, m_scope); m_beginp = NULL; if (nodep->modp()) nodep->modp()->accept(*this); } m_scope = oldscope; m_beginp = oldbeginp; m_modSymp = oldModSymp; m_curSymp = oldCurSymp; m_paramNum = oldParamNum; } virtual void visit(AstCellInline* nodep, AstNUser*) { UINFO(5," CELLINLINE under "<name(); string::size_type pos; if ((pos=dottedname.rfind("__DOT__")) != string::npos) { string dotted = dottedname.substr(0, pos); string ident = dottedname.substr(pos+strlen("__DOT__")); string baddot; VSymEnt* okSymp; aboveSymp = m_statep->findDotted(aboveSymp, dotted, baddot, okSymp); if (!aboveSymp) { nodep->v3fatalSrc("Can't find cellinline insertion point at '"<prettyName()); } m_statep->insertInline(aboveSymp, m_modSymp, nodep, ident); } else { // No __DOT__, just directly underneath m_statep->insertInline(aboveSymp, m_modSymp, nodep, nodep->name()); } } virtual void visit(AstDefParam* nodep, AstNUser*) { nodep->user1p(m_curSymp); nodep->iterateChildren(*this); } virtual void visit(AstGenerate* nodep, AstNUser*) { // Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks // See t_gen_forif.v for an example. bool lastInGen = m_inGenerate; { m_inGenerate = true; nodep->iterateChildren(*this); } m_inGenerate = lastInGen; } virtual void visit(AstBegin* nodep, AstNUser*) { UINFO(5," "<forPrimary() && !nodep->user4SetOnce()) { if (nodep->name() == "genblk") { ++m_beginNum; nodep->name(nodep->name()+cvtToStr(m_beginNum)); } // Just for loop index, make special name. The [00] is so it will "dearray" to same // name as after we expand the GENFOR if (nodep->genforp()) nodep->name(nodep->name()); } // All blocks are numbered in the standard, IE we start with "genblk1" even if only one. if (nodep->name()=="" && nodep->unnamed()) { // Unnamed blocks are only important when they contain var // decls, so search for them. (Otherwise adding all the // unnamed#'s would just confuse tracing variables in // places such as tasks, where "task ...; begin ... end" // are common. for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp=stmtp->nextp()) { if (stmtp->castVar()) { ++m_modBeginNum; nodep->name("unnamedblk"+cvtToStr(m_modBeginNum)); break; } } } int oldNum = m_beginNum; AstBegin* oldbegin = m_beginp; VSymEnt* oldCurSymp = m_curSymp; { m_beginNum = 0; m_beginp = nodep; m_curSymp = m_statep->insertBlock(m_curSymp, nodep->name(), nodep, m_packagep); m_curSymp->fallbackp(oldCurSymp); // Iterate nodep->iterateChildren(*this); } m_curSymp = oldCurSymp; m_beginp = oldbegin; m_beginNum = oldNum; } virtual void visit(AstNodeFTask* nodep, AstNUser*) { // NodeTask: Remember its name for later resolution UINFO(5," "<v3fatalSrc("Function/Task not under module??\n"); // Remember the existing symbol table scope VSymEnt* oldCurSymp = m_curSymp; { // Create symbol table for the task's vars m_curSymp = m_statep->insertBlock(m_curSymp, nodep->name(), nodep, m_packagep); m_curSymp->fallbackp(oldCurSymp); // Convert the func's range to the output variable // This should probably be done in the Parser instead, as then we could // just attact normal signal attributes to it. if (nodep->fvarp() && !nodep->fvarp()->castVar()) { AstNodeDType* dtypep = nodep->fvarp()->castNodeDType(); // If unspecified, function returns one bit; however when we support NEW() it could // also return the class reference. if (dtypep) dtypep->unlinkFrBack(); else dtypep = new AstBasicDType(nodep->fileline(), AstBasicDTypeKwd::LOGIC); AstVar* newvarp = new AstVar(nodep->fileline(), AstVarType::OUTPUT, nodep->name(), VFlagChildDType(), dtypep); // Not dtype resolved yet newvarp->funcReturn(true); newvarp->trace(false); // Not user visible newvarp->attrIsolateAssign(nodep->attrIsolateAssign()); nodep->addFvarp(newvarp); // Explicit insert required, as the var name shadows the upper level's task name m_statep->insertSym(m_curSymp, newvarp->name(), newvarp, NULL/*packagep*/); } m_ftaskp = nodep; nodep->iterateChildren(*this); m_ftaskp = NULL; } m_curSymp = oldCurSymp; } virtual void visit(AstVar* nodep, AstNUser*) { // Var: Remember its name for later resolution if (!m_curSymp || !m_modSymp) nodep->v3fatalSrc("Var not under module??\n"); nodep->iterateChildren(*this); if (!m_statep->forScopeCreation()) { // Find under either a task or the module's vars VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name()); if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) foundp = m_modSymp; // Conflicts with modname? AstVar* findvarp = foundp ? foundp->nodep()->castVar() : NULL; bool ins=false; if (!foundp) { ins=true; } else if (!findvarp && foundp && m_curSymp->findIdFlat(nodep->name())) { nodep->v3error("Unsupported in C: Variable has same name as " <nodep())<<": "<prettyName()); } else if (findvarp != nodep) { UINFO(4,"DupVar: "<nodep()<parentp()<parentp() == m_curSymp // Only when on same level && !foundp->imported()) { // and not from package if ((findvarp->isIO() && nodep->isSignal()) || (findvarp->isSignal() && nodep->isIO())) { findvarp->combineType(nodep); nodep->fileline()->modifyStateInherit(nodep->fileline()); AstBasicDType* bdtypep = findvarp->childDTypep()->castBasicDType(); if (bdtypep && bdtypep->implicit()) { // Then have "input foo" and "real foo" so the dtype comes from the other side. AstNodeDType* newdtypep = nodep->subDTypep(); if (!newdtypep || !nodep->childDTypep()) findvarp->v3fatalSrc("No child type?"); bdtypep->unlinkFrBack()->deleteTree(); newdtypep->unlinkFrBack(); findvarp->childDTypep(newdtypep); } nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else { nodep->v3error("Duplicate declaration of signal: "<prettyName()<warnMore()<<"... Location of original declaration"); } } else { // User can disable the message at either point if (!(m_ftaskp && m_ftaskp->dpiImport()) && (!m_ftaskp || m_ftaskp != foundp->nodep()) // Not the function's variable hiding function && !nodep->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN) && !foundp->nodep()->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)) { nodep->v3warn(VARHIDDEN,"Declaration of signal hides declaration in upper scope: "<prettyName()<nodep()->warnMore()<<"... Location of original declaration"); } ins = true; } } if (ins) { VSymEnt* insp = m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep); if (m_statep->forPrimary() && nodep->isGParam()) { m_paramNum++; VSymEnt* symp = m_statep->insertSym(m_curSymp, "__paramNumber"+cvtToStr(m_paramNum), nodep, m_packagep); symp->exported(false); } if (nodep->subDTypep()->castIfaceRefDType()) { // Can't resolve until interfaces and modport names are known; see notes at top m_statep->insertIfaceVarSym(insp); } } } } virtual void visit(AstTypedef* nodep, AstNUser*) { // Remember its name for later resolution if (!m_curSymp) nodep->v3fatalSrc("Typedef not under module??\n"); nodep->iterateChildren(*this); m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep); } virtual void visit(AstCFunc* nodep, AstNUser*) { // For dotted resolution, ignore all AstVars under functions, otherwise shouldn't exist if (m_statep->forScopeCreation()) nodep->v3fatalSrc("No CFuncs expected in tree yet"); } virtual void visit(AstEnumItem* nodep, AstNUser*) { // EnumItem: Remember its name for later resolution nodep->iterateChildren(*this); // Find under either a task or the module's vars VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name()); if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) foundp = m_modSymp; // Conflicts with modname? AstEnumItem* findvarp = foundp ? foundp->nodep()->castEnumItem() : NULL; bool ins=false; if (!foundp) { ins=true; } else if (findvarp != nodep) { UINFO(4,"DupVar: "<parentp() == m_curSymp // Only when on same level && !foundp->imported()) { // and not from package nodep->v3error("Duplicate declaration of enum value: "<prettyName()<warnMore()<<"... Location of original declaration"); } else { // User can disable the message at either point if (!nodep->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN) && !foundp->nodep()->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN)) { nodep->v3warn(VARHIDDEN,"Declaration of enum value hides declaration in upper scope: "<prettyName()<nodep()->warnMore()<<"... Location of original declaration"); } ins = true; } } if (ins) { m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_packagep); } } virtual void visit(AstPackageImport* nodep, AstNUser*) { UINFO(2," Link: "<getNodeSym(nodep->packagep()); if (nodep->name()!="*") { VSymEnt* impp = srcp->findIdFlat(nodep->name()); if (!impp) { nodep->v3error("Import object not found: "<packagep()->prettyName()<<"::"<prettyName()); } } m_curSymp->importFromPackage(m_statep->symsp(), srcp, nodep->name()); UINFO(9," Link Done: "<iterateChildren(*this); } public: // CONSTUCTORS LinkDotFindVisitor(AstNetlist* rootp, LinkDotState* statep) { UINFO(4,__FUNCTION__<<": "<accept(*this); } virtual ~LinkDotFindVisitor() {} }; //====================================================================== class LinkDotParamVisitor : public AstNVisitor { private: // NODE STATE // Cleared on global // *::user1p() -> See LinkDotState // *::user2p() -> See LinkDotState // *::user4() -> See LinkDotState // STATE LinkDotState* m_statep; // State to pass between visitors, including symbol table AstNodeModule* m_modp; // Current module int debug() { return LinkDotState::debug(); } void pinImplicitExprRecurse(AstNode* nodep) { // Under a pin, Check interconnect expression for a pin reference or a concat. // Create implicit variable as needed if (nodep->castDot()) { // Not creating a simple implied type, // and implying something else would just confuse later errors } else if (nodep->castVarRef() || nodep->castParseRef()) { // To prevent user errors, we should only do single bit // implicit vars, however some netlists (MIPS) expect single // bit implicit wires to get created with range 0:0 etc. m_statep->implicitOkAdd(m_modp, nodep->name()); } // These are perhaps a little too generous, as a SELect of siga[sigb] // perhaps shouldn't create an implicit variable. But, we've warned... else { if (nodep->op1p()) pinImplicitExprRecurse(nodep->op1p()); if (nodep->op2p()) pinImplicitExprRecurse(nodep->op2p()); if (nodep->op3p()) pinImplicitExprRecurse(nodep->op3p()); if (nodep->op4p()) pinImplicitExprRecurse(nodep->op4p()); if (nodep->nextp()) pinImplicitExprRecurse(nodep->nextp()); } } // VISITs virtual void visit(AstTypeTable* nodep, AstNUser*) {} virtual void visit(AstNodeModule* nodep, AstNUser*) { UINFO(5," "<dead() || !nodep->user4()) { UINFO(4,"Mark dead module "<forPrearray()) nodep->v3fatalSrc("Dead module persisted past where should have removed"); // Don't remove now, because we may have a tree of parameterized modules with VARXREFs into the deleted module region // V3Dead should cleanup. // Downstream visitors up until V3Dead need to check for nodep->dead. nodep->dead(true); } else { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } } virtual void visit(AstPin* nodep, AstNUser*) { // Pin: Link to submodule's port // Deal with implicit definitions - do before Resolve visitor as may be referenced above declaration if (nodep->exprp() // Else specifically unconnected pin && !nodep->svImplicit()) { // SV 19.11.3: .name pins don't allow implicit decls pinImplicitExprRecurse(nodep->exprp()); } } virtual void visit(AstDefParam* nodep, AstNUser*) { nodep->iterateChildren(*this); nodep->v3warn(DEFPARAM,"Suggest replace defparam with Verilog 2001 #(."<prettyName()<<"(...etc...))"); VSymEnt* foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->path()); AstCell* cellp = foundp->nodep()->castCell(); if (!cellp) { nodep->v3error("In defparam, cell "<path()<<" never declared"); } else { AstNode* exprp = nodep->rhsp()->unlinkFrBack(); UINFO(9,"Defparam cell "<path()<<"."<name() <<" attach-to "<prettyName()); } else if (!refp->isIO() && !refp->isIfaceRef()) { nodep->v3error("Pin is not an in/out/inout/interface: "<prettyName()); } else { refp->user4(true); VSymEnt* symp = m_statep->insertSym(m_statep->getNodeSym(m_modp), "__pinNumber"+cvtToStr(nodep->pinNum()), refp, NULL/*packagep*/); symp->exported(false); } // Ports not needed any more nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } virtual void visit(AstAssignW* nodep, AstNUser*) { // Deal with implicit definitions // We used to nodep->allowImplicit() here, but it turns out // normal "assigns" can also make implicit wires. Yuk. pinImplicitExprRecurse(nodep->lhsp()); nodep->iterateChildren(*this); } virtual void visit(AstAssignAlias* nodep, AstNUser*) { // tran gates need implicit creation // As VarRefs don't exist in forPrimary, sanity check if (m_statep->forPrimary()) nodep->v3fatalSrc("Assign aliases unexpected pre-dot"); if (AstVarRef* forrefp = nodep->lhsp()->castVarRef()) { pinImplicitExprRecurse(forrefp); } if (AstVarRef* forrefp = nodep->rhsp()->castVarRef()) { pinImplicitExprRecurse(forrefp); } nodep->iterateChildren(*this); } virtual void visit(AstImplicit* nodep, AstNUser*) { // Unsupported gates need implicit creation pinImplicitExprRecurse(nodep); // We're done with implicit gates nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkDotParamVisitor(AstNetlist* rootp, LinkDotState* statep) { UINFO(4,__FUNCTION__<<": "<accept(*this); } virtual ~LinkDotParamVisitor() {} }; //====================================================================== class LinkDotScopeVisitor : public AstNVisitor { // STATE LinkDotState* m_statep; // State to pass between visitors, including symbol table AstScope* m_scopep; // The current scope VSymEnt* m_modSymp; // Symbol entry for current module int debug() { return LinkDotState::debug(); } // VISITs virtual void visit(AstNetlist* nodep, AstNUser* vup) { // Recurse..., backward as must do packages before using packages nodep->iterateChildrenBackwards(*this); } virtual void visit(AstScope* nodep, AstNUser*) { UINFO(8," SCOPE "<forScopeCreation()) v3fatalSrc("Scopes should only exist right after V3Scope"); // Using the CELL names, we created all hierarchy. We now need to match this Scope // up with the hierarchy created by the CELL names. m_modSymp = m_statep->getScopeSym(nodep); m_scopep = nodep; nodep->iterateChildren(*this); m_modSymp = NULL; m_scopep = NULL; } virtual void visit(AstVarScope* nodep, AstNUser*) { if (!nodep->varp()->isFuncLocal()) { VSymEnt* varSymp = m_statep->insertSym(m_modSymp, nodep->varp()->name(), nodep, NULL); if (nodep->varp()->isIfaceRef() && nodep->varp()->isIfaceParent()) { UINFO(9,"Iface parent ref var "<varp()->name()<<" "<varp()->dtypep()->castIfaceRefDType(); if (!dtypep) nodep->v3fatalSrc("Non AstIfaceRefDType on isIfaceRef() var"); UINFO(9,"Iface parent dtype "<cellName(); string baddot; VSymEnt* okSymp; VSymEnt* cellSymp = m_statep->findDotted(m_modSymp, ifcellname, baddot, okSymp); if (!cellSymp) nodep->v3fatalSrc("No symbol for interface cell: " <prettyName(ifcellname)); UINFO(5, " Found interface cell: se"<<(void*)cellSymp<<" "<nodep()<modportName()!="") { VSymEnt* mpSymp = m_statep->findDotted(m_modSymp, ifcellname, baddot, okSymp); if (!mpSymp) { nodep->v3fatalSrc("No symbol for interface modport: " <prettyName(dtypep->modportName())); } else cellSymp = mpSymp; UINFO(5, " Found modport cell: se"<<(void*)cellSymp<<" "<nodep()<insertScopeAlias(LinkDotState::SAMN_IFTOP, varSymp, cellSymp); } } } virtual void visit(AstNodeFTask* nodep, AstNUser*) { VSymEnt* symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, NULL); symp->fallbackp(m_modSymp); // No recursion, we don't want to pick up variables } virtual void visit(AstAssignAlias* nodep, AstNUser*) { // Track aliases created by V3Inline; if we get a VARXREF(aliased_from) // we'll need to replace it with a VARXREF(aliased_to) if (debug()>=9) nodep->dumpTree(cout,"-\t\t\t\talias: "); AstVarScope* fromVscp = nodep->lhsp()->castVarRef()->varScopep(); AstVarScope* toVscp = nodep->rhsp()->castVarRef()->varScopep(); if (!fromVscp || !toVscp) nodep->v3fatalSrc("Bad alias scopes"); fromVscp->user2p(toVscp); nodep->iterateChildren(*this); } virtual void visit(AstAssignVarScope* nodep, AstNUser*) { UINFO(5,"ASSIGNVARSCOPE "<=9) nodep->dumpTree(cout,"-\t\t\t\tavs: "); VSymEnt* rhsSymp; { AstVarRef* refp = nodep->rhsp()->castVarRef(); if (!refp) nodep->v3fatalSrc("Unsupported: Non VarRef attached to interface pin"); string scopename = refp->name(); string baddot; VSymEnt* okSymp; VSymEnt* symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp); if (!symp) nodep->v3fatalSrc("No symbol for interface alias rhs"); UINFO(5, " Found a linked scope RHS: "<nodep()<lhsp()->castVarXRef(); if (!refp) nodep->v3fatalSrc("Unsupported: Non VarXRef attached to interface pin"); string scopename = refp->dotted()+"."+refp->name(); string baddot; VSymEnt* okSymp; VSymEnt* symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp); if (!symp) nodep->v3fatalSrc("No symbol for interface alias lhs"); UINFO(5, " Found a linked scope LHS: "<nodep()<insertScopeAlias(LinkDotState::SAMN_IFTOP, lhsSymp, rhsSymp); // We have stored the link, we don't need these any more nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } // For speed, don't recurse things that can't have scope // Note we allow AstNodeStmt's as generates may be under them virtual void visit(AstCell*, AstNUser*) {} virtual void visit(AstVar*, AstNUser*) {} virtual void visit(AstNodeMath*, AstNUser*) {} virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkDotScopeVisitor(AstNetlist* rootp, LinkDotState* statep) { UINFO(4,__FUNCTION__<<": "<accept(*this); } virtual ~LinkDotScopeVisitor() {} }; //====================================================================== // Iterate an interface to resolve modports class LinkDotIfaceVisitor : public AstNVisitor { // STATE LinkDotState* m_statep; // State to pass between visitors, including symbol table VSymEnt* m_curSymp; // Symbol Entry for current table, where to lookup/insert // METHODS int debug() { return LinkDotState::debug(); } // VISITs virtual void visit(AstModport* nodep, AstNUser*) { // Modport: Remember its name for later resolution UINFO(5," fiv: "<insertBlock(m_curSymp, nodep->name(), nodep, NULL); m_curSymp->fallbackp(oldCurSymp); nodep->iterateChildren(*this); } m_curSymp = oldCurSymp; } virtual void visit(AstModportFTaskRef* nodep, AstNUser*) { UINFO(5," fif: "<iterateChildren(*this); if (nodep->isExport()) nodep->v3error("Unsupported: modport export"); VSymEnt* symp = m_curSymp->findIdFallback(nodep->name()); if (!symp) { nodep->v3error("Modport item not found: "<prettyName()); } else if (AstNodeFTask* ftaskp = symp->nodep()->castNodeFTask()) { // Make symbol under modport that points at the _interface_'s var, not the modport. nodep->ftaskp(ftaskp); VSymEnt* subSymp = m_statep->insertSym(m_curSymp, nodep->name(), ftaskp, NULL/*package*/); m_statep->insertScopeAlias(LinkDotState::SAMN_MODPORT, subSymp, symp); } else { nodep->v3error("Modport item is not a function/task: "<prettyName()); } if (m_statep->forScopeCreation()) { // Done with AstModportFTaskRef. // Delete to prevent problems if we dead-delete pointed to ftask nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } } virtual void visit(AstModportVarRef* nodep, AstNUser*) { UINFO(5," fiv: "<iterateChildren(*this); VSymEnt* symp = m_curSymp->findIdFallback(nodep->name()); if (!symp) { nodep->v3error("Modport item not found: "<prettyName()); } else if (AstVar* varp = symp->nodep()->castVar()) { // Make symbol under modport that points at the _interface_'s var, not the modport. nodep->varp(varp); m_statep->insertSym(m_curSymp, nodep->name(), varp, NULL/*package*/); } else if (AstVarScope* vscp = symp->nodep()->castVarScope()) { // Make symbol under modport that points at the _interface_'s var, not the modport. nodep->varp(vscp->varp()); m_statep->insertSym(m_curSymp, nodep->name(), vscp, NULL/*package*/); } else { nodep->v3error("Modport item is not a variable: "<prettyName()); } if (m_statep->forScopeCreation()) { // Done with AstModportVarRef. // Delete to prevent problems if we dead-delete pointed to variable nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkDotIfaceVisitor(AstIface* nodep, VSymEnt* curSymp, LinkDotState* statep) { UINFO(4,__FUNCTION__<<": "<accept(*this); } virtual ~LinkDotIfaceVisitor() {} }; void LinkDotState::computeIfaceModSyms() { for (IfaceModSyms::iterator it=m_ifaceModSyms.begin(); it!=m_ifaceModSyms.end(); ++it) { AstIface* nodep = it->first; VSymEnt* symp = it->second; LinkDotIfaceVisitor(nodep, symp, this); } m_ifaceModSyms.clear(); } //====================================================================== class LinkDotResolveVisitor : public AstNVisitor { private: // NODE STATE // Cleared on global // *::user1p() -> See LinkDotState // *::user2p() -> See LinkDotState // *::user3() // bool. Processed // *::user4() -> See LinkDotState // Cleared on Cell // AstVar::user5() // bool. True if pin used in this cell AstUser3InUse m_inuser3; AstUser5InUse m_inuser5; // TYPES enum DotPosition { DP_NONE=0, // Not under a DOT DP_PACKAGE, // {package}:: DOT DP_SCOPE, // [DOT...] {scope-or-var} DOT DP_FINAL, // [DOT...] {var-or-func-or-dtype} with no following dots DP_MEMBER }; // DOT {member-name} [DOT...] // STATE LinkDotState* m_statep; // State, including dotted symbol table VSymEnt* m_curSymp; // SymEnt for current lookup point VSymEnt* m_modSymp; // SymEnt for current module VSymEnt* m_pinSymp; // SymEnt for pin lookups AstCell* m_cellp; // Current cell AstNodeModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Current function/task int m_modportNum; // Uniqueify modport numbers struct DotStates { DotPosition m_dotPos; // Scope part of dotted resolution VSymEnt* m_dotSymp; // SymEnt for dotted AstParse lookup AstDot* m_dotp; // Current dot bool m_dotErr; // Error found in dotted resolution, ignore upwards string m_dotText; // String of dotted names found in below parseref DotStates() { init(NULL); } ~DotStates() {} void init(VSymEnt* curSymp) { m_dotPos = DP_NONE; m_dotSymp = curSymp; m_dotp = NULL; m_dotErr = false; m_dotText = ""; } string ascii() const { static const char* names[] = { "NONE","PACKAGE","SCOPE","FINAL","MEMBER" }; ostringstream sstr; sstr<<"ds="<prettyName()); } else { nodep->v3warn(IMPLICIT,"Signal definition not found, creating implicitly: "<prettyName()); } } AstVar* newp = new AstVar (nodep->fileline(), AstVarType::WIRE, nodep->name(), VFlagLogicPacked(), 1); newp->trace(modp->modTrace()); nodep->varp(newp); modp->addStmtp(newp); // Link it to signal list, must add the variable under the module; current scope might be lower now m_statep->insertSym(moduleSymp, newp->name(), newp, NULL/*packagep*/); } } void taskFuncSwapCheck(AstNodeFTaskRef* nodep) { if (nodep->taskp() && nodep->taskp()->castTask() && nodep->castFuncRef()) nodep->v3error("Illegal call of a task as a function: "<prettyName()); } inline void checkNoDot(AstNode* nodep) { if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) { //UINFO(9,"ds="<v3error("Syntax Error: Not expecting "<type()<<" under a "<backp()->type()<<" in dotted expression"); m_ds.m_dotErr = true; } } AstVar* makeIfaceModportVar(FileLine* fl, AstCell* cellp, AstIface* ifacep, AstModport* modportp) { // Create iface variable, using duplicate var when under same module scope string varName = ifacep->name()+"__Vmp__"+modportp->name()+"__Viftop"+cvtToStr(++m_modportNum); AstIfaceRefDType* idtypep = new AstIfaceRefDType(fl, cellp->name(), ifacep->name(), modportp->name()); idtypep->cellp(cellp); AstVar* varp = new AstVar(fl, AstVarType::IFACEREF, varName, VFlagChildDType(), idtypep); varp->isIfaceParent(true); m_modp->addStmtp(varp); return varp; } // VISITs virtual void visit(AstNetlist* nodep, AstNUser* vup) { // Recurse..., backward as must do packages before using packages nodep->iterateChildrenBackwards(*this); } virtual void visit(AstTypeTable* nodep, AstNUser*) {} virtual void visit(AstNodeModule* nodep, AstNUser*) { if (nodep->dead()) return; checkNoDot(nodep); UINFO(8," "<getNodeSym(nodep); // Until overridden by a SCOPE m_cellp = NULL; m_modp = nodep; m_modportNum = 0; nodep->iterateChildren(*this); m_modp = NULL; m_ds.m_dotSymp = m_curSymp = m_modSymp = NULL; } virtual void visit(AstScope* nodep, AstNUser*) { UINFO(8," "<getScopeSym(nodep); nodep->iterateChildren(*this); m_ds.m_dotSymp = m_curSymp = m_modSymp = NULL; m_modSymp = oldModSymp; m_curSymp = oldCurSymp; } virtual void visit(AstCellInline* nodep, AstNUser*) { checkNoDot(nodep); if (m_statep->forScopeCreation()) { nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL; } } virtual void visit(AstCell* nodep, AstNUser*) { // Cell: Recurse inside or cleanup not founds checkNoDot(nodep); m_cellp = nodep; AstNode::user5ClearTree(); if (!nodep->modp()) { nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out } else { if (nodep->modp()->castNotFoundModule()) { // Prevent warnings about missing pin connects if (nodep->pinsp()) nodep->pinsp()->unlinkFrBackWithNext()->deleteTree(); if (nodep->paramsp()) nodep->paramsp()->unlinkFrBackWithNext()->deleteTree(); } // Need to pass the module info to this cell, so we can link up the pin names // However can't use m_curSymp as pin connections need to use the instantiator's symbols else { m_pinSymp = m_statep->getNodeSym(nodep->modp()); UINFO(4,"(Backto) Link Cell: "<dumpTree(cout,"linkcell:"); } //if (debug()) { nodep->modp()->dumpTree(cout,"linkcemd:"); } nodep->iterateChildren(*this); m_pinSymp = NULL; } } m_cellp = NULL; // Parent module inherits child's publicity // This is done bottom up in the LinkBotupVisitor stage } virtual void visit(AstPin* nodep, AstNUser*) { // Pin: Link to submodule's port checkNoDot(nodep); nodep->iterateChildren(*this); if (!nodep->modVarp()) { if (!m_pinSymp) nodep->v3fatalSrc("Pin not under cell?\n"); VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name()); AstVar* refp = foundp->nodep()->castVar(); const char* whatp = nodep->param() ? "parameter pin" : "pin"; if (!refp) { if (nodep->name() == "__paramNumber1" && m_cellp->modp()->castPrimitive()) { // Primitive parameter is really a delay we can just ignore nodep->unlinkFrBack()->deleteTree(); nodep=NULL; return; } nodep->v3error(ucfirst(whatp)<<" not found: "<prettyName()); } else if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) { nodep->v3error(ucfirst(whatp)<<" is not an in/out/inout/param/interface: "<prettyName()); } else { nodep->modVarp(refp); if (refp->user5p() && refp->user5p()->castNode()!=nodep) { nodep->v3error("Duplicate "<prettyName()<user5p()->castNode()->warnMore() <<"... Location of original "<user5p(nodep); } } } // Early return() above when deleted } virtual void visit(AstDot* nodep, AstNUser*) { // Legal under a DOT: AstDot, AstParseRef, AstPackageRef, AstNodeSel // also a DOT can be part of an expression, but only above plus AstFTaskRef are legal children // DOT(PACKAGEREF, PARSEREF(text)) // DOT(DOT(DOT(PARSEREF(text), ... if (nodep->user3SetOnce()) return; UINFO(8," "<=9) nodep->dumpTree("-dot-in: "); m_ds.init(m_curSymp); // Start from current point } m_ds.m_dotp = nodep; // Always, not just at start m_ds.m_dotPos = DP_SCOPE; // m_ds.m_dotText communicates the cell prefix between stages if (nodep->lhsp()->castPackageRef()) { if (!start) { nodep->lhsp()->v3error("Package reference may not be embedded in dotted reference"); m_ds.m_dotErr=true; } m_ds.m_dotPos = DP_PACKAGE; } else { m_ds.m_dotPos = DP_SCOPE; nodep->lhsp()->iterateAndNext(*this); //if (debug()>=9) nodep->dumpTree("-dot-lho: "); } if (!m_ds.m_dotErr) { // Once something wrong, give up if (start && m_ds.m_dotPos==DP_SCOPE) m_ds.m_dotPos = DP_FINAL; // Top 'final' dot RHS is final RHS, else it's a DOT(DOT(x,*here*),real-rhs) which we consider a RHS nodep->rhsp()->iterateAndNext(*this); //if (debug()>=9) nodep->dumpTree("-dot-rho: "); } if (start) { AstNode* newp; if (m_ds.m_dotErr) { newp = new AstConst(nodep->fileline(),AstConst::LogicFalse()); } else { // RHS is what we're left with newp = nodep->rhsp()->unlinkFrBack(); } if (debug()>=9) newp->dumpTree("-dot-out: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else { // Dot midpoint AstNode* newp = nodep->rhsp()->unlinkFrBack(); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } } if (start) { m_ds = lastStates; } else { m_ds.m_dotp = lastStates.m_dotp; } } virtual void visit(AstParseRef* nodep, AstNUser*) { if (nodep->user3SetOnce()) return; UINFO(9," linkPARSEREF "<v3fatalSrc("NULL lookup symbol table"); if (!m_statep->forPrimary()) nodep->v3fatalSrc("ParseRefs should no longer exist"); DotStates lastStates = m_ds; bool start = !m_ds.m_dotp; if (start) { m_ds.init(m_curSymp); // Note m_ds.m_dot remains NULL; this is a reference not under a dot } if (m_ds.m_dotPos == DP_MEMBER) { // Found a Var, everything following is membership. {scope}.{var}.HERE {member} AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); AstNode* newp = new AstMemberSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name()); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else { // string expectWhat; bool allowScope = false; bool allowVar = false; if (m_ds.m_dotPos == DP_PACKAGE) { // {package}::{a} AstPackage* packagep = NULL; expectWhat = "scope/variable"; allowScope = true; allowVar = true; if (!m_ds.m_dotp->lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link"); packagep = m_ds.m_dotp->lhsp()->castPackageRef()->packagep(); if (!packagep) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link"); m_ds.m_dotSymp = m_statep->getNodeSym(packagep); m_ds.m_dotPos = DP_SCOPE; } else if (m_ds.m_dotPos == DP_SCOPE) { // {a}.{b}, where {a} maybe a module name // or variable, where dotting into structure member expectWhat = "scope/variable"; allowScope = true; allowVar = true; } else if (m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_FINAL) { expectWhat = "variable"; allowVar = true; } else { UINFO(1,"ds="<v3fatalSrc("Unhandled AstParseRefExp"); } // Lookup VSymEnt* foundp; string baddot; VSymEnt* okSymp = NULL; if (allowScope) { foundp = m_statep->findDotted(m_ds.m_dotSymp, nodep->name(), baddot, okSymp); // Maybe NULL } else { foundp = m_ds.m_dotSymp->findIdFallback(nodep->name()); } if (foundp) UINFO(9," found=se"<<(void*)foundp<<" exp="<name(); m_ds.m_dotSymp = foundp; m_ds.m_dotPos = DP_SCOPE; // Upper AstDot visitor will handle it from here } else if (foundp->nodep()->castCell() && allowVar && m_cellp && foundp->nodep()->castCell()->modp()->castIface()) { // Interfaces can be referenced like a variable for interconnect AstCell* cellp = foundp->nodep()->castCell(); VSymEnt* cellEntp = m_statep->getNodeSym(cellp); if (!cellEntp) nodep->v3fatalSrc("No interface sym entry"); VSymEnt* parentEntp = cellEntp->parentp(); // Container of the var; probably a module or generate begin string findName = nodep->name()+"__Viftop"; AstVar* ifaceRefVarp = parentEntp->findIdFallback(findName)->nodep()->castVar(); if (!ifaceRefVarp) nodep->v3fatalSrc("Can't find interface var ref: "<name(); m_ds.m_dotSymp = foundp; m_ds.m_dotPos = DP_SCOPE; UINFO(9," cell -> iface varref "<nodep()<fileline(), ifaceRefVarp, false); nodep->replaceWith(newp); pushDeletep(nodep); nodep = NULL; } } else if (AstVar* varp = foundp->nodep()->castVar()) { if (AstIfaceRefDType* ifacerefp = varp->subDTypep()->castIfaceRefDType()) { if (!ifacerefp->ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface"); // Really this is a scope reference into an interface UINFO(9,"varref-ifaceref "<name(); m_ds.m_dotSymp = m_statep->getNodeSym(ifacerefp->ifaceViaCellp()); m_ds.m_dotPos = DP_SCOPE; ok = true; AstNode* newp = new AstVarRef(nodep->fileline(), varp, false); nodep->replaceWith(newp); pushDeletep(nodep); nodep = NULL; } else if (allowVar) { AstNodeVarRef* newp; if (m_ds.m_dotText != "") { newp = new AstVarXRef(nodep->fileline(), nodep->name(), m_ds.m_dotText, false); // lvalue'ness computed later newp->varp(varp); m_ds.m_dotText = ""; } else { newp = new AstVarRef(nodep->fileline(), nodep->name(), false); // lvalue'ness computed later newp->varp(varp); newp->packagep(foundp->packagep()); UINFO(9," new "<replaceWith(newp); pushDeletep(nodep); nodep = NULL; m_ds.m_dotPos = DP_MEMBER; ok = true; } } else if (AstModport* modportp = foundp->nodep()->castModport()) { // A scope reference into an interface's modport (not necessarily at a pin connection) UINFO(9,"cell-ref-to-modport "<nodep()<nodep()->castCell() || !m_ds.m_dotSymp->nodep()->castCell()->modp() || !m_ds.m_dotSymp->nodep()->castCell()->modp()->castIface()) { nodep->v3error("Modport not referenced as ."<prettyName()); } else if (!m_ds.m_dotSymp->nodep()->castCell()->modp() || !m_ds.m_dotSymp->nodep()->castCell()->modp()->castIface()) { nodep->v3error("Modport not referenced from underneath an interface: "<prettyName()); } else { AstCell* cellp = m_ds.m_dotSymp->nodep()->castCell(); if (!cellp) nodep->v3fatalSrc("Modport not referenced from a cell"); AstIface* ifacep = cellp->modp()->castIface(); //string cellName = m_ds.m_dotText; // Use cellp->name if (m_ds.m_dotText!="") m_ds.m_dotText += "."; m_ds.m_dotText += nodep->name(); m_ds.m_dotSymp = m_statep->getNodeSym(modportp); m_ds.m_dotPos = DP_SCOPE; ok = true; AstVar* varp = makeIfaceModportVar(nodep->fileline(), cellp, ifacep, modportp); AstVarRef* refp = new AstVarRef(varp->fileline(), varp, false); nodep->replaceWith(refp); pushDeletep(nodep); nodep = NULL; } } else if (AstEnumItem* valuep = foundp->nodep()->castEnumItem()) { if (allowVar) { AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep, foundp->packagep()); nodep->replaceWith(newp); pushDeletep(nodep); nodep = NULL; ok = true; m_ds.m_dotText = ""; } } // if (!ok) { bool checkImplicit = (!m_ds.m_dotp && m_ds.m_dotText==""); bool err = !(checkImplicit && m_statep->implicitOk(m_modp, nodep->name())); if (err) { if (foundp) { nodep->v3error("Found definition of '"<prettyName() <<"'"<<" as a "<nodep()->typeName() <<" but expected a "<prettyName()); } else { nodep->v3error("Can't find definition of '"<<(baddot!=""?baddot:nodep->prettyName())<<"' in dotted " <prettyName()); okSymp->cellErrorScopes(nodep, AstNode::prettyName(m_ds.m_dotText)); } m_ds.m_dotErr = true; } if (checkImplicit) { // Else if a scope is allowed, making a signal won't help error cascade // Create if implicit, and also if error (so only complain once) AstVarRef* newp = new AstVarRef(nodep->fileline(), nodep->name(), false); nodep->replaceWith(newp); pushDeletep(nodep); nodep = NULL; createImplicitVar (m_curSymp, newp, m_modp, m_modSymp, err); } } } if (start) { m_ds = lastStates; } } virtual void visit(AstVarRef* nodep, AstNUser*) { // VarRef: Resolve its reference // ParseRefs are used the first pass (forPrimary) so we shouldn't get can't find // errors here now that we have a VarRef. // No checkNoDot; created and iterated from a parseRef nodep->iterateChildren(*this); if (!nodep->varp()) { UINFO(9," linkVarRef se"<<(void*)m_curSymp<<" n="<v3fatalSrc("NULL lookup symbol table"); VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name()); if (AstVar* varp = foundp->nodep()->castVar()) { nodep->varp(varp); nodep->packagep(foundp->packagep()); // Generally set by parse, but might be an import } if (!nodep->varp()) { nodep->v3error("Can't find definition of signal, again: "<prettyName()); } } } virtual void visit(AstVarXRef* nodep, AstNUser*) { // VarRef: Resolve its reference // We always link even if varp() is set, because the module we choose may change // due to creating new modules, flattening, etc. if (nodep->user3SetOnce()) return; UINFO(8," "<varp(NULL); // Module that is not in hierarchy. We'll be dead code eliminating it later. } else { string baddot; VSymEnt* okSymp; VSymEnt* dotSymp = m_curSymp; // Start search at current scope if (nodep->inlinedDots()!="") { // Correct for current scope dotSymp = m_modSymp; // Dotted lookup is always relative to module, as maybe variable name lower down with same scope name we want to ignore (t_math_divw) string inl = AstNode::dedotName(nodep->inlinedDots()); dotSymp = m_statep->findDotted(dotSymp, inl, baddot, okSymp); if (!dotSymp) { nodep->v3fatalSrc("Couldn't resolve inlined scope '"<inlinedDots()); } } dotSymp = m_statep->findDotted(dotSymp, nodep->dotted(), baddot, okSymp); // Maybe NULL if (!m_statep->forScopeCreation()) { VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); AstVar* varp = foundp->nodep()->castVar(); // maybe NULL nodep->varp(varp); UINFO(7," Resolved "<varp()) { nodep->v3error("Can't find definition of '"<dotted()+"."+nodep->prettyName()); okSymp->cellErrorScopes(nodep); } } else { string baddot; VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); AstVarScope* vscp = foundp->nodep()->castVarScope(); // maybe NULL if (!vscp) { nodep->v3error("Can't find varpin scope of '"<dotted()+"."+nodep->prettyName()); okSymp->cellErrorScopes(nodep); } else { while (vscp->user2p()) { // If V3Inline aliased it, pick up the new signal UINFO(7," Resolved pre-alias "<user2p()->castNode()->castVarScope(); } // Convert the VarXRef to a VarRef, so we don't need later optimizations to deal with VarXRef. nodep->varp(vscp->varp()); nodep->varScopep(vscp); UINFO(7," Resolved "<fileline(), vscp, nodep->lvalue()); nodep->replaceWith(newvscp); nodep->deleteTree(); nodep=NULL; UINFO(9," new "<iterateChildren(*this); } virtual void visit(AstMethodSel* nodep, AstNUser*) { // Created here so should already be resolved. DotStates lastStates = m_ds; { m_ds.init(m_curSymp); nodep->iterateChildren(*this); } m_ds = lastStates; } virtual void visit(AstVar* nodep, AstNUser*) { checkNoDot(nodep); nodep->iterateChildren(*this); if (m_statep->forPrimary() && nodep->isIO() && !m_ftaskp && !nodep->user4()) { nodep->v3error("Input/output/inout does not appear in port list: "<prettyName()); } } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { if (nodep->user3SetOnce()) return; UINFO(8," "<lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link"); if (!m_ds.m_dotp->lhsp()->castPackageRef()->packagep()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link"); nodep->packagep(m_ds.m_dotp->lhsp()->castPackageRef()->packagep()); m_ds.m_dotPos = DP_SCOPE; m_ds.m_dotp = NULL; } else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) { nodep->dotted(m_ds.m_dotText); // Maybe "" } else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) { // Found a Var, everything following is method call. {scope}.{var}.HERE {method} ( ARGS ) AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); AstNode* argsp = NULL; if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext(); AstNode* newp = new AstMethodSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name(), argsp); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; return; } else { checkNoDot(nodep); } if (nodep->packagep() && nodep->taskp()) { // References into packages don't care about cell hierarchy. } else if (!m_modSymp) { UINFO(9,"Dead module for "<taskp(NULL); // Module that is not in hierarchy. We'll be dead code eliminating it later. } else if (nodep->dotted()=="" && nodep->taskp()) { // Earlier should have setup the links // Might be under a BEGIN we're not processing, so don't relink it } else { string baddot; VSymEnt* okSymp = NULL; VSymEnt* dotSymp = m_curSymp; // Start search at module, as a variable of same name under a subtask isn't a relevant hit // // however a function under a begin/end is. So we want begins, but not the function if (nodep->packagep()) { // Look only in specified package dotSymp = m_statep->getNodeSym(nodep->packagep()); } else { if (nodep->inlinedDots()!="") { // Correct for current scope dotSymp = m_modSymp; // Dotted lookup is always relative to module, as maybe variable name lower down with same scope name we want to ignore (t_math_divw) string inl = AstNode::dedotName(nodep->inlinedDots()); UINFO(8,"\t\tInlined "<findDotted(dotSymp, inl, baddot, okSymp); if (!dotSymp) { okSymp->cellErrorScopes(nodep); nodep->v3fatalSrc("Couldn't resolve inlined scope '"<inlinedDots()); } } dotSymp = m_statep->findDotted(dotSymp, nodep->dotted(), baddot, okSymp); // Maybe NULL } VSymEnt* foundp = NULL; AstNodeFTask* taskp = NULL; foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); taskp = foundp ? foundp->nodep()->castNodeFTask() : NULL; // Maybe NULL if (taskp) { nodep->taskp(taskp); nodep->packagep(foundp->packagep()); UINFO(7," Resolved "<v3error("Found definition of '"<prettyName() <<"'"<<" as a "<nodep()->typeName() <<" but expected a task/function"); } else if (nodep->dotted() == "") { nodep->v3error("Can't find definition of task/function: "<prettyName()); } else { nodep->v3error("Can't find definition of '"<dotted()+"."+nodep->prettyName()); okSymp->cellErrorScopes(nodep); } } taskFuncSwapCheck(nodep); } DotStates lastStates = m_ds; { m_ds.init(m_curSymp); nodep->iterateChildren(*this); } m_ds = lastStates; } virtual void visit(AstSelBit* nodep, AstNUser*) { if (nodep->user3SetOnce()) return; nodep->lhsp()->iterateAndNext(*this); if (m_ds.m_dotPos == DP_SCOPE) { // Already under dot, so this is {modulepart} DOT {modulepart} if (AstConst* constp = nodep->rhsp()->castConst()) { string index = AstNode::encodeNumber(constp->toSInt()); m_ds.m_dotText += "__BRA__"+index+"__KET__"; } else { nodep->v3error("Unsupported: Non-constant inside []'s in the cell part of a dotted reference"); } // And pass up m_ds.m_dotText } // Pass dot state down to fromp() nodep->fromp()->iterateAndNext(*this); DotStates lastStates = m_ds; { m_ds.init(m_curSymp); nodep->bitp()->iterateAndNext(*this); nodep->attrp()->iterateAndNext(*this); } m_ds = lastStates; } virtual void visit(AstNodePreSel* nodep, AstNUser*) { // Excludes simple AstSelBit, see above if (nodep->user3SetOnce()) return; if (m_ds.m_dotPos == DP_SCOPE) { // Already under dot, so this is {modulepart} DOT {modulepart} nodep->v3error("Syntax Error: Range ':', '+:' etc are not allowed in the cell part of a dotted reference"); m_ds.m_dotErr = true; return; } nodep->lhsp()->iterateAndNext(*this); DotStates lastStates = m_ds; { m_ds.init(m_curSymp); nodep->rhsp()->iterateAndNext(*this); nodep->thsp()->iterateAndNext(*this); nodep->attrp()->iterateAndNext(*this); } m_ds = lastStates; } virtual void visit(AstMemberSel* nodep, AstNUser*) { // checkNoDot not appropriate, can be under a dot nodep->iterateChildren(*this); } virtual void visit(AstBegin* nodep, AstNUser*) { UINFO(5," "<getNodeSym(nodep); UINFO(5," cur=se"<<(void*)m_curSymp<iterateChildren(*this); } m_ds.m_dotSymp = m_curSymp = oldCurSymp; UINFO(5," cur=se"<<(void*)m_curSymp<getNodeSym(nodep); nodep->iterateChildren(*this); } m_ds.m_dotSymp = m_curSymp = oldCurSymp; m_ftaskp = NULL; } virtual void visit(AstRefDType* nodep, AstNUser*) { // Resolve its reference if (nodep->user3SetOnce()) return; if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) { if (!m_ds.m_dotp->lhsp()->castPackageRef()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link"); if (!m_ds.m_dotp->lhsp()->castPackageRef()->packagep()) m_ds.m_dotp->lhsp()->v3fatalSrc("Bad package link"); nodep->packagep(m_ds.m_dotp->lhsp()->castPackageRef()->packagep()); m_ds.m_dotPos = DP_SCOPE; m_ds.m_dotp = NULL; } else { checkNoDot(nodep); } if (!nodep->defp()) { VSymEnt* foundp; if (nodep->packagep()) { foundp = m_statep->getNodeSym(nodep->packagep())->findIdFlat(nodep->name()); } else { foundp = m_curSymp->findIdFallback(nodep->name()); } if (AstTypedef* defp = foundp->nodep()->castTypedef()) { nodep->refDTypep(defp->subDTypep()); nodep->packagep(foundp->packagep()); } else { nodep->v3error("Can't find typedef: "<prettyName()); } } nodep->iterateChildren(*this); } virtual void visit(AstDpiExport* nodep, AstNUser*) { // AstDpiExport: Make sure the function referenced exists, then dump it nodep->iterateChildren(*this); checkNoDot(nodep); VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name()); AstNodeFTask* taskp = foundp->nodep()->castNodeFTask(); if (!taskp) { nodep->v3error("Can't find definition of exported task/function: "<prettyName()); } else if (taskp->dpiExport()) { nodep->v3error("Function was already DPI Exported, duplicate not allowed: "<prettyName()); } else { taskp->dpiExport(true); if (nodep->cname()!="") taskp->cname(nodep->cname()); } nodep->unlinkFrBack()->deleteTree(); } virtual void visit(AstPackageImport* nodep, AstNUser*) { // No longer needed checkNoDot(nodep); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate checkNoDot(nodep); nodep->iterateChildren(*this); } public: // CONSTUCTORS LinkDotResolveVisitor(AstNetlist* rootp, LinkDotState* statep) { UINFO(4,__FUNCTION__<<": "<accept(*this); } virtual ~LinkDotResolveVisitor() {} }; //###################################################################### // Link class functions int V3LinkDot::debug() { return LinkDotState::debug(); } void V3LinkDot::linkDotGuts(AstNetlist* rootp, VLinkDotStep step) { if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot.tree")); LinkDotState state (rootp, step); LinkDotFindVisitor visitor(rootp,&state); if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find.tree")); if (step == LDS_PRIMARY || step == LDS_PARAMED) { // Initial link stage, resolve parameters LinkDotParamVisitor visitors(rootp,&state); if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-param.tree")); } else if (step == LDS_ARRAYED) {} else if (step == LDS_SCOPED) { // Well after the initial link when we're ready to operate on the flat design, // process AstScope's. This needs to be separate pass after whole hierarchy graph created. LinkDotScopeVisitor visitors(rootp,&state); if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-scoped.tree")); } else v3fatalSrc("Bad case"); state.dump(); state.computeIfaceModSyms(); state.computeIfaceVarSyms(); state.computeScopeAliases(); state.dump(); LinkDotResolveVisitor visitorb(rootp,&state); } verilator-3.874/src/V3Coverage.cpp0000664000177100017500000003544312525171733017001 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Netlist (top level) functions // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // COVERAGE TRANSFORMATIONS: // At each IF/(IF else)/CASEITEM, // If there's no coverage off on the block below it, // or a $stop // Insert a COVERDECL node in the module. // (V3Emit reencodes into per-module numbers for emitting.) // Insert a COVERINC node at the end of the statement list // for that if/else/case. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Coverage.h" #include "V3Ast.h" //###################################################################### // Coverage state, as a visitor of each AstNode class CoverageVisitor : public AstNVisitor { private: // TYPES typedef map FileMap; struct ToggleEnt { string m_comment; // Comment for coverage dump AstNode* m_varRefp; // How to get to this element AstNode* m_chgRefp; // How to get to this element ToggleEnt(const string& comment, AstNode* vp, AstNode* cp) : m_comment(comment), m_varRefp(vp), m_chgRefp(cp) {} ~ToggleEnt() {} void cleanup() { m_varRefp->deleteTree(); m_varRefp=NULL; m_chgRefp->deleteTree(); m_chgRefp=NULL; } }; // NODE STATE // Entire netlist: // AstIf::user1() -> bool. True indicates ifelse processed AstUser1InUse m_inuser1; // STATE bool m_checkBlock; // Should this block get covered? AstNodeModule* m_modp; // Current module to add statement to bool m_inToggleOff; // In function/task etc bool m_inModOff; // In module with no coverage FileMap m_fileps; // Column counts for each fileline string m_beginHier; // AstBegin hier name for user coverage points // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } const char* varIgnoreToggle(AstVar* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3TraceDecl::varIgnoreTrace string prettyName = nodep->prettyName(); if (!nodep->isToggleCoverable()) return "Not relevant signal type"; if (!v3Global.opt.coverageUnderscore()) { if (prettyName.c_str()[0] == '_') return "Leading underscore"; if (prettyName.find("._") != string::npos) return "Inlined leading underscore"; } if ((nodep->width()*nodep->dtypep()->arrayUnpackedElements()) > 256) return "Wide bus/array > 256 bits"; // We allow this, though tracing doesn't // if (nodep->arrayp(1)) return "Unsupported: Multi-dimensional array"; return NULL; } AstCoverInc* newCoverInc(FileLine* fl, const string& hier, const string& page_prefix, const string& comment) { // For line coverage, we may have multiple if's on one line, so disambiguate if // everything is otherwise identical // (Don't set column otherwise as it may result in making bins not match up with // different types of coverage enabled.) string key = fl->filename()+"\001"+cvtToStr(fl->lineno())+"\001"+hier+"\001"+page_prefix+"\001"+comment; int column = 0; FileMap::iterator it = m_fileps.find(key); if (it == m_fileps.end()) { m_fileps.insert(make_pair(key,column+1)); } else { column = (it->second)++; } // We could use the basename of the filename to the page, but seems better for code // from an include file to be listed under the module using it rather than the include file. // Note the module name could have parameters appended, we'll consider this // a feature as it allows for each parameterized block to be counted separately. // Someday the user might be allowed to specify a different page suffix string page = page_prefix + "/" + m_modp->prettyName(); AstCoverDecl* declp = new AstCoverDecl(fl, column, page, comment); declp->hier(hier); m_modp->addStmtp(declp); return new AstCoverInc(fl, declp); } // VISITORS - BOTH virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; m_inModOff = nodep->isTop(); // Ignore coverage on top module; it's a shell we created m_fileps.clear(); nodep->iterateChildren(*this); m_modp = NULL; m_inModOff = true; } // VISITORS - TOGGLE COVERAGE virtual void visit(AstNodeFTask* nodep, AstNUser*) { bool oldtog = m_inToggleOff; { m_inToggleOff = true; nodep->iterateChildren(*this); } m_inToggleOff = oldtog; } virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); if (m_modp && !m_inModOff && !m_inToggleOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageToggle()) { const char* disablep = varIgnoreToggle(nodep); if (disablep) { UINFO(4, " Disable Toggle: "<shortName(); AstVar* chgVarp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, newvarname, nodep); m_modp->addStmtp(chgVarp); // Create bucket for each dimension * bit. // This is necessarily an O(n^2) expansion, which is why // we limit coverage to signals with < 256 bits. ToggleEnt newvec (string(""), new AstVarRef(nodep->fileline(), nodep, false), new AstVarRef(nodep->fileline(), chgVarp, true)); toggleVarRecurse(nodep->dtypeSkipRefp(), 0, newvec, nodep, chgVarp); newvec.cleanup(); } } } void toggleVarBottom(AstNodeDType* dtypep, int depth, // per-iteration const ToggleEnt& above, AstVar* varp, AstVar* chgVarp) { // Constant AstCoverToggle* newp = new AstCoverToggle (varp->fileline(), newCoverInc(varp->fileline(), "", "v_toggle", varp->name()+above.m_comment), above.m_varRefp->cloneTree(true), above.m_chgRefp->cloneTree(true)); m_modp->addStmtp(newp); } void toggleVarRecurse(AstNodeDType* dtypep, int depth, // per-iteration const ToggleEnt& above, AstVar* varp, AstVar* chgVarp) { // Constant if (AstBasicDType* bdtypep = dtypep->castBasicDType()) { if (bdtypep->isRanged()) { for (int index_docs=bdtypep->lsb(); index_docsmsb()+1; index_docs++) { int index_code = index_docs - bdtypep->lsb(); ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]", new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code, 1), new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true), index_code, 1)); toggleVarBottom(dtypep, depth+1, newent, varp, chgVarp); newent.cleanup(); } } else { toggleVarBottom(dtypep, depth+1, above, varp, chgVarp); } } else if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) { for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) { int index_code = index_docs - adtypep->lsb(); ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]", new AstArraySel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code), new AstArraySel(varp->fileline(), above.m_chgRefp->cloneTree(true), index_code)); toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth+1, newent, varp, chgVarp); newent.cleanup(); } } else if (AstPackArrayDType* adtypep = dtypep->castPackArrayDType()) { for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) { AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp(); int index_code = index_docs - adtypep->lsb(); ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]", new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code*subtypep->width(), subtypep->width()), new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true), index_code*subtypep->width(), subtypep->width())); toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth+1, newent, varp, chgVarp); newent.cleanup(); } } else if (AstStructDType* adtypep = dtypep->castStructDType()) { // For now it's packed, so similar to array for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) { AstNodeDType* subtypep = itemp->subDTypep()->skipRefp(); int index_code = itemp->lsb(); ToggleEnt newent (above.m_comment+string(".")+itemp->name(), new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code, subtypep->width()), new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true), index_code, subtypep->width())); toggleVarRecurse(subtypep, depth+1, newent, varp, chgVarp); newent.cleanup(); } } else if (AstUnionDType* adtypep = dtypep->castUnionDType()) { // Arbitrarially handle only the first member of the union if (AstMemberDType* itemp = adtypep->membersp()) { AstNodeDType* subtypep = itemp->subDTypep()->skipRefp(); ToggleEnt newent (above.m_comment+string(".")+itemp->name(), above.m_varRefp->cloneTree(true), above.m_chgRefp->cloneTree(true)); toggleVarRecurse(subtypep, depth+1, newent, varp, chgVarp); newent.cleanup(); } } else { dtypep->v3fatalSrc("Unexpected node data type in toggle coverage generation: "<prettyTypeName()); } } // VISITORS - LINE COVERAGE virtual void visit(AstIf* nodep, AstNUser*) { // Note not AstNodeIf; other types don't get covered UINFO(4," IF: "<elsesp()->castIf() && !nodep->elsesp()->castIf()->nextp()); if (elsif) nodep->elsesp()->castIf()->user1(true); // nodep->ifsp()->iterateAndNext(*this); if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it UINFO(4," COVER: "<user1()) { nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "elsif")); } else { nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "if")); } } // Don't do empty else's, only empty if/case's if (nodep->elsesp()) { m_checkBlock = true; nodep->elsesp()->iterateAndNext(*this); if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it UINFO(4," COVER: "<addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "v_line", "else")); } } } m_checkBlock = true; // Reset as a child may have cleared it } } virtual void visit(AstCaseItem* nodep, AstNUser*) { UINFO(4," CASEI: "<fileline()->coverageOn() && v3Global.opt.coverageLine()) { nodep->bodysp()->iterateAndNext(*this); if (m_checkBlock) { // if the case body didn't disable it UINFO(4," COVER: "<addBodysp(newCoverInc(nodep->fileline(), "", "v_line", "case")); } m_checkBlock = true; // Reset as a child may have cleared it } } virtual void visit(AstPslCover* nodep, AstNUser*) { UINFO(4," PSLCOVER: "<iterateChildren(*this); if (!nodep->coverincp()) { // Note the name may be overridden by V3Assert processing nodep->coverincp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover")); } m_checkBlock = true; // Reset as a child may have cleared it } virtual void visit(AstStop* nodep, AstNUser*) { UINFO(4," STOP: "<pragType() == AstPragmaType::COVERAGE_BLOCK_OFF) { // Skip all NEXT nodes under this block, and skip this if/case branch UINFO(4," OFF: "<unlinkFrBack()->deleteTree(); nodep=NULL; } else { if (m_checkBlock) nodep->iterateChildren(*this); } } virtual void visit(AstBegin* nodep, AstNUser*) { // Record the hierarchy of any named begins, so we can apply to user // coverage points. This is because there may be cov points inside // generate blocks; each point should get separate consideration. // (Currently ignored for line coverage, since any generate iteration // covers the code in that line.) string oldHier = m_beginHier; bool oldtog = m_inToggleOff; { m_inToggleOff = true; if (nodep->name()!="") { m_beginHier = m_beginHier + (m_beginHier!=""?".":"") + nodep->name(); } nodep->iterateChildren(*this); } m_beginHier = oldHier; m_inToggleOff = oldtog; } // VISITORS - BOTH virtual void visit(AstNode* nodep, AstNUser*) { // Default: Just iterate if (m_checkBlock) { nodep->iterateChildren(*this); m_checkBlock = true; // Reset as a child may have cleared it } } public: // CONSTUCTORS CoverageVisitor(AstNetlist* rootp) { // Operate on all modules m_checkBlock = true; m_beginHier = ""; m_inToggleOff = false; m_inModOff = true; rootp->iterateChildren(*this); } virtual ~CoverageVisitor() {} }; //###################################################################### // Coverage class functions void V3Coverage::coverage(AstNetlist* rootp) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3GraphTest.cpp0000664000177100017500000002772012525171733017146 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Graph tests // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3Graph.h" #include "V3GraphDfa.h" //###################################################################### //###################################################################### // Test class class V3GraphTest { public: // ***These tests only run with DEBUG ON*** static int debug() { static int level = -1; // Note setting just --debug will not enable this, as we exit when we run the test if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__, 0); return level; } protected: // MEMBERS DfaGraph m_graph; // METHODS - for children virtual void runTest() = 0; // Run the test virtual string name() = 0; // Name of the test // Utilities void dump() { if (debug()>=9) { m_graph.dumpDotFilePrefixed("v3graphtest_"+name()); } } public: V3GraphTest() {} virtual ~V3GraphTest() {} void run() { if (debug()) runTest(); } }; //###################################################################### //###################################################################### // Vertices and nodes class V3GraphTestVertex : public V3GraphVertex { string m_name; public: V3GraphTestVertex(V3Graph* graphp, string name) : V3GraphVertex(graphp), m_name(name) {} virtual ~V3GraphTestVertex() {} // Accessors virtual string name() const { return m_name; } }; class V3GraphTestVarVertex : public V3GraphTestVertex { public: V3GraphTestVarVertex(V3Graph* graphp, string name) : V3GraphTestVertex(graphp, name) {} virtual ~V3GraphTestVarVertex() {} // Accessors virtual string dotColor() const { return "blue"; } }; //###################################################################### //###################################################################### // Test vertices and nodes class V3GraphTestStrong : public V3GraphTest { public: virtual string name() { return "strong"; } virtual void runTest() { V3Graph* gp = &m_graph; // Verify we break edges at a good point // A simple alg would make 3 breaks, below only requires b->i to break V3GraphTestVertex* i = new V3GraphTestVarVertex(gp,"*INPUTS*"); V3GraphTestVertex* a = new V3GraphTestVarVertex(gp,"a"); V3GraphTestVertex* b = new V3GraphTestVarVertex(gp,"b"); V3GraphTestVertex* g1 = new V3GraphTestVarVertex(gp,"g1"); V3GraphTestVertex* g2 = new V3GraphTestVarVertex(gp,"g2"); V3GraphTestVertex* g3 = new V3GraphTestVarVertex(gp,"g3"); V3GraphTestVertex* q = new V3GraphTestVarVertex(gp,"q"); new V3GraphEdge(gp, i, a, 2, true); new V3GraphEdge(gp, a, b, 2, true); new V3GraphEdge(gp, b, g1, 2, true); new V3GraphEdge(gp, b, g2, 2, true); new V3GraphEdge(gp, b, g3, 2, true); new V3GraphEdge(gp, g1, a, 2, true); new V3GraphEdge(gp, g3, g2, 2, true); new V3GraphEdge(gp, g2, g3, 2, true); new V3GraphEdge(gp, g1, q, 2, true); new V3GraphEdge(gp, g2, q, 2, true); new V3GraphEdge(gp, g3, q, 2, true); gp->stronglyConnected(&V3GraphEdge::followAlwaysTrue); dump(); UASSERT(i->color()!=a->color() && a->color() != g2->color() && g2->color() != q->color(), "Separate colors not assigned"); UASSERT(a->color()==b->color() && a->color()==g1->color(), "Strongly connected nodes not colored together"); UASSERT(g2->color()==g3->color(), "Strongly connected nodes not colored together"); } }; class V3GraphTestAcyc : public V3GraphTest { public: virtual string name() { return "acyc"; } virtual void runTest() { V3Graph* gp = &m_graph; // Verify we break edges at a good point // A simple alg would make 3 breaks, below only requires b->i to break V3GraphTestVertex* i = new V3GraphTestVarVertex(gp,"*INPUTS*"); V3GraphTestVertex* a = new V3GraphTestVarVertex(gp,"a"); V3GraphTestVertex* b = new V3GraphTestVarVertex(gp,"b"); V3GraphTestVertex* g1 = new V3GraphTestVarVertex(gp,"g1"); V3GraphTestVertex* g2 = new V3GraphTestVarVertex(gp,"g2"); V3GraphTestVertex* g3 = new V3GraphTestVarVertex(gp,"g3"); new V3GraphEdge(gp, i, a, 2, true); new V3GraphEdge(gp, a, b, 2, true); new V3GraphEdge(gp, b, g1, 2, true); new V3GraphEdge(gp, b, g2, 2, true); new V3GraphEdge(gp, b, g3, 2, true); new V3GraphEdge(gp, g1, a, 2, true); new V3GraphEdge(gp, g2, a, 2, true); new V3GraphEdge(gp, g3, a, 2, true); gp->acyclic(&V3GraphEdge::followAlwaysTrue); gp->order(); dump(); } }; class V3GraphTestVars : public V3GraphTest { public: virtual string name() { return "vars"; } virtual void runTest() { V3Graph* gp = &m_graph; V3GraphTestVertex* clk = new V3GraphTestVarVertex(gp,"$clk"); V3GraphTestVertex* a = new V3GraphTestVarVertex(gp,"$a"); V3GraphTestVertex* a_dly = new V3GraphTestVarVertex(gp,"$a_dly"); V3GraphTestVertex* a_dlyblk= new V3GraphTestVarVertex(gp,"$a_dlyblk"); V3GraphTestVertex* b = new V3GraphTestVarVertex(gp,"$b"); V3GraphTestVertex* b_dly = new V3GraphTestVarVertex(gp,"$b_dly"); V3GraphTestVertex* b_dlyblk= new V3GraphTestVarVertex(gp,"$b_dlyblk"); V3GraphTestVertex* c = new V3GraphTestVarVertex(gp,"$c"); V3GraphTestVertex* i = new V3GraphTestVarVertex(gp,"$i"); V3GraphTestVertex* ap = new V3GraphTestVarVertex(gp,"$a_pre"); V3GraphTestVertex* bp = new V3GraphTestVarVertex(gp,"$b_pre"); V3GraphTestVertex* cp = new V3GraphTestVarVertex(gp,"$c_pre"); V3GraphTestVertex* n; // Logical order between clk, and posedge blocks // implemented by special CLK prod/cons? // Required order between first x_DLY<=x_pre and final x<=x_DLY // implemented by producer/consumer on a_dly signals // Required order between first x_DLY<=x_pre and x_DLY<=setters // implemented by fake dependency on _dlyblk // Required order between x_DLY<=setters and final x<=x_DLY // implemented by producer/consumer on a_dly signals // Desired order between different _DLY blocks so we can elim temporaries // implemented by cutable "pre" signal dependencies n = new V3GraphTestVertex(gp,"*INPUTS*"); { new V3GraphEdge(gp, n, clk, 2); new V3GraphEdge(gp, n, i, 2); } V3GraphTestVertex* posedge = n = new V3GraphTestVertex(gp,"*posedge clk*"); { new V3GraphEdge(gp, clk, n, 2); } // AssignPre's VarRefs on LHS: generate special BLK // normal: VarRefs on LHS: generate normal // underSBlock: VarRefs on RHS: consume 'pre' (required to save cutable tests) n = new V3GraphTestVertex(gp,"a_dlyacyclic(&V3GraphEdge::followAlwaysTrue); gp->order(); dump(); } }; //====================================================================== class DfaTestVertex : public DfaVertex { string m_name; public: DfaTestVertex(DfaGraph* graphp, string name) : DfaVertex(graphp), m_name(name) {} virtual ~DfaTestVertex() {} // Accessors virtual string name() const { return m_name; } }; class V3GraphTestDfa : public V3GraphTest { public: virtual string name() { return "dfa"; } virtual void runTest() { DfaGraph* gp = &m_graph; // NFA Pattern for ( (LR) | (L*R)) Z DfaTestVertex* st = new DfaTestVertex(gp,"*START*"); st->start(true); DfaTestVertex* sl = new DfaTestVertex(gp,"sL"); DfaTestVertex* srs = new DfaTestVertex(gp,"sR*"); DfaTestVertex* sls = new DfaTestVertex(gp,"sL*"); DfaTestVertex* sr = new DfaTestVertex(gp,"sR"); DfaTestVertex* sz = new DfaTestVertex(gp,"sZ"); DfaTestVertex* sac = new DfaTestVertex(gp,"*ACCEPT*"); sac->accepting(true); AstNUser* L = AstNUser::fromInt(0xaa); AstNUser* R = AstNUser::fromInt(0xbb); AstNUser* Z = AstNUser::fromInt(0xcc); new DfaEdge(gp, st, sl, DfaEdge::EPSILON()); new DfaEdge(gp, sl, srs, L); new DfaEdge(gp, srs, srs, R); new DfaEdge(gp, srs, sz, Z); new DfaEdge(gp, sz, sac, DfaEdge::EPSILON()); new DfaEdge(gp, st, sls, DfaEdge::EPSILON()); new DfaEdge(gp, sls, sls, L); new DfaEdge(gp, sls, sr, R); new DfaEdge(gp, sr, sz, Z); new DfaEdge(gp, sz, sac, DfaEdge::EPSILON()); dump(); gp->nfaToDfa(); dump(); gp->dfaReduce(); dump(); gp->dfaComplement(); dump(); gp->dfaReduce(); dump(); } }; //====================================================================== class V3GraphTestImport : public V3GraphTest { // cppcheck-suppress functionConst void dotImport(); public: virtual string name() { return "import"; } virtual void runTest() { DfaGraph* gp = &m_graph; if (V3GraphTest::debug()) gp->debug(9); dotImport(); dump(); gp->acyclic(&V3GraphEdge::followAlwaysTrue); dump(); gp->rank(&V3GraphEdge::followAlwaysTrue); dump(); } }; #if 0 # include "graph_export.cpp" #else void V3GraphTestImport::dotImport() { } #endif //====================================================================== void V3Graph::test() { // Execute all of the tests UINFO(2,__FUNCTION__<<": "< #include #include #include #include #include #include #include #include #if defined(WIN32) || defined(__MINGW32__) # include // mkdir #endif #include "V3Global.h" #include "V3String.h" #include "V3Os.h" //###################################################################### // Environment string V3Os::getenvStr(const string& envvar, const string& defaultValue) { if (const char* envvalue = getenv(envvar.c_str())) { return envvalue; } else { return defaultValue; } } void V3Os::setenvStr(const string& envvar, const string& value, const string& why) { if (why != "") { UINFO(1,"export "<(vareq.c_str())); #endif } //###################################################################### // Generic filename utilities string V3Os::filenameFromDirBase (const string& dir, const string& basename) { // Don't return ./{filename} because if filename was absolute, that makes it relative if (dir == ".") return basename; else return dir+"/"+basename; } string V3Os::filenameDir (const string& filename) { string::size_type pos; if ((pos = filename.rfind("/")) != string::npos) { return filename.substr(0,pos); } else { return "."; } } string V3Os::filenameNonDir (const string& filename) { string::size_type pos; if ((pos = filename.rfind("/")) != string::npos) { return filename.substr(pos+1); } else { return filename; } } string V3Os::filenameNonExt (const string& filename) { string base = filenameNonDir(filename); string::size_type pos; if ((pos = base.find(".")) != string::npos) { base.erase(pos); } return base; } string V3Os::filenameSubstitute (const string& filename) { string out; enum { NONE, PAREN, CURLY } brackets = NONE; for (string::size_type pos = 0; pos < filename.length(); ++pos) { if ((filename[pos] == '$') && (pos+1 < filename.length())) { switch (filename[pos+1]) { case '{': brackets = CURLY; break; case '(': brackets = PAREN; break; default: brackets = NONE; break; } if (brackets != NONE) pos = pos+1; string::size_type endpos = pos+1; while (((endpos+1) < filename.length()) && (((brackets==NONE) && (isalnum(filename[endpos+1]) || filename[endpos+1]=='_')) || ((brackets==CURLY) && (filename[endpos+1]!='}')) || ((brackets==PAREN) && (filename[endpos+1]!=')')))) ++endpos; // Catch bracket errors if (((brackets==CURLY) && (filename[endpos+1]!='}')) || ((brackets==PAREN) && (filename[endpos+1]!=')'))) { v3fatal("Unmatched brackets in variable substitution in file: "+filename); } string envvar = filename.substr(pos+1,endpos-pos); const char* envvalue = NULL; if (envvar != "") envvalue = getenv(envvar.c_str()); if (envvalue) { out += envvalue; if (brackets==NONE) pos = endpos; else pos = endpos+1; } else { out += filename[pos]; // *pos == '$' } } else { out += filename[pos]; } } return out; } bool V3Os::filenameIsRel(const string& filename) { return (filename.length()>0 && filename[0] != '/'); } //###################################################################### // Directory utilities void V3Os::createDir(const string& dirname) { #if defined(_WIN32) || defined(__MINGW32__) mkdir(dirname.c_str()); #else mkdir(dirname.c_str(), 0777); #endif } void V3Os::unlinkRegexp(const string& dir, const string& regexp) { if (DIR* dirp = opendir(dir.c_str())) { while (struct dirent* direntp = readdir(dirp)) { if (VString::wildmatch(direntp->d_name, regexp.c_str())) { string fullname = dir + "/" + string(direntp->d_name); unlink (fullname.c_str()); } } closedir(dirp); } } verilator-3.874/src/V3WidthSel.cpp0000664000177100017500000005017512525171734016771 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Expression width calculations // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3WidthSel's Transformations: // Top down traversal: // Replace SELPLUS/SELMINUS with SEL // Replace SELEXTRACT with SEL // Replace SELBIT with SEL or ARRAYSEL // // This code was once in V3LinkResolve, but little endian bit vectors won't // work that early. It was considered for V3Width and V3Param, but is // fairly ugly both places as the nodes change in too strongly // interconnected ways. // //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include "V3Global.h" #include "V3Width.h" #include "V3Const.h" //###################################################################### // Width state, as a visitor of each AstNode class WidthSelVisitor : public AstNVisitor { private: // IMPORTANT //**** This is not a normal visitor, in that all iteration is instead // done by the caller (V3Width). This avoids duplicating much of the // complicated GenCase/GenFor/Cell/Function call logic that all depends // on if widthing top-down or just for parameters. #define iterateChildren DO_NOT_iterateChildern_IN_V3WidthSel // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void checkConstantOrReplace(AstNode* nodep, const string& message) { // See also V3Width::checkConstantOrReplace // Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us! if (!nodep->castConst()) { nodep->v3error(message); nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1)); pushDeletep(nodep); nodep=NULL; } } // RETURN TYPE struct FromData { AstNode* m_errp; // Node that was found, for error reporting if not known type AstNodeDType* m_dtypep; // Data type for the 'from' slice VNumRange m_fromRange; // Numeric range bounds for the 'from' slice FromData(AstNode* errp, AstNodeDType* dtypep, VNumRange fromRange) { m_errp=errp; m_dtypep=dtypep; m_fromRange=fromRange; } ~FromData() {} }; FromData fromDataForArray(AstNode* nodep, AstNode* basefromp, bool rangedSelect) { // What is the data type and information for this SEL-ish's from()? UINFO(9," fromData start ddtypep = "<castAttrOf()) { basefromp = basefromp->castAttrOf()->fromp(); continue; } break; } if (!basefromp || !basefromp->dtypep()) nodep->v3fatalSrc("Select with no from dtype"); AstNodeDType* ddtypep = basefromp->dtypep()->skipRefp(); AstNode* errp = ddtypep; UINFO(9," fromData.ddtypep = "<castNodeArrayDType()) { fromRange = adtypep->declRange(); } else if (AstNodeClassDType* adtypep = ddtypep->castNodeClassDType()) { fromRange = adtypep->declRange(); } else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) { if (adtypep->isRanged()) { if (adtypep->rangep() && (!adtypep->rangep()->msbp()->castConst() || !adtypep->rangep()->lsbp()->castConst())) nodep->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep) fromRange = adtypep->declRange(); } else { nodep->v3error("Illegal bit or array select; type does not have a bit range, or bad dimension: type is " <prettyName()); } } else { nodep->v3error("Illegal bit or array select; type already selected, or bad dimension: type is " <prettyName()); } return FromData(errp,ddtypep,fromRange); } AstNode* newSubNeg(AstNode* lhsp, vlsint32_t rhs) { // Return lhs-rhs, but if rhs is negative use an add, so we won't // have to deal with signed math and related 32bit sign extension problems if (rhs == 0) { return lhsp; } else if (lhsp->castConst()) { // Optional vs just making add/sub below, but saves constification some work V3Number num (lhsp->fileline(), lhsp->width()); num.opSub(lhsp->castConst()->num(), V3Number(lhsp->fileline(), 32, rhs)); num.isSigned(lhsp->isSigned()); AstNode* newp = new AstConst(lhsp->fileline(), num); return newp; } else if (rhs > 0) { AstNode* newp = new AstSub(lhsp->fileline(), lhsp, new AstConst(lhsp->fileline(), AstConst::Unsized32(), rhs)); // We must make sure sub gets sign of original value, not from the constant newp->dtypeFrom(lhsp); return newp; } else { // rhs < 0; AstNode* newp = new AstAdd(lhsp->fileline(), lhsp, new AstConst(lhsp->fileline(), AstConst::Unsized32(), -rhs)); // We must make sure sub gets sign of original value, not from the constant newp->dtypeFrom(lhsp); return newp; } } AstNode* newSubNeg(vlsint32_t lhs, AstNode* rhsp) { // Return lhs-rhs // We must make sure sub gets sign of original value AstNode* newp = new AstSub(rhsp->fileline(), new AstConst(rhsp->fileline(), AstConst::Unsized32(), lhs), rhsp); newp->dtypeFrom(rhsp); // Important as AstSub default is lhs's sign return newp; } AstNode* newSubLsbOf(AstNode* underp, VNumRange fromRange) { // Account for a variable's LSB in bit selections // Will likely become SUB(underp, lsb_of_signal) // Don't report WIDTH warnings etc here, as may be inside a generate branch that will be deleted // SUB #'s Not needed when LSB==0 and MSB>=0 (ie [0:-13] must still get added!) if (!fromRange.ranged()) { // vector without range, or 0 lsb is ok, for example a INTEGER x; y = x[21:0]; return underp; } else { if (fromRange.littleEndian()) { // reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under) AstNode* newp = newSubNeg(fromRange.hi(), underp); return newp; } else { // reg [3:1] needs a SUB(under,1) AstNode* newp = newSubNeg(underp, fromRange.lo()); return newp; } } } AstNodeDType* sliceDType(AstPackArrayDType* nodep, int msb, int lsb) { // Return slice needed for msb/lsb, either as original dtype or a new slice dtype if (nodep->declRange().elements() == (msb-lsb+1) // Extracting whole of original array && nodep->declRange().lo() == lsb) { return nodep; } else { // Need a slice data type, which is an array of the extracted type, but with (presumably) different size VNumRange newRange (msb, lsb, nodep->declRange().littleEndian()); AstNodeDType* vardtypep = new AstPackArrayDType(nodep->fileline(), nodep->subDTypep(), // Need to strip off array reference new AstRange(nodep->fileline(), newRange)); v3Global.rootp()->typeTablep()->addTypesp(vardtypep); return vardtypep; } } // VISITORS // If adding new visitors, insure V3Width's visit(TYPE) calls into here virtual void visit(AstSelBit* nodep, AstNUser*) { // Select of a non-width specified part of an array, i.e. "array[2]" // This select style has a lsb and msb (no user specified width) UINFO(6,"SELBIT "<=9) nodep->backp()->dumpTree(cout,"--SELBT0: "); // lhsp/rhsp do not need to be constant AstNode* fromp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting if (debug()>=9) nodep->dumpTree(cout,"--SELBT2: "); FromData fromdata = fromDataForArray(nodep, fromp, false); AstNodeDType* ddtypep = fromdata.m_dtypep; VNumRange fromRange = fromdata.m_fromRange; UINFO(6," ddtypep "<castUnpackArrayDType()) { // SELBIT(array, index) -> ARRAYSEL(array, index) AstNode* subp = rhsp; if (fromRange.lo()!=0 || fromRange.hi()<0) { subp = newSubNeg (subp, fromRange.lo()); } AstArraySel* newp = new AstArraySel (nodep->fileline(), fromp, subp); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference if (debug()>=9) newp->dumpTree(cout,"--SELBTn: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) { // SELBIT(array, index) -> SEL(array, index*width-of-subindex, width-of-subindex) AstNode* subp = rhsp; if (fromRange.lo()!=0 || fromRange.hi()<0) { subp = newSubNeg (subp, fromRange.lo()); } if (!fromRange.elements() || (adtypep->width() % fromRange.elements())!=0) adtypep->v3fatalSrc("Array extraction with width miscomputed " <width()<<"/"<width() / fromRange.elements(); AstSel* newp = new AstSel (nodep->fileline(), fromp, new AstMul(nodep->fileline(), new AstConst(nodep->fileline(),AstConst::Unsized32(),elwidth), subp), new AstConst (nodep->fileline(),AstConst::Unsized32(),elwidth)); newp->declRange(fromRange); newp->declElWidth(elwidth); newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference if (debug()>=9) newp->dumpTree(cout,"--SELBTn: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else if (ddtypep->castBasicDType()) { // SELBIT(range, index) -> SEL(array, index, 1) AstSel* newp = new AstSel (nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange), // Unsized so width from user new AstConst (nodep->fileline(),AstConst::Unsized32(),1)); newp->declRange(fromRange); UINFO(6," new "<=9) newp->dumpTree(cout,"--SELBTn: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else if (ddtypep->castNodeClassDType()) { // It's packed, so a bit from the packed struct // SELBIT(range, index) -> SEL(array, index, 1) AstSel* newp = new AstSel (nodep->fileline(), fromp, newSubLsbOf(rhsp, fromRange), // Unsized so width from user new AstConst (nodep->fileline(),AstConst::Unsized32(),1)); newp->declRange(fromRange); UINFO(6," new "<=9) newp->dumpTree(cout,"--SELBTn: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else { // NULL=bad extract, or unknown node type nodep->v3error("Illegal bit or array select; type already selected, or bad dimension: type is" <prettyName()); // How to recover? We'll strip a dimension. nodep->replaceWith(fromp); pushDeletep(nodep); nodep=NULL; } if (!rhsp->backp()) pushDeletep(rhsp); rhsp=NULL; } virtual void visit(AstSelExtract* nodep, AstNUser*) { // Select of a range specified part of an array, i.e. "array[2:3]" // SELEXTRACT(from,msb,lsb) -> SEL(from, lsb, 1+msb-lsb) // This select style has a (msb or lsb) and width UINFO(6,"SELEXTRACT "<=9) nodep->dumpTree(cout,"--SELEX0: "); // Below 2 lines may change nodep->widthp() V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node V3Const::constifyParamsEdit(nodep->msbp()); // May relink pointed to node //if (debug()>=9) nodep->dumpTree(cout,"--SELEX3: "); checkConstantOrReplace(nodep->lsbp(), "First value of [a:b] isn't a constant, maybe you want +: or -:"); checkConstantOrReplace(nodep->msbp(), "Second value of [a:b] isn't a constant, maybe you want +: or -:"); AstNode* fromp = nodep->lhsp()->unlinkFrBack(); AstNode* msbp = nodep->rhsp()->unlinkFrBack(); AstNode* lsbp = nodep->thsp()->unlinkFrBack(); vlsint32_t msb = msbp->castConst()->toSInt(); vlsint32_t lsb = lsbp->castConst()->toSInt(); FromData fromdata = fromDataForArray(nodep, fromp, false); AstNodeDType* ddtypep = fromdata.m_dtypep; VNumRange fromRange = fromdata.m_fromRange; if (ddtypep->castUnpackArrayDType()) { // Slice extraction if (fromRange.elements() == (msb-lsb+1) && fromRange.lo() == lsb) { // Extracting whole of original array nodep->replaceWith(fromp); pushDeletep(nodep); nodep=NULL; } else { // TODO when unpacked arrays fully supported probably need new data type here AstArraySel* newp = new AstArraySel (nodep->fileline(), fromp, lsbp); newp->start(lsb); newp->length((msb - lsb) + 1); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } } else if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) { // SELEXTRACT(array, msb, lsb) -> SEL(array, lsb*width-of-subindex, width-of-subindex*(msb-lsb)) if (!fromRange.elements() || (adtypep->width() % fromRange.elements())!=0) adtypep->v3fatalSrc("Array extraction with width miscomputed " <width()<<"/"<width() / fromRange.elements(); AstSel* newp = new AstSel (nodep->fileline(), fromp, new AstConst(nodep->fileline(),AstConst::Unsized32(),lsb*elwidth), new AstConst(nodep->fileline(),AstConst::Unsized32(),(msb-lsb+1)*elwidth)); newp->declRange(fromRange); newp->declElWidth(elwidth); newp->dtypeFrom(sliceDType(adtypep, msb, lsb)); //if (debug()>=9) newp->dumpTree(cout,"--EXTBTn: "); if (newp->widthMin()!=(int)newp->widthConst()) nodep->v3fatalSrc("Width mismatch"); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else if (ddtypep->castBasicDType()) { if (fromRange.littleEndian()) { // Below code assumes big bit endian; just works out if we swap int x = msb; msb = lsb; lsb = x; } if (lsb > msb) { nodep->v3error("["<fileline(), AstConst::Unsized32(), // Unsized so width from user msb +1-lsb); AstSel* newp = new AstSel (nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange), widthp); newp->declRange(fromRange); UINFO(6," new "<=9) newp->dumpTree(cout,"--SELEXnew: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else if (ddtypep->castNodeClassDType()) { // Classes aren't little endian if (lsb > msb) { nodep->v3error("["<fileline(), AstConst::Unsized32(), // Unsized so width from user msb +1-lsb); AstSel* newp = new AstSel (nodep->fileline(), fromp, newSubLsbOf(lsbp, fromRange), widthp); newp->declRange(fromRange); UINFO(6," new "<=9) newp->dumpTree(cout,"--SELEXnew: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else { // NULL=bad extract, or unknown node type nodep->v3error("Illegal range select; type already selected, or bad dimension: type is " <prettyName()); UINFO(1," Related ddtype: "<replaceWith(fromp); pushDeletep(nodep); nodep=NULL; } // delete whataver we didn't use in reconstruction if (!fromp->backp()) pushDeletep(fromp); fromp=NULL; if (!msbp->backp()) pushDeletep(msbp); msbp=NULL; if (!lsbp->backp()) pushDeletep(lsbp); lsbp=NULL; } void replaceSelPlusMinus(AstNodePreSel* nodep) { // Select of a range specified with +: or -:, i.e. "array[2+:3], [2-:3]" // This select style has a lsb and width UINFO(6,"SELPLUS/MINUS "<widthp() if (debug()>=9) nodep->dumpTree(cout,"--SELPM0: "); V3Const::constifyParamsEdit(nodep->thsp()); // May relink pointed to node checkConstantOrReplace(nodep->thsp(), "Width of :+ or :- bit extract isn't a constant"); if (debug()>=9) nodep->dumpTree(cout,"--SELPM3: "); // Now replace it with an AstSel AstNode* fromp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* widthp = nodep->thsp()->unlinkFrBack(); int width = widthp->castConst()->toSInt(); if (width > (1<<28)) nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: "<prettyName()); if (width<0) nodep->v3error("Width of :+ or :- is < 0: "<prettyName()); FromData fromdata = fromDataForArray(nodep, fromp, width!=1); AstNodeDType* ddtypep = fromdata.m_dtypep; VNumRange fromRange = fromdata.m_fromRange; if (ddtypep->castBasicDType() || ddtypep->castPackArrayDType() || (ddtypep->castNodeClassDType() && ddtypep->castNodeClassDType()->packedUnsup())) { int elwidth = 1; AstNode* newwidthp = widthp; if (AstPackArrayDType* adtypep = ddtypep->castPackArrayDType()) { elwidth = adtypep->width() / fromRange.elements(); newwidthp = new AstConst (nodep->fileline(),AstConst::Unsized32(), width * elwidth); } AstNode* newlsbp = NULL; if (nodep->castSelPlus()) { if (fromRange.littleEndian()) { // SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width) newlsbp = newSubNeg((fromRange.hi()-width+1), rhsp); } else { // SELPLUS(from,lsb,width) -> SEL(from, lsb-vector_lsb, width) newlsbp = newSubNeg(rhsp, fromRange.lo()); } } else if (nodep->castSelMinus()) { if (fromRange.littleEndian()) { // SELMINUS(from,msb,width) -> SEL(from, msb-[bit]) newlsbp = newSubNeg(fromRange.hi(), rhsp); } else { // SELMINUS(from,msb,width) -> SEL(from, msb-(width-1)-lsb#) newlsbp = newSubNeg(rhsp, fromRange.lo()+(width-1)); } } else { nodep->v3fatalSrc("Bad Case"); } if (elwidth != 1) newlsbp = new AstMul (nodep->fileline(), newlsbp, new AstConst (nodep->fileline(), elwidth)); AstSel* newp = new AstSel (nodep->fileline(), fromp, newlsbp, newwidthp); newp->declRange(fromRange); newp->declElWidth(elwidth); UINFO(6," new "<=9) newp->dumpTree(cout,"--SELNEW: "); nodep->replaceWith(newp); pushDeletep(nodep); nodep=NULL; } else { // NULL=bad extract, or unknown node type nodep->v3error("Illegal +: or -: select; type already selected, or bad dimension: type is " <prettyTypeName()); // How to recover? We'll strip a dimension. nodep->replaceWith(fromp); pushDeletep(nodep); nodep=NULL; } // delete whataver we didn't use in reconstruction if (!fromp->backp()) pushDeletep(fromp); fromp=NULL; if (!rhsp->backp()) pushDeletep(rhsp); rhsp=NULL; if (!widthp->backp()) pushDeletep(widthp); widthp=NULL; } virtual void visit(AstSelPlus* nodep, AstNUser*) { replaceSelPlusMinus(nodep); } virtual void visit(AstSelMinus* nodep, AstNUser*) { replaceSelPlusMinus(nodep); } // If adding new visitors, insure V3Width's visit(TYPE) calls into here //-------------------- // Default virtual void visit(AstNode* nodep, AstNUser*) { // See notes above; we never iterate nodep->v3fatalSrc("Shouldn't iterate in V3WidthSel"); } public: // CONSTUCTORS WidthSelVisitor() {} AstNode* mainAcceptEdit(AstNode* nodep) { return nodep->acceptSubtreeReturnEdits(*this); } virtual ~WidthSelVisitor() {} }; //###################################################################### // Width class functions AstNode* V3Width::widthSelNoIterEdit(AstNode* nodep) { UINFO(4,__FUNCTION__<<": "< #include #include #include #include #include "V3Global.h" #include "V3Table.h" #include "V3Simulate.h" #include "V3Stats.h" #include "V3Ast.h" //###################################################################### // Table class functions // CONFIG static const double TABLE_MAX_BYTES = 1*1024*1024; // 1MB is max table size (better be lots of instructs to be worth it!) static const double TABLE_TOTAL_BYTES = 64*1024*1024; // 64MB is close to max memory of some systems (256MB or so), so don't get out of control static const double TABLE_SPACE_TIME_MULT = 8; // Worth 8 bytes of data to replace a instruction static const int TABLE_MIN_NODE_COUNT = 32; // If < 32 instructions, not worth the effort //###################################################################### class TableVisitor; class TableSimulateVisitor : public SimulateVisitor { // MEMBERS TableVisitor* m_cbthis; ///< Class for callback public: virtual void varRefCb(AstVarRef* nodep); ///< Call other-this function on all new var references // CONSTRUCTORS TableSimulateVisitor(TableVisitor* cbthis) { m_cbthis = cbthis; } virtual ~TableSimulateVisitor() {} }; //###################################################################### // Table class functions class TableVisitor : public AstNVisitor { private: // NODE STATE // Cleared on each always/assignw // STATE double m_totalBytes; // Total bytes in tables created V3Double0 m_statTablesCre; // Statistic tracking // State cleared on each module AstNodeModule* m_modp; // Current MODULE int m_modTables; // Number of tables created in this module deque m_modTableVscs; // All tables created // State cleared on each scope AstScope* m_scopep; // Current SCOPE // State cleared on each always/assignw bool m_assignDly; // Consists of delayed assignments instead of normal assignments int m_inWidth; // Input table width int m_outWidth; // Output table width deque m_inVarps; // Input variable list deque m_outVarps; // Output variable list deque m_outNotSet; // True if output variable is not set at some point // When creating a table deque m_tableVarps; // Table being created // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } bool treeTest(AstAlways* nodep) { // Process alw/assign tree m_inWidth = 0; m_outWidth = 0; m_inVarps.clear(); m_outVarps.clear(); m_outNotSet.clear(); // Collect stats TableSimulateVisitor chkvis (this); chkvis.mainTableCheck(nodep); m_assignDly = chkvis.isAssignDly(); // Also sets m_inWidth // Also sets m_outWidth // Also sets m_inVarps // Also sets m_outVarps // Calc data storage in bytes size_t chgWidth = m_outVarps.size(); // Width of one change-it-vector if (chgWidth<8) chgWidth = 8; double space = (pow((double)2,((double)(m_inWidth))) *(double)(m_outWidth+chgWidth)); // Instruction count bytes (ok, it's space also not time :) double bytesPerInst = 4; double time = (chkvis.instrCount()*bytesPerInst + chkvis.dataCount()) + 1; // +1 so won't div by zero if (chkvis.instrCount() < TABLE_MIN_NODE_COUNT) { chkvis.clearOptimizable(nodep,"Table has too few nodes involved"); } if (space > TABLE_MAX_BYTES) { chkvis.clearOptimizable(nodep,"Table takes too much space"); } if (space > time * TABLE_SPACE_TIME_MULT) { chkvis.clearOptimizable(nodep,"Table has bad tradeoff"); } if (m_totalBytes > TABLE_TOTAL_BYTES) { chkvis.clearOptimizable(nodep,"Table out of memory"); } if (!m_outWidth || !m_inWidth) { chkvis.clearOptimizable(nodep,"Table has no outputs"); } UINFO(4, " Test: Opt="<<(chkvis.optimizable()?"OK":"NO") <<", Instrs="<varScopep(); if (nodep->lvalue()) { m_outWidth += nodep->varp()->dtypeSkipRefp()->widthTotalBytes(); m_outVarps.push_back(vscp); } else { // We'll make the table with a separate natural alignment for each // output var, so always have char, 16 or 32 bit widths, so use widthTotalBytes m_inWidth += nodep->varp()->width(); // Space for var m_inVarps.push_back(vscp); } } private: void createTable(AstAlways* nodep) { // We've determined this table of nodes is optimizable, do it. ++m_modTables; ++m_statTablesCre; // Index into our table AstVar* indexVarp = new AstVar (nodep->fileline(), AstVarType::BLOCKTEMP, "__Vtableidx" + cvtToStr(m_modTables), VFlagBitPacked(), m_inWidth); m_modp->addStmtp(indexVarp); AstVarScope* indexVscp = new AstVarScope (indexVarp->fileline(), m_scopep, indexVarp); m_scopep->addVarp(indexVscp); // Change it variable FileLine* fl = nodep->fileline(); AstNodeArrayDType* dtypep = new AstUnpackArrayDType (fl, nodep->findBitDType(m_outVarps.size(), m_outVarps.size(), AstNumeric::UNSIGNED), new AstRange (fl, VL_MASK_I(m_inWidth), 0)); v3Global.rootp()->typeTablep()->addTypesp(dtypep); AstVar* chgVarp = new AstVar (fl, AstVarType::MODULETEMP, "__Vtablechg" + cvtToStr(m_modTables), dtypep); chgVarp->isConst(true); chgVarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL)); m_modp->addStmtp(chgVarp); AstVarScope* chgVscp = new AstVarScope (chgVarp->fileline(), m_scopep, chgVarp); m_scopep->addVarp(chgVscp); createTableVars(nodep); AstNode* stmtsp = createLookupInput(nodep, indexVscp); createTableValues(nodep, chgVscp); // Collapse duplicate tables chgVscp = findDuplicateTable(chgVscp); for (deque::iterator it = m_tableVarps.begin(); it!=m_tableVarps.end(); ++it) { *it = findDuplicateTable(*it); } createOutputAssigns(nodep, stmtsp, indexVscp, chgVscp); // Link it in. if (AstAlways* nodeap = nodep->castAlways()) { // Keep sensitivity list, but delete all else nodeap->bodysp()->unlinkFrBackWithNext()->deleteTree(); nodeap->addStmtp(stmtsp); if (debug()>=6) nodeap->dumpTree(cout," table_new: "); } else { nodep->v3fatalSrc("Creating table under unknown node type"); } // Cleanup internal structures m_tableVarps.clear(); } void createTableVars(AstNode* nodep) { // Create table for each output for (deque::iterator it = m_outVarps.begin(); it!=m_outVarps.end(); ++it) { AstVarScope* outvscp = *it; AstVar* outvarp = outvscp->varp(); FileLine* fl = nodep->fileline(); AstNodeArrayDType* dtypep = new AstUnpackArrayDType (fl, outvarp->dtypep(), new AstRange (fl, VL_MASK_I(m_inWidth), 0)); v3Global.rootp()->typeTablep()->addTypesp(dtypep); AstVar* tablevarp = new AstVar (fl, AstVarType::MODULETEMP, "__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(), dtypep); tablevarp->isConst(true); tablevarp->isStatic(true); tablevarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL)); m_modp->addStmtp(tablevarp); AstVarScope* tablevscp = new AstVarScope(tablevarp->fileline(), m_scopep, tablevarp); m_scopep->addVarp(tablevscp); m_tableVarps.push_back(tablevscp); } } AstNode* createLookupInput(AstNode* nodep, AstVarScope* indexVscp) { // Concat inputs into a single temp variable (inside always) // First var in inVars becomes the LSB of the concat AstNode* concatp = NULL; for (deque::iterator it = m_inVarps.begin(); it!=m_inVarps.end(); ++it) { AstVarScope* invscp = *it; AstVarRef* refp = new AstVarRef (nodep->fileline(), invscp, false); if (concatp) { concatp = new AstConcat (nodep->fileline(), refp, concatp); } else concatp = refp; } AstNode* stmtsp = new AstAssign (nodep->fileline(), new AstVarRef (nodep->fileline(), indexVscp, true), concatp); return stmtsp; } void createTableValues(AstAlways* nodep, AstVarScope* chgVscp) { // Create table // There may be a simulation path by which the output doesn't change value. // We could bail on these cases, or we can have a "change it" boolean. // We've choosen the later route, since recirc is common in large FSMs. for (deque::iterator it = m_outVarps.begin(); it!=m_outVarps.end(); ++it) { m_outNotSet.push_back(false); } uint32_t inValueNextInitArray=0; TableSimulateVisitor simvis (this); for (uint32_t inValue=0; inValue <= VL_MASK_I(m_inWidth); inValue++) { // Make a new simulation structure so we can set new input values UINFO(8," Simulating "<::iterator it = m_inVarps.begin(); it!=m_inVarps.end(); ++it) { AstVarScope* invscp = *it; // LSB is first variable, so extract it that way simvis.newNumber(invscp, VL_MASK_I(invscp->width()) & (inValue>>shift)); shift += invscp->width(); // We're just using32 bit arithmetic, because there's no way the input table can be 2^32 bytes! if (shift>31) nodep->v3fatalSrc("shift overflow"); UINFO(8," Input "<name()<<" = "<<*(simvis.fetchNumber(invscp))<v3fatalSrc("Optimizable cleared, even though earlier test run said not: "<fileline(), m_outVarps.size(), 0); for (deque::iterator it = m_outVarps.begin(); it!=m_outVarps.end(); ++it) { AstVarScope* outvscp = *it; V3Number* outnump = simvis.fetchOutNumberNull(outvscp); AstNode* setp; if (!outnump) { UINFO(8," Output "<name()<<" never set\n"); m_outNotSet[outnum] = true; // Value in table is arbitrary, but we need something setp = new AstConst (outvscp->fileline(), V3Number(outvscp->fileline(), outvscp->width(), 0)); } else { UINFO(8," Output "<name()<<" = "<<*outnump<fileline(), *outnump); } // Note InitArray requires us to have the values in inValue order m_tableVarps[outnum]->varp()->valuep()->castInitArray()->addInitsp(setp); outnum++; } { // Set changed table if (inValue != inValueNextInitArray++) nodep->v3fatalSrc("InitArray requires us to have the values in inValue order"); AstNode* setp = new AstConst (nodep->fileline(), outputChgMask); chgVscp->varp()->valuep()->castInitArray()->addInitsp(setp); } } // each value } AstVarScope* findDuplicateTable(AstVarScope* vsc1p) { // See if another table we've created is identical, if so use it for both. // (A more 'modern' way would be to instead use V3Hashed::findDuplicate) AstVar* var1p = vsc1p->varp(); for (deque::iterator it = m_modTableVscs.begin(); it!=m_modTableVscs.end(); ++it) { AstVarScope* vsc2p= *it; AstVar* var2p = vsc2p->varp(); if (var1p->width() == var2p->width() && (var1p->dtypep()->arrayUnpackedElements() == var2p->dtypep()->arrayUnpackedElements())) { AstNode* init1p = var1p->valuep()->castInitArray(); AstNode* init2p = var2p->valuep()->castInitArray(); if (init1p->sameGateTree(init2p)) { UINFO(8," Duplicate table var "<iterateChildren(*this); m_scopep = NULL; } virtual void visit(AstAlways* nodep, AstNUser*) { UINFO(4," ALWAYS "<iterateChildren(*this); } public: // CONSTRUCTORS TableVisitor(AstNetlist* nodep) { m_modp = NULL; m_modTables = 0; m_scopep = NULL; m_assignDly = 0; m_inWidth = 0; m_outWidth = 0; m_totalBytes = 0; nodep->accept(*this); } virtual ~TableVisitor() { V3Stats::addStat("Optimizations, Tables created", m_statTablesCre); } }; //###################################################################### void TableSimulateVisitor::varRefCb(AstVarRef* nodep) { // Called by checking on each new varref encountered // We cross-call into a TableVisitor function. m_cbthis->simulateVarRefCb(nodep); } //###################################################################### // Table class functions void V3Table::tableAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 3); } verilator-3.874/src/V3LinkLevel.h0000664000177100017500000000250112525171733016565 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Link modules/signals together // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3LINKLEVEL_H_ #define _V3LINKLEVEL_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" //============================================================================ class V3LinkLevel { private: static void wrapTopCell(AstNetlist* nodep); static void wrapTopPackages(AstNetlist* nodep); public: static void modSortByLevel(); static void wrapTop(AstNetlist* nodep); }; #endif // Guard verilator-3.874/src/verilog.l0000664000177100017500000014562512534317670016163 0ustar wsnyderwsnyder/* -*- C++ -*- */ /************************************************************************** * DESCRIPTION: Verilator: Flex input file * * Code available from: http://www.veripool.org/verilator * ************************************************************************** * * Copyright 2003-2015 by Wilson Snyder. Verilator 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *************************************************************************/ %option interactive c++ stack noyywrap %{ /* %option nodefault */ #include #include #include #include "V3Number.h" #include "V3ParseImp.h" // Defines YYTYPE; before including bison header #include "V3ParseBison.h" // Generated by bison extern void yyerror(const char*); extern void yyerrorf(const char* format, ...); #define STATE_VERILOG_RECENT S12 // State name for most recent Verilog Version #define PARSEP V3ParseImp::parsep() #define SYMP PARSEP->symp() #define YY_INPUT(buf,result,max_size) \ result = PARSEP->flexPpInputToLex(buf,max_size); //====================================================================== #define NEXTLINE() {PARSEP->linenoInc();} #define LINECHECKS(textp,len) { const char* cp=textp; for (int n=len; n; --n) if (cp[n]=='\n') NEXTLINE(); } #define LINECHECK() LINECHECKS(yytext,yyleng) #define CRELINE() (PARSEP->copyOrSameFileLine()) #define FL { yylval.fl = CRELINE(); } #define RETURN_BBOX_SYS_OR_MSG(msg,yytext) { \ if (!v3Global.opt.bboxSys()) yyerrorf(msg,yytext); \ return yaD_IGNORE; } void V3ParseImp::ppline (const char* textp) { // Handle `line directive int enterExit; fileline()->lineDirective(textp, enterExit/*ref*/); } void V3ParseImp::verilatorCmtLint(const char* textp, bool warnOff) { const char* sp = textp; while (*sp && !isspace(*sp)) sp++; while (*sp && isspace(*sp)) sp++; while (*sp && !isspace(*sp)) sp++; while (*sp && isspace(*sp)) sp++; string msg = sp; string::size_type pos; if ((pos=msg.find("*")) != string::npos) { msg.erase(pos); } if (!(PARSEP->fileline()->warnOff(msg, warnOff))) { if (!PARSEP->optFuture(msg)) { yyerrorf("Unknown verilator lint message code: %s, in %s",msg.c_str(), textp); } } } void V3ParseImp::verilatorCmtLintSave() { m_lintState.push_back(*PARSEP->fileline()); } void V3ParseImp::verilatorCmtLintRestore() { if (m_lintState.empty()) { yyerrorf("/*verilator lint_restore*/ without matching save."); return; } PARSEP->fileline()->warnStateFrom(m_lintState.back()); m_lintState.pop_back(); } void V3ParseImp::verilatorCmtBad(const char* textp) { string cmtparse = textp; if (cmtparse.substr(0,strlen("/*verilator")) == "/*verilator") { cmtparse.replace(0,strlen("/*verilator"), ""); } while (isspace(cmtparse[0])) { cmtparse.replace(0,1, ""); } string cmtname; for (int i=0; isalnum(cmtparse[i]); i++) { cmtname += cmtparse[i]; } if (!PARSEP->optFuture(cmtname)) { yyerrorf("Unknown verilator comment: %s",textp); } } // See V3Read.cpp //void V3ParseImp::statePop() { yy_pop_state(); } //====================================================================== void yyerror(const char* errmsg) { PARSEP->fileline()->v3error(errmsg); } void yyerrorf(const char* format, ...) { const int maxlen = 2000; char msg[maxlen]; va_list ap; va_start(ap,format); VL_VSNPRINTF(msg,maxlen,format,ap); msg[maxlen-1] = '\0'; va_end(ap); yyerror(msg); } /**********************************************************************/ %} %e 2000 %p 5000 %n 2500 %k 1000 %a 15000 %o 25000 %s V95 V01 V05 S05 S09 S12 %s STRING ATTRMODE TABLE %s VA5 SAX VLT %s SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR SYSCDTOR %s IGNORE ws [ \t\f\r]+ wsnr [ \t\f]+ crnl [\r]*[\n] /* identifier */ id [a-zA-Z_][a-zA-Z0-9_$]* /* escaped identifier */ escid \\[^ \t\f\r\n]+ word [a-zA-Z0-9_]+ /* verilog numbers, constructed to not match the ' that begins a '( or '{ */ vnum1 [0-9]*?['']s?[bcodhBCODH][ \t\n]*[A-Fa-f0-9xXzZ_?]* vnum2 [0-9]*?['']s?[01xXzZ] vnum3 [0-9][_0-9]*[ \t\n]*['']s?[bcodhBCODH]?[ \t]*[A-Fa-f0-9xXzZ_?]+ vnum4 [0-9][_0-9]*[ \t\n]*['']s?[bcodhBCODH] vnum5 [0-9][_0-9]*[ \t\n]*['']s vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} %% .|\n {BEGIN STATE_VERILOG_RECENT; yyless(0); } /************************************************************************/ /* Verilator control files */ { {ws} { } /* otherwise ignore white-space */ {crnl} { NEXTLINE(); } /* Count line numbers */ "coverage_off" { FL; return yVLT_COVERAGE_OFF; } "lint_off" { FL; return yVLT_LINT_OFF; } "tracing_off" { FL; return yVLT_TRACING_OFF; } -?"-file" { FL; return yVLT_D_FILE; } -?"-lines" { FL; return yVLT_D_LINES; } -?"-msg" { FL; return yVLT_D_MSG; } } /************************************************************************/ /* Verilog 1995 */ { {ws} { } /* otherwise ignore white-space */ {crnl} { NEXTLINE(); } /* Count line numbers */ /* Extensions to Verilog set, some specified by PSL */ "$c"[0-9]* { FL; return yD_C; } /*Verilator only*/ /* System Tasks */ "$bitstoreal" { FL; return yD_BITSTOREAL; } "$ceil" { FL; return yD_CEIL; } "$display" { FL; return yD_DISPLAY; } "$exp" { FL; return yD_EXP; } "$fclose" { FL; return yD_FCLOSE; } "$fdisplay" { FL; return yD_FDISPLAY; } "$feof" { FL; return yD_FEOF; } "$fflush" { FL; return yD_FFLUSH; } "$fgetc" { FL; return yD_FGETC; } "$fgets" { FL; return yD_FGETS; } "$finish" { FL; return yD_FINISH; } "$floor" { FL; return yD_FLOOR; } "$fopen" { FL; return yD_FOPEN; } "$fscanf" { FL; return yD_FSCANF; } "$fullskew" { FL; return yaTIMINGSPEC; } "$fwrite" { FL; return yD_FWRITE; } "$hold" { FL; return yaTIMINGSPEC; } "$itor" { FL; return yD_ITOR; } "$ln" { FL; return yD_LN; } "$log10" { FL; return yD_LOG10; } "$nochange" { FL; return yaTIMINGSPEC; } "$period" { FL; return yaTIMINGSPEC; } "$pow" { FL; return yD_POW; } "$random" { FL; return yD_RANDOM; } "$readmemb" { FL; return yD_READMEMB; } "$readmemh" { FL; return yD_READMEMH; } "$realtime" { FL; return yD_REALTIME; } "$realtobits" { FL; return yD_REALTOBITS; } "$recovery" { FL; return yaTIMINGSPEC; } "$recrem" { FL; return yaTIMINGSPEC; } "$removal" { FL; return yaTIMINGSPEC; } "$rtoi" { FL; return yD_RTOI; } "$setup" { FL; return yaTIMINGSPEC; } "$setuphold" { FL; return yaTIMINGSPEC; } "$sformat" { FL; return yD_SFORMAT; } "$skew" { FL; return yaTIMINGSPEC; } "$sqrt" { FL; return yD_SQRT; } "$sscanf" { FL; return yD_SSCANF; } "$stime" { FL; return yD_STIME; } "$stop" { FL; return yD_STOP; } "$swrite" { FL; return yD_SWRITE; } "$system" { FL; return yD_SYSTEM; } "$test$plusargs" { FL; return yD_TESTPLUSARGS; } "$time" { FL; return yD_TIME; } "$timeskew" { FL; return yaTIMINGSPEC; } "$value$plusargs" { FL; return yD_VALUEPLUSARGS; } "$width" { FL; return yaTIMINGSPEC; } "$write" { FL; return yD_WRITE; } /* Keywords */ "always" { FL; return yALWAYS; } "and" { FL; return yAND; } "assign" { FL; return yASSIGN; } "begin" { FL; return yBEGIN; } "buf" { FL; return yBUF; } "bufif0" { FL; return yBUFIF0; } "bufif1" { FL; return yBUFIF1; } "case" { FL; return yCASE; } "casex" { FL; return yCASEX; } "casez" { FL; return yCASEZ; } "cmos" { FL; return yCMOS; } "default" { FL; return yDEFAULT; } "defparam" { FL; return yDEFPARAM; } "disable" { FL; return yDISABLE; } "edge" { FL; return yEDGE; } "else" { FL; return yELSE; } "end" { FL; return yEND; } "endcase" { FL; return yENDCASE; } "endfunction" { FL; return yENDFUNCTION; } "endmodule" { FL; return yENDMODULE; } "endprimitive" { FL; return yENDPRIMITIVE; } "endspecify" { FL; return yENDSPECIFY; } "endtable" { yyerrorf("Syntax error: ENDTABLE outside of TABLE"); } "endtask" { FL; return yENDTASK; } "for" { FL; return yFOR; } "forever" { FL; return yFOREVER; } "function" { FL; return yFUNCTION; } "if" { FL; return yIF; } "initial" { FL; return yINITIAL; } "inout" { FL; return yINOUT; } "input" { FL; return yINPUT; } "integer" { FL; return yINTEGER; } "macromodule" { FL; return yMODULE; } "module" { FL; return yMODULE; } "nand" { FL; return yNAND; } "negedge" { FL; return yNEGEDGE; } "nmos" { FL; return yNMOS; } "nor" { FL; return yNOR; } "not" { FL; return yNOT; } "notif0" { FL; return yNOTIF0; } "notif1" { FL; return yNOTIF1; } "or" { FL; return yOR; } "output" { FL; return yOUTPUT; } "parameter" { FL; return yPARAMETER; } "pmos" { FL; return yPMOS; } "posedge" { FL; return yPOSEDGE; } "primitive" { FL; return yPRIMITIVE; } "pulldown" { FL; return yPULLDOWN; } "pullup" { FL; return yPULLUP; } "rcmos" { FL; return yRCMOS; } "real" { FL; return yREAL; } "realtime" { FL; return yREALTIME; } "reg" { FL; return yREG; } "repeat" { FL; return yREPEAT; } "rnmos" { FL; return yRNMOS; } "rpmos" { FL; return yRPMOS; } "rtran" { FL; return yRTRAN; } "rtranif0" { FL; return yRTRANIF0; } "rtranif1" { FL; return yRTRANIF1; } "scalared" { FL; return ySCALARED; } "specify" { FL; return ySPECIFY; } "specparam" { FL; return ySPECPARAM; } "supply0" { FL; return ySUPPLY0; } "supply1" { FL; return ySUPPLY1; } "table" { yy_push_state(TABLE); FL; return yTABLE; } "task" { FL; return yTASK; } "time" { FL; return yTIME; } "tran" { FL; return yTRAN; } "tranif0" { FL; return yTRANIF0; } "tranif1" { FL; return yTRANIF1; } "tri" { FL; return yTRI; } "tri0" { FL; return yTRI0; } "tri1" { FL; return yTRI1; } "vectored" { FL; return yVECTORED; } "while" { FL; return yWHILE; } "wire" { FL; return yWIRE; } "xnor" { FL; return yXNOR; } "xor" { FL; return yXOR; } /* Special errors */ "$displayb" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $display with %%b format instead: %s",yytext); } "$displayh" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $display with %%x format instead: %s",yytext); } "$displayo" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $display with %%o format instead: %s",yytext); } "$fdisplayb" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fdisplay with %%b format instead: %s",yytext); } "$fdisplayh" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fdisplay with %%x format instead: %s",yytext); } "$fdisplayo" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fdisplay with %%o format instead: %s",yytext); } "$fwriteb" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fwrite with %%b format instead: %s",yytext); } "$fwriteh" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fwrite with %%x format instead: %s",yytext); } "$fwriteo" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $fwrite with %%o format instead: %s",yytext); } "$writeb" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $write with %%b format instead: %s",yytext); } "$writeh" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $write with %%x format instead: %s",yytext); } "$writeo" { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported: Use $write with %%o format instead: %s",yytext); } /* Generic unsupported warnings */ "deassign" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "event" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "force" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "fork" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "highz0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "highz1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "join" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "large" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "medium" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "pull0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "pull1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "release" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "small" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "strong0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "strong1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "triand" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "trior" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "trireg" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "wait" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "wand" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "weak0" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "weak1" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } "wor" { yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext); } } /* Verilog 2001 */ { /* System Tasks */ "$signed" { FL; return yD_SIGNED; } "$unsigned" { FL; return yD_UNSIGNED; } /* Keywords */ "automatic" { FL; return yAUTOMATIC; } "endgenerate" { FL; return yENDGENERATE; } "generate" { FL; return yGENERATE; } "genvar" { FL; return yGENVAR; } "ifnone" { FL; return yaTIMINGSPEC; } "localparam" { FL; return yLOCALPARAM; } "noshowcancelled" { FL; return yaTIMINGSPEC; } "pulsestyle_ondetect" { FL; return yaTIMINGSPEC; } "pulsestyle_onevent" { FL; return yaTIMINGSPEC; } "showcancelled" { FL; return yaTIMINGSPEC; } "signed" { FL; return ySIGNED; } "unsigned" { FL; return yUNSIGNED; } /* Generic unsupported keywords */ "cell" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "config" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "design" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "endconfig" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "incdir" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "include" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented; probably you want `include instead: %s",yytext); } "instance" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "liblist" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "library" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } "use" { yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented: %s",yytext); } } /* Verilog 2005 */ { /* Keywords */ "uwire" { FL; return yWIRE; } } /* System Verilog 2005 */ { /* System Tasks */ "$bits" { FL; return yD_BITS; } "$clog2" { FL; return yD_CLOG2; } "$countones" { FL; return yD_COUNTONES; } "$dimensions" { FL; return yD_DIMENSIONS; } "$error" { FL; return yD_ERROR; } "$fatal" { FL; return yD_FATAL; } "$high" { FL; return yD_HIGH; } "$increment" { FL; return yD_INCREMENT; } "$info" { FL; return yD_INFO; } "$isunknown" { FL; return yD_ISUNKNOWN; } "$left" { FL; return yD_LEFT; } "$low" { FL; return yD_LOW; } "$onehot" { FL; return yD_ONEHOT; } "$onehot0" { FL; return yD_ONEHOT0; } "$right" { FL; return yD_RIGHT; } "$size" { FL; return yD_SIZE; } "$unpacked_dimensions" { FL; return yD_UNPACKED_DIMENSIONS; } "$warning" { FL; return yD_WARNING; } /* SV2005 Keywords */ "$unit" { FL; return yD_UNIT; } /* Yes, a keyword, not task */ "always_comb" { FL; return yALWAYS_COMB; } "always_ff" { FL; return yALWAYS_FF; } "always_latch" { FL; return yALWAYS_LATCH; } "assert" { FL; return yASSERT; } "bind" { FL; return yBIND; } "bit" { FL; return yBIT; } "break" { FL; return yBREAK; } "byte" { FL; return yBYTE; } "chandle" { FL; return yCHANDLE; } "clocking" { FL; return yCLOCKING; } "const" { FL; return yCONST__LEX; } "context" { FL; return yCONTEXT; } "continue" { FL; return yCONTINUE; } "cover" { FL; return yCOVER; } "do" { FL; return yDO; } "endclocking" { FL; return yENDCLOCKING; } "endinterface" { FL; return yENDINTERFACE; } "endpackage" { FL; return yENDPACKAGE; } "endprogram" { FL; return yENDPROGRAM; } "endproperty" { FL; return yENDPROPERTY; } "enum" { FL; return yENUM; } "export" { FL; return yEXPORT; } "final" { FL; return yFINAL; } "iff" { FL; return yIFF; } "import" { FL; return yIMPORT; } "inside" { FL; return yINSIDE; } "int" { FL; return yINT; } "interface" { FL; return yINTERFACE; } "logic" { FL; return yLOGIC; } "longint" { FL; return yLONGINT; } "modport" { FL; return yMODPORT; } "package" { FL; return yPACKAGE; } "packed" { FL; return yPACKED; } "priority" { FL; return yPRIORITY; } "program" { FL; return yPROGRAM; } "property" { FL; return yPROPERTY; } "pure" { FL; return yPURE; } "rand" { FL; return yRAND; } "randc" { FL; return yRANDC; } "return" { FL; return yRETURN; } "shortint" { FL; return ySHORTINT; } "static" { FL; return ySTATIC; } "string" { FL; return ySTRING; } "struct" { FL; return ySTRUCT; } "timeprecision" { FL; return yTIMEPRECISION; } "timeunit" { FL; return yTIMEUNIT; } "typedef" { FL; return yTYPEDEF; } "union" { FL; return yUNION; } "unique" { FL; return yUNIQUE; } "var" { FL; return yVAR; } "void" { FL; return yVOID; } /* Generic unsupported warnings */ /* Note assert_strobe was in SystemVerilog 3.1, but removed for SystemVerilog 2005 */ "$root" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "alias" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "assume" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "before" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "binsof" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "class" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "constraint" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "covergroup" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "coverpoint" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "cross" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "dist" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "endclass" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "endgroup" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "endsequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "expect" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "extends" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "extern" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "first_match" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "foreach" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "forkjoin" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "ignore_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "illegal_bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "intersect" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "join_any" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "join_none" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "local" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "matches" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "new" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "null" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "protected" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "randcase" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "randomize" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "randsequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "ref" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "sequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "shortreal" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "solve" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "super" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "tagged" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "this" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "throughout" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "type" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "virtual" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "wait_order" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "wildcard" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "with" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } "within" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); } } /* SystemVerilog 2009 */ { /* Keywords */ "global" { FL; return yGLOBAL__LEX; } "unique0" { FL; return yUNIQUE0; } /* Generic unsupported warnings */ "accept_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "checker" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "endchecker" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "eventually" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "implies" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "let" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "nexttime" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "reject_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "restrict" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_always" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_eventually" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_nexttime" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_until" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "s_until_with" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "strong" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "sync_accept_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "sync_reject_on" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "until" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "until_with" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "untyped" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } "weak" { yyerrorf("Unsupported: SystemVerilog 2009 reserved word not implemented: %s",yytext); } } /* System Verilog 2012 */ { /* Keywords */ "implements" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); } "interconnect" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); } "nettype" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); } "soft" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); } } /* Default PLI rule */ { "$"[a-zA-Z_$][a-zA-Z0-9_$]* { string str (yytext,yyleng); yylval.strp = PARSEP->newString(AstNode::encodeName(str)); // Lookup unencoded name including the $, to avoid hitting normal signals if (SYMP->symCurrentp()->findIdFallback(str)) { FL; return yaD_DPI; } else { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported or unknown PLI call: %s",yytext); } } } /************************************************************************/ /* AMS */ { /* Generic unsupported warnings */ "above" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "abs" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "absdelay" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "abstol" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ac_stim" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "access" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "acos" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "acosh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "aliasparam" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "analog" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "analysis" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "asin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "asinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "assert" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "atan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "atan2" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "atanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "branch" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ceil" { FL; return yD_CEIL; } "connect" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "connectmodule" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "connectrules" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "continuous" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "cos" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "cosh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "cross" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ddt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ddt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ddx" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "discipline" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "discrete" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "domain" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "driver_update" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "endconnectrules" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "enddiscipline" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "endnature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "endparamset" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "exclude" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "exp" { FL; return yD_EXP; } "final_step" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "flicker_noise" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "floor" { FL; return yD_FLOOR; } "flow" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "from" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ground" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "hypot" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "idt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "idt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "idtmod" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "inf" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "initial_step" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "laplace_nd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "laplace_np" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "laplace_zd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "laplace_zp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "last_crossing" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "limexp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "ln" { FL; return yD_LN; } "log" { FL; return yD_LOG10; } "max" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "merged" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "min" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "net_resolution" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "noise_table" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "paramset" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "potential" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "pow" { FL; return yD_POW; } "resolveto" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "sin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "sinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "slew" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "split" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "sqrt" { FL; return yD_SQRT; } "string" { FL; return ySTRING; } "tan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "tanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "timer" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "transition" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "units" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "white_noise" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "wreal" { FL; return yWREAL; } "zi_nd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "zi_np" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "zi_zd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } "zi_zp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); } } /************************************************************************/ /* Meta comments */ /* Converted from //{cmt}verilator ...{cmt} by preprocessor */ { "/*verilator"{ws}*"*/" {} /* Ignore empty comments, may be `endif // verilator */ "/*verilator clock_enable*/" { FL; return yVL_CLOCK_ENABLE; } "/*verilator coverage_block_off*/" { FL; return yVL_COVERAGE_BLOCK_OFF; } "/*verilator full_case*/" { FL; return yVL_FULL_CASE; } "/*verilator inline_module*/" { FL; return yVL_INLINE_MODULE; } "/*verilator isolate_assignments*/" { FL; return yVL_ISOLATE_ASSIGNMENTS; } "/*verilator no_inline_module*/" { FL; return yVL_NO_INLINE_MODULE; } "/*verilator no_inline_task*/" { FL; return yVL_NO_INLINE_TASK; } "/*verilator parallel_case*/" { FL; return yVL_PARALLEL_CASE; } "/*verilator public*/" { FL; return yVL_PUBLIC; } "/*verilator public_flat*/" { FL; return yVL_PUBLIC_FLAT; } "/*verilator public_flat_rd*/" { FL; return yVL_PUBLIC_FLAT_RD; } "/*verilator public_flat_rw*/" { FL; return yVL_PUBLIC_FLAT_RW; } // The @(edge) is converted by the preproc "/*verilator public_module*/" { FL; return yVL_PUBLIC_MODULE; } "/*verilator sc_clock*/" { FL; return yVL_CLOCK; } "/*verilator clocker*/" { FL; return yVL_CLOCKER; } "/*verilator no_clocker*/" { FL; return yVL_NO_CLOCKER; } "/*verilator sc_bv*/" { FL; return yVL_SC_BV; } "/*verilator sformat*/" { FL; return yVL_SFORMAT; } "/*verilator systemc_clock*/" { FL; return yVL_CLOCK; } "/*verilator tracing_off*/" {PARSEP->fileline()->tracingOn(false); } "/*verilator tracing_on*/" {PARSEP->fileline()->tracingOn(true); } "/*verilator coverage_off*/" {PARSEP->fileline()->coverageOn(false); } "/*verilator coverage_on*/" {PARSEP->fileline()->coverageOn(true); } "/*verilator lint_off"[^*]*"*/" {PARSEP->verilatorCmtLint(yytext, true); } "/*verilator lint_on"[^*]*"*/" {PARSEP->verilatorCmtLint(yytext, false); } "/*verilator lint_restore*/" {PARSEP->verilatorCmtLintRestore(); } "/*verilator lint_save*/" {PARSEP->verilatorCmtLintSave(); } "/**/" { } "/*"[^*]+"*/" {PARSEP->verilatorCmtBad(yytext); } } /************************************************************************/ /* Single character operator thingies */ { "{" { FL; return yytext[0]; } "}" { FL; return yytext[0]; } "!" { FL; return yytext[0]; } "#" { FL; return yytext[0]; } "$" { FL; return yytext[0]; } "%" { FL; return yytext[0]; } "&" { FL; return yytext[0]; } "(" { FL; return yytext[0]; } ")" { FL; return yytext[0]; } "*" { FL; return yytext[0]; } "+" { FL; return yytext[0]; } "," { FL; return yytext[0]; } "-" { FL; return yytext[0]; } "." { FL; return yytext[0]; } "/" { FL; return yytext[0]; } ":" { FL; return yytext[0]; } ";" { FL; return yytext[0]; } "<" { FL; return yytext[0]; } "=" { FL; return yytext[0]; } ">" { FL; return yytext[0]; } "?" { FL; return yytext[0]; } "@" { FL; return yytext[0]; } "[" { FL; return yytext[0]; } "]" { FL; return yytext[0]; } "^" { FL; return yytext[0]; } "|" { FL; return yytext[0]; } "~" { FL; return yytext[0]; } } /************************************************************************/ /* Operators and multi-character symbols */ /* Verilog 1995 Operators */ { "&&" { FL; return yP_ANDAND; } "||" { FL; return yP_OROR; } "<=" { FL; return yP_LTE; } ">=" { FL; return yP_GTE; } "<<" { FL; return yP_SLEFT; } ">>" { FL; return yP_SRIGHT; } "==" { FL; return yP_EQUAL; } "!=" { FL; return yP_NOTEQUAL; } "===" { FL; return yP_CASEEQUAL; } "!==" { FL; return yP_CASENOTEQUAL; } "^~" { FL; return yP_XNOR; } "~^" { FL; return yP_XNOR; } "~&" { FL; return yP_NAND; } "~|" { FL; return yP_NOR; } "->" { FL; return yP_MINUSGT; } "=>" { FL; return yP_EQGT; } "*>" { FL; return yP_ASTGT; } "&&&" { FL; return yP_ANDANDAND; } } /* Verilog 2001 Operators */ { "<<<" { FL; return yP_SLEFT; } ">>>" { FL; return yP_SSRIGHT; } "**" { FL; return yP_POW; } "+:" { FL; return yP_PLUSCOLON; } "-:" { FL; return yP_MINUSCOLON; } ".*" { FL; return yP_DOTSTAR; } } /* SystemVerilog Operators */ { "'" { FL; return yP_TICK; } "'{" { FL; return yP_TICKBRA; } "==?" { FL; return yP_WILDEQUAL; } "!=?" { FL; return yP_WILDNOTEQUAL; } "++" { FL; return yP_PLUSPLUS; } "--" { FL; return yP_MINUSMINUS; } "+=" { FL; return yP_PLUSEQ; } "-=" { FL; return yP_MINUSEQ; } "*=" { FL; return yP_TIMESEQ; } "/=" { FL; return yP_DIVEQ; } "%=" { FL; return yP_MODEQ; } "&=" { FL; return yP_ANDEQ; } "|=" { FL; return yP_OREQ; } "^=" { FL; return yP_XOREQ; } "<<=" { FL; return yP_SLEFTEQ; } ">>=" { FL; return yP_SRIGHTEQ; } "<<<=" { FL; return yP_SLEFTEQ; } ">>>=" { FL; return yP_SSRIGHTEQ; } "->>" { FL; return yP_MINUSGTGT; } "##" { FL; return yP_POUNDPOUND; } "@@" { FL; return yP_ATAT; } "::" { FL; return yP_COLONCOLON; } ":=" { FL; return yP_COLONEQ; } ":/"[^\/\*] { FL; return yP_COLONDIV; } /* : then comment is not ":/" */ "|->" { FL; return yP_ORMINUSGT; } "|=>" { FL; return yP_OREQGT; } /* Some simulators allow whitespace here. Grr */ "["{ws}*"*" { FL; return yP_BRASTAR; } "["{ws}*"=" { FL; return yP_BRAEQ; } "["{ws}*"->" { FL; return yP_BRAMINUSGT; } } /* Identifiers and numbers */ { {escid} { FL; yylval.strp = PARSEP->newString (AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash return yaID__LEX; } {id} { FL; yylval.strp = PARSEP->newString(AstNode::encodeName(string(yytext))); return yaID__LEX; } \"[^\"\\]*\" { FL; yylval.strp = PARSEP->newString(yytext+1,yyleng-2); return yaSTRING; } \" { yy_push_state(STRING); yymore(); } {vnum} { /* "# 1'b0" is a delay value so must lex as "#" "1" "'b0" */ if (PARSEP->prevLexToken()=='#') { int shortlen = 0; while (isdigit(yytext[shortlen])) shortlen++; if (shortlen) { // Push rest for later parse PARSEP->unputString(yytext+shortlen, yyleng-shortlen); FL; LINECHECKS(yytext,shortlen); // Return is stuff before ' yytext[shortlen] = '\0'; yylval.nump = PARSEP->newNumber(yylval.fl, (char*)yytext); return yaINTNUM; } } FL; LINECHECK(); yylval.nump = PARSEP->newNumber(yylval.fl,(char*)yytext); return yaINTNUM; } [0-9][_0-9]* { FL; yylval.nump = PARSEP->newNumber(yylval.fl,(char*)yytext); return yaINTNUM; } [0-9][_0-9]*(\.[_0-9]+)([eE][-+]?[_0-9]+)? { FL; yylval.cdouble = PARSEP->parseDouble(yytext, yyleng); return yaFLOATNUM; } [0-9][_0-9]*(\.[_0-9]+)?([eE][-+]?[_0-9]+) { FL; yylval.cdouble = PARSEP->parseDouble(yytext, yyleng); return yaFLOATNUM; } [0-9][_0-9]*(\.[_0-9]+)?(fs|ps|ns|us|ms|s|step) { FL; yylval.cdouble = 0; /* Only for times, not used yet */ return yaTIMENUM; } } /************************************************************************/ /* STRINGS */ <> { yyerrorf("EOF in unterminated string"); yyleng = 0; yy_pop_state(); } {crnl} { yyerrorf("Unterminated string"); NEXTLINE(); } \\{crnl} { yymore(); NEXTLINE(); } \\. { yymore(); } \" { yy_pop_state(); FL; yylval.strp = PARSEP->newString(yytext+1,yyleng-2); return yaSTRING; } {word} { yymore(); } . { yymore(); } /************************************************************************/ /* Attributes */ {crnl} { yymore(); NEXTLINE(); } "*)" { yy_pop_state(); } {word} { yymore(); } . { yymore(); } <> { yyerrorf("EOF in (*"); yyleng = 0; yy_pop_state(); } /************************************************************************/ /* Attributes */ /* Note simulators vary in support for "(* /_*something*_/ foo*)" where _ doesn't exist */ { "(*"({ws}|{crnl})*({id}|{escid}) { yymore(); yy_push_state(ATTRMODE); } // Doesn't match (*), but (* attr_spec } /************************************************************************/ /* Tables */ \\{crnl} { yymore(); NEXTLINE(); }
{crnl} { NEXTLINE(); yymore(); }
";" { FL; yylval.strp = PARSEP->newString(yytext,yyleng); return yaTABLELINE; }
"endtable" { yy_pop_state(); FL; return yENDTABLE; }
. { yymore(); }
<> { yyerrorf("EOF in TABLE"); yyleng = 0; yy_pop_state(); } /************************************************************************/ /* Preprocessor */ /* Common for all SYSC header states */ /* OPTIMIZE: we return one per line, make it one for the entire block */ { "`accelerate" { } // Verilog-XL compatibility "`autoexpand_vectornets" { } // Verilog-XL compatibility "`celldefine" { PARSEP->inCellDefine(true); } "`default_decay_time"{ws}+[^\n\r]* { } // Verilog spec - delays only "`default_nettype"{ws}+"wire" { PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE,true); } "`default_nettype"{ws}+"none" { PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE,false); } "`default_nettype"{ws}+[a-zA-Z0-9]* { yyerrorf("Unsupported: `default_nettype of other than none or wire: %s",yytext); } "`default_trireg_strength"{ws}+[^\n\r]* { yyerrorf("Unsupported: Verilog optional directive not implemented: %s",yytext); } "`delay_mode_distributed" { } // Verilog spec - delays only "`delay_mode_path" { } // Verilog spec - delays only "`delay_mode_unit" { } // Verilog spec - delays only "`delay_mode_zero" { } // Verilog spec - delays only "`disable_portfaults" { } // Verilog-XL compatibility "`enable_portfaults" { } // Verilog-XL compatibility "`endcelldefine" { PARSEP->inCellDefine(false); } "`endprotect" { } "`expand_vectornets" { } // Verilog-XL compatibility "`inline" { } "`line"{ws}+[^\n\r]*{crnl} { PARSEP->ppline(yytext); } "`noaccelerate" { } // Verilog-XL compatibility "`noexpand_vectornets" { } // Verilog-XL compatibility "`noremove_gatenames" { } // Verilog-XL compatibility "`noremove_netnames" { } // Verilog-XL compatibility "`nosuppress_faults" { } // Verilog-XL compatibility "`nounconnected_drive" { } // Verilog-XL compatibility "`portcoerce" { } "`pragma"{ws}+[^\n\r]* { } // Verilog 2005 "`protect" { } "`remove_gatenames" { } // Verilog-XL compatibility "`remove_netnames" { } // Verilog-XL compatibility "`resetall" { PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE,true); } // Rest handled by preproc "`suppress_faults" { } // Verilog-XL compatibility "`timescale"{ws}+[^\n\r]* { } // Verilog spec - not supported /* See also setLanguage below */ "`begin_keywords"[ \t]*\"1364-1995\" { yy_push_state(V95); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1364-2001\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"VAMS[-0-9.]*\" { yy_push_state(VA5); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1800-2009\" { yy_push_state(S09); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1800-2012\" { yy_push_state(S12); PARSEP->pushBeginKeywords(YY_START); } "`begin_keywords"[ \t]*\"1800[+]VAMS\" { yy_push_state(SAX); PARSEP->pushBeginKeywords(YY_START); } /*Latest SV*/ "`end_keywords" { yy_pop_state(); if (!PARSEP->popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); } /* Verilator */ "`systemc_ctor" { BEGIN SYSCCTOR; } "`systemc_dtor" { BEGIN SYSCDTOR; } "`systemc_header" { BEGIN SYSCHDR; } "`systemc_imp_header" { BEGIN SYSCIMPH; } "`systemc_implementation" { BEGIN SYSCIMP; } "`systemc_interface" { BEGIN SYSCINT; } "`verilator_config" { BEGIN VLT; } "`verilog" { BEGIN PARSEP->lastVerilogState(); } } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCHDR; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCINT; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCIMP; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCIMPH; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCCTOR; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { FL; NEXTLINE(); yylval.strp = PARSEP->newString(yytext); return yaSCDTOR; } [ \t]*[^` \t\n\r][^\n\r]*{crnl} { NEXTLINE(); } /* Pick up text-type data */ { {wsnr}* { yymore(); } {crnl} { NEXTLINE(); yymore(); } } /************************************************************************/ /* Default rules - leave last */ { "`"[a-zA-Z_0-9]+ { FL; yyerrorf("Define or directive not defined: %s",yytext); } "//"[^\n]* { } /* throw away single line comments */ . { FL; return yytext[0]; } /* return single char ops. */ } /* Catch all - absolutely last */ <*>.|\n { yyerrorf("Missing verilog.l rule: Default rule invoked in state %d: %s", YY_START, yytext); } %% int V3ParseImp::stateVerilogRecent() { return STATE_VERILOG_RECENT; } double V3ParseImp::parseDouble(const char* textp, size_t length) { char* strgp = new char[length+1]; char* dp=strgp; for (const char* sp=textp; sp<(textp+length); ++sp) { if (*sp != '_') *dp++ = *sp; } *dp++ = '\0'; char* endp = strgp; double d = strtod(strgp, &endp); size_t parsed_len = endp-strgp; if (parsed_len != strlen(strgp)) { yyerrorf("Syntax error parsing real: %s",strgp); } delete strgp; return d; } int V3ParseImp::lexToken() { // called from lexToBison, has a "this" // Fetch next token from prefetch or real lexer int token; if (m_ahead) { // We prefetched an extra token, give it back m_ahead = false; token = m_aheadToken; yylval = m_aheadVal; } else { // Parse new token token = yylexReadTok(); //yylval // Set by yylexReadTok() } // If a paren, read another if (token == yCONST__LEX || token == yGLOBAL__LEX // Never put yID_* here; below symbol table resolution would break ) { if (debugFlex()) { cout<<" lexToken: reading ahead to find possible strength"<newString("global"); } // Avoid 2009 "global" conflicting with old code when we can } // If add to above "else if", also add to "if (token" further above } // If an id, change the type based on symbol table // Note above sometimes converts yGLOBAL to a yaID__LEX if (token == yaID__LEX) { AstNode* scp; if (VSymEnt* look_underp = SYMP->nextId()) { if (debugFlex()) { cout<<" lexToken: next id lookup forced under "<findIdFallback(*(yylval.strp))->nodep(); // "consume" it. Must set again if want another token under temp scope SYMP->nextId(NULL); } else { UINFO(7," lexToken: find upward "<symCurrentp()<<" for '"<<*(yylval.strp)<<"'"<=9) SYMP->symCurrentp()->dump(cout," -findtree: ",true); scp = SYMP->symCurrentp()->findIdFallback(*(yylval.strp))->nodep(); } yylval.scp = scp; if (scp) { UINFO(7," lexToken: Found "<castTypedef()) token = yaID__aTYPE; else if (scp->castTypedefFwd()) token = yaID__aTYPE; else if (scp->castPackage()) token = yaID__aPACKAGE; //UNSUP else if (scp->castClass()) token = yaID__aCLASS; //UNSUP else if (scp->castCoverGroup()) token = yaID__aCOVERGROUP; else token = yaID__ETC; } else { // Not found token = yaID__ETC; } } return token; } int V3ParseImp::lexToBison() { // Called as global since bison doesn't have our pointer int tok = lexToken(); //yylval.scp = NULL; // Symbol table not yet needed - no packages if (debugFlex()>=6 || debugBison()>=6) { cout<<" {"<filenameLetters()<lineno() <<"} lexToBison TOKEN="< #include #include #include #include using namespace std; //********************************************************************** //**** OS and compiler specifics #include "verilatedos.h" verilator-3.874/src/VlcTest.h0000664000177100017500000001030012525171734016050 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: verilator_coverage: Test/coverage file container // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _VLCTEST_H_ #define _VLCTEST_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "VlcPoint.h" #include "VlcBucket.h" #include #include //******************************************************************** // VlcTest - a single testrun i.e. a file containing coverage data class VlcTest { private: // MEMBERS string m_name; //< Name of the test double m_computrons; //< Runtime for the test vluint64_t m_testrun; //< Test run number, for database use vluint64_t m_rank; //< Execution rank suggestion vluint64_t m_rankPoints; //< Ranked additional points vluint64_t m_user; //< User data for algorithms (not persisted in .dat file) VlcBuckets m_buckets; //< Coverage data for each coverage point public: // CONSTRUCTORS VlcTest(const string& name, vluint64_t testrun, double comp) { m_name = name; m_computrons = comp; m_testrun = testrun; m_rank = 0; m_rankPoints = 0; m_user = 0; } ~VlcTest() {} // ACCESSORS const string& name() const { return m_name; } double computrons() const { return m_computrons; } vluint64_t testrun() const { return m_testrun; } VlcBuckets& buckets() { return m_buckets; } vluint64_t bucketsCovered() const { return m_buckets.bucketsCovered(); } vluint64_t rank() const { return m_rank; } void rank(vluint64_t flag) { m_rank = flag; } vluint64_t rankPoints() const { return m_rankPoints; } void rankPoints(vluint64_t flag) { m_rankPoints = flag; } vluint64_t user() const { return m_user; } void user(vluint64_t flag) { m_user = flag; } // METHODS static void dumpHeader() { cout<<"Tests:\n"; //cout<<" Testrun, Computrons,"; // Currently not loaded cout<<" Covered, Rank, RankPts, Filename"< ByName; private: // MEMBERS ByName m_tests; //< List of all tests public: // ITERATORS typedef ByName::iterator iterator; ByName::iterator begin() { return m_tests.begin(); } ByName::iterator end() { return m_tests.end(); } public: // CONSTRUCTORS VlcTests() {} ~VlcTests() { for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) { delete *it; *it=NULL; } } // METHODS void dump(bool bucketsToo) { UINFO(2,"dumpTests...\n"); VlcTest::dumpHeader(); for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) { (*it)->dump(bucketsToo); } } VlcTest* newTest(const string& name, vluint64_t testrun, double comp) { VlcTest* testp = new VlcTest(name, testrun, comp); m_tests.push_back(testp); return testp; } void clearUser() { for (ByName::iterator it = m_tests.begin(); it != m_tests.end(); ++it) { (*it)->user(0); } } }; //###################################################################### #endif // Guard verilator-3.874/src/V3Hashed.h0000664000177100017500000000611712525171733016103 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Hash AST trees to find duplicates // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2005-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3HASHED_H_ #define _V3HASHED_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" #include //============================================================================ class VHashedBase { public: // CONSTRUCTORS VHashedBase() {} ~VHashedBase() {} // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } }; //============================================================================ struct V3HashedUserCheck { // Functor for V3Hashed::findDuplicate virtual bool check(AstNode*,AstNode*) =0; V3HashedUserCheck() {} virtual ~V3HashedUserCheck() {} }; class V3Hashed : public VHashedBase { // NODE STATE // AstNode::user4() -> V3Hash. Hash value of this node (hash of 0 is illegal) AstUser4InUse m_inuser4; // TYPES typedef multimap HashMmap; public: typedef HashMmap::iterator iterator; private: // MEMBERS HashMmap m_hashMmap; // hashvalue -> nodes with that hash public: // CONSTRUCTORS V3Hashed() { clear(); } ~V3Hashed() {} // ACCESSORS HashMmap& mmap() { return m_hashMmap; } // Return map for iteration iterator begin() { return m_hashMmap.begin(); } iterator end() { return m_hashMmap.end(); } // METHODS void clear() { m_hashMmap.clear(); AstNode::user4ClearTree(); } iterator hashAndInsert(AstNode* nodep); // Hash the node, and insert into map. Return iterator to inserted void hash(AstNode* nodep); // Only hash the node bool sameNodes(AstNode* node1p, AstNode* node2p); // After hashing, and tell if identical void erase(iterator it); // Remove node from structures iterator findDuplicate(AstNode* nodep); // Return duplicate in hash, if any iterator findDuplicate(AstNode* nodep, V3HashedUserCheck* checkp); // Extra user checks for sameness AstNode* iteratorNodep(iterator it) { return it->second; } void dumpFile(const string& filename, bool tree); void dumpFilePrefixed(const string& nameComment, bool tree=false); static V3Hash nodeHash(AstNode* nodep) { return V3Hash(nodep->user4p()); } }; #endif // Guard verilator-3.874/src/V3Task.h0000664000177100017500000000303612525171733015606 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Inlining of modules // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* #ifndef _V3TASK_H_ #define _V3TASK_H_ 1 #include "config_build.h" #include "verilatedos.h" #include "V3Error.h" #include "V3Ast.h" #include //============================================================================ typedef pair V3TaskConnect; // [port, pin-connects-to] typedef vector V3TaskConnects; // [ [port, pin-connects-to] ... ] //============================================================================ class V3Task { public: static void taskAll(AstNetlist* nodep); static V3TaskConnects taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp); // Return vector of [port, pin-connects-to] (SLOW) }; #endif // Guard verilator-3.874/README0000664000177100017500000001573412534631200014411 0ustar wsnyderwsnyderNAME This is the Verilator package README file. DISTRIBUTION http://www.veripool.org/verilator This package is Copyright 2003-2015 by Wilson Snyder. (Report bugs to .) Verilator 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. (See the documentation for more details.) This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. DESCRIPTION Verilator converts synthesizable (generally not behavioral) Verilog code into C++ or SystemC code. It is not a complete simulator, just a translator. Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage code. For C++ format, it outputs .cpp and .h files. For SystemC format, it outputs .cpp and .h files using the standard SystemC headers. The resulting files are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module. This is compiled in C++, and linked with the Verilated files. The resulting executable will perform the actual simulation. SUPPORTED SYSTEMS Verilator is developed and has primary testing on Ubuntu. Versions have also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It should run with minor porting on any Linix-ish platform. Verilator also works on Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated output (not Verilator itself) compiles under MSVC++ 2008 and newer. INSTALLATION For more details see . If you will be modifying Verilator, you should use the "git" method as it will let you track changes. * The latest version is available at . Download the latest package from that site, and decompress. tar xvzf verilator_version.tgz * If you will be using SystemC (vs straight C++ output), download SystemC from . Follow their installation instructions. You will need to set SYSTEMC_INCLUDE to point to the include directory with systemc.h in it, and SYSTEMC_LIBDIR to points to the directory with libsystemc.a in it. (Older installations may set SYSTEMC and SYSTEMC_ARCH instead.) * You will need the "flex" and "bison" packages installed. * "cd" to the Verilator directory containing this README. * You now have to decide how you're going to eventually install the kit. Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE, and SYSTEMC_LIBDIR as defaults into the executable, so try to have them correct before configuring. 1. Our personal favorite is to always run Verilator from the kit directory. This allows the easiest experimentation and upgrading. It's also how most EDA tools operate; to run you point to the tarball, no install is needed. export VERILATOR_ROOT=`pwd` # if your shell is bash setenv VERILATOR_ROOT `pwd` # if your shell is csh ./configure 2. To install globally onto a "cad" disk with multiple versions of every tool, and add it to path using Modules/modulecmd: unset VERILATOR_ROOT # if your shell is bash unsetenv VERILATOR_ROOT # if your shell is csh # For the tarball, use the version number instead of git describe ./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"` After installing you'll want a module file like the following: set install_root /CAD_DISK/verilator/{version-number-used-above} setenv VERILATOR_ROOT $install_root prepend-path PATH $install_root/bin prepend-path MANPATH $install_root/man 3. The next option is to install it globally, using the normal system paths: unset VERILATOR_ROOT # if your shell is bash unsetenv VERILATOR_ROOT # if your shell is csh ./configure 4. Alternatively you can configure a prefix that install will populate, as most GNU tools support: unset VERILATOR_ROOT # if your shell is bash unsetenv VERILATOR_ROOT # if your shell is csh ./configure --prefix /opt/verilator-VERSION Then after installing you will need to add /opt/verilator-VERSION/bin to PATH. * Type "make" to compile Verilator. Type "make test" to check the compilation. Configure with "--enable-longtests" for more complete developer tests. Additional packages may be required for these tests. You may get a error about a typedef conflict for uint32_t. Edit verilated.h to change the typedef to work, probably to @samp{typedef unsigned long uint32_t;}. * If you used the VERILATOR_ROOT scheme you're done. Programs should set the environment variable VERILATOR_ROOT to point to this distribution, then execute $VERILATOR_ROOT/bin/verilator, which will find the path to all needed files. If you used the prefix scheme, now do a "make install". To run verilator, have the verilator binary directory in your PATH (this should already be true if using the default configure), and make sure VERILATOR_ROOT is not set. USAGE DOCUMENTATION Detailed documentation and the man page can be seen by running: bin/verilator --help or reading verilator.txt in the same directory as this README. DIRECTORY STRUCTURE The directories in the kit after de-taring are as follows: bin/verilator => Compiler Wrapper invoked to Verilate code include/ => Files that should be in your -I compiler path include/verilated*.cpp => Global routines to link into your simulator include/verilated*.h => Global headers include/verilated.v => Stub defines for linting include/verilated.mk => Common makefile src/ => Translator source code test_v => Example Verilog code for other test dirs test_c => Example Verilog->C++ conversion test_sc => Example Verilog->SystemC conversion test_verilated => Internal tests test_regress => Internal tests LIMITATIONS See verilator.txt (or execute "bin/verilator --help") for limitations. verilator-3.874/Makefile.in0000664000177100017500000004151212525737570015610 0ustar wsnyderwsnyder#***************************************************************************** # DESCRIPTION: Verilator top level: Makefile pre-configure version # # This file is part of Verilator. # # Code available from: http://www.veripool.org/verilator # #***************************************************************************** # # Copyright 2003-2015 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. # # Verilator is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # #****************************************************************************/ # # make all to compile and build Verilator. # make install to install it. # make TAGS to update tags tables. # # make clean or make mostlyclean # Delete all files from the current directory that are normally # created by building the program. Don't delete the files that # record the configuration. Also preserve files that could be made # by building, but normally aren't because the distribution comes # with them. # # make distclean # Delete all files from the current directory that are created by # configuring or building the program. If you have unpacked the # source and built the program without creating any other files, # `make distclean' should leave only the files that were in the # distribution. # # make maintainer-clean # Delete everything from the current directory that can be # reconstructed with this Makefile. This typically includes # everything deleted by distclean, plus more: C source files # produced by Bison, tags tables, info files, and so on. # # make extraclean # Still more severe - delete backup and autosave files, too. #### Start of system configuration section. #### srcdir = @srcdir@ VPATH = @srcdir@ HOST = @HOST@ DOXYGEN = doxygen INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ MAKEINFO = makeinfo POD2TEXT = pod2text POD2LATEXFIX = $(srcdir)/src/pod2latexfix PERL = @PERL@ # Destination prefix for RPMs DESTDIR = #### Don't edit: You're much better using configure switches to set these prefix = @prefix@ exec_prefix = @exec_prefix@ # Directory in which to install scripts. bindir = @bindir@ # Directory in which to install scripts. mandir = @mandir@ # Directory in which to install library files. datadir = @datadir@ # Directory in which to install documentation info files. infodir = @infodir@ # Directory in which to install package specific files # Generally ${prefix}/share/verilator pkgdatadir = @pkgdatadir@ # Directory in which to install pkgconfig file # Generall ${prefix}/share/pkgconfig pkgconfigdir = @pkgconfigdir@ # Directory in which to install data across multiple architectures datarootdir = @datarootdir@ # Compile options CFG_WITH_CCWARN = @CFG_WITH_CCWARN@ CFG_WITH_DEFENV = @CFG_WITH_DEFENV@ CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@ PACKAGE_VERSION = @PACKAGE_VERSION@ #### End of system configuration section. #### ###################################################################### SHELL = /bin/sh SUBDIRS = src test_verilated test_c test_sc test_regress INFOS = README README.html README.pdf internals.txt internals.html \ internals.pdf verilator.txt verilator.html verilator.pdf \ $(VL_INST_MAN_FILES) # Files that can be generated, but should be up to date for a distribution. DISTDEP = info Makefile DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \ *.in *.ac \ Changes TODO \ MANIFEST.SKIP \ bin/* \ doxygen-mainpage doxygen.config veripool-logo.png \ install-sh configure mkinstalldirs *.pod \ include/*.[chv]* \ include/*.in \ include/.*ignore \ include/vltstd/*.[chv]* \ .*attributes */.*attributes */*/.*attributes \ src/.*ignore src/*.in src/*.cpp src/*.[chly] \ src/astgen src/bisonpre src/*fix src/cppcheck_filtered \ src/vlcovgen \ src/.gdbinit \ src/*.pl src/*.pod \ test_*/.*ignore test_*/Makefile* test_*/*.cpp \ test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \ test_verilated/vgen*.pl \ test_regress/t/t*/*.sv* \ test_regress/t/t*/*.v* \ test_regress/t/*.cpp \ test_regress/t/*.h \ test_regress/t/*.dat \ test_regress/t/*.mem \ test_regress/t/*.out \ test_regress/t/*.pl \ test_regress/t/*.pf \ test_regress/t/*.v* \ INST_PROJ_FILES = \ bin/verilator \ bin/verilator_coverage \ bin/verilator_includer \ bin/verilator_profcfunc \ include/verilated.mk \ include/*.[chv]* \ include/vltstd/*.[chv]* \ INST_PROJ_BIN_FILES = \ verilator_bin \ verilator_bin_dbg \ verilator_coverage_bin_dbg \ DISTFILES := $(DISTFILES_INC) ifeq ($(OBJCACHE_JOBS),) ifneq ($(OBJCACHE_HOSTS),) export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)") endif endif default: all all: all_nomsg msg_test all_nomsg: verilator_exe $(VL_INST_MAN_FILES) .PHONY:verilator_exe .PHONY:verilator_bin .PHONY:verilator_bin_dbg .PHONY:verilator_coverage_bin_dbg verilator_exe verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg: @echo ------------------------------------------------------------ @echo "making verilator in src" ; \ (cd src && $(MAKE) $(OBJCACHE_JOBS) ) .PHONY:msg_test msg_test: all_nomsg @echo "Build complete!" @echo @echo "Type 'make test' to test." @echo .PHONY:test ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users test: test_c test_sc test_verilated test_regress else test: test_c test_sc endif @echo "Tests passed!" @echo @echo "Type 'make install' to install documentation." @echo test_c: all_nomsg @(cd test_c && $(MAKE)) test_c_debug: all_nomsg @(cd test_c && $(MAKE) test_debug) test_sc: all_nomsg @(cd test_sc && $(MAKE)) test_sc_debug: all_nomsg @(cd test_sc && $(MAKE) test_debug) test_verilated: all_nomsg @(cd test_verilated && $(MAKE)) test_regress: all_nomsg @(cd test_regress && $(MAKE)) info: $(INFOS) # Use --no-split to avoid creating filenames > 14 chars. %.1: ${srcdir}/bin/% pod2man $< $@ verilator.txt: ${srcdir}/bin/verilator $(POD2TEXT) $< $@ verilator.html: ${srcdir}/bin/verilator pod2html $< >$@ # PDF needs DIST variables; but having configure.ac as dependency isn't detected verilator.pdf: ${srcdir}/bin/verilator Makefile pod2latex --full --out verilator.tex ${srcdir}/bin/verilator $(PERL) $(POD2LATEXFIX) "$(DISTTITLE)" "${DISTDATE}" < verilator.tex > verilator2.tex mv verilator2.tex verilator.tex pdflatex verilator.tex pdflatex verilator.tex -rm -f verilator.toc verilator.aux verilator.idx verilator.out README: README.pod -rm -f $@ $(POD2TEXT) --loose $< > $@ README.html: README.pod pod2html $< >$@ # PDF needs DIST variables; but having configure.ac as dependency isn't detected README.pdf: README.pod Makefile pod2latex --full --out README.tex README.pod $(PERL) $(POD2LATEXFIX) "$(DISTTITLE) README File" "${DISTDATE}" < README.tex > README2.tex mv README2.tex README.tex pdflatex README.tex pdflatex README.tex -rm -f README.toc README.aux README.idx README.out internals.txt: internals.pod -rm -f $@ $(POD2TEXT) --loose $< > $@ internals.html: internals.pod pod2html $< >$@ # PDF needs DIST variables; but having configure.ac as dependency isn't detected internals.pdf: internals.pod Makefile pod2latex --full --out internals.tex internals.pod $(PERL) $(POD2LATEXFIX) "$(DISTTITLE) Internals Manual" "${DISTDATE}" < internals.tex > internals2.tex mv internals2.tex internals.tex pdflatex internals.tex pdflatex internals.tex -rm -f internals.toc internals.aux internals.idx internals.out # See uninstall also - don't put wildcards in this variable, it might uninstall other stuff VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg \ verilator_coverage verilator_includer verilator_profcfunc # Some scripts go into both the search path and pkgdatadir, # so they can be found by the user, and under $VERILATOR_ROOT. # See uninstall also - don't put wildcards in this variable, it might uninstall other stuff VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_profcfunc.1 VL_INST_INC_BLDDIR_FILES = \ include/verilated.mk \ # Files under srcdir, instead of build time VL_INST_INC_SRCDIR_FILES = \ include/*.[chv]* \ include/vltstd/*.[chv]* \ VL_INST_DATA_SRCDIR_FILES = \ test_v/*.[chv]* \ test_c/*.[chv]* test_c/Makefile test_c/Makefile_obj \ test_sc/*.[chv]* test_sc/Makefile test_sc/Makefile_obj \ installbin: $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator ) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage $(DESTDIR)$(bindir)/verilator_coverage ) ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc ) ( $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin ) ( $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg ) ( $(INSTALL_PROGRAM) verilator_coverage_bin_dbg $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg ) $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer ) # Man files can either be part of the original kit, or built in current directory # So important we use $< so VPATH is searched installman: $(VL_INST_MAN_FILES) $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1 for p in $^ ; do \ $(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \ done installdata: $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/include/vltstd for p in $(VL_INST_INC_BLDDIR_FILES) ; do \ $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \ done cd $(srcdir) \ ; for p in $(VL_INST_INC_SRCDIR_FILES) ; do \ $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \ done $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_c $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_sc $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_v cd $(srcdir) \ ; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \ $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/examples/$$p; \ done $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgconfigdir) $(INSTALL_DATA) verilator.pc $(DESTDIR)$(pkgconfigdir) # We don't trust rm -rf, so rmdir instead as it will fail if user put in other files uninstall: -cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_BIN_FILES) -cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_BIN_FILES) -cd $(DESTDIR)$(mandir)/man1 && rm -f $(VL_INST_MAN_FILES) -cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_BLDDIR_FILES) -cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES) -cd $(DESTDIR)$(pkgdatadir)/examples && rm -f $(VL_INST_DATA_SRCDIR_FILES) -rm $(DESTDIR)$(pkgconfigdir)/verilator.pc -rmdir $(DESTDIR)$(pkgdatadir)/bin -rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd -rmdir $(DESTDIR)$(pkgdatadir)/include -rmdir $(DESTDIR)$(pkgdatadir)/examples/test_c -rmdir $(DESTDIR)$(pkgdatadir)/examples/test_sc -rmdir $(DESTDIR)$(pkgdatadir)/examples/test_sp -rmdir $(DESTDIR)$(pkgdatadir)/examples/test_v -rmdir $(DESTDIR)$(pkgdatadir)/examples -rmdir $(DESTDIR)$(pkgdatadir) -rmdir $(DESTDIR)$(pkgconfigdir) install: all_nomsg install-all install-all: installbin installman installdata install-msg install-here: installman ftp ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users DISTNAMEREV = $(shell sed -e '/DTVERSION/!d' -e 's/.*verilator_\([^"]*\).*/\1/' -e q ${srcdir}/src/config_rev.h) DIRPROJECT := $(shell project_dir --project) VERILATOR_CAD_DIR = $(CAD_DIR)/verilator/$(DISTNAMEREV)/$(DIRPROJECT_ARCH) INST_PROJ_CVS = cp_if_cvs_diff install-project: dist @echo "Install-project to $(DIRPROJECT)" strip verilator_bin* strip verilator_coverage_bin* $(MAKE) install-project-quick for p in $(VL_INST_MAN_FILES) ; do \ $(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \ done $(INST_PROJ_CVS) $(DISTNAME).tgz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz rm $(DISTNAME).tgz install-project-quick: ifeq ($(CFG_WITH_DEFENV),yes) @echo "%Error: Reconfigure with './configure --disable-defenv' to avoid hardcoded paths." false endif @echo "Install-project-quick (no strip) to $(DIRPROJECT)" for p in $(INST_PROJ_FILES) ; do \ $(INST_PROJ_CVS) $$p $(DIRPROJECT)/hw/utils/verilator/$$p; \ done for p in $(INST_PROJ_BIN_FILES) ; do \ $(INST_PROJ_CVS) $$p $(DIRPROJECT)/hw/utils/verilator/$$p-$(DIRPROJECT_ARCH); \ done install-cadtools: dist @echo "Install-project to $(CAD_DIR)" strip verilator_bin* strip verilator_coverage_bin* $(MAKE) install-cadtools-quick $(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/man/man1 for p in $(VL_INST_MAN_FILES) ; do \ $(INSTALL_DATA) $$p $(VERILATOR_CAD_DIR)/man/man1/$$p; \ done $(INST_PROJ_CVS) $(DISTNAME).tgz $(VERILATOR_CAD_DIR)/verilator.tgz rm $(DISTNAME).tgz install-cadtools-quick: ifeq ($(CFG_WITH_DEFENV),yes) @echo "%Error: Reconfigure with './configure --disable-defenv' to avoid hardcoded paths." false endif @echo "Install-cadtools-quick (no strip) to $(VERILATOR_CAD_DIR)" $(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/include/vltstd $(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/bin for p in $(INST_PROJ_FILES) ; do \ $(INST_PROJ_CVS) $$p $(VERILATOR_CAD_DIR)/$$p; \ done for p in $(INST_PROJ_BIN_FILES) ; do \ $(INST_PROJ_CVS) $$p $(VERILATOR_CAD_DIR)/$$p; \ done # VERILATOR_AUTHOR_SITE endif # Use --xml flag to see the cppcheck code to use for suppression CPPCHECK = src/cppcheck_filtered CPPCHECK_FLAGS = --enable=all --inline-suppr \ --suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList CPPCHECK_FLAGS += --xml CPPCHECK_CPP = $(wildcard $(srcdir)/include/*.cpp $(srcdir)/src/*.cpp) CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP)) CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src cppcheck: $(CPPCHECK_DEP) %.cppcheck: %.cpp $(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 $(CPPCHECK_INC) $< ftp: info install-msg: @echo "Installed!" @echo @echo "For documentation see 'man verilator' or 'verilator --help'" @echo "For forums and to report bugs see http://www.veripool.org/verilator" @echo IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in # autoheader might not change config_build.h.in, so touch it ${srcdir}/config_build.h: ${srcdir}/config_build.h.in configure cd ${srcdir} && autoheader touch $@ Makefile: Makefile.in config.status $(IN_WILD) ./config.status src/Makefile: src/Makefile.in Makefile config.status: configure ./config.status --recheck configure: configure.ac ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users autoconf --warnings=all else autoconf endif maintainer-clean:: @echo "This command is intended for maintainers to use;" @echo "rebuilding the deleted files requires makeinfo." rm -f *.info* $(INFOS) configure clean mostlyclean distclean maintainer-clean maintainer-copy:: for dir in $(SUBDIRS); do \ echo making $@ in $$dir ; \ (cd $$dir && $(MAKE) $@) ; \ done clean mostlyclean distclean maintainer-clean:: rm -f $(SCRIPTS) *.tmp rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas rm -f *.tex distclean maintainer-clean:: rm -f Makefile config.status config.cache config.log TAGS rm -f verilator_bin* verilator_coverage_bin* rm -f include/verilated.mk include/verilated_config.h TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \ ${srcdir}/*.in ${srcdir}/*.pod TAGS: $(TAGFILES) etags $(TAGFILES) .PHONY: doxygen doxygen: $(DOXYGEN) doxygen.config ###################################################################### # Test targets dist-file-list: @echo "begin-dist-file-list:"; # Scripts look for this @echo $(wildcard $(DISTFILES)) @echo "end-dist-file-list:"; # Scripts look for this ###################################################################### # Distributions DISTTITLE := Verilator $(word 1,$(PACKAGE_VERSION)) DISTNAME := verilator-$(word 1,$(PACKAGE_VERSION)) DISTDATEPRE := $(word 2,$(PACKAGE_VERSION)) DISTDATE := $(subst /,-,$(DISTDATEPRE)) DISTTAGNAME := $(subst .,_,$(subst -,_,$(DISTNAME))) tag: svnorcvs tag $(DISTTAGNAME) # Don't depend on DISTFILES because there's no rule for "standards.info*". dist: $(DISTDEP) maintainer-copy -rm -fr $(DISTNAME) for file in $(DISTFILES); do \ mkdir -p `dirname $(DISTNAME)/$$file` >/dev/null ; \ ln $$file $(DISTNAME)/$$file \ || { echo copying $$file instead; cp -p $$file $(DISTNAME)/$$file;}; \ done; true; chmod -R a+r $(DISTNAME) tar chf $(DISTNAME).tar $(DISTNAME) gzip --force --best $(DISTNAME).tar mv $(DISTNAME).tar.gz $(DISTNAME).tgz rm -fr $(DISTNAME) maintainer-diff: svnorcvs diff $(DISTTAGNAME) preexist: svnorcvs nexists $(DISTTAGNAME) maintainer-dist: preexist dist tag svnorcvs release $(DISTNAME).tgz verilator-3.874/test_c/0000775000177100017500000000000012534632371015012 5ustar wsnyderwsnyderverilator-3.874/test_c/.gitignore0000664000177100017500000000004712111011551016761 0ustar wsnyderwsnyder*.dmp *.log *.csrc *.vcd obj_* project verilator-3.874/test_c/Makefile_obj0000664000177100017500000000215612525171734017311 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003-2015 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. # #***************************************************************************** default: simx include Vtop.mk ####################################################################### # Compile flags CPPFLAGS += -DVL_DEBUG=1 ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users CPPFLAGS += -DVL_THREADED=1 CPPFLAGS += -W -Werror -Wall endif ####################################################################### # Linking final exe -- presumes have a sim_main.cpp simx: sim_main.o $(VK_GLOBAL_OBJS) $(VM_PREFIX)__ALL.a $(LINK) $(LDFLAGS) -g $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) 2>&1 | c++filt sim_main.o: sim_main.cpp $(VM_PREFIX).h verilator-3.874/test_c/sim_main.cpp0000664000177100017500000000445212525171734017320 0ustar wsnyderwsnyder// DESCRIPTION: Verilator Example: Top level main for invoking model // // Copyright 2003-2015 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. #include // Defines common routines #include "Vtop.h" // From Verilating "top.v" #if VM_TRACE # include // Trace file format header #endif Vtop *top; // Instantiation of module vluint64_t main_time = 0; // Current simulation time (64-bit unsigned) double sc_time_stamp () { // Called by $time in Verilog return main_time; // Note does conversion to real, to match SystemC } int main(int argc, char **argv, char **env) { if (0 && argc && argv && env) {} // Prevent unused variable warnings top = new Vtop; // Create instance of module Verilated::commandArgs(argc, argv); Verilated::debug(0); #if VM_TRACE // If verilator was invoked with --trace Verilated::traceEverOn(true); // Verilator must compute traced signals VL_PRINTF("Enabling waves...\n"); VerilatedVcdC* tfp = new VerilatedVcdC; top->trace (tfp, 99); // Trace 99 levels of hierarchy tfp->open ("vlt_dump.vcd"); // Open the dump file #endif top->reset_l = 1; // Set some inputs top->fastclk = 0; top->clk = 0; top->passed = 0; while (main_time < 60 && !top->passed && !Verilated::gotFinish()) { if ((main_time % 10) == 3) { // Toggle clock top->clk = 1; } if ((main_time % 10) == 8) { top->clk = 0; } if (main_time > 10) { top->reset_l = 1; // Deassert reset } else if (main_time > 1) { top->reset_l = 0; // Assert reset } top->eval(); // Evaluate model #if VM_TRACE if (tfp) tfp->dump (main_time); // Create waveform trace for this timestamp #endif // Read outputs VL_PRINTF ("[%" VL_PRI64 "d] %x %x %x %x %x_%08x_%08x\n", main_time, top->clk, top->reset_l, top->passed, top->out_small, top->out_wide[2], top->out_wide[1], top->out_wide[0]); top->fastclk = !top->fastclk; main_time++; // Time passes... } top->final(); #if VM_TRACE if (tfp) tfp->close(); #endif if (!top->passed) { VL_PRINTF ("A Test failed\n"); abort(); } else { VL_PRINTF ("All Tests passed\n"); } exit(0L); } verilator-3.874/test_c/Makefile0000664000177100017500000000431512525171734016456 0ustar wsnyderwsnyder#***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside source directory # # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # # Copyright 2003-2015 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. # #****************************************************************************/ default: show_config test_default # This must point to the root of the VERILATOR kit VERILATOR_ROOT := $(shell pwd)/.. export VERILATOR_ROOT # Pick up PERL and other variable settings include $(VERILATOR_ROOT)/include/verilated.mk DEBUG_QUIET = --debug --debugi 0 --gdbbt --no-dump-tree DEBUG_ON = --debug --trace-dups --gdbbt #DEBUG = $(DEBUG_ON) VALGRIND_ON = $(DEBUG_ON) --gdb "valgrind -v --leak-check=yes" ###################################################################### test_default: prep compile run test_debug: prep_dbg compile run test_valgrind: prep_vg compile run VERILATOR_FLAGS = --cc -f $(VERILATOR_ROOT)/test_v/input.vc top.v VERILATOR_FLAGS += --trace #show_config: Is the very first time we've executed Verilator after building #so we make sure to run with --gdbbt, so if it dumps we'll get a trace. show_config: $(PERL) $(VERILATOR_ROOT)/bin/verilator $(DEBUG_QUIET) -V #prep: Is the very first time we're running a Verilation #so we make sure to run with --gdbbt, so if it dumps we'll get a trace. prep: $(PERL) $(VERILATOR_ROOT)/bin/verilator $(DEBUG_QUIET) $(VERILATOR_FLAGS) prep_dbg: $(PERL) $(VERILATOR_ROOT)/bin/verilator $(DEBUG_ON) $(VERILATOR_FLAGS) prep_vg: $(PERL) $(VERILATOR_ROOT)/bin/verilator $(VALGRIND_ON) $(VERILATOR_FLAGS) compile: cd obj_dir ; $(MAKE) -j 3 -f ../Makefile_obj run: obj_dir/simx ###################################################################### obj_dir: mkdir $@ ###################################################################### maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir *.log *.dmp *.vpd core verilator-3.874/test_verilated/0000775000177100017500000000000012534632371016547 5ustar wsnyderwsnyderverilator-3.874/test_verilated/.gitignore0000664000177100017500000000006612111011552020520 0ustar wsnyderwsnyder*.old obj_dir vgen.v simv* *.key csrc *.log INCA_libs verilator-3.874/test_verilated/sim_main.v0000664000177100017500000000146712525171734020543 0ustar wsnyderwsnyder// DESCRIPTION: Verilator Test: Top level main for invoking model // // Copyright 2003-2015 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. module sim_main; /*verilator public_module*/ reg clk; reg check; wire done; vgen vgen (/*AUTOINST*/ // Outputs .done (done), // Inputs .clk (clk), .check (check)); integer i; initial begin check = 1'b0; clk = 1'b0; for (i=0; i<10*vgen.CYCLES; i=i+1) begin #5; clk = ~clk; #5; clk = ~clk; end check = 1'b1; for (i=0; i<10; i=i+1) begin #5; clk = ~clk; #5; clk = ~clk; end end endmodule verilator-3.874/test_verilated/Makefile_obj0000664000177100017500000000210512331302177021030 0ustar wsnyderwsnyder# -*- Makefile -*- #***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside object directory # # This is executed in the object directory, and called by ../Makefile # # Copyright 2003 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. # #***************************************************************************** default: simx include Vvgen.mk ####################################################################### # Use sp_log.cpp, so we can get output in sim.log # Needed by tracing routines CPPFLAGS += -DVL_DEBUG=1 CPPFLAGS += $(CPPFLAGS_ADD) ####################################################################### # Linking final exe -- presumes have a sim_main.cpp simx: sim_main.o $(VK_GLOBAL_OBJS) $(VM_PREFIX)__ALL.a $(LINK) $(LDFLAGS) -g $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) 2>&1 | c++filt sim_main.o: sim_main.cpp $(VM_PREFIX).h verilator-3.874/test_verilated/vgen.pl0000775000177100017500000012224112525171734020051 0ustar wsnyderwsnyder#!/usr/bin/perl -w # See copyright, etc in below POD section. ###################################################################### require 5.006_001; use Getopt::Long; use IO::File; use Pod::Usage; use Data::Dumper; $Data::Dumper::Indent = 1; use Bit::Vector; use strict; use vars qw ($Debug); our @Orig_ARGV = @ARGV; our $Rerun_Args = $0." ".join(' ',@Orig_ARGV); use vars qw (@Blocks %Vars %VarAttrs %VarsBlock %Tree @Commit $Depth %IdWidth %Ops); #====================================================================== # width=> Number of bits the output size is, 0=you tell me. # func=> What to put in output file # signed=> 0=unsigned output, 1=signed output, '%1'=signed if op1 signed # lsb=> LSB for variable declarations # em=> How to calculate emulated return value # %w Width of this output op ($treeref->{width}) # %v Output value ($treeref->{val}) # %1r First operand ($treeref->{op1}) # %1v First operand value ($treeref->{op1}{val}) # %1w First operand width ($treeref->{op1}{width}) our $Raise_Weight_Max = 50; %Ops = ( 'VCONST'=> {weight=>1&&20, width=>0, sc=>1, terminal=>1, v=>'%v', }, 'VIDNEW'=> {weight=>1&&10, width=>0, sc=>1, terminal=>0, v=>'%i', }, 'VIDOLD'=> {weight=>1&&20, width=>0, sc=>1, terminal=>0, v=>'%i', }, 'VIDSAME'=> {weight=>1&&20, width=>0, sc=>1, terminal=>0, v=>'%i', }, 'VRANGE'=> {weight=>1&&30, width=>0, signed=>0,sc=>0, terminal=>0, v=>'%i[%2:%3]', }, 'VBITSEL'=> {weight=>1&&10, width=>1, signed=>0,sc=>0, terminal=>0, v=>'%i[%2]', }, 'VBITSELP'=> {weight=>1&&10, width=>0, signed=>0,sc=>0, terminal=>0, v=>'%i[%2+:%3]', }, 'VBITSELM'=> {weight=>1&&10, width=>0, signed=>0,sc=>0, terminal=>0, v=>'%i[%2-:%3]', }, # Unary 'VEXTEND'=> {weight=>1&&3, width=>-2, signed=>0,sc=>0, terminal=>0, v=>'{%xd\'h0,%1}', }, 'VLOGNOT'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(! %1)', }, 'VREDAND'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(& %1)', }, 'VREDOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(| %1)', }, 'VREDNAND'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(~& %1)', }, 'VREDNOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(~| %1)', }, 'VREDXNOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(^~ %1)', }, 'VREDXOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(^ %1)', }, 'VNOT'=> {weight=>1&&3, width=>0, sc=>1, terminal=>0, v=>'(~ %1)', }, 'VNEGATE'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(- %1)', }, 'VCOUNTONES'=> {weight=>0&&2, width=>32, signed=>0, sc=>0, terminal=>0, v=>'\$countones(%1)', }, # No ncv support 'VONEHOT'=> {weight=>0&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'\$onehot(%1)', }, # No ncv support 'VONEHOT0'=> {weight=>0&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'\$onehot0(%1)', }, # No ncv support # Binary 'VAND'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(%1 & %2)', }, 'VOR'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(%1 | %2)', }, 'VNAND'=> {weight=>1&&0, width=>0, sc=>0, terminal=>0, v=>'(%1 ~& %2)', }, #FIX vcs bug! 'VNOR'=> {weight=>1&&0, width=>0, sc=>0, terminal=>0, v=>'(%1 ~| %2)', }, #FIX vcs bug! 'VXOR'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(%1 ^ %2)', }, 'VXNOR'=> {weight=>1&&0, width=>0, sc=>0, terminal=>0, v=>'(%1 ^~ %2)', }, #FIX vcs bug! 'VEQ'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 == %2)', }, 'VNEQ'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 != %2)', }, 'VGT'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 > %2)', }, 'VGTE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 >= %2)', }, 'VLT'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 < %2)', }, 'VLTE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 <= %2)', }, 'VEQCASE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 === %2)', }, # FIX just a = for now 'VNEQCASE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 !== %2)', }, # FIX just a != for now 'VLOGOR'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 || %2)', }, 'VLOGAND'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 && %2)', }, 'VADD'=> {weight=>1&&10, width=>0, sc=>1, terminal=>0, v=>'(%1 + %2)', }, 'VSUB'=> {weight=>1&&10, width=>0, sc=>1, terminal=>0, v=>'(%1 - %2)', }, 'VMUL'=> {weight=>1&&15,width=>0, sc=>1, terminal=>0, v=>'(%1 * %2)', }, # High % as rarely applyable 'VDIV'=> {weight=>1&&8, width=>0, sc=>1, terminal=>0, v=>'((%2)==%xw\'h0 ? %xw\'%xsh0:(%1 / %2))', }, 'VMODDIV'=> {weight=>1&&8, width=>0, sc=>1, terminal=>0, v=>'((%2)==%xw\'h0 ? %xw\'%xsh0:(%1 %% %2))', }, #'VPOW'=> {weight=>2&&0,width=>-64, sc=>0, terminal=>0, v=>'(%1 ** %2)', }, 'VSHIFTL'=> {weight=>1&&8, width=>0, signed=>0, sc=>0, terminal=>0, v=>'(%1 << %2)', }, 'VSHIFTLS'=> {weight=>1&&8, width=>0, signed=>1, sc=>0, terminal=>0, v=>'(%1 <<< %2)', }, 'VSHIFTR'=> {weight=>1&&8, width=>0, signed=>0, sc=>0, terminal=>0, v=>'(%1 >> %2)', }, 'VSHIFTRS'=> {weight=>1&&15,width=>0, signed=>1, sc=>0, terminal=>0, v=>'(%1 >>> %2)', }, # ShiftR seems to sign extend differently for <=32 and >32 bits 'VCONCAT'=> {weight=>1&&4, width=>-2,signed=>0, sc=>0, terminal=>0, v=>'{%1,%2}', }, 'VREPLIC'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'{%1{%2}}', }, 'VREPLIC1W'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'{%1{%2}}', }, 'VSIGNED'=> {weight=>1&&2, width=>0, signed=>1, sc=>0, terminal=>0, v=>'\$signed(%1)', }, 'VUNSIGNED'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'\$unsigned(%1)', }, # Triops 'VCOND'=> {weight=>1&&4, width=>0, sc=>0, terminal=>0, v=>'(%1 ? %2 : %3)', }, # Control flow #VIF #VFOR #VCASE #VCASEX #VCASEZ ); my %ops2 = ( 'VCONST'=> {pl=>'', rnd=>'rnd_const(%tr);'}, 'VIDNEW'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=next_id(%tw);' .' $Vars{%i}=gen_leaf(width=>%tw,trunc=>1,signed=>%tg);' .' $VarAttrs{%i}{lsb} = rnd_lsb();' .' id_commit(%tr,"%i");1;',}, 'VIDOLD'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=id_old(%tr);', ok_id_width=>1,}, 'VIDSAME'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=id_same(%tr);', ok_id_width=>1,}, # These create IDs they then extract from 'VRANGE'=> {pl=>'VRANGE(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});', rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();' .' my $lsb=rnd(128-%tw); my $msb=$lsb+%tw-1;' .' %2r=val_leaf($msb); %3r=val_leaf($lsb);' .' $Vars{%i}=gen_leaf(width=>($msb+1));'}, 'VBITSEL'=> {pl=>'VRANGE(%tr,$Vars{%i}{val},%2v,%2v,$VarAttrs{%i}{lsb});', rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();' .' my $wid=min(128,rnd_width()|3);' .' %2r=gen_leaf(width=>(log2($wid)-1),signed=>0);' .' $Vars{%i}=gen_leaf(width=>$wid);'}, 'VBITSELP'=> {pl=>'VBITSELP(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});', rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();' .' my $wid=min(128,(%tw+rnd_width()|3)); %3r=val_leaf(%tw); my $maxval = $wid-%tw; %2r=(($maxval<4)?val_leaf($maxval):gen_leaf(width=>(log2($maxval)-1),signed=>0));' .' $Vars{%i}=gen_leaf(width=>$wid);'}, 'VBITSELM'=> {pl=>'VBITSELM(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});', rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();' .' my $wid=min(128,(%tw+rnd_width()|3)); %3r=val_leaf(%tw); my $maxval = $wid-1; my $minval=%tw-1; %2r=val_leaf(rnd($maxval-$minval)+$minval);' .' $Vars{%i}=gen_leaf(width=>$wid);'}, # No easy way to make expr with specified minimum # Unary 'VEXTEND'=> {pl=>'VRESIZE (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>rnd_width(%tw-1));'}, 'VLOGNOT'=> {pl=>'VLOGNOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDAND'=> {pl=>'VREDAND (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDOR'=> {pl=>'VREDOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDNAND'=> {pl=>'VREDNAND (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDNOR'=> {pl=>'VREDNOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDXOR'=> {pl=>'VREDXOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VREDXNOR'=> {pl=>'VREDXNOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VNOT'=> {pl=>'VNOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VNEGATE'=> {pl=>'VNEGATE (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VCOUNTONES'=> {pl=>'VCOUNTONES(%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VONEHOT'=> {pl=>'VONEHOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, 'VONEHOT0'=> {pl=>'VONEHOT0 (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'}, # Binary 'VAND'=> {pl=>'VAND (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VOR'=> {pl=>'VOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VNAND'=> {pl=>'VNAND (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VNOR'=> {pl=>'VNOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VXOR'=> {pl=>'VXOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VXNOR'=> {pl=>'VXNOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VEQ'=> {pl=>'VEQ (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VNEQ'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VGT'=> {pl=>'VGT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VGTE'=> {pl=>'VGE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VLT'=> {pl=>'VLT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VLTE'=> {pl=>'VLE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VEQCASE'=> {pl=>'VEQ (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VNEQCASE'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'}, 'VLOGOR'=> {pl=>'VLOGOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>0);'}, 'VLOGAND'=> {pl=>'VLOGAND(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>0);'}, 'VADD'=> {pl=>'VADD (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,}, 'VSUB'=> {pl=>'VSUB (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,}, 'VMUL'=> {pl=>'VMUL (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,}, # Multiply generates larger width, so need truncate for safety 'VDIV'=> {pl=>'VDIV (%tr,%1r,%2r,0);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, 'VMODDIV'=> {pl=>'VDIV (%tr,%1r,%2r,1);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'}, #'VPOW'=> {pl=>'VPOW (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>min(%tw,6),signed=>%tg); %2r=gen_leaf(width=>min(%tw,8),signed=>%tg);', trunc=>1,}, # Generates larger width, so need truncate for safety 'VSHIFTL'=> {pl=>'VSHIFTL(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'}, 'VSHIFTLS'=> {pl=>'VSHIFTL(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'}, 'VSHIFTR'=> {pl=>'VSHIFTR(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'}, 'VSHIFTRS'=> {pl=>'VSHIFTRS(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'}, 'VCONCAT'=> {pl=>'VCONCAT(%tr,%1v,%2v);', rnd=>'my $d=(rnd(%tw-2)+1); %1r=gen_leaf(width=>$d,signed=>0); %2r=gen_leaf(width=>(%tw-$d),signed=>0);'}, 'VREPLIC'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'my $d=rnd_rep_width(%tw); %1r=val_leaf($d); %2r=gen_leaf(width=>(%tw/$d),signed=>0);'}, 'VREPLIC1W'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'%1r=val_leaf(%tw); %2r=gen_leaf(width=>1,signed=>0);'}, 'VSIGNED'=> {pl=>'VCLONE (%tr,%1v,0);', rnd=>'%1r=gen_leaf(width=>%tw);'}, 'VUNSIGNED'=> {pl=>'VCLONE (%tr,%1v,0);', rnd=>'%1r=gen_leaf(width=>%tw);'}, # Triops 'VCOND'=> {pl=>'VCOND(%tr,%1v,%2v,%3v);', rnd=>'%1r=gen_leaf(width=>1); %2r=gen_leaf(width=>%tw,signed=>%tg); %3r=gen_leaf(width=>%tw,signed=>%tg);'}, ); foreach my $op (keys %ops2) { while ((my $key,my $val) = each %{$ops2{$op}}) { $Ops{$op}{$key} = $val; } } #====================================================================== # main #Bit::Vector->Configuration("ops=arithmetic"); my $opt_seed=5; our $Opt_NumOps = 300; our $Opt_Depth = 4; our $Opt_Signed = 1; our $Opt_Raise; our $Opt_Sc; our $Opt_BlockStmts = 2; our $Signed_Pct = 60; $Debug = 0; if (! GetOptions ( "help" => \&usage, "debug" => \&debug, "depth=i" => \$Opt_Depth, "blockstmts=i"=> \$Opt_BlockStmts, "numops=i" => \$Opt_NumOps, "raise=i" => \$Opt_Raise, "seed=i" => \$opt_seed, "signed!" => \$Opt_Signed, "sc!" => \$Opt_Sc, "<>" => \¶meter, )) { usage(); } if ($opt_seed==0) { srand(); $opt_seed = rnd(1<<20)+1; $Rerun_Args =~ s/-seed[= ]+0/-seed=$opt_seed/; print " $Rerun_Args\n"; } srand($opt_seed); init(); selftest(); gentest(); write_output_sc("vgen.cpp") if $Opt_Sc; write_output_v("vgen.v") if !$Opt_Sc; #---------------------------------------------------------------------- sub usage { pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT); exit (1); } sub debug { $Debug = 1; } sub parameter { my $param = shift; die "%Error: Unknown parameter: $param\n"; } ####################################################################### ####################################################################### ####################################################################### ####################################################################### # Global Functions sub init { for my $op (keys %Ops) { my $opref = $Ops{$op}; $opref->{name} = $op; gen_v($opref); gen_pl($opref); gen_rnd($opref); $opref->{weight} = 0 if $Opt_Sc && !$opref->{sc}; $opref->{weight} = 2 if $Opt_Sc && $op eq 'VCONST'; } raise(); } sub raise { for (my $i=0; $i<($Opt_Raise||0); $i++) { my @ops = (values %Ops); while (1) { my $rndop = $ops[rnd($#ops + 1)]; next if !$rndop->{weight}; # Don't turn on disabled ops $rndop->{weight} += rnd($Raise_Weight_Max); printf "\tWeight %-15s +%d\n",$rndop->{name},$rndop->{weight}; last; } } } sub gentest { for (my $opn=0; $opn<$Opt_NumOps/$Opt_BlockStmts; $opn++) { do_a_test(); } } ####################################################################### # Randomization sub _rnd_op_ok { my $opref = shift; my $paramref = shift; return (($opref->{width} == 0 || $opref->{width} == $paramref->{width} # Note -2 means >, while -32 means {width}==-31 && $paramref->{width}<=31) # -31... must be <31 bits || ($opref->{width}==-32 && $paramref->{width}<=32) # -32... must be <32 bits || ($opref->{width}==-63 && $paramref->{width}<=63) # -63... must be <63 bits || ($opref->{width}==-64 && $paramref->{width}<=64) # -64... must be <64 bits || ($opref->{width}==-2 && $paramref->{width}>=2) # -2... must be >2 bits ) && (!$opref->{ok_id_width} || $IdWidth{$paramref->{width}}{$paramref->{signed}||0}) && (!defined $opref->{signed} || ($opref->{signed} == ($paramref->{signed}||0))) && (!$opref->{trunc} || $paramref->{trunc}) && (!$opref->{opt_signed} || $Opt_Signed) && (($Depth < $Opt_Depth && !$paramref->{need_terminal}) || $opref->{terminal})); } sub rnd_op { my $paramref = shift; my $totweight = 0; foreach my $opref (values %Ops) { if (_rnd_op_ok($opref,$paramref)) { $totweight += $opref->{weight}; } } my $chooseweight = rnd($totweight); $totweight = 0; foreach my $opref (values %Ops) { if (_rnd_op_ok($opref,$paramref)) { $totweight += $opref->{weight}; if ($chooseweight < $totweight) { return $opref; } } } die "%Error: No instructions match,"; } sub rnd_width { my $max = shift; my $v = rnd(100); my $n = (0 || (($v<20) && 1) || (($v<25) && 2) || (($v<30) && 31) || (($v<35) && 32) || (($v<40) && 63) || (($v<45) && 64) || (($v<50) && 95) || (($v<55) && 96) || (rnd(128)+1)); if ($Opt_Sc) { $n = (0 #|| (($v<50) && 32) || (32)); #(!$max) or die "%Error: --sc max must 32/64/96,"; } if ($max && $n>=$max) { $n = rnd($max-1)+1; } return $n; } sub rnd_rep_width { my $out = shift; return 1 if $out==1; # We'd like to pick any divisor that works. my @factors; for (my $div=1; $div<$out; $div++) { if (int($out/$div)==($out/$div)) { push @factors, $div; } } my $fac = $factors[rnd($#factors+1)]; #print "RND REP $out -> $fac (@factors)\n" if $Debug; return $fac; } sub rnd_const { my $treeref = shift; my $width = $treeref->{width} or die; my $v = rnd(100); my $val = Bit::Vector->new($width); if ($v<25) { # zero } elsif ($v<50) { # ones $val->Word_Store(0,~0); $val->Word_Store(1,~0) if $width>32; $val->Word_Store(2,~0) if $width>64; $val->Word_Store(3,~0) if $width>96; } elsif ($v<60) { # one $val->Word_Store(0,1); } else { #random $val->Word_Store(0,rnd_int()); $val->Word_Store(1,rnd_int()) if $width>32; $val->Word_Store(2,rnd_int()) if $width>64; $val->Word_Store(3,rnd_int()) if $width>96; } $treeref->{val} = $val; } sub rnd_int { my $v = rnd(100); return 0 if ($v<25); return ~0 if ($v<50); return 1 if ($v<60); return rnd32(); } sub rnd_lsb { return 0; #return rnd(8)-4; # Not working yet } sub rnd { return (int(rand($_[0]))) if ($_[0] < (1<<15)); return (rnd32() % $_[0]); } sub rnd32 { my $vp = int(rand(1<<16)); $vp ^= (int(rand(1<<8)))<<16;# Single 1<<16 doesn't work $vp ^= (int(rand(1<<8)))<<24; return ($vp); } ####################################################################### our $Next_Id = 0; sub next_id { # Note width hasn't been determined yet $Next_Id++; my $id = sprintf("W%04d",$Next_Id); return $id; } sub id_commit { my $treeref = shift; my $width = $treeref->{width}; my $signed = $treeref->{signed}; my $id = shift; push @Commit, sub { $IdWidth{$width}{$signed} = [] if !$IdWidth{$width}{$signed}; push @{$IdWidth{$width}{$signed}}, $id; $VarsBlock{$id}{set} = 1; 1; }; } sub id_old { my $treeref = shift; my $width = $treeref->{width}; my $signed = $treeref->{signed}; my $n = $#{$IdWidth{$width}{$signed}} + 1; my $idn = rnd($n); my $id = $IdWidth{$width}{$signed}[$idn]; $VarsBlock{$id}{used} = 1; return $id; } sub id_same { my $treeref = shift; my $width = $treeref->{width}; my $signed = $treeref->{signed}; my @possible; foreach my $id (keys %VarsBlock) { next if !$VarsBlock{$id}{used}; my $varref = $Vars{$id}; next if $varref->{signed} != $signed; next if $varref->{width} != $width; push @possible, $id; } my $n = $#possible + 1; if ($n<1) { # Nothing, grab another! return id_old($treeref,$width,$signed); } my $idn = rnd($n); my $id = $possible[$idn]; $VarsBlock{$id}{used} = 1; return $id; } sub write_output_v { my $filename = shift; my $fh = IO::File->new($filename, "w") or die("%Error: $! $filename,\n"); print $fh "// Created by: $Rerun_Args\n"; print $fh "module vgen (clk, check, done);\n"; print $fh " input clk;\n"; print $fh " input check;\n"; print $fh " output done;\n"; print $fh ' initial $write("\n*** Vgen.v starting, seed = ',$opt_seed,'\n");',"\n"; print $fh " // verilator lint_off UNSIGNED\n"; print $fh " // verilator lint_off CMPCONST\n"; print $fh " // verilator lint_off WIDTH\n"; print $fh "\n"; my $cycles = 2; foreach my $var (sort (keys %Vars)) { print $fh "",decl_text ($var),"\n"; } foreach my $block (@Blocks) { print $fh "\t//".('='x60)."\n"; my $style = rnd(100); if ($style < 15) { # This allows statements to get split up, and constants to propagate print $fh " always @(", join(" or ", ('check', @{$block->{inputs}})); print $fh ") begin : $block->{name}\n"; print $fh @{$block->{preass}}; print $fh " end\n"; print $fh " always @(posedge clk) begin : $block->{name}Check\n"; print $fh @{$block->{body}}; print $fh " end\n"; } elsif ($style < 40) { print $fh " always @(", join(" or ", ('check', @{$block->{inputs}})); print $fh ") begin : $block->{name}\n"; print $fh @{$block->{preass}}; print $fh @{$block->{body}}; print $fh " end\n"; } else { foreach my $stmt (@{$block->{preass}}) { $cycles++; print $fh " always @(posedge clk) begin\n"; $stmt =~ s/ = / <= /mg; print $fh $stmt; print $fh " end\n"; } print $fh " always @(posedge clk) begin\n"; print $fh @{$block->{body}}; print $fh " end\n"; } } print $fh "\n"; print $fh " reg done; initial done=1'b0;\n"; print $fh " reg ddone; initial ddone=1'b0;\n"; print $fh " always @(posedge clk) begin\n"; print $fh " if (check) begin\n"; print $fh " done <= 1'b1;\n"; print $fh " end\n"; print $fh " if (done && !ddone) begin\n"; print $fh " ddone <= 1'b1;\n"; print $fh ' $write("*-* All Finished *-*\n");',"\n"; print $fh " end\n"; print $fh " end\n"; print $fh "\n"; print $fh " parameter [31:0] CYCLES /*verilator public*/ = $cycles;\n"; print $fh "endmodule\n"; $fh->close(); } sub write_output_sc { my $filename = shift; my $fh = IO::File->new($filename, "w") or die("%Error: $! $filename,\n"); print $fh "// -*- SystemC -*-\n"; print $fh "// Created by: $Rerun_Args\n"; # Classes foreach my $block (@Blocks) { print $fh "class $block->{name};\n"; } print $fh "\n"; # Headers print $fh "//".('='x60)."\n"; print $fh "SC_MODULE(Vgen) {\n"; print $fh "public:\n"; print $fh " sc_in_clk clk;\n"; print $fh " sc_in check;\n"; print $fh " static const int CYCLES /*verilator public*/ = ",$#Blocks+3,";\n"; print $fh "\n"; foreach my $var (sort (keys %Vars)) { print $fh "",decl_text ($var,"sc_signal"),"\n"; } print $fh "\n"; foreach my $block (@Blocks) { print $fh " $block->{name}* ".lc($block->{name}).";\n"; } print $fh " SC_CTOR(Vgen);\n"; print $fh "};\n\n"; # Sub Interface print $fh "//".('='x60)."\n"; foreach my $block (@Blocks) { print $fh "SC_MODULE($block->{name}) {\n"; print $fh "public:\n"; print $fh " sc_in_clk clk;\n"; print $fh " sc_in check;\n"; foreach my $var (@{$block->{inputs}}) { print $fh "",decl_text ($var,"sc_in"),"\n"; } foreach my $var (@{$block->{outputs}}) { print $fh "",decl_text ($var,"sc_out"),"\n"; } print $fh " SC_CTOR($block->{name});\n"; print $fh " void clkPosedge();\n"; print $fh "};\n\n"; } # Implementation print $fh "//".('='x60)."\n"; print $fh "SP_CTOR_IMP(Vgen) : clk(\"clk\"), check(\"check\") {\n"; foreach my $block (@Blocks) { print $fh " //\n"; print $fh " SP_CELL (".lc($block->{name}).", $block->{name});\n"; print $fh " SP_PIN (".lc($block->{name}).", clk, clk);\n"; print $fh " SP_PIN (".lc($block->{name}).", check, check);\n"; foreach my $var (@{$block->{inputs}}, @{$block->{outputs}}, ) { print $fh " SP_PIN (".lc($block->{name}).", $var, $var);\n"; } } print $fh "}\n\n"; # Sub Implementations print $fh "//".('='x60)."\n"; foreach my $block (@Blocks) { print $fh "SP_CTOR_IMP($block->{name}) {\n"; print $fh " SC_METHOD(clkPosedge);\n"; print $fh " sensitive << clk.pos();\n"; print $fh "}\n\n"; print $fh "void $block->{name}::clkPosedge() {\n"; print $fh @{$block->{preass}}; print $fh @{$block->{body}}; print $fh "}\n\n"; } $fh->close(); } ###################################################################### sub callers { for (my $i=0; ; $i++) { my @c = caller($i); last if !$c[0]; print "Caller $i: ",join(' ',@c[0..3]),"\n"; } } ####################################################################### ####################################################################### ####################################################################### ####################################################################### # Code generation/emitting Functions sub do_a_test { local $Depth = 0; @Commit = (); %VarsBlock = (); my $block = { name=>"Block".($#Blocks+2), body=>[], preass=>[], inputs=>[], outputs=>[], }; for (my $i=0; $i<$Opt_BlockStmts; $i++) { my $treeref = gen_leaf(width=>0); push @{$block->{body}}, "\tif ($treeref->{text} != ".$treeref->val_to_text().") if (check) ".stop_text().";\n"; } foreach my $var (keys %VarsBlock) { push @{$block->{inputs}}, $var if $VarsBlock{$var}{used} && !$VarsBlock{$var}{set}; } foreach my $var (reverse (sort (keys %Vars))) { my $varref = $Vars{$var}; next if $varref->{printedit}; $varref->{printedit} = 1; push @{$block->{outputs}}, $var; push @{$block->{preass}}, sprintf ("\t$var = %s;\n" ,$varref->{text}); } foreach my $com (@Commit) { &{$com} or die "%Error: Can't eval:\n$com\n $@ "; } push @Blocks, $block; } sub gen_leaf { my $inforef = {width=>0, # Anything need_terminal=>0, #trunc=>undef, # Allow multiply op @_}; $inforef->{width} ||= rnd_width(); $inforef->{signed} = ($Opt_Signed && $inforef->{width}>1 && (rnd(100)<$Signed_Pct))?1:0 if !defined $inforef->{signed}; print +((" "x$Depth)."Leaf of width $inforef->{width}\n") if $Debug; my $op = rnd_op($inforef); my $treeref = new Vg::Base; while ((my $key,my $val) = each %{$op}) { $treeref->{$key} = $val; } while ((my $key,my $val) = each %{$inforef}) { $treeref->{$key} = $val; } local $Depth = $Depth+1; print "RndSub $treeref->{rnd_sub_text}\n" if $Debug; $treeref->{rnd_sub}($treeref); $treeref->tree_dump() if $Debug; print "RndPl\n" if $Debug; $treeref->{pl_sub}($treeref); print "RndV\n" if $Debug; $treeref->{text} = $treeref->{v_sub}($treeref); print "Done\n" if $Debug; print " Value ",$treeref->{val}," = ",$treeref->val_to_text(),"\n" if $Debug; #$treeref->tree_dump() if $Debug; $treeref->{val_size} = $treeref->{val}->Size; #Debugging $treeref->{val_text} = $treeref->{val}->to_Hex; #Debugging ($treeref->{val}->Size == $treeref->{width}) or die "%Error: Size mismatch ",$treeref->{val}->Size,"!=",$treeref->{width},"\n",Dumper($treeref); return $treeref; } sub gen_v { my $opref = shift; my $fmt = $opref->{v}; $fmt =~ s/%1/%s/g; $fmt =~ s/%2/%s/g; $fmt =~ s/%3/%s/g; $fmt =~ s/%v/%s/g; $fmt =~ s/%i/%s/g; $fmt =~ s/%x[wds]/%s/g; my $argl = $opref->{v}; my @args; while ($argl =~ s/(%x.|%.)//) { my $arg = $1; push @args, '$treeref->{op1}{text}' if $arg =~ /%1/; push @args, '$treeref->{op2}{text}' if $arg =~ /%2/; push @args, '$treeref->{op3}{text}' if $arg =~ /%3/; push @args, '$treeref->val_to_text' if $arg =~ /%v/; push @args, '$treeref->{id}' if $arg =~ /%i/; push @args, '$treeref->{signed}?"s":""' if $arg =~ /%xs/; push @args, '$treeref->{width}' if $arg =~ /%xw/; push @args, '$treeref->{width}-$treeref->{op1}{width}' if $arg =~ /%xd/; } my $func = ("sub { " ." my \$treeref = shift;" ." sprintf(\"$fmt\",".join(',',@args).");" ."}"); my $set = ("\$opref->{v_sub} = $func; 1;"); $opref->{v_sub_text} = $func; # For seeing it in debugging dumps #print "Op V $opref->{name} $set\n"; eval($set) or die "%Error: Can't eval:\n$set\n $@ "; } sub escapes { my $str = shift; my $cmt = shift; $str =~ s/%tr/\$treeref/g; $str =~ s/%tg/\$treeref->{signed}/g; $str =~ s/%tv/\$treeref->{val}/g; $str =~ s/%tw/\$treeref->{width}/g; # $str =~ s/%1r/\$treeref->{op1}/g; $str =~ s/%1g/\$treeref->{op1}{signed}/g; $str =~ s/%1n/(\$treeref->{op1}{val}->Word_Read(0))/g; $str =~ s/%1v/\$treeref->{op1}{val}/g; $str =~ s/%1w/\$treeref->{op1}{width}/g; # $str =~ s/%2r/\$treeref->{op2}/g; $str =~ s/%2g/\$treeref->{op2}{signed}/g; $str =~ s/%2n/(\$treeref->{op2}{val}->Word_Read(0))/g; $str =~ s/%2v/\$treeref->{op2}{val}/g; $str =~ s/%2w/\$treeref->{op2}{width}/g; # $str =~ s/%3r/\$treeref->{op3}/g; $str =~ s/%3g/\$treeref->{op3}{signed}/g; $str =~ s/%3n/(\$treeref->{op3}{val}->Word_Read(0))/g; $str =~ s/%3v/\$treeref->{op3}{val}/g; $str =~ s/%3w/\$treeref->{op3}{width}/g; # $str =~ s/%i/\$treeref->{id}/g; ($str !~ /%/) or die "%Error: $cmt: Unknown %% escape in $str,"; return $str; } sub gen_pl { my $opref = shift; my $str = escapes($opref->{pl}, $opref->{name}); my $func = ("sub { " ." my \$treeref = shift;" ." $str;" ."}"); my $set = ("\$opref->{pl_sub} = $func; 1;"); $opref->{pl_sub_text} = $func; # For seeing it in debugging dumps #print "Op PL $opref->{name} $set\n"; eval($set) or die "%Error: Can't eval:\n$set\n $@ "; } sub gen_rnd { my $opref = shift; my $str = escapes($opref->{rnd}, $opref->{name}); my $func = ("sub { " ." my \$treeref = shift;" ." $str;" ."}"); my $set = ("\$opref->{rnd_sub} = $func; 1;"); $opref->{rnd_sub_text} = $func; # For seeing it in debugging dumps #print "Op RND $opref->{name} $set\n"; eval($set) or die "%Error: Can't eval:\n$set\n $@ "; } sub stop_text { return $Opt_Sc?'USTOP()':'$stop'; } sub decl_text { my $var = shift; my $decl_with = shift; my $varref = $Vars{$var}; if ($Opt_Sc) { (!$varref->{signed}) or die "%Error: No signed SystemC yet\n"; my $type = (( ($varref->{val}->Size == 32) && "sc_dt::uint32") || (($varref->{val}->Size == 64) && "sc_dt::uint64")); $type or die "%Error: Unknown Size ".$varref->{val}->Size,","; return sprintf " %s<%s> %s; //=%s" , $decl_with, $type, $var, $varref->{val}->to_Hex; } else { return sprintf " reg %s [%3d:%3d] %s %s; //=%d'h%s" , ($varref->{signed}?"signed":" ") , ($varref->{val}->Size)-1+$VarAttrs{$var}{lsb}, , $VarAttrs{$var}{lsb} , $var , (rnd(100)<30 ? "/*verilator public*/":(" "x length("/*verilator public*/"))) , $varref->{val}->Size , lc $varref->{val}->to_Hex; } } ####################################################################### ####################################################################### ####################################################################### ####################################################################### # Math Functions sub selftest { my $o = {}; VDIV($o, {val=>Bit::Vector->new_Dec(8,0xff)}, {val=>Bit::Vector->new_Dec(8,0x13)}, 0); ($o->{val}->Word_Read(0) == 0x0d) or die; VDIV($o, {val=>Bit::Vector->new_Dec(8,0xff)}, {val=>Bit::Vector->new_Dec(8,0x13)}, 1); ($o->{val}->Word_Read(0) == 0x08) or die; VDIV($o, {val=>Bit::Vector->new_Dec(8,0xff), signed=>1}, {val=>Bit::Vector->new_Dec(8,0x13), signed=>1}, 0); ($o->{val}->Word_Read(0) == 0x00) or die; VDIV($o, {val=>Bit::Vector->new_Dec(8,0xff), signed=>1}, {val=>Bit::Vector->new_Dec(8,0x13), signed=>1}, 1); ($o->{val}->Word_Read(0) == 0xff) or die; VDIV($o, {val=>Bit::Vector->new_Dec(8,0xff), signed=>1}, {val=>Bit::Vector->new_Dec(8,0xdb), signed=>1}, 1); ($o->{val}->Word_Read(0) == 0xff) or die; VDIV($o, {val=>Bit::Vector->new_Dec(8,0x72), signed=>1}, {val=>Bit::Vector->new_Dec(8,0xdb), signed=>1}, 1); ($o->{val}->Word_Read(0) == 0x3) or die; } sub val_leaf { return {width=>32, signed=>0, val=>Bit::Vector->new_Dec(32,$_[0]), text=>$_[0],}; } sub makebool { return (Bit::Vector->new_Dec(1,$_[0])); } sub newsized { return (Bit::Vector->new($_[0]->Size)); } sub max { return $_[0]<$_[1] ? $_[1] : $_[0]; } sub min { return $_[0]>$_[1] ? $_[1] : $_[0]; } sub log2 { for (my $i=31; $i>=0; $i--) { return $i+1 if $_[0]>(1<<$i); } return 0; } sub countones { my $out = 0; for (my $bit=0; $bit < $_[0]->Size; $bit++) { $out ++ if $_[0]->bit_test($bit); } return $out; } sub VLOGNOT { $_[0]{val} = makebool(($_[1]->is_empty)?1:0); } sub VNEGATE { $_[0]{val} = my $o = newsized($_[1]); $o->Negate($_[1]); } sub VCOUNTONES { $_[0]{val} = Bit::Vector->new_Dec(32,countones($_[1])); } sub VONEHOT { $_[0]{val} = makebool((countones($_[1])==1)?1:0); } sub VONEHOT0 { $_[0]{val} = makebool((countones($_[1])<=1)?1:0); } sub VLOGAND { $_[0]{val} = makebool((!($_[1]->is_empty) && !($_[2]->is_empty))?1:0); } sub VLOGOR { $_[0]{val} = makebool((!($_[1]->is_empty) || !($_[2]->is_empty))?1:0); } sub VCOND { if (!($_[1]->is_empty)) { $_[0]{val}=$_[2]->Clone; } else { $_[0]{val}=$_[3]->Clone; } } sub VREDAND { $_[0]{val} = makebool(($_[1]->is_full)?1:0); } sub VREDOR { $_[0]{val} = makebool(($_[1]->is_empty)?0:1); } sub VREDNAND { $_[0]{val} = makebool(($_[1]->is_full)?0:1); } sub VREDNOR { $_[0]{val} = makebool(($_[1]->is_empty)?1:0); } sub VREDXOR { my $out = 0; for (my $bit=0; $bit < $_[1]->Size; $bit++) { $out ^= $_[1]->bit_test($bit); } $_[0]{val} = makebool($out); } sub VREDXNOR { my $out = 1; for (my $bit=0; $bit < $_[1]->Size; $bit++) { $out ^= $_[1]->bit_test($bit); } $_[0]{val} = makebool($out); } sub eithercompare { ($_[1]->{signed} && $_[2]->{signed}) ? $_[1]{val}->Compare($_[2]{val}) : $_[1]{val}->Lexicompare($_[2]{val}); } sub VEQ { $_[0]{val} = makebool( (eithercompare($_[0],$_[1],$_[2])==0) ?1:0); } sub VNE { $_[0]{val} = makebool( (eithercompare($_[0],$_[1],$_[2])!=0) ?1:0); } sub VLT { $_[0]{val} = makebool( (eithercompare($_[0],$_[1],$_[2])< 0) ?1:0); } sub VLE { $_[0]{val} = makebool( (eithercompare($_[0],$_[1],$_[2])<=0) ?1:0); } sub VGT { $_[0]{val} = makebool( (eithercompare($_[0],$_[1],$_[2])> 0) ?1:0); } sub VGE { $_[0]{val} = makebool( (eithercompare($_[0],$_[1],$_[2])>=0) ?1:0); } sub VSHIFTLxx { print "$Vars{vq}->ShiftL($_[0],$_[1]);\n"; print " ",$_[0]->to_Hex," ",$_[1]->to_Hex,";\n"; my $out = $_[0]->Clone; $out->Move_Left($_[1]->Word_Read(0)); print $out->to_Hex,"\n"; return $out; } sub VAND { $_[0]{val}=my $o=newsized($_[1]); $o->Intersection($_[1],$_[2]); } sub VOR { $_[0]{val}=my $o=newsized($_[1]); $o->Union($_[1],$_[2]); } sub VNAND { $_[0]{val}=my $o=newsized($_[1]); $o->Intersection($_[1],$_[2]); $o->Complement($o); } sub VNOR { $_[0]{val}=my $o=newsized($_[1]); $o->Union($_[1],$_[2]); $o->Complement($o); } sub VXOR { $_[0]{val}=my $o=newsized($_[1]); $o->ExclusiveOr($_[1],$_[2]); } sub VXNOR{ $_[0]{val}=my $o=newsized($_[1]); $o->ExclusiveOr($_[1],$_[2]); $o->Complement($o); } sub VNOT { $_[0]{val}=my $o=newsized($_[1]); $o->Complement($_[1]); } sub VSHIFTL{ $_[0]{val}=my $o=$_[1]->Clone; $o->Move_Left ($_[2]->Word_Read(0)); } sub VSHIFTR{ $_[0]{val}=my $o=$_[1]->Clone; $o->Move_Right($_[2]->Word_Read(0)); } sub VSHIFTRS{$_[0]{val}=my $o=$_[1]->Clone; $o->Move_Right($_[2]->Word_Read(0)); if ($_[1]->msb() && $_[2]->Word_Read(0)>0) {$o->Interval_Fill(max(0,$o->Size-1-$_[2]->Word_Read(0)), $o->Size-1); } #print (" SHI ",$_[0]{val}->to_Hex,' = ',$_[1]->to_Hex,' >>> ',$_[2]->Word_Read(0),"\n"); } sub VCLONE { $_[0]{val}=$_[1]->Clone; } sub VRESIZE { $_[0]{val}=$_[1]->Clone; $_[0]{val}->Resize($_[0]{width}); } sub VADD { $_[0]{val}=my $o=newsized($_[1]); $o->add($_[1],$_[2],0); } sub VSUB { $_[0]{val}=my $o=newsized($_[1]); $o->subtract($_[1],$_[2],0); } sub VMUL { # Multiply is signed, so need an additional sign bit my $a=$_[1]->Clone; $a->Resize($a->Size + 1); my $b=$_[2]->Clone; $b->Resize($b->Size + 1); my $mo=Bit::Vector->new($_[1]->Size + $_[2]->Size + 1); $mo->Multiply($a,$b); my $o=newsized($_[1]); $o->Interval_Copy($mo,0,0,$_[1]->Size); $_[0]{val}=$o; } sub VDIV { my $is_mod = $_[3]; if ($_[2]{val}->is_empty) { # Avoid divide by zero $_[0]{val}=newsized($_[1]{val}); return; } my $a=$_[1]{val}->Clone; if (!$_[1]->{signed}) { $a->Resize($a->Size + 1); } my $b=$_[2]{val}->Clone; if (!$_[2]->{signed}) { $b->Resize($b->Size + 1); } #print ("//DIVpp ",$_[1]->to_Hex,' ',$_[2]->to_Hex,' ',$_[1]->Size,'.',$_[2]->Size," \n"); #print ("//DIVpp ",$a->to_Hex,' ',$b->to_Hex,' ',$a->Size,'.',$b->Size," \n"); my $quo=newsized($a); my $rem=newsized($a); $quo->Divide($a,$b,$rem); # No division by zero - handled by if above my $o=newsized($_[1]{val}); $o->Interval_Copy($is_mod ? $rem : $quo,0,0,$_[1]{val}->Size); #print "//DIV",($_[1]->{signed}?"S":" "),' w',$a->Size,' ',$_[1]{val}->to_Hex,' ',$_[2]{val}->to_Hex,' =',$quo->to_Hex,'.',$rem->to_Hex," \n"; $_[0]{val}=$o; } sub VPOW { # Power is a signed operation my $a=$_[1]{val}->Clone; if (!$_[1]->{signed}) { $a->Resize($_[1]{val}->Size + 1); } my $b=$_[2]{val}->Clone; if (!$_[2]->{signed}) { $b->Resize($_[2]{val}->Size + 1); } print "VVpow = ",$_[1]{val}->to_Hex," ** ",$_[2]{val}->to_Hex,"\n"; my $mo=Bit::Vector->new($_[1]{val}->Size + 1); $mo->Power($a,$b); my $o=Bit::Vector->new($_[0]{width}); $o->Interval_Copy($mo,0,0,$_[1]{val}->Size); $_[0]{val}=$o; print "VV = $o\n"; } sub VRANGE { #print "RANGE ",$_[1]->to_Hex,' ',$_[2]->to_Hex,' ',$_[3]->to_Hex," \n"; return VRANGE_CONST($_[0],$_[1],$_[2]->Word_Read(0),$_[3]->Word_Read(0), $_[4]); } sub VBITSELP { return VRANGE_CONST($_[0],$_[1],$_[2]->Word_Read(0)+$_[3]->Word_Read(0)-1, $_[2]->Word_Read(0), $_[4]); } sub VBITSELM { return VRANGE_CONST($_[0],$_[1],$_[2]->Word_Read(0), $_[2]->Word_Read(0)-$_[3]->Word_Read(0)+1, $_[4]); } sub VRANGE_CONST { # to, from, msb, lsb, variable_lsb_to_subtract #print "RANGE ",$_[1]->to_Hex,' ',$_[2],' ',$_[3],' ',$_[4]," \n"; my $size = $_[2] - $_[3] + 1; my $o=Bit::Vector->new($size); if ($_[3] < $_[1]->Size) { $o->Interval_Copy($_[1],0,$_[3]-$_[4],$size); } $_[0]{val}=$o; } sub VCONCAT { my $o=Bit::Vector->new($_[1]->Size + $_[2]->Size); $o->Interval_Copy($_[1],$_[2]->Size,0,$_[1]->Size); $o->Interval_Copy($_[2],0,0,$_[2]->Size); $_[0]{val}=$o; } sub VREPLIC { my $o=Bit::Vector->new($_[1]->Word_Read(0) * $_[2]->Size); my $pos = 0; for (my $time=0; $time<($_[1]->Word_Read(0)); $time++) { $o->Interval_Copy($_[2],$pos,0,$_[2]->Size); $pos += $_[2]->Size; } $_[0]{val}=$o; } ####################################################################### ####################################################################### ####################################################################### package Vg::Base; use Data::Dumper; use strict; #------------------------------------------------------------ # CREATORS sub new { my $class = shift; my $self = { width=>0, # Width of expression, 0=Pick a width #signed=>0/1, # Undef = pick a sign @_}; bless $self, $class; return $self; } # ACCESSORS #------------------------------------------------------------ # OUTPUTTING sub val_to_text { my $treeref = shift; my $val = lc $treeref->{val}->to_Hex(); $val = "0" if $treeref->{val}->is_empty; if ($Opt_Sc) { return ("0x".$val .(($treeref->{width}>32)?"ULL":"UL") ); } else { return ($treeref->{width} .($treeref->{signed}?"'sh":"'h") .$val); } } sub tree_dump { my $treeref = shift; print Dumper($treeref); } ####################################################################### __END__ =pod =head1 NAME vgen.pl - Generate random verilog code =head1 SYNOPSIS vgen.pl =head1 DESCRIPTION vgen.pl generates automatic random verilog programs. =head1 ARGUMENTS =over 4 =item --help Displays this message and program version and exits. =item --blockstmts Number of statements per block. Defaults to 2. =item --depth Maximum depth of generated expressions. =item --initial Put all statements into an initial block. This will probably be optimized down to a NOP. =item --numops Number of operations to create. =item --raise Pick the specified number of random opcodes, and raise their frequency. =item --sc Output SystemC code (Experimental). =item --seed Seed for the random number generator. Defaults to 5, 0=randomize. =item --signed Include some signed arithmetic in the generated code. Experimental. =back =head1 DISTRIBUTION Copyright 2001-2015 by Wilson Snyder. Verilator 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. =head1 AUTHORS Wilson Snyder =head1 SEE ALSO =cut ###################################################################### ### Local Variables: ### compile-command: "./vgen.pl -sc --depth=10 --blockstmts=10" ### compile-command: "make " ### End: verilator-3.874/test_verilated/sim_main.cpp0000664000177100017500000000223612525171734021053 0ustar wsnyderwsnyder// DESCRIPTION: Verilator Test: Top level main for invoking model // // Copyright 2003-2015 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. #include #include "Vvgen.h" #include "Vvgen_vgen.h" // For v Vvgen *top; vluint64_t main_time = 0; double sc_time_stamp () { return main_time; } int main(int argc, char **argv, char **env) { Verilated::commandArgs(argc, argv); Verilated::debug(0); // We compiled with it on for testing, turn it back off top = new Vvgen; top->check = 0; top->clk = 0; #define CYCTIME 10 // Cycle the interpreter while (main_time < CYCTIME*top->v->CYCLES) { top->eval(); main_time += CYCTIME/2; top->clk = !top->clk; top->eval(); main_time += CYCTIME/2; top->clk = !top->clk; } // Do a checking run top->check = 1; for (int i=0; i<10; i++) { top->eval(); main_time += CYCTIME/2; top->clk = !top->clk; top->eval(); main_time += CYCTIME/2; top->clk = !top->clk; } top->final(); exit(0L); } verilator-3.874/test_verilated/vgen.v0000664000177100017500000027377212525247731017721 0ustar wsnyderwsnyder// Created by: vgen.pl module vgen (clk, check, done); input clk; input check; output done; initial $write("\n*** Vgen.v starting, seed = 5\n"); // verilator lint_off UNSIGNED // verilator lint_off CMPCONST // verilator lint_off WIDTH reg signed [127: 0] W0001 ; //=128'h00000000000000000000000000000000 reg [ 3: 0] W0002 ; //=4'h0 reg signed [127: 0] W0003 ; //=128'hffffffffffffffffffffffffffffffff reg [ 68: 0] W0004 /*verilator public*/; //=69'h000000000000000000 reg [ 76: 0] W0005 ; //=77'h00000000000000000000 reg [ 76: 0] W0006 /*verilator public*/; //=77'h00000000000000000000 reg [ 66: 0] W0007 ; //=67'h717d4750300000000 reg signed [114: 0] W0008 ; //=115'h7ffffffffffffffffffffffffffff reg signed [ 70: 0] W0009 ; //=71'h000000000000000001 reg [ 7: 0] W0010 /*verilator public*/; //=8'h4f reg signed [ 90: 0] W0011 ; //=91'h00000000000000000000000 reg signed [101: 0] W0012 /*verilator public*/; //=102'h00000000000000000000000000 reg signed [ 62: 0] W0013 ; //=63'h0000000000000001 reg [ 6: 0] W0014 /*verilator public*/; //=7'h7f reg [108: 0] W0015 ; //=109'h1fffffffffffffffffffffffffff reg [108: 0] W0016 ; //=109'h1fffffffffffffffffffffffffff reg [ 66: 0] W0017 /*verilator public*/; //=67'h00000000000000000 reg [ 7: 0] W0018 ; //=8'hff reg signed [ 94: 0] W0019 /*verilator public*/; //=95'h000000000000000000000000 reg signed [ 96: 0] W0020 ; //=97'h000000001abf37a3000000001 reg signed [ 96: 0] W0021 ; //=97'h1ffffffffffffffffffffffff reg signed [125: 0] W0022 ; //=126'h3fffffffffffffffffffffffffffffff reg signed [122: 0] W0023 ; //=123'h7ffffffbce03e2bdb14609fe7e28b41 reg signed [ 83: 0] W0024 ; //=84'h0000000000000e1fe9094 reg signed [ 83: 0] W0025 ; //=84'h0f66afffffffe308b3d7c reg [ 74: 0] W0026 ; //=75'h0000000000000000000 reg signed [ 38: 0] W0027 ; //=39'h005f38482c reg signed [ 6: 0] W0028 ; //=7'h7f reg signed [ 38: 0] W0029 ; //=39'h005f38482c reg signed [ 94: 0] W0030 /*verilator public*/; //=95'h000000000000000000000000 reg [111: 0] W0031 ; //=112'h0000000000000000000000000000 reg [ 95: 0] W0032 ; //=96'h000000000000000000000000 reg signed [124: 0] W0033 ; //=125'h00000000000000000000000000000000 reg signed [ 98: 0] W0034 ; //=99'h7913abf27d9460ca500000000 reg signed [ 31: 0] W0035 ; //=32'h00000000 reg signed [ 5: 0] W0036 ; //=6'h00 reg signed [ 5: 0] W0037 ; //=6'h00 reg [ 94: 0] W0038 /*verilator public*/; //=95'h0000003fffffffffffffffff reg signed [ 66: 0] W0039 /*verilator public*/; //=67'h0001fc7de7a700000 reg signed [ 3: 0] W0040 ; //=4'h0 reg signed [ 3: 0] W0041 ; //=4'h0 reg signed [105: 0] W0042 ; //=106'h3ffffffffffffffffffffffffff reg signed [ 66: 0] W0043 /*verilator public*/; //=67'h65e205928eff62598 reg signed [ 30: 0] W0044 /*verilator public*/; //=31'h7fffffff reg signed [ 5: 0] W0045 /*verilator public*/; //=6'h00 reg [ 0: 0] W0046 ; //=1'h1 reg signed [ 70: 0] W0047 ; //=71'h000000000000000000 reg signed [ 86: 0] W0048 ; //=87'h0000000000000000000000 reg signed [ 60: 0] W0049 ; //=61'h1fffffffffffffff reg signed [ 6: 0] W0050 ; //=7'h00 reg [ 62: 0] W0051 ; //=63'h00000001bf003b47 reg signed [ 50: 0] W0052 ; //=51'h0000000000000 reg signed [107: 0] W0053 ; //=108'h0170f5f330fffffffff5d6adc0b reg signed [107: 0] W0054 ; //=108'h0170f5f330fffffffff5d6adc0b reg signed [ 1: 0] W0055 ; //=2'h0 reg signed [ 1: 0] W0056 ; //=2'h0 reg signed [ 1: 0] W0057 ; //=2'h0 reg [ 52: 0] W0058 ; //=53'h0f53da00000000 reg signed [ 26: 0] W0059 ; //=27'h0000001 reg signed [ 80: 0] W0060 ; //=81'h000000000000000000000 reg signed [ 6: 0] W0061 ; //=7'h7f reg signed [ 94: 0] W0062 ; //=95'h000000000000000000000000 reg signed [ 94: 0] W0063 ; //=95'h000000000000000000000000 reg signed [ 62: 0] W0064 ; //=63'h7fffffffffffffff reg [122: 0] W0065 ; //=123'h0000000000000000000000000000000 reg [122: 0] W0066 ; //=123'h0000000000000000000000000000000 reg [122: 0] W0067 /*verilator public*/; //=123'h0000000000000000000000000000000 reg signed [125: 0] W0068 ; //=126'h00000000000000000000000000000000 reg signed [ 50: 0] W0069 ; //=51'h7ffffffffffff reg signed [ 38: 0] W0070 ; //=39'h0000000000 reg [125: 0] W0071 ; //=126'h00000000000000000000000000000000 reg [125: 0] W0072 ; //=126'h00000000000000000000000000000000 reg signed [ 76: 0] W0073 ; //=77'h1fffd5a87217b1928f62 reg signed [ 76: 0] W0074 ; //=77'h19b700000000b1928142 reg signed [ 76: 0] W0075 ; //=77'h1fffffffffffffffffff reg [ 22: 0] W0076 ; //=23'h7f07a4 reg signed [ 26: 0] W0077 ; //=27'h2fe0f49 reg [ 39: 0] W0078 ; //=40'hff2efa1bb2 reg [ 62: 0] W0079 /*verilator public*/; //=63'h6800000000000000 reg signed [ 92: 0] W0080 /*verilator public*/; //=93'h1fffffff4d82b9fb00000000 reg [ 6: 0] W0081 /*verilator public*/; //=7'h7f reg [ 45: 0] W0082 ; //=46'h0000ffffffff reg signed [112: 0] W0083 ; //=113'h1ea01ffffffff00000000c2c8ff94 reg signed [112: 0] W0084 /*verilator public*/; //=113'h1ea01ffffffff00000000c2c8ff94 reg signed [ 89: 0] W0085 ; //=90'h3ffffffffffffffffffffff reg [ 0: 0] W0086 /*verilator public*/; //=1'h1 reg [ 91: 0] W0087 ; //=92'h00000000000000000000000 reg [126: 0] W0088 ; //=127'h00000000000000000000000000000000 reg signed [ 95: 0] W0089 ; //=96'h000000000000000000000000 reg signed [ 26: 0] W0090 /*verilator public*/; //=27'h0000000 reg signed [ 26: 0] W0091 ; //=27'h0000000 reg signed [ 26: 0] W0092 ; //=27'h7ffffff reg signed [126: 0] W0093 /*verilator public*/; //=127'h00000000000000000000000000000000 reg signed [ 56: 0] W0094 /*verilator public*/; //=57'h1ffffffffffffff reg signed [ 19: 0] W0095 ; //=20'h00000 reg signed [ 19: 0] W0096 /*verilator public*/; //=20'hfffff reg signed [ 74: 0] W0097 ; //=75'h7ff7e019ac646679f3d reg signed [ 85: 0] W0098 /*verilator public*/; //=86'h3fffffffffffffffffffff reg signed [121: 0] W0099 /*verilator public*/; //=122'h3ffffffffffffffffffffffffffffff reg signed [121: 0] W0100 ; //=122'h3ffffffffffffffffffffffffffffff reg signed [ 7: 0] W0101 ; //=8'h85 reg [ 0: 0] W0102 ; //=1'h0 reg [ 0: 0] W0103 ; //=1'h0 reg signed [ 83: 0] W0104 ; //=84'h000000000000000000000 reg signed [ 83: 0] W0105 /*verilator public*/; //=84'h0000000000000e1fe9094 reg signed [ 3: 0] W0106 ; //=4'hf reg signed [ 88: 0] W0107 ; //=89'h0000000fb47be1e00000001 reg signed [ 88: 0] W0108 /*verilator public*/; //=89'h1ffffff04b841e1ffffffff reg signed [ 66: 0] W0109 ; //=67'h00000000000000000 reg signed [ 66: 0] W0110 /*verilator public*/; //=67'h00000000000000000 reg [119: 0] W0111 ; //=120'hffffffffffffffffffffffffffffff reg [116: 0] W0112 ; //=117'h1fffffffffffffffffffffffffffff reg signed [121: 0] W0113 ; //=122'h3ffffffffffffffffffffffffffffff reg signed [116: 0] W0114 /*verilator public*/; //=117'h0058950000000000000001e74304cc reg signed [ 11: 0] W0115 /*verilator public*/; //=12'h000 reg signed [ 11: 0] W0116 ; //=12'h000 reg signed [ 57: 0] W0117 /*verilator public*/; //=58'h000000000000000 reg [ 98: 0] W0118 /*verilator public*/; //=99'h7ffffffffffffffffffffffff reg signed [116: 0] W0119 ; //=117'h1fffffffffffffffffffffffffffff reg signed [ 93: 0] W0120 ; //=94'h000000010000000000000001 reg [ 38: 0] W0121 ; //=39'h0000000000 reg [ 38: 0] W0122 ; //=39'h0000000000 reg signed [ 38: 0] W0123 ; //=39'h0000000000 reg [ 28: 0] W0124 ; //=29'h1fffffff reg signed [ 38: 0] W0125 ; //=39'h0000000000 reg signed [ 2: 0] W0126 ; //=3'h0 reg [ 70: 0] W0127 ; //=71'h1900000000ffffffff reg [ 2: 0] W0128 /*verilator public*/; //=3'h7 reg signed [ 14: 0] W0129 ; //=15'h6102 reg signed [ 63: 0] W0130 ; //=64'h0000000000000000 reg signed [ 63: 0] W0131 /*verilator public*/; //=64'h000000004e5361b5 reg signed [126: 0] W0132 /*verilator public*/; //=127'h00000000000000000000000000000000 reg signed [125: 0] W0133 ; //=126'h3ee9a075ffffffffef0f331858d8680b reg signed [ 53: 0] W0134 ; //=54'h00000000000000 reg signed [ 1: 0] W0135 ; //=2'h0 reg signed [ 21: 0] W0136 /*verilator public*/; //=22'h000000 reg signed [ 21: 0] W0137 ; //=22'h3fffff reg signed [104: 0] W0138 /*verilator public*/; //=105'h000000000000000000000000000 reg signed [ 78: 0] W0139 ; //=79'h00000000000000000000 reg [108: 0] W0140 ; //=109'h1fffffffffffffffffffffffffff reg signed [110: 0] W0141 ; //=111'h7fffffffffffffffffffffffffff reg signed [ 68: 0] W0142 ; //=69'h000000000000000000 reg [110: 0] W0143 ; //=111'h0000000000000000000000000000 reg signed [112: 0] W0144 ; //=113'h00000000000000000000000000000 reg signed [112: 0] W0145 ; //=113'h0000000000000ffffffff4c1151ce reg signed [ 63: 0] W0146 /*verilator public*/; //=64'h0000000000000001 reg signed [ 90: 0] W0147 /*verilator public*/; //=91'h7fffffffffffffff80880ab reg signed [ 90: 0] W0148 /*verilator public*/; //=91'h7fffffffffffffff80880ab reg signed [ 63: 0] W0149 ; //=64'h0000000000000000 reg signed [ 34: 0] W0150 ; //=35'h7ffffffff reg signed [ 34: 0] W0151 ; //=35'h7ffffffff reg signed [ 7: 0] W0152 ; //=8'h00 reg [ 0: 0] W0153 /*verilator public*/; //=1'h1 reg signed [127: 0] W0154 ; //=128'h87b2a85700000001ffffffffffffffff reg [ 44: 0] W0155 ; //=45'h000000000000 reg [102: 0] W0156 ; //=103'h00000000000000000000000000 reg [119: 0] W0157 ; //=120'h2ad85ce1a84cdbc0e0e871ffffffff reg signed [106: 0] W0158 ; //=107'h001a90c7bc2ffffffff61887cef reg [ 0: 0] W0159 ; //=1'h0 reg signed [125: 0] W0160 ; //=126'h0d26cc57ffffffffffffffff00000001 reg [ 0: 0] W0161 ; //=1'h1 reg signed [125: 0] W0162 ; //=126'h14787ad000000000673e5b6918cb109a reg [ 63: 0] W0163 ; //=64'hffffffffffffffff reg signed [105: 0] W0164 /*verilator public*/; //=106'h3ffffffffffffffffffffffffff reg signed [120: 0] W0165 /*verilator public*/; //=121'h0000000000000000000000000000000 reg [100: 0] W0166 ; //=101'h00ce5c6a8d8c0e8e38ffffffff reg signed [ 12: 0] W0167 ; //=13'h0000 reg signed [ 12: 0] W0168 ; //=13'h0000 reg signed [ 74: 0] W0169 /*verilator public*/; //=75'h0000000100000000000 reg signed [ 74: 0] W0170 ; //=75'h0000000100000000000 reg signed [ 7: 0] W0171 ; //=8'h2c reg signed [ 86: 0] W0172 ; //=87'h7ffffeffffffffd20026d0 reg signed [ 13: 0] W0173 /*verilator public*/; //=14'h0000 reg signed [ 13: 0] W0174 /*verilator public*/; //=14'h3fff reg signed [107: 0] W0175 ; //=108'h000000000000000000000000000 reg [ 2: 0] W0176 ; //=3'h6 reg signed [ 38: 0] W0177 ; //=39'h0000000000 reg signed [ 82: 0] W0178 ; //=83'h5a3feffffffffa74f99bd reg signed [ 82: 0] W0179 /*verilator public*/; //=83'h5a3feffffffffa74f99bd reg signed [107: 0] W0180 ; //=108'hfffffffffffffffffffffffffff reg signed [ 66: 0] W0181 ; //=67'h7ffffffffffffffff reg [ 94: 0] W0182 ; //=95'h000000000000000000000000 reg [116: 0] W0183 ; //=117'h000000000000000000000000000000 reg [116: 0] W0184 ; //=117'h1fffffffffffffffffffffffffffff reg [ 22: 0] W0185 ; //=23'h000000 reg [ 0: 0] W0186 /*verilator public*/; //=1'h1 reg [ 37: 0] W0187 ; //=38'h3c00000003 reg signed [ 67: 0] W0188 ; //=68'hf00000000ffffffff reg signed [ 67: 0] W0189 ; //=68'h00000000000000000 reg signed [ 7: 0] W0190 /*verilator public*/; //=8'hff reg [ 34: 0] W0191 /*verilator public*/; //=35'h7ffffffff reg signed [127: 0] W0192 /*verilator public*/; //=128'hffffffffffffffffffffffffffffffff reg signed [ 58: 0] W0193 /*verilator public*/; //=59'h7ffffffffffffff reg [ 42: 0] W0194 ; //=43'h7ffffffffff reg [ 4: 0] W0195 /*verilator public*/; //=5'h01 reg [119: 0] W0196 /*verilator public*/; //=120'h000000000000000000000000000000 reg signed [ 17: 0] W0197 ; //=18'h00001 reg signed [ 22: 0] W0198 ; //=23'h7fffff reg signed [ 1: 0] W0199 /*verilator public*/; //=2'h0 reg signed [ 1: 0] W0200 ; //=2'h0 reg signed [ 28: 0] W0201 ; //=29'h05936cd9 reg signed [ 78: 0] W0202 ; //=79'h00000000000000000000 reg signed [ 37: 0] W0203 /*verilator public*/; //=38'h0000000000 reg [107: 0] W0204 /*verilator public*/; //=108'hfffffffffffffffffffffffffff reg signed [ 37: 0] W0205 ; //=38'h3fb060d2b2 reg signed [ 87: 0] W0206 ; //=88'h0000000000000000000000 reg signed [ 87: 0] W0207 ; //=88'h0000000000000000000000 reg signed [ 1: 0] W0208 /*verilator public*/; //=2'h3 reg signed [ 1: 0] W0209 ; //=2'h1 reg [ 66: 0] W0210 ; //=67'h00000000000000000 reg signed [113: 0] W0211 ; //=114'h3ffffffffffffffffffffffffffff reg signed [102: 0] W0212 ; //=103'h00000000000000000000000000 reg [118: 0] W0213 ; //=119'h00000000000000000000017a9ad868 reg signed [111: 0] W0214 ; //=112'hd6b4ffffffffecfde9a900000001 reg signed [ 6: 0] W0215 ; //=7'h00 reg signed [ 35: 0] W0216 ; //=36'h000000000 reg signed [ 35: 0] W0217 ; //=36'h127a0ea26 reg [ 81: 0] W0218 ; //=82'h000000000000000000000 reg [127: 0] W0219 ; //=128'h00000000000000000000000000000000 reg signed [ 84: 0] W0220 /*verilator public*/; //=85'h0000000000000000000000 reg [ 31: 0] W0221 /*verilator public*/; //=32'h00000000 reg signed [126: 0] W0222 /*verilator public*/; //=127'h00000000ffffffffffffffff05de7de9 reg signed [ 45: 0] W0223 ; //=46'h000000000001 reg [ 66: 0] W0224 ; //=67'h7ffffffffffffffff reg [ 94: 0] W0225 ; //=95'h000000000000000000000000 reg [ 34: 0] W0226 ; //=35'h000000000 reg signed [ 78: 0] W0227 ; //=79'h000000000000000fffff reg signed [ 78: 0] W0228 ; //=79'h0000ffffffff00000000 reg signed [ 5: 0] W0229 ; //=6'h02 reg [ 0: 0] W0230 ; //=1'h1 reg [ 66: 0] W0231 ; //=67'h7ffffffffffffffff reg signed [127: 0] W0232 ; //=128'hffffffffffffffffffffffffffffffff reg signed [123: 0] W0233 ; //=124'h0000001ea881ab1000000001a85ba7a reg signed [ 54: 0] W0234 ; //=55'h000001ffffffff reg [115: 0] W0235 ; //=116'h00000000000000000000000000000 reg signed [124: 0] W0236 ; //=125'h1123198b7e03b2359874995a00000000 reg signed [ 98: 0] W0237 ; //=99'h04d0f023900000000ffffffff reg signed [ 66: 0] W0238 ; //=67'h00000000000000001 reg [ 0: 0] W0239 /*verilator public*/; //=1'h1 reg signed [ 4: 0] W0240 ; //=5'h00 reg signed [ 4: 0] W0241 /*verilator public*/; //=5'h1f reg signed [ 4: 0] W0242 ; //=5'h10 reg signed [ 2: 0] W0243 ; //=3'h3 reg signed [ 26: 0] W0244 ; //=27'h0000000 reg [ 28: 0] W0245 ; //=29'h1fffffff reg [ 93: 0] W0246 ; //=94'h3fffffffffffffffffffffff reg [ 93: 0] W0247 ; //=94'h000000000000000000000000 reg [126: 0] W0248 ; //=127'h00000000000000000000000000000000 reg signed [ 6: 0] W0249 ; //=7'h00 reg [ 92: 0] W0250 ; //=93'h000000000000000000000000 reg [ 92: 0] W0251 ; //=93'h000000000000000000000000 reg [ 94: 0] W0252 ; //=95'h000000000000000000000000 reg [ 66: 0] W0253 ; //=67'h783fcffffffffffff reg signed [ 84: 0] W0254 ; //=85'h1e0ff3ffffffffffffffff reg signed [ 80: 0] W0255 ; //=81'h000000000000000000000 reg [ 50: 0] W0256 /*verilator public*/; //=51'h7ffffffffffff reg [ 0: 0] W0257 ; //=1'h0 reg [ 98: 0] W0258 ; //=99'h7fffffffdc26eb98e2a835027 reg [114: 0] W0259 ; //=115'h7fffffffdc26eb98e2a835027aaef reg signed [126: 0] W0260 ; //=127'h7fffffffdc26eb98e2a835027aaef3e4 reg signed [ 64: 0] W0261 ; //=65'h00000000000000000 reg signed [ 7: 0] W0262 ; //=8'h01 reg signed [ 85: 0] W0263 ; //=86'h0fb71a800000002f0333b9 reg signed [ 7: 0] W0264 ; //=8'hff reg signed [ 30: 0] W0265 ; //=31'h7fffffff reg signed [ 44: 0] W0266 ; //=45'h16d2ffffffff reg signed [127: 0] W0267 ; //=128'hffffffffffffffffffffffffffffffff reg signed [ 35: 0] W0268 /*verilator public*/; //=36'hfffffffff reg [ 94: 0] W0269 /*verilator public*/; //=95'h000000000000000000000000 reg [116: 0] W0270 ; //=117'h000000000000000000000000000000 reg [ 34: 0] W0271 ; //=35'h000000000 reg [125: 0] W0272 /*verilator public*/; //=126'h00000000000000000000000000000000 reg signed [ 12: 0] W0273 ; //=13'h0000 reg signed [ 27: 0] W0274 ; //=28'h0000000 reg [ 42: 0] W0275 /*verilator public*/; //=43'h7ffffffffff reg signed [ 92: 0] W0276 ; //=93'h000000000000000000000000 reg [ 54: 0] W0277 ; //=55'h00000000000000 reg [ 95: 0] W0278 /*verilator public*/; //=96'h000000000000000000000000 reg signed [ 38: 0] W0279 ; //=39'h005f38482c reg signed [ 78: 0] W0280 ; //=79'h7fff87182181ffffffff reg [126: 0] W0281 ; //=127'h00000000000000000000000000000000 reg signed [ 77: 0] W0282 ; //=78'h00000000000000000001 reg [ 54: 0] W0283 ; //=55'h4676b5c84a0634 reg [ 86: 0] W0284 ; //=87'h7fffffffffffffffffffff reg signed [127: 0] W0285 ; //=128'h00000000000000000000000000000000 reg [100: 0] W0286 /*verilator public*/; //=101'h00000000000000000000000000 reg [102: 0] W0287 ; //=103'h00000000000000000000000000 reg signed [113: 0] W0288 /*verilator public*/; //=114'h00000000000000000000000000000 reg [ 47: 0] W0289 ; //=48'h000000000000 reg signed [127: 0] W0290 ; //=128'h00000000000000000000000000000000 reg signed [ 34: 0] W0291 ; //=35'h000000000 reg signed [ 30: 0] W0292 ; //=31'h7fffffff reg [ 90: 0] W0293 ; //=91'h00000000000000000000000 reg [127: 0] W0294 /*verilator public*/; //=128'hffffffffffffffffffffffffffffffff reg [ 58: 0] W0295 ; //=59'h1cb682e00000000 reg [ 70: 0] W0296 ; //=71'h1900000000ffffffff reg signed [ 6: 0] W0297 ; //=7'h7f reg signed [ 3: 0] W0298 ; //=4'h0 reg [123: 0] W0299 ; //=124'h6cfbaebfc86e1c0a97f60e4af292b85 reg [ 34: 0] W0300 ; //=35'h000000000 reg signed [126: 0] W0301 ; //=127'h7fffffffffffffffffffffffffffffff reg [ 12: 0] W0302 /*verilator public*/; //=13'h0001 reg signed [110: 0] W0303 ; //=111'h6483041c277c0000000098007584 reg signed [126: 0] W0304 ; //=127'h7fffffffffffffffffffffffffffffff reg signed [ 78: 0] W0305 ; //=79'h0000eac0ae48ceb2ae66 reg signed [ 78: 0] W0306 ; //=79'h53bf3d286da2ffffffff reg [ 0: 0] W0307 ; //=1'h0 reg signed [ 54: 0] W0308 ; //=55'h00000000000000 reg signed [ 57: 0] W0309 ; //=58'h3ffffffffffffff reg signed [124: 0] W0310 ; //=125'h00000000000000000000000000000000 reg [124: 0] W0311 /*verilator public*/; //=125'h1ebf98350000000056ed349dffffffff reg [124: 0] W0312 /*verilator public*/; //=125'h1ebf98350000000056ed349dffffffff reg signed [ 18: 0] W0313 ; //=19'h74f08 reg signed [104: 0] W0314 ; //=105'h000000000000000000000000000 reg signed [ 86: 0] W0315 ; //=87'h000000000000010301a280 reg signed [ 22: 0] W0316 ; //=23'h7fffff reg [127: 0] W0317 /*verilator public*/; //=128'hffffffffffffffffffffffffffffffff reg signed [ 87: 0] W0318 ; //=88'h0000000000000000000000 reg signed [ 87: 0] W0319 ; //=88'h0000000000000000000000 reg signed [ 73: 0] W0320 ; //=74'h3ffffffffffffffffff reg [ 96: 0] W0321 ; //=97'h0000000000000000000374acf reg signed [115: 0] W0322 ; //=116'h000004a144132ffffffffffffffff reg [ 19: 0] W0323 ; //=20'h00000 reg signed [ 22: 0] W0324 /*verilator public*/; //=23'h283d11 reg [ 85: 0] W0325 ; //=86'h0000000000000000000000 //============================================================ always @(check) begin : Block1 W0003 = 128'shffffffffffffffffffffffffffffffff; W0002 = (4'hf << {1'h1,2'h0}); W0001 = (W0003 <<< (8'shff >>> 4'shf)); if (96'sh0 != 96'sh0) if (check) $stop; if (W0001[W0002+:96] != 96'h0) if (check) $stop; end //============================================================ always @(check) begin : Block2 W0009 = $signed(71'h000000000000000001); W0008 = 115'sh7ffffffffffffffffffffffffffff; W0007 = ((W0009[66-:67])==67'h0 ? 67'h0:($unsigned(67'sh717d4750300000000) / W0009[66-:67])); W0006 = 77'h0; W0005 = W0006[76:0]; W0004 = W0005[76:8]; end always @(posedge clk) begin : Block2Check if (W0004[68:17] != 52'h0) if (check) $stop; if (W0007[(~ (((6'h0c)==6'h0 ? 6'h0:(6'h0 % 6'h0c)) & W0008[82-:6]))] != 1'h0) if (check) $stop; end //============================================================ always @(check) begin : Block3 W0011 = ((((91'sh7ffffffffffffff7920fc03)==91'h0 ? 91'sh0:(91'sh00000000000000000000001 / 91'sh7ffffffffffffff7920fc03)) <<< (8'sh0 >>> 4'sh0)) >>> ((8'sh0 & 8'shff) >>> 4'shf)); W0010 = 8'h4f; end always @(posedge clk) begin : Block3Check if (((((95'sh0 >>> $signed(8'sh0)))==95'h0 ? 95'sh0:(((((95'sh0)==95'h0 ? 95'sh0:(95'sh000000000000000000000001 / 95'sh0)))==95'h0 ? 95'sh0:((95'sh7fffffffffffffffffffffff >>> 8'shcd) / ((95'sh0)==95'h0 ? 95'sh0:(95'sh000000000000000000000001 / 95'sh0)))) / (95'sh0 >>> $signed(8'sh0)))) >= $signed(((1'h0 ? 95'h7fffffffffffffffffffffff : 95'h7fffffffffffffffffffffff) << W0010))) != 1'h1) if (check) $stop; if (W0011[90:89] != 2'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0012 <= ((102'sh3f3ec596b700000000d12d2796)==102'h0 ? 102'sh0:(102'sh0 % 102'sh3f3ec596b700000000d12d2796)); end always @(posedge clk) begin if ((~ ((1'h1)==1'h0 ? 1'h0:((((65'sh0ffffffffffffffff)==65'h0 ? 65'sh0:(65'sh0 % 65'sh0ffffffffffffffff)) !== (65'sh10000000000000001 >>> 8'shff)) / 1'h1))) != 1'h0) if (check) $stop; if ((((~ W0012))==102'h0 ? 102'sh0:(102'sh00ffffffffffffffff38390476 % (~ W0012))) != 102'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block5 W0018 = 8'hff; W0017 = (((((~ 67'h7ffffffffffffffff))==67'h0 ? 67'h0:(67'h0 / (~ 67'h7ffffffffffffffff))))==67'h0 ? 67'h0:({W0018,59'h0} % (((~ 67'h7ffffffffffffffff))==67'h0 ? 67'h0:(67'h0 / (~ 67'h7ffffffffffffffff))))); W0016 = 109'h1fffffffffffffffffffffffffff; W0015 = W0016; W0014 = W0015[108:102]; W0013 = ((63'sh7fffffffffffffff)==63'h0 ? 63'sh0:(63'sh7fffffffffffffff / 63'sh7fffffffffffffff)); if ((((61'h0000000180c90692)==61'h0 ? 61'h0:(W0013[2+:61] / 61'h0000000180c90692)) >> W0014) != 61'h0) if (check) $stop; if (W0017[62-:63] != 63'h0) if (check) $stop; end //============================================================ always @(check) begin : Block6 W0021 = 97'sh1ffffffffffffffffffffffff; W0020 = (97'sh000000001abf37a3000000000 + 97'sh0000000000000000000000001); W0019 = 95'sh0; end always @(posedge clk) begin : Block6Check if ((((((95'sh43c6f640ffffffff8eca1caf >>> 8'sh01) <<< ((8'shff)==8'h0 ? 8'sh0:(8'sh01 % 8'shff))) <<< ((((8'sh68)==8'h0 ? 8'sh0:(8'shff % 8'sh68)))==8'h0 ? 8'sh0:(8'shff / ((8'sh68)==8'h0 ? 8'sh0:(8'shff % 8'sh68))))))==95'h0 ? 95'sh0:((((95'sh0)==95'h0 ? 95'sh0:(W0019 / 95'sh0)) <<< ((8'shff >>> 4'sh0) >>> (4'shf | 4'shf))) / (((95'sh43c6f640ffffffff8eca1caf >>> 8'sh01) <<< ((8'shff)==8'h0 ? 8'sh0:(8'sh01 % 8'shff))) <<< ((((8'sh68)==8'h0 ? 8'sh0:(8'shff % 8'sh68)))==8'h0 ? 8'sh0:(8'shff / ((8'sh68)==8'h0 ? 8'sh0:(8'shff % 8'sh68))))))) != 95'sh0) if (check) $stop; if (((W0021)==97'h0 ? 97'sh0:(((W0020)==97'h0 ? 97'sh0:((~ 97'sh0ffffffffffffffff648b6e1f) % W0020)) / W0021)) != 97'sh00000000119d226becb67d8c4) if (check) $stop; end //============================================================ always @(posedge clk) begin W0023 <= 123'sh7ffffffbce03e2bdb14609fe7e28b41; end always @(posedge clk) begin W0022 <= 126'sh3fffffffffffffffffffffffffffffff; end always @(posedge clk) begin if (W0022[125:125] != 1'h1) if (check) $stop; if (W0023[94-:95] != 95'h3ce03e2bdb14609fe7e28b41) if (check) $stop; end //============================================================ always @(posedge clk) begin if (102'sh3fffffffffffffffffffffffff != 102'sh3fffffffffffffffffffffffff) if (check) $stop; if (9'h1ff != 9'h1ff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0031 <= 112'h0; end always @(posedge clk) begin W0030 <= (W0031[111:111] ? 95'sh27674746565249ff00000001 : W0019); end always @(posedge clk) begin W0029 <= (- 39'sh7fa0c7b7d4); end always @(posedge clk) begin W0028 <= (7'sh7f >>> 4'sh1); end always @(posedge clk) begin W0027 <= W0029; end always @(posedge clk) begin W0026 <= W0030[94:20]; end always @(posedge clk) begin W0025 <= ((~ 84'shf099500000001cf74c284) - 84'shfffffffffffffffffffff); end always @(posedge clk) begin W0024 <= (~ 84'shfffffffffffff1e016f6b); end always @(posedge clk) begin if (((W0025)==84'h0 ? 84'sh0:($signed(W0024) % W0025)) != 84'sh0000000000000e1fe9094) if (check) $stop; if (W0026[W0027[W0028[2+:5]+:6]+:2] != 2'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0034 <= 99'sh7913abf27d9460ca500000000; end always @(posedge clk) begin W0033 <= 125'sh0; end always @(posedge clk) begin W0032 <= W0033[124:29]; end always @(posedge clk) begin if (((W0032 & W0034[3+:96]) << W0018) != 96'h0) if (check) $stop; if ((((((67'sh0 >>> 8'sh01) <<< ((8'sh0)==8'h0 ? 8'sh0:(8'shff % 8'sh0))))==67'h0 ? 67'sh0:(67'sh3ffffffffffffffff % ((67'sh0 >>> 8'sh01) <<< ((8'sh0)==8'h0 ? 8'sh0:(8'shff % 8'sh0))))) <<< 8'shff) != 67'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (32'hffffffff != 32'hffffffff) if (check) $stop; if (W0012 != 102'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0037 <= 6'sh0; end always @(posedge clk) begin W0036 <= (6'sh0c * 6'sh0); end always @(posedge clk) begin W0035 <= 32'sh0; end always @(posedge clk) begin if (((((W0035)==32'h0 ? 32'sh0:(((32'sh00000001)==32'h0 ? 32'sh0:(32'shffffffff / 32'sh00000001)) % W0035)) <<< W0036) | ((32'shffffffff | (32'sh0 <<< 6'sh0)) >>> (1'h1 ? (6'sh0 | 6'sh3f) : $signed(6'h3f)))) != 32'shffffffff) if (check) $stop; if (((((- 31'sh7fffffff) <<< ((6'sh0)==6'h0 ? 6'sh0:(6'sh34 % 6'sh0))) | (((31'sh0 >>> 6'sh0))==31'h0 ? 31'sh0:(((31'sh0)==31'h0 ? 31'sh0:(31'sh7fffffff / 31'sh0)) / (31'sh0 >>> 6'sh0)))) >>> (((W0037 | 6'sh3f))==6'h0 ? 6'sh0:((((6'sh3f)==6'h0 ? 6'sh0:(6'sh0 % 6'sh3f)) >>> 4'sh0) % (W0037 | 6'sh3f)))) != 31'sh00000001) if (check) $stop; end //============================================================ always @(check or W0010) begin : Block13 W0039 = (67'sh200000001fc7de7a7 <<< ((8'sh42)==8'h0 ? 8'sh0:((8'sh14 >>> 4'sh0) % 8'sh42))); W0038 = {25'h0,((70'sh14ffffffffcc4030b9)==70'h0 ? 70'sh0:(70'sh3fffffffffffffffff % 70'sh14ffffffffcc4030b9))}; end always @(posedge clk) begin : Block13Check if ({(78'h3fffffffffffffffffff << W0010),W0038[87-:41]} != 119'h0000000000000000000000007fffff) if (check) $stop; if (W0039[3+:64] != 64'h0003f8fbcf4e0000) if (check) $stop; end //============================================================ always @(check) begin : Block14 W0042 = 106'sh3ffffffffffffffffffffffffff; W0041 = (4'sh0 * 4'sh0); W0040 = (W0041 & 4'sh0); if (W0040[3:3] != 1'h0) if (check) $stop; if ((((((106'sh3ffffffffff0000000000000000 >>> 8'shff))==106'h0 ? 106'sh0:((106'sh0 >>> 8'sh91) / (106'sh3ffffffffff0000000000000000 >>> 8'shff))) | ((((106'sh3ffffffffffffffffffffffffff)==106'h0 ? 106'sh0:(106'sh3ffffffffff00000000e89b775c / 106'sh3ffffffffffffffffffffffffff)))==106'h0 ? 106'sh0:((106'sh0 >>> 8'shff) % ((106'sh3ffffffffffffffffffffffffff)==106'h0 ? 106'sh0:(106'sh3ffffffffff00000000e89b775c / 106'sh3ffffffffffffffffffffffffff))))) !== W0042) != 1'h1) if (check) $stop; end //============================================================ always @(check or W0036) begin : Block15 W0045 = ((W0036)==6'h0 ? 6'sh0:(W0036 % W0036)); W0044 = 31'sh7fffffff; W0043 = 67'sh65e205928eff62598; if (95'h7fffffffffffffffffffffff != 95'h7fffffffffffffffffffffff) if (check) $stop; if ((((W0043[35-:1] ? W0044 : (31'sh0 <<< 6'sh3f)) >>> $signed((1'h1 ? 6'sh16 : 6'sh3f))) <<< W0045) != 31'sh7fffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if (72'sh0109a648c500000000 != 72'sh0109a648c500000000) if (check) $stop; if (2'h0 != 2'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0050 <= 7'sh0; end always @(posedge clk) begin W0049 <= (61'sh1fffffffffffffff <<< W0050); end always @(posedge clk) begin W0048 <= $signed(87'h0); end always @(posedge clk) begin W0047 <= (71'sh0 <<< 8'sh2b); end always @(posedge clk) begin W0046 <= 1'h1; end always @(posedge clk) begin if (((((1'h1 << 1'h1) ^ W0046) ^ (((63'sh0 && 79'h0))==1'h0 ? 1'h0:((1'h1 >> 1'h1) % (63'sh0 && 79'h0)))) || (W0047[68-:68] << W0048[86:79])) != 1'h1) if (check) $stop; if (((61'sh0)==61'h0 ? 61'sh0:(W0049 % 61'sh0)) != 61'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0052 <= ((((51'sh7ffffffffffff)==51'h0 ? 51'sh0:((51'sh7ffffffffffff >>> 7'sh54) % 51'sh7ffffffffffff)))==51'h0 ? 51'sh0:(51'sh7ffffffffffff % ((51'sh7ffffffffffff)==51'h0 ? 51'sh0:((51'sh7ffffffffffff >>> 7'sh54) % 51'sh7ffffffffffff)))); end always @(posedge clk) begin W0051 <= 63'h00000001bf003b47; end always @(posedge clk) begin if (W0051[62:53] != 10'h0) if (check) $stop; if (W0052[50:50] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0054 <= (108'sh0170f5f330fffffffff5d6adc0c + 108'shfffffffffffffffffffffffffff); end always @(posedge clk) begin W0053 <= (((1'h0 ? 108'sh0 : 108'sh0) <<< ((8'sh0)==8'h0 ? 8'sh0:(8'sh0 % 8'sh0))) | W0054); end always @(posedge clk) begin if (W0053[107:40] != 68'h0170f5f330fffffff) if (check) $stop; if (31'h7fffffff != 31'h7fffffff) if (check) $stop; end //============================================================ always @(check) begin : Block20 W0057 = (2'sh3 - 2'sh3); W0056 = (2'sh0 >>> 2'sh0); W0055 = (((2'sh0)==2'h0 ? 2'sh0:(2'sh3 / 2'sh0)) ^ (2'sh3 <<< 2'sh2)); if ((((W0056 >>> (((2'sh3)==2'h0 ? 2'sh0:(2'sh0 / 2'sh3)) <<< ((2'sh3)==2'h0 ? 2'sh0:(2'sh0 / 2'sh3)))))==2'h0 ? 2'sh0:(W0055 / (W0056 >>> (((2'sh3)==2'h0 ? 2'sh0:(2'sh0 / 2'sh3)) <<< ((2'sh3)==2'h0 ? 2'sh0:(2'sh0 / 2'sh3)))))) != 2'sh0) if (check) $stop; if (((2'sh3)==2'h0 ? 2'sh0:((W0057 <<< (2'sh0 <<< (2'sh1 >>> 2'sh0))) / 2'sh3)) != 2'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (99'sh153fb34be2a39f49d00000000 != 99'sh153fb34be2a39f49d00000000) if (check) $stop; if ((W0055 | 2'sh0) != 2'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((~| 1'h1) != 1'h0) if (check) $stop; if (16'sh0 != 16'sh0) if (check) $stop; end //============================================================ always @(check or W0046) begin : Block23 W0058 = (- ((~ 53'h0f53d9ffffffff) >> (7'h7f >> 4'hf))); if (W0046 != 1'h1) if (check) $stop; if (W0058[52:52] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0060 <= 81'sh0; end always @(posedge clk) begin W0059 <= (- 27'sh7ffffff); end always @(posedge clk) begin if (W0059[26:9] != 18'h0) if (check) $stop; if ((((((((1'h0 ? 81'sh0000014a54695ffffffff : 81'sh000000000000000000001))==81'h0 ? 81'sh0:(81'sh1004affffffff7fc42288 / (1'h0 ? 81'sh0000014a54695ffffffff : 81'sh000000000000000000001))))==81'h0 ? 81'sh0:((W0060 >>> (8'shff <<< 4'sh0)) % (((1'h0 ? 81'sh0000014a54695ffffffff : 81'sh000000000000000000001))==81'h0 ? 81'sh0:(81'sh1004affffffff7fc42288 / (1'h0 ? 81'sh0000014a54695ffffffff : 81'sh000000000000000000001))))))==81'h0 ? 81'sh0:(81'sh1f0aaffffffffffffffff % (((((1'h0 ? 81'sh0000014a54695ffffffff : 81'sh000000000000000000001))==81'h0 ? 81'sh0:(81'sh1004affffffff7fc42288 / (1'h0 ? 81'sh0000014a54695ffffffff : 81'sh000000000000000000001))))==81'h0 ? 81'sh0:((W0060 >>> (8'shff <<< 4'sh0)) % (((1'h0 ? 81'sh0000014a54695ffffffff : 81'sh000000000000000000001))==81'h0 ? 81'sh0:(81'sh1004affffffff7fc42288 / (1'h0 ? 81'sh0000014a54695ffffffff : 81'sh000000000000000000001))))))) != 81'sh0) if (check) $stop; end //============================================================ always @(check or W0050) begin : Block25 W0063 = 95'sh0; W0062 = W0063; W0061 = (W0050 + (1'h1 ? 7'sh7f : 7'sh0)); end always @(posedge clk) begin : Block25Check if (((((1'h1 ? 33'sh0 : 33'sh000000001) >>> (7'sh0 <<< 4'sh0)) >>> W0050) <<< W0061) != 33'sh0) if (check) $stop; if (((95'sh18c772827149783f00000000)==95'h0 ? 95'sh0:(((95'sh7fffffffffffffffffffffff)==95'h0 ? 95'sh0:(W0062 / 95'sh7fffffffffffffffffffffff)) % 95'sh18c772827149783f00000000)) != 95'sh0) if (check) $stop; end //============================================================ always @(check or W0046) begin : Block26 W0064 = 63'sh7fffffffffffffff; if ({38{{1{(W0046 ? ((1'h0)==1'h0 ? 1'h0:(1'h1 % 1'h0)) : W0046)}}}} != 38'h0) if (check) $stop; if ((W0064 | 63'sh7fffffffffffffff) != 63'sh7fffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0068 <= ((126'sh3fffffffffffffffffffffffffffffff)==126'h0 ? 126'sh0:(126'sh00000000000000000000000000000001 % 126'sh3fffffffffffffffffffffffffffffff)); end always @(posedge clk) begin W0067 <= 123'h0; end always @(posedge clk) begin W0066 <= W0067; end always @(posedge clk) begin W0065 <= (W0066 + W0068[125:3]); end always @(posedge clk) begin if (21'h0 != 21'h0) if (check) $stop; if (W0065 != 123'h0) if (check) $stop; end //============================================================ always @(check or W0018) begin : Block28 W0072 = (126'h3fffffff000000015e4ef77c00000000 >> W0018); W0071 = W0072[125:0]; W0070 = ((((39'sh7fffffffff)==39'h0 ? 39'sh0:(39'sh0 / 39'sh7fffffffff)))==39'h0 ? 39'sh0:(((39'sh0)==39'h0 ? 39'sh0:(39'sh7f2a25b834 % 39'sh0)) / ((39'sh7fffffffff)==39'h0 ? 39'sh0:(39'sh0 / 39'sh7fffffffff)))); W0069 = 51'sh7ffffffffffff; if (W0069[W0070[31-:5]+:1] != 1'h1) if (check) $stop; if (W0071[125:30] != 96'h0) if (check) $stop; end //============================================================ always @(check or W0063) begin : Block29 W0075 = (77'sh1fca000000001ab47a2b >>> 8'shff); W0074 = 77'sh19b700000000b1928142; W0073 = (((77'sh1fff8e21b6c8ffffffff)==77'h0 ? 77'sh0:(W0074 % 77'sh1fff8e21b6c8ffffffff)) + W0075); if (W0073 != 77'sh1fffd5a87217b1928f62) if (check) $stop; if (W0063 != 95'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0078 <= (40'h0 | 40'hff2efa1bb2); end always @(posedge clk) begin W0077 <= (27'sh2fe0f49 | ((27'sh0)==27'h0 ? 27'sh0:(27'sh2b714f6 / 27'sh0))); end always @(posedge clk) begin W0076 <= W0077[W0078[39:39]+:23]; end always @(posedge clk) begin if (96'shffffffffc51f36f7ffffffff != 96'shffffffffc51f36f7ffffffff) if (check) $stop; if (W0076[22:22] != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0081 <= 7'h7f; end always @(posedge clk) begin W0080 <= 93'sh1fffffff4d82b9fb00000000; end always @(posedge clk) begin W0079 <= {((~ 1'h0) ? 5'h1a : W0080[92:88]),(58'h3ffffffffffffff << W0081)}; end always @(posedge clk) begin if (W0079[62:32] != 31'h68000000) if (check) $stop; if ((((((16'shffff)==16'h0 ? 16'sh0:(16'shffff % 16'shffff)) <<< 5'sh1f) <<< 5'sh1f) <<< 5'sh1f) != 16'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0082 <= 46'h0000ffffffff; end always @(posedge clk) begin if (W0082[45:45] != 1'h0) if (check) $stop; if (W0046 != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0084 <= 113'sh1ea01ffffffff00000000c2c8ff94; end always @(posedge clk) begin W0083 <= W0084; end always @(posedge clk) begin if (W0083[112:112] != 1'h1) if (check) $stop; if (W0035 != 32'sh0) if (check) $stop; end //============================================================ always @(check or W0046) begin : Block34 end always @(posedge clk) begin : Block34Check if (((((((32'sh28aef9b9)==32'h0 ? 32'sh0:(32'shffffffff / 32'sh28aef9b9)) == ((32'sh0)==32'h0 ? 32'sh0:(32'sh0 % 32'sh0))) | ((! 1'h0) >> (96'h0 && 17'sh1dc8d))))==1'h0 ? 1'h0:(W0046 / ((((32'sh28aef9b9)==32'h0 ? 32'sh0:(32'shffffffff / 32'sh28aef9b9)) == ((32'sh0)==32'h0 ? 32'sh0:(32'sh0 % 32'sh0))) | ((! 1'h0) >> (96'h0 && 17'sh1dc8d))))) != 1'h1) if (check) $stop; if (W0046 != 1'h1) if (check) $stop; end //============================================================ always @(check) begin : Block35 if (((116'hfffffffffffffffffffffffffffff)==116'h0 ? 116'h0:(116'hfffffffffffffffffffffffffffff / 116'hfffffffffffffffffffffffffffff)) != 116'h00000000000000000000000000001) if (check) $stop; if (15'sh7fff != 15'sh7fff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0088 <= 127'h0; end always @(posedge clk) begin W0087 <= W0088[5'h01+:92]; end always @(posedge clk) begin W0086 <= 1'h1; end always @(posedge clk) begin W0085 <= ((90'sh3ffffffffffffffffffffff <<< 8'sh0) >>> ((8'shff)==8'h0 ? 8'sh0:(8'sh47 / 8'shff))); end always @(posedge clk) begin if (((((W0087[91:90])==2'h0 ? 2'h0:({((1'h0)==1'h0 ? 1'h0:(1'h1 % 1'h0)),W0086} / W0087[91:90])))==2'h0 ? 2'h0:(W0085[89:88] / ((W0087[91:90])==2'h0 ? 2'h0:({((1'h0)==1'h0 ? 1'h0:(1'h1 % 1'h0)),W0086} / W0087[91:90])))) != 2'h0) if (check) $stop; if (((W0035)==32'h0 ? 32'sh0:(W0035 % W0035)) != 32'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((((((38'sh35ffffffff)==38'h0 ? 38'sh0:(38'sh3fffffffff % 38'sh35ffffffff)))==38'h0 ? 38'sh0:((((38'sh3fa82dc20e >>> 7'sh01))==38'h0 ? 38'sh0:(38'sh0 / (38'sh3fa82dc20e >>> 7'sh01))) % ((38'sh35ffffffff)==38'h0 ? 38'sh0:(38'sh3fffffffff % 38'sh35ffffffff)))) >>> (((((7'sh0 >>> 4'shf))==7'h0 ? 7'sh0:(W0061 / (7'sh0 >>> 4'shf))))==7'h0 ? 7'sh0:(7'sh60 / (((7'sh0 >>> 4'shf))==7'h0 ? 7'sh0:(W0061 / (7'sh0 >>> 4'shf)))))) != 38'sh0) if (check) $stop; if (1'h1 != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0089 <= (1'h1 ? 96'sh0 : 96'shffffffff6192239500000000); end always @(posedge clk) begin if ((((W0089)==96'h0 ? 96'sh0:(96'shffffffffffffffff64616519 / W0089)) >>> (- ($signed(8'sh0) >>> W0041))) != 96'sh0) if (check) $stop; if (2'h3 != 2'h3) if (check) $stop; end //============================================================ always @(check or W0042) begin : Block39 W0092 = 27'sh7ffffff; W0091 = (((27'sh0000001)==27'h0 ? 27'sh0:(27'sh0000001 / 27'sh0000001)) + W0092); W0090 = W0091; end always @(posedge clk) begin : Block39Check if (W0090 != 27'sh0) if (check) $stop; if (W0042 != 106'sh3ffffffffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check) begin : Block40 W0093 = (((((127'sh00000001d6d57a196a929ef5ffffffff)==127'h0 ? 127'sh0:(127'sh0 % 127'sh00000001d6d57a196a929ef5ffffffff)) & (127'sh0 & 127'sh7fffffffffffffffffffffffffffffff)))==127'h0 ? 127'sh0:((((127'sh00000000000000000000000000000001 & 127'sh7fffffffffffffffffffffffffffffff))==127'h0 ? 127'sh0:((127'sh0 <<< 8'shff) / (127'sh00000000000000000000000000000001 & 127'sh7fffffffffffffffffffffffffffffff))) % (((127'sh00000001d6d57a196a929ef5ffffffff)==127'h0 ? 127'sh0:(127'sh0 % 127'sh00000001d6d57a196a929ef5ffffffff)) & (127'sh0 & 127'sh7fffffffffffffffffffffffffffffff)))); if (32'she674c3e8 != 32'she674c3e8) if (check) $stop; if (W0093[126:15] != 112'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0094 <= (~ 57'sh0); end always @(posedge clk) begin if ((~ W0094[56:25]) != 32'h0) if (check) $stop; if (W0064 != 63'sh7fffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0096 <= (1'h1 ? 20'shfffff : 20'sh0); end always @(posedge clk) begin W0095 <= (((20'sh0 >>> (6'sh3f >>> 4'sh0)))==20'h0 ? 20'sh0:(W0096 / (20'sh0 >>> (6'sh3f >>> 4'sh0)))); end always @(posedge clk) begin if (((((91'sh0)==91'h0 ? 91'sh0:((((91'sh7ffffff1ef0755a00000000 <<< 8'shd8))==91'h0 ? 91'sh0:($signed(91'sh3f89d7f00000000ffffffff) / (91'sh7ffffff1ef0755a00000000 <<< 8'shd8))) % 91'sh0)))==91'h0 ? 91'sh0:(91'sh00000000000000000000001 % ((91'sh0)==91'h0 ? 91'sh0:((((91'sh7ffffff1ef0755a00000000 <<< 8'shd8))==91'h0 ? 91'sh0:($signed(91'sh3f89d7f00000000ffffffff) / (91'sh7ffffff1ef0755a00000000 <<< 8'shd8))) % 91'sh0)))) != 91'sh0) if (check) $stop; if (W0095 != 20'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0097 <= ((75'sh7ff7e019ac646679f3d >>> 8'sh0) ^ 75'sh0); end always @(posedge clk) begin if ($signed(W0097[74:16]) != 59'sh7ff7e019ac64667) if (check) $stop; if (W0046 != 1'h1) if (check) $stop; end //============================================================ always @(check) begin : Block44 W0101 = (8'shff * 8'sh7b); W0100 = (122'sh3ffffff000000010000000000000001 >>> 8'shff); W0099 = (W0100 >>> W0101); W0098 = ((((86'sh0 >>> 8'sh01) | 86'sh16da685016495100000000))==86'h0 ? 86'sh0:(((86'sh3fffffffffffffffffffff >>> 8'sh01) <<< (8'sh0 <<< 4'sh1)) % ((86'sh0 >>> 8'sh01) | 86'sh16da685016495100000000))); if (W0098 != 86'sh3fffffffffffffffffffff) if (check) $stop; if (W0099[121:91] != 31'h7fffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0104 <= (W0024 <<< 8'shff); end always @(posedge clk) begin W0103 <= 1'h0; end always @(posedge clk) begin W0102 <= W0103; end always @(posedge clk) begin if (W0102 != 1'h0) if (check) $stop; if (((2'h0)==2'h0 ? 2'h0:(W0104[83:82] % 2'h0)) != 2'h0) if (check) $stop; end //============================================================ always @(check or W0024 or W0062) begin : Block46 W0106 = 4'shf; W0105 = (W0024 <<< ((1'h0 ? 8'sh0 : 8'sh0) <<< W0106)); if ({128{(| (W0062 >>> (8'sh01 >>> 4'sh4)))}} != 128'h0) if (check) $stop; if (W0105[83:83] != 1'h0) if (check) $stop; end //============================================================ always @(check or W0101) begin : Block47 W0108 = 89'sh1ffffff04b841e1ffffffff; W0107 = ((89'sh0 >>> W0101) - W0108); if (39'h0 != 39'h0) if (check) $stop; if (W0107 != 89'sh0000000fb47be1e00000001) if (check) $stop; end //============================================================ always @(check) begin : Block48 end always @(posedge clk) begin : Block48Check if (((48'sh00009b021b77)==48'h0 ? 48'sh0:(((48'shc4c800000001)==48'h0 ? 48'sh0:(48'sh30853054aa34 / 48'shc4c800000001)) / 48'sh00009b021b77)) != 48'sh0) if (check) $stop; if ((71'sh0 ^ 71'sh0) != 71'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block49 W0110 = (((67'sh7ffffffffffffffff)==67'h0 ? 67'sh0:(67'sh7ffffffffffffffff / 67'sh7ffffffffffffffff)) * (67'sh0ffffffff29ed52ab >>> 8'shff)); W0109 = W0110; end always @(posedge clk) begin : Block49Check if (W0109[1'h0+:63] != 63'h0) if (check) $stop; if (29'sh0 != 29'sh0) if (check) $stop; end //============================================================ always @(check or W0100 or W0049) begin : Block50 W0113 = W0100; W0112 = W0113[121:5]; W0111 = (120'hffffffffffffffffffffffffffffff & 120'hffffffffffffffffffffffffffffff); if (W0049 != 61'sh1fffffffffffffff) if (check) $stop; if (((W0112[116:2])==115'h0 ? 115'h0:((1'h1 ? W0111[119:5] : {115{((1'h1)==1'h0 ? 1'h0:(1'h1 % 1'h1))}}) % W0112[116:2])) != 115'h0) if (check) $stop; end //============================================================ always @(check or W0101) begin : Block51 W0116 = 12'sh0; W0115 = ((12'sh0)==12'h0 ? 12'sh0:((W0116 <<< (5'sh1f >>> 4'sh9)) / 12'sh0)); W0114 = 117'sh0058950000000000000001e74304cc; if (((((| 19'sh7ffff) | 1'h1) ? (~ (117'sh1fffffffffffffffffffffffffffff >>> 8'sh7b)) : W0114) >>> ((- W0101) >>> (4'sh0 >>> (3'sh1 >>> 3'sh1)))) != 117'sh0) if (check) $stop; if (W0115 != 12'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0120 <= 94'sh000000010000000000000001; end always @(posedge clk) begin W0119 <= 117'sh1fffffffffffffffffffffffffffff; end always @(posedge clk) begin W0118 <= (W0119[116:18] >> W0120[93:86]); end always @(posedge clk) begin W0117 <= 58'sh0; end always @(posedge clk) begin if (((58'sh3ffffffffffffff)==58'h0 ? 58'sh0:(W0117 / 58'sh3ffffffffffffff)) != 58'sh0) if (check) $stop; if ((W0118[27-:1] < W0102) != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0126 <= (- ((3'sh0)==3'h0 ? 3'sh0:(3'sh0 % 3'sh0))); end always @(posedge clk) begin W0125 <= 39'sh0; end always @(posedge clk) begin W0124 <= (- 29'h00000001); end always @(posedge clk) begin W0123 <= ($unsigned(1'h1) ? W0125 : W0029); end always @(posedge clk) begin W0122 <= 39'h0; end always @(posedge clk) begin W0121 <= ((125'sh00000001ffffffff0000000000000000 === 125'sh1fffffff467a88e33d244b6effffffff) ? (39'h7f5ce6b058 ^ 39'h7fffffffff) : W0122); end always @(posedge clk) begin if ((W0121[5'h1f] ? W0123[W0124[28:24]] : W0126[2+:1]) != 1'h0) if (check) $stop; if (10'sh0 != 10'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if ($signed(W0003) != 128'shffffffffffffffffffffffffffffffff) if (check) $stop; if (((1'h1)==1'h0 ? 1'h0:(1'h0 % 1'h1)) != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0127 <= {1{71'h1900000000ffffffff}}; end always @(posedge clk) begin if (84'sh00000ffffffff00000000 != 84'sh00000ffffffff00000000) if (check) $stop; if ((((W0127 >> 8'hff))==71'h0 ? 71'h0:(((71'h000000000000000001)==71'h0 ? 71'h0:(71'h05ffffffff00000000 % 71'h000000000000000001)) % (W0127 >> 8'hff))) != 71'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0128 <= 3'h7; end always @(posedge clk) begin if ($signed(((W0128[1-:1] ? (1'h1 ? 64'sh0 : 64'sh0) : 64'sh0000000000000001) <<< ((7'sh02 >>> 4'sh0) <<< 4'sh0))) != 64'sh0) if (check) $stop; if ((62'sh000000012b5522c1 <<< ((W0050 & W0061) >>> (4'shf | W0106))) != 62'sh000000012b5522c1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0131 <= (64'shffffffffb1ac9e4b * 64'shffffffffffffffff); end always @(posedge clk) begin W0130 <= ((W0131)==64'h0 ? 64'sh0:(64'sh0 / W0131)); end always @(posedge clk) begin W0129 <= (- ((15'sh3dfc >>> 5'sh0) >>> (- 5'sh1f))); end always @(posedge clk) begin if (W0129[12-:13] != 13'h0102) if (check) $stop; if (W0130 != 64'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0132 <= ((1'h1 ? 127'sh0000000100000000ffffffff5b9f9e19 : 127'sh00000001169fc5f7000000012a56ed19) <<< 8'shff); end always @(posedge clk) begin if (95'h4fde55d45c1283dc00000000 != 95'h4fde55d45c1283dc00000000) if (check) $stop; if ((~| W0132[126:22]) != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0133 <= (~ 126'sh01165f8a0000000010f0cce7a72797f4); end always @(posedge clk) begin if ((W0025 <<< W0101) != 84'sh0) if (check) $stop; if ((~ $signed(W0133[125:3])) != 123'sh022cbf140000000021e199cf4e4f2fe) if (check) $stop; end //============================================================ always @(posedge clk) begin if (((((111'sh0 | 111'sh0) <<< W0101) | ((((111'sh0)==111'h0 ? 111'sh0:(111'sh0000000000010000000000000000 % 111'sh0)))==111'h0 ? 111'sh0:((111'sh7fffffffffffffffffffffffffff >>> 8'sh0) / ((111'sh0)==111'h0 ? 111'sh0:(111'sh0000000000010000000000000000 % 111'sh0))))) >>> ((8'sh0)==8'h0 ? 8'sh0:((W0101 <<< (4'shf & 4'sh5)) / 8'sh0))) != 111'sh0) if (check) $stop; if (58'sh000000021435d6c != 58'sh000000021435d6c) if (check) $stop; end //============================================================ always @(check or W0101 or W0041 or W0064) begin : Block61 if (((((((~ 101'sh1fffffffffffffffffffffffff))==101'h0 ? 101'sh0:(((101'sh07801e45c800000000ffffffff)==101'h0 ? 101'sh0:(101'sh1fffffffffffffffffffffffff / 101'sh07801e45c800000000ffffffff)) / (~ 101'sh1fffffffffffffffffffffffff))) <<< (W0101 >>> W0041)))==101'h0 ? 101'sh0:(101'sh00000000000000000000000001 % ((((~ 101'sh1fffffffffffffffffffffffff))==101'h0 ? 101'sh0:(((101'sh07801e45c800000000ffffffff)==101'h0 ? 101'sh0:(101'sh1fffffffffffffffffffffffff / 101'sh07801e45c800000000ffffffff)) / (~ 101'sh1fffffffffffffffffffffffff))) <<< (W0101 >>> W0041)))) != 101'sh0) if (check) $stop; if (W0064 != 63'sh7fffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0135 <= W0057; end always @(posedge clk) begin W0134 <= (((54'sh0)==54'h0 ? 54'sh0:(54'sh00000000000001 / 54'sh0)) >>> 7'sh0a); end always @(posedge clk) begin if ({W0134[53:26],W0002} != 32'h0) if (check) $stop; if (W0135 != 2'sh0) if (check) $stop; end //============================================================ always @(check or W0101) begin : Block63 W0138 = ((((105'sh000000000000000000000000001)==105'h0 ? 105'sh0:(105'sh000435bd744a118e85a13113d46 % 105'sh000000000000000000000000001)) >>> W0101) >>> 8'sh0); W0137 = 22'sh3fffff; W0136 = ((~ W0137) * 22'sh0); end always @(posedge clk) begin : Block63Check if (W0136 != 22'sh0) if (check) $stop; if (W0138[104:104] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0142 <= ((69'sh0100000000813c7a4d >>> 8'sh01) <<< W0101); end always @(posedge clk) begin W0141 <= 111'sh7fffffffffffffffffffffffffff; end always @(posedge clk) begin W0140 <= W0141[2+:109]; end always @(posedge clk) begin W0139 <= ((((79'sh0)==79'h0 ? 79'sh0:(79'sh7fffffffffffffffffff / 79'sh0)) | ((79'sh7fffffffffffffffffff)==79'h0 ? 79'sh0:(79'sh0 / 79'sh7fffffffffffffffffff))) >>> W0101); end always @(posedge clk) begin if (W0139[2+:77] != 77'h0) if (check) $stop; if (((W0142[68:38])==31'h0 ? 31'h0:(({31{(50'h000013409567c < 50'h3ffffffffffff)}} >> W0140[108:103]) / W0142[68:38])) != 31'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0145 <= 113'sh0000000000000ffffffff4c1151ce; end always @(posedge clk) begin W0144 <= (W0145 >>> W0101); end always @(posedge clk) begin W0143 <= W0144[112:2]; end always @(posedge clk) begin if (W0143[101-:31] != 31'h0) if (check) $stop; if (20'shfffff != 20'shfffff) if (check) $stop; end //============================================================ always @(check) begin : Block66 W0146 = 64'sh0000000000000001; if (W0146[63:0] != 64'h0000000000000001) if (check) $stop; if (119'sh568a090000000000000000423f5c93 != 119'sh568a090000000000000000423f5c93) if (check) $stop; end //============================================================ always @(check or W0032 or W0131) begin : Block67 W0149 = (64'sh7678f4d600000000 * 64'sh0); W0148 = ((91'sh7ffffffc3cd5432ffffffff)==91'h0 ? 91'sh0:(91'sh1df9587a0fc14750ca1a6d9 / 91'sh7ffffffc3cd5432ffffffff)); W0147 = W0148; if (W0032 != 96'h0) if (check) $stop; if ((W0147[90:90] ? W0131 : (((64'shffffffffffffffff >>> (- 7'sh0)))==64'h0 ? 64'sh0:(W0149 % (64'shffffffffffffffff >>> (- 7'sh0))))) != 64'sh000000004e5361b5) if (check) $stop; end //============================================================ always @(posedge clk) begin W0152 <= 8'sh0; end always @(posedge clk) begin W0151 <= (35'sh7ffffffff >>> 7'sh0); end always @(posedge clk) begin W0150 <= (W0151 >>> 7'sh7f); end always @(posedge clk) begin if (W0150[32-:32] != 32'hffffffff) if (check) $stop; if (((((W0021)==97'h0 ? 97'sh0:((97'sh1ffffffffffffffffffffffff <<< W0152) % W0021)))==97'h0 ? 97'sh0:(((97'sh000000001b3ba0b19e4f928ee)==97'h0 ? 97'sh0:((((- 97'sh1ffffffffffffffffffffffff))==97'h0 ? 97'sh0:((~ 97'sh0) % (- 97'sh1ffffffffffffffffffffffff))) % 97'sh000000001b3ba0b19e4f928ee)) / ((W0021)==97'h0 ? 97'sh0:((97'sh1ffffffffffffffffffffffff <<< W0152) % W0021)))) != 97'sh0) if (check) $stop; end //============================================================ always @(check or W0102 or W0046) begin : Block69 W0157 = 120'h2ad85ce1a84cdbc0e0e871ffffffff; W0156 = 103'h0; W0155 = W0156[102:58]; W0154 = 128'sh87b2a85700000001ffffffffffffffff; W0153 = W0046; if (W0153 != 1'h1) if (check) $stop; if ((W0154[W0155[44:39]+:63] >> ((W0102 & 1'h0) ? {(~ 1'h1),W0157[119:114]} : ((7'h0 << 4'hf) << 4'h5))) != 63'h7fffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0158 <= 107'sh001a90c7bc2ffffffff61887cef; end always @(posedge clk) begin if (W0158[106:1] != 106'h000d4863de17fffffffb0c43e77) if (check) $stop; if ((((((118'sh3fffffffffffffffffffffffffffff)==118'h0 ? 118'sh0:(118'sh3fffffffffffffffffffff8fca9cb5 / 118'sh3fffffffffffffffffffffffffffff)) >>> ((8'sh01)==8'h0 ? 8'sh0:(8'shff / 8'sh01))) <<< W0152) <<< 8'sh0) != 118'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (W0064 != 63'sh7fffffffffffffff) if (check) $stop; if (11'sh0 != 11'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0161 <= (! 73'sh0); end always @(posedge clk) begin W0160 <= 126'sh0d26cc57ffffffffffffffff00000001; end always @(posedge clk) begin W0159 <= W0160[125:125]; end always @(posedge clk) begin if (((((1'h1 >> 1'h0) >> (120'shffffffffffffffffffffffffffffff || 100'hfffffffffffffffffffffffff)) << W0159) < 1'h0) != 1'h0) if (check) $stop; if ((W0161 & 1'h1) != 1'h1) if (check) $stop; end //============================================================ always @(check or W0102 or W0089) begin : Block73 end always @(posedge clk) begin : Block73Check if (W0089 != 96'sh0) if (check) $stop; if (W0102 != 1'h0) if (check) $stop; end //============================================================ always @(check or W0101 or W0042) begin : Block74 W0165 = ((121'sh0)==121'h0 ? 121'sh0:(121'sh1ffffff00000001ffffffffffffffff % 121'sh0)); W0164 = W0042; W0163 = (W0164[105:42] + W0165[120:57]); W0162 = (126'sh0 - 126'sh2b87852fffffffff98c1a496e734ef66); end always @(posedge clk) begin : Block74Check if ((((W0162)==126'h0 ? 126'sh0:(((((126'sh1e2a40e8e4cd5afbff8ce12e00000000)==126'h0 ? 126'sh0:(126'sh0 % 126'sh1e2a40e8e4cd5afbff8ce12e00000000)))==126'h0 ? 126'sh0:((126'sh0 <<< 8'sh0) / ((126'sh1e2a40e8e4cd5afbff8ce12e00000000)==126'h0 ? 126'sh0:(126'sh0 % 126'sh1e2a40e8e4cd5afbff8ce12e00000000)))) / W0162)) >>> W0101) != 126'sh0) if (check) $stop; if (W0163 != 64'hffffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0171 <= 8'sh2c; end always @(posedge clk) begin W0170 <= (75'sh0000000000000000001 <<< W0171); end always @(posedge clk) begin W0169 <= W0170; end always @(posedge clk) begin W0168 <= 13'sh0; end always @(posedge clk) begin W0167 <= (W0168 >>> (~ 5'sh1f)); end always @(posedge clk) begin W0166 <= 101'h00ce5c6a8d8c0e8e38ffffffff; end always @(posedge clk) begin if (((({38'h0,11'sh001} & W0166[100:52]) << (((7'h73)==7'h0 ? 7'h0:(7'h07 % 7'h73)) << W0002)) << W0167[12:6]) != 49'h0) if (check) $stop; if (W0169[74:74] != 1'h0) if (check) $stop; end //============================================================ always @(check or W0102 or W0032) begin : Block76 W0174 = (14'sh0 + 14'sh3fff); W0173 = ((14'sh3fff & 14'sh0001) + W0174); W0172 = (87'sh7fffff0000000000000000 ^ 87'sh000001ffffffffd20026d0); end always @(posedge clk) begin : Block76Check if (((W0032 || W0172) <= W0102) != 1'h0) if (check) $stop; if (W0173 != 14'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0175 <= (($signed((108'sh000000000000000000000000001 >>> 8'sh01)))==108'h0 ? 108'sh0:(W0054 / $signed((108'sh000000000000000000000000001 >>> 8'sh01)))); end always @(posedge clk) begin if ((W0102 ? W0044 : 31'sh0) != 31'sh0) if (check) $stop; if (W0175[107:107] != 1'h0) if (check) $stop; end //============================================================ always @(check) begin : Block78 W0179 = 83'sh5a3feffffffffa74f99bd; W0178 = W0179; W0177 = ((39'sh76ffffffff)==39'h0 ? 39'sh0:(39'sh7f4d68efac / 39'sh76ffffffff)); W0176 = ((3'h7 << {1'h0,2'h1}) << W0177[38:36]); if (W0176[1-:2] != 2'h2) if (check) $stop; if (W0178[82:82] != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0180 <= 108'shfffffffffffffffffffffffffff; end always @(posedge clk) begin if (99'sh30000000100000001ffffffff != 99'sh30000000100000001ffffffff) if (check) $stop; if (W0180[107:107] != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0181 <= (67'sh7ffffffffffffffff >>> (8'shff <<< 4'shf)); end always @(posedge clk) begin if (((W0181[66:66])==1'h0 ? 1'h0:(W0102 % W0181[66:66])) != 1'h0) if (check) $stop; if (W0102 != 1'h0) if (check) $stop; end //============================================================ always @(check) begin : Block81 W0184 = 117'h1fffffffffffffffffffffffffffff; W0183 = (((117'h000000000000000000000000000001)==117'h0 ? 117'h0:(117'h0 / 117'h000000000000000000000000000001)) & W0184); W0182 = W0183[116:22]; if (W0182[6'h01] != 1'h0) if (check) $stop; if ((~ (((((85'sh0 >>> 8'sh06))==85'h0 ? 85'sh0:(85'sh000000ffffffff0c94e8cc / (85'sh0 >>> 8'sh06))))==85'h0 ? 85'sh0:((- 85'sh18109300000000ffffffff) % (((85'sh0 >>> 8'sh06))==85'h0 ? 85'sh0:(85'sh000000ffffffff0c94e8cc / (85'sh0 >>> 8'sh06)))))) != 85'sh1fffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check) begin : Block82 W0188 = 68'shf00000000ffffffff; W0187 = W0188[67:30]; W0186 = W0187[37:37]; W0185 = (({23{1'h1}})==23'h0 ? 23'h0:((~ 23'h7fffff) / {23{1'h1}})); if ((W0185[16-:1] >> W0186) != 1'h0) if (check) $stop; if (105'sh1ffffffffffffffffffffffffff != 105'sh1ffffffffffffffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0190 <= 8'shff; end always @(posedge clk) begin W0189 <= ((W0102 ? (68'sh0 <<< 8'sh01) : (68'sh0 >>> 8'shff)) >>> (((8'shff)==8'h0 ? 8'sh0:(8'shff % 8'shff)) & W0190)); end always @(posedge clk) begin if (W0189[67:8] != 60'h0) if (check) $stop; if ((W0089 >>> W0101) != 96'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block84 W0195 = 5'h01; W0194 = 43'h7ffffffffff; W0193 = 59'sh7ffffffffffffff; W0192 = (~ 128'sh0); W0191 = W0192[W0193[52-:6]+:35]; if ((W0191[25-:1] ^ W0194[(W0195 ^ ((5'h1f)==5'h0 ? 5'h0:(5'h01 / 5'h1f)))+:1]) != 1'h0) if (check) $stop; if (38'sh3fffffffff != 38'sh3fffffffff) if (check) $stop; end //============================================================ always @(check) begin : Block85 W0197 = $signed(18'h00001); W0196 = (((120'h0 << (8'h0 | 8'h0)))==120'h0 ? 120'h0:(120'h000000ec84af558ee1d84a00000000 % (120'h0 << (8'h0 | 8'h0)))); if (W0196[119:13] != 107'h0) if (check) $stop; if (W0197 != 18'sh00001) if (check) $stop; end //============================================================ always @(posedge clk) begin W0200 <= (((2'sh0 <<< 2'sh0))==2'h0 ? 2'sh0:(W0057 % (2'sh0 <<< 2'sh0))); end always @(posedge clk) begin W0199 <= W0200; end always @(posedge clk) begin W0198 <= (~ (((23'sh0 >>> 6'sh2e))==23'h0 ? 23'sh0:(((23'sh000001)==23'h0 ? 23'sh0:(23'sh0 / 23'sh000001)) / (23'sh0 >>> 6'sh2e)))); end always @(posedge clk) begin if (W0198[6-:1] != 1'h1) if (check) $stop; if (W0199 != 2'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0201 <= (29'sh0b26d9b3 >>> 6'sh01); end always @(posedge clk) begin if ($unsigned((($unsigned(2'h0) << 2'h3) << W0201[28:27])) != 2'h0) if (check) $stop; if (115'sh7ffffffffffffffffffffffffffff != 115'sh7ffffffffffffffffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0205 <= (38'sh3fb060d2b2 >>> W0050); end always @(posedge clk) begin W0204 <= {108{1'h1}}; end always @(posedge clk) begin W0203 <= (38'sh3fb79b3bee & (- 38'sh0)); end always @(posedge clk) begin W0202 <= (((((79'sh0)==79'h0 ? 79'sh0:(79'sh00000000000000000001 / 79'sh0)))==79'h0 ? 79'sh0:(79'sh376500000000ffffffff / ((79'sh0)==79'h0 ? 79'sh0:(79'sh00000000000000000001 / 79'sh0)))) & 79'sh7fffffffffffffffffff); end always @(posedge clk) begin if (W0202[W0203[37:34]+:59] != 59'h0) if (check) $stop; if ((W0204[107:1] >> W0205[37:30]) != 107'h0) if (check) $stop; end //============================================================ always @(check) begin : Block89 if (115'sh00000000000000000000000000001 != 115'sh00000000000000000000000000001) if (check) $stop; if (101'sh00000000000000000000000001 != 101'sh00000000000000000000000001) if (check) $stop; end //============================================================ always @(posedge clk) begin W0207 <= ((88'sh000001ffffffff00000000 & 88'sh3e64240000000078cc724f) <<< (8'shff <<< 4'sh0)); end always @(posedge clk) begin W0206 <= W0207; end always @(posedge clk) begin if (W0206[87:25] != 63'h0) if (check) $stop; if (((28'shbf65019)==28'h0 ? 28'sh0:(28'sh0 / 28'shbf65019)) != 28'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block91 W0209 = 2'sh1; W0208 = (((31'sh7fffffff > 31'sh7fffffff) ? W0209 : (2'sh0 | 2'sh3)) - ((2'sh0 >>> 2'sh3) <<< (2'sh3 & 2'sh3))); end always @(posedge clk) begin : Block91Check if (W0208 != 2'sh3) if (check) $stop; if (1'h1 != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0212 <= 103'sh0; end always @(posedge clk) begin W0211 <= 114'sh3ffffffffffffffffffffffffffff; end always @(posedge clk) begin W0210 <= {67{1'h0}}; end always @(posedge clk) begin if (((W0135 >>> (W0135 >>> (2'sh3 >>> 2'sh1))) >>> (((((2'sh0)==2'h0 ? 2'sh0:(2'sh3 % 2'sh0)))==2'h0 ? 2'sh0:(((2'sh0)==2'h0 ? 2'sh0:(2'sh3 % 2'sh0)) % ((2'sh0)==2'h0 ? 2'sh0:(2'sh3 % 2'sh0)))) ^ ((2'sh3)==2'h0 ? 2'sh0:(2'sh0 % 2'sh3)))) != 2'sh0) if (check) $stop; if (((W0210[W0211[113:108]+:1] | ((1'h1)==1'h0 ? 1'h0:(W0212[6'h3f] / 1'h1))) ? 106'sh3ff0000000031c912336e782a09 : (((W0042 >>> (8'sh01 >>> 4'shf)))==106'h0 ? 106'sh0:(((106'sh000000000009792207d6f11bae9 <<< 8'sh0) <<< W0171) % (W0042 >>> (8'sh01 >>> 4'shf))))) != 106'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0215 <= W0050; end always @(posedge clk) begin W0214 <= 112'shd6b4ffffffffecfde9a900000001; end always @(posedge clk) begin W0213 <= ((119'h58f8d8c7a168b300000000ffffffff)==119'h0 ? 119'h0:(119'h00000000000000000000017a9ad868 % 119'h58f8d8c7a168b300000000ffffffff)); end always @(posedge clk) begin if ((W0213[(6'h0 | W0214[111:106])+:1] >> W0215[6:6]) != 1'h0) if (check) $stop; if ((95'sh7fffffffffffffffffffffff <<< 8'sh0) != 95'sh7fffffffffffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0220 <= 85'sh0; end always @(posedge clk) begin W0219 <= 128'h0; end always @(posedge clk) begin W0218 <= ((66'sh056bab9843fc1db15 === (1'h0 ? 66'sh0 : 66'sh00000000000000001)) ? (~ ((82'h3ffffffffffffffffffff)==82'h0 ? 82'h0:(82'h0 / 82'h3ffffffffffffffffffff))) : (W0219[91-:82] << W0220[84:77])); end always @(posedge clk) begin W0217 <= 36'sh127a0ea26; end always @(posedge clk) begin W0216 <= ((((36'sh000000001)==36'h0 ? 36'sh0:(36'sh000000001 % 36'sh000000001)))==36'h0 ? 36'sh0:(W0217 / ((36'sh000000001)==36'h0 ? 36'sh0:(36'sh000000001 % 36'sh000000001)))); end always @(posedge clk) begin if ((W0216 >>> ((((7'sh0)==7'h0 ? 7'sh0:(7'sh7f % 7'sh0)) <<< ((4'shf)==4'h0 ? 4'sh0:(4'shf / 4'shf))) & W0050)) != 36'sh0) if (check) $stop; if (W0218[81:18] != 64'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (2'h0 != 2'h0) if (check) $stop; if (W0089 != 96'sh0) if (check) $stop; end //============================================================ always @(check or W0159 or W0153) begin : Block96 W0226 = 35'h0; W0225 = 95'h0; W0224 = 67'h7ffffffffffffffff; W0223 = 46'sh000000000001; W0222 = 127'sh00000000ffffffffffffffff05de7de9; W0221 = (((W0224[6'h2e+:1] ? W0225[85-:32] : W0226[3+:32]))==32'h0 ? 32'h0:(W0222[W0223[45:40]+:32] % (W0224[6'h2e+:1] ? W0225[85-:32] : W0226[3+:32]))); end always @(posedge clk) begin : Block96Check if ({64{(((W0159 === {1{1'h1}}))==1'h0 ? 1'h0:(W0153 / (W0159 === {1{1'h1}})))}} != 64'h0) if (check) $stop; if (W0221 != 32'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((95'h000000000000000000000001 << {6'h0,W0209}) != 95'h000000000000000000000002) if (check) $stop; if ((((((64'sh0)==64'h0 ? 64'sh0:(64'sh0 / 64'sh0)) >>> (~ 7'sh7f)) >>> ((~ 7'sh7f) <<< W0106)) >>> W0061) != 64'sh0) if (check) $stop; end //============================================================ always @(check or W0186 or W0171 or W0086 or W0064) begin : Block98 W0228 = (79'sh0000ffffffff00000000 >>> 8'sh0); W0227 = (W0228 >>> W0171); end always @(posedge clk) begin : Block98Check if (W0227[76-:35] != 35'h0) if (check) $stop; if (((W0086 ? W0186 : W0186) ? 63'sh0 : W0064) != 63'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0229 <= ((1'h1 ? 6'sh01 : 6'sh3f) <<< 4'sh1); end always @(posedge clk) begin if (((- ((31'sh0 && 1'h0) ? $signed(49'sh0) : ((49'sh1ffffffffffff)==49'h0 ? 49'sh0:(49'sh1ffffffffffff % 49'sh1ffffffffffff)))) <<< 7'sh7f) != 49'sh0) if (check) $stop; if ((W0229 | 6'sh0) != 6'sh02) if (check) $stop; end //============================================================ always @(posedge clk) begin W0232 <= W0003; end always @(posedge clk) begin W0231 <= W0232[119-:67]; end always @(posedge clk) begin W0230 <= 1'h1; end always @(posedge clk) begin if (29'sh00000001 != 29'sh00000001) if (check) $stop; if (((W0231[3+:64])==64'h0 ? 64'h0:((({63'h0,(| 11'sh7ff)})==64'h0 ? 64'h0:((W0230 ? ((64'hfc760b3554ab0a5a)==64'h0 ? 64'h0:(64'hffffffffffffffff % 64'hfc760b3554ab0a5a)) : W0163) % {63'h0,(| 11'sh7ff)})) / W0231[3+:64])) != 64'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0236 <= 125'sh1123198b7e03b2359874995a00000000; end always @(posedge clk) begin W0235 <= (({115'h0,1'h0})==116'h0 ? 116'h0:(W0236[124:9] / {115'h0,1'h0})); end always @(posedge clk) begin W0234 <= 55'sh000001ffffffff; end always @(posedge clk) begin W0233 <= 124'sh0000001ea881ab1000000001a85ba7a; end always @(posedge clk) begin if (((W0235)==116'h0 ? 116'h0:((W0233[123:8] >> ((((8'h0)==8'h0 ? 8'h0:(8'h0 / 8'h0)))==8'h0 ? 8'h0:(W0234[54:47] % ((8'h0)==8'h0 ? 8'h0:(8'h0 / 8'h0))))) % W0235)) != 116'h0) if (check) $stop; if ((W0086 << 1'h1) != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if ((54'sh3fffffffffffff | (((((54'sh037c369df3ee68)==54'h0 ? 54'sh0:(54'sh3ae196a0f8ef2e % 54'sh037c369df3ee68)))==54'h0 ? 54'sh0:((1'h1 ? 54'sh0 : 54'sh00000000000001) % ((54'sh037c369df3ee68)==54'h0 ? 54'sh0:(54'sh3ae196a0f8ef2e % 54'sh037c369df3ee68)))) <<< (W0061 >>> W0106))) != 54'sh3fffffffffffff) if (check) $stop; if (W0062 != 95'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0237 <= 99'sh04d0f023900000000ffffffff; end always @(posedge clk) begin if (96'sh0 != 96'sh0) if (check) $stop; if ((((((W0237[1'h0+:95])==95'h0 ? 95'h0:(((95'h7fffffffffffffffffffffff)==95'h0 ? 95'h0:(95'h7fffffffffffffffffffffff % 95'h7fffffffffffffffffffffff)) % W0237[1'h0+:95])) ^ 95'h00000000f764bf15b0ba3d42))==95'h0 ? 95'h0:(95'h7fffffffffffffffffffffff % (((W0237[1'h0+:95])==95'h0 ? 95'h0:(((95'h7fffffffffffffffffffffff)==95'h0 ? 95'h0:(95'h7fffffffffffffffffffffff % 95'h7fffffffffffffffffffffff)) % W0237[1'h0+:95])) ^ 95'h00000000f764bf15b0ba3d42))) != 95'h00000000be009a70f1ba2ef5) if (check) $stop; end //============================================================ always @(check or W0044) begin : Block104 W0239 = ((1'h1)==1'h0 ? 1'h0:(1'h1 / 1'h1)); W0238 = 67'sh00000000000000001; if ($unsigned((((W0238[48-:1])==1'h0 ? 1'h0:((^~ 1'h0) / W0238[48-:1])) << W0239)) != 1'h0) if (check) $stop; if (W0044 != 31'sh7fffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if (55'h7fffff00000000 != 55'h7fffff00000000) if (check) $stop; if ({81{1'h1}} != 81'h1ffffffffffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if (W0064 != 63'sh7fffffffffffffff) if (check) $stop; if (52'sh0 != 52'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0244 <= (27'sh0 >>> 6'sh3f); end always @(posedge clk) begin W0243 <= 3'sh3; end always @(posedge clk) begin W0242 <= 5'sh10; end always @(posedge clk) begin W0241 <= 5'sh1f; end always @(posedge clk) begin W0240 <= 5'sh0; end always @(posedge clk) begin if (((((W0241 <<< (4'shf >>> 3'sh1)) | (- W0242)))==5'h0 ? 5'sh0:(((W0240 >>> W0041) >>> W0106) / ((W0241 <<< (4'shf >>> 3'sh1)) | (- W0242)))) != 5'sh0) if (check) $stop; if ((W0243[(1'h0 ? {1{1'h0}} : (1'h1 | 1'h1))] << ({6'h0,4'sh1} !== W0244[11-:10])) != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0252 <= 95'h0; end always @(posedge clk) begin W0251 <= W0252[93-:93]; end always @(posedge clk) begin W0250 <= W0251; end always @(posedge clk) begin W0249 <= 7'sh0; end always @(posedge clk) begin W0248 <= 127'h0; end always @(posedge clk) begin W0247 <= 94'h0; end always @(posedge clk) begin W0246 <= (~ W0247); end always @(posedge clk) begin W0245 <= W0246[93:65]; end always @(posedge clk) begin if (W0245[28:28] != 1'h1) if (check) $stop; if (((W0250[92:61])==32'h0 ? 32'h0:((W0248[93-:32] << W0249[5-:6]) / W0250[92:61])) != 32'h0) if (check) $stop; end //============================================================ always @(check or W0086 or W0103) begin : Block109 W0256 = 51'h7ffffffffffff; W0255 = (81'sh000018a995eff00000000 <<< 8'sh32); W0254 = 85'sh1e0ff3ffffffffffffffff; W0253 = W0254[84:18]; if ((((({1{W0256[5'h0+:2]}})==2'h0 ? 2'h0:(W0255[80:79] / {1{W0256[5'h0+:2]}})))==2'h0 ? 2'h0:(W0253[51-:2] % (({1{W0256[5'h0+:2]}})==2'h0 ? 2'h0:(W0255[80:79] / {1{W0256[5'h0+:2]}})))) != 2'h0) if (check) $stop; if ((W0086 << W0103) != 1'h1) if (check) $stop; end //============================================================ always @(check or W0230 or W0103) begin : Block110 W0261 = 65'sh0; W0260 = 127'sh7fffffffdc26eb98e2a835027aaef3e4; W0259 = W0260[126:12]; W0258 = W0259[114:16]; W0257 = ((W0103)==1'h0 ? 1'h0:(W0230 / W0103)); if (W0257 != 1'h0) if (check) $stop; if ((W0258[94-:95] << W0261[64:57]) != 95'h7ffffffdc26eb98e2a835027) if (check) $stop; end //============================================================ always @(check or W0106) begin : Block111 W0263 = ((86'sh3fffffffffffffffffffff)==86'h0 ? 86'sh0:((86'sh2091caffffffffa1f9988f >>> 8'sh01) / 86'sh3fffffffffffffffffffff)); W0262 = 8'sh01; if (((95'sh0000000000000001ffffffff | 95'sh0) >>> $signed((W0262 >>> W0106))) != 95'sh0000000000000001ffffffff) if (check) $stop; if (((86'sh3a2187ffffffffffffffff)==86'h0 ? 86'sh0:(W0263 / 86'sh3a2187ffffffffffffffff)) != 86'sh3ffffffffffffffffffffe) if (check) $stop; end //============================================================ always @(posedge clk) begin W0265 <= (1'h1 ? 31'sh7fffffff : 31'sh78a01e1c); end always @(posedge clk) begin W0264 <= (8'shff + 8'sh0); end always @(posedge clk) begin if (((((90'sh0)==90'h0 ? 90'sh0:((90'sh0 | 90'sh1eadb0d0000000000000000) / 90'sh0)) >>> W0152) >>> (((((8'sh0 >>> 4'shf))==8'h0 ? 8'sh0:(W0190 / (8'sh0 >>> 4'shf))))==8'h0 ? 8'sh0:(W0264 % (((8'sh0 >>> 4'shf))==8'h0 ? 8'sh0:(W0190 / (8'sh0 >>> 4'shf)))))) != 90'sh0) if (check) $stop; if ((((((1'h1)==1'h0 ? 1'h0:((2'h3 || 103'h0) % 1'h1)))==1'h0 ? 1'h0:(W0265[4-:1] % ((1'h1)==1'h0 ? 1'h0:((2'h3 || 103'h0) % 1'h1)))) >> W0086) != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0266 <= 45'sh16d2ffffffff; end always @(posedge clk) begin if (((((W0266[44:44] ? (99'sh0 <<< 8'sh01) : (99'sh1c923146300000000ffffffff <<< 8'shff)) >>> 8'sh08))==99'h0 ? 99'sh0:(((((99'sh7457b32a630fc8a7b00000000 & 99'sh7ffffffffffffffffffffffff))==99'h0 ? 99'sh0:(((99'sh2f9b3e0760000000000000000)==99'h0 ? 99'sh0:(99'sh0 / 99'sh2f9b3e0760000000000000000)) % (99'sh7457b32a630fc8a7b00000000 & 99'sh7ffffffffffffffffffffffff))) <<< W0190) % ((W0266[44:44] ? (99'sh0 <<< 8'sh01) : (99'sh1c923146300000000ffffffff <<< 8'shff)) >>> 8'sh08))) != 99'sh0) if (check) $stop; if (W0257 != 1'h0) if (check) $stop; end //============================================================ always @(check or W0003 or W0217 or W0200) begin : Block114 W0268 = 36'shfffffffff; W0267 = (W0003 >>> ((8'sh61)==8'h0 ? 8'sh0:(8'shc9 % 8'sh61))); if ((W0267[85-:31] || W0200) != 1'h1) if (check) $stop; if ((- ((W0217)==36'h0 ? 36'sh0:(((W0268)==36'h0 ? 36'sh0:((36'sh0 >>> 7'sh0) % W0268)) % W0217))) != 36'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0273 <= 13'sh0; end always @(posedge clk) begin W0272 <= 126'h0; end always @(posedge clk) begin W0271 <= {29'h0,(W0229 >>> W0106)}; end always @(posedge clk) begin W0270 <= {26'h0,91'h0}; end always @(posedge clk) begin W0269 <= (95'h0 * 95'h000000000000000000000001); end always @(posedge clk) begin if (((W0269 ^ W0270[116:22]) >> 8'h0) != 95'h0) if (check) $stop; if (W0271[(((W0159 ? W0273[12:8] : ((5'h1f)==5'h0 ? 5'h0:(5'h01 / 5'h1f))))==5'h0 ? 5'h0:((5'h14 & W0272[125:121]) % (W0159 ? W0273[12:8] : ((5'h1f)==5'h0 ? 5'h0:(5'h01 / 5'h1f)))))+:1] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin if (45'sh1fdfc108b63f != 45'sh1fdfc108b63f) if (check) $stop; if (63'sh0 != 63'sh0) if (check) $stop; end //============================================================ always @(check or W0089 or W0056) begin : Block117 if (W0056 != 2'sh0) if (check) $stop; if (((96'shffffffffffffffffffffffff)==96'h0 ? 96'sh0:(W0089 % 96'shffffffffffffffffffffffff)) != 96'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0278 <= 96'h0; end always @(posedge clk) begin W0277 <= W0278[95:41]; end always @(posedge clk) begin W0276 <= 93'sh0; end always @(posedge clk) begin W0275 <= 43'h7ffffffffff; end always @(posedge clk) begin W0274 <= (((28'shfffffff <<< 6'sh3f) >>> (- 6'sh1c)) * (- (28'shfffffff >>> 6'sh0))); end always @(posedge clk) begin if (W0274 != 28'sh0) if (check) $stop; if ((W0275[42:29] & ((((1'h0 ? 14'h3fff : 14'h0))==14'h0 ? 14'h0:(W0276[92:79] % (1'h0 ? 14'h3fff : 14'h0))) >> W0277[54:50])) != 14'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0280 <= 79'sh7fff87182181ffffffff; end always @(posedge clk) begin W0279 <= W0029; end always @(posedge clk) begin if (W0279[W0280[78:74]] != 1'h0) if (check) $stop; if ((W0044 >>> W0045) != 31'sh7fffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0281 <= (((~ (127'h0 << 8'hd7)))==127'h0 ? 127'h0:(127'h0 % (~ (127'h0 << 8'hd7)))); end always @(posedge clk) begin if (W0281[126:0] != 127'h0) if (check) $stop; if (W0103 != 1'h0) if (check) $stop; end //============================================================ always @(check or W0152) begin : Block121 W0282 = 78'sh00000000000000000001; end always @(posedge clk) begin : Block121Check if ($unsigned((((W0282)==78'h0 ? 78'sh0:((78'sh00000000000000000001 >>> 8'sh0) / W0282)) >>> W0152)) != 78'h00000000000000000001) if (check) $stop; if (96'sh0 != 96'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0283 <= 55'h4676b5c84a0634; end always @(posedge clk) begin if (W0283[54:53] != 2'h2) if (check) $stop; if (((((^ 1'h1) ? ((95'sh0)==95'h0 ? 95'sh0:(95'sh7fffffffffffffffffffffff % 95'sh0)) : W0062) >>> 8'sh0) <<< 8'sh01) != 95'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block123 W0288 = (114'sh0 >>> 8'shff); W0287 = W0288[113:11]; W0286 = 101'h0; W0285 = 128'sh0; W0284 = 87'h7fffffffffffffffffffff; end always @(posedge clk) begin : Block123Check if ((~ ((W0284[6'h27+:1] ? W0285[106-:63] : W0286[100:38]) === 63'h65a29186ffffffff)) != 1'h1) if (check) $stop; if ($signed(W0287[102:71]) != 32'sh0) if (check) $stop; end //============================================================ always @(check) begin : Block124 W0290 = ((128'sh62aa887fd0add0ee000000009f6f690b)==128'h0 ? 128'sh0:(128'sh00000000000000000000000000000001 / 128'sh62aa887fd0add0ee000000009f6f690b)); W0289 = (W0290[59-:48] * (((48'hffffffffffff >> 7'h77))==48'h0 ? 48'h0:((~ 48'h0) % (48'hffffffffffff >> 7'h77)))); if (20'sh0 != 20'sh0) if (check) $stop; if (W0289 != 48'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0292 <= 31'sh7fffffff; end always @(posedge clk) begin W0291 <= 35'sh0; end always @(posedge clk) begin if ((~ W0291[W0292[11-:5]+:1]) != 1'h1) if (check) $stop; if ((W0221 >> $unsigned((~ W0229))) != 32'h0) if (check) $stop; end //============================================================ always @(check or W0135) begin : Block126 W0294 = 128'hffffffffffffffffffffffffffffffff; W0293 = {23'h0,(~ W0294[5'h18+:68])}; if (W0293[17-:1] != 1'h0) if (check) $stop; if (W0135 != 2'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0295 <= (~ 59'h63497d1ffffffff); end always @(posedge clk) begin if ($unsigned(W0103) != 1'h0) if (check) $stop; if ((W0103 ? ((({23'h0,8'shff} << 6'h3f))==31'h0 ? 31'h0:(W0295[47-:31] % ({23'h0,8'shff} << 6'h3f))) : (- ((1'h1 ? 31'h7fffffff : 31'h0) >> 6'h0))) != 31'h00000001) if (check) $stop; end //============================================================ always @(check or W0127 or W0061) begin : Block128 W0300 = ((35'h7ffffffff)==35'h0 ? 35'h0:(35'h7ffffffff % 35'h7ffffffff)); W0299 = 124'h6cfbaebfc86e1c0a97f60e4af292b85; W0298 = 4'sh0; W0297 = (W0061 >>> W0298); W0296 = ((((95'sh000000002bed12745a7ae0bf === 95'sh7fffffffffffffffffffffff))==1'h0 ? 1'h0:((96'sh0 == 96'sh0) % (95'sh000000002bed12745a7ae0bf === 95'sh7fffffffffffffffffffffff))) ? ((W0127)==71'h0 ? 71'h0:(W0299[123:53] / W0127)) : W0127); end always @(posedge clk) begin : Block128Check if (W0296[W0297[1+:6]+:1] != 1'h0) if (check) $stop; if ((! ((37'sh0 == (37'sh0000000001 >>> 7'sh0)) << W0300[16-:1])) != 1'h1) if (check) $stop; end //============================================================ always @(check or W0101 or W0044 or W0179) begin : Block129 if ((W0179 >>> W0101) != 83'sh7ffffffffffffffffffff) if (check) $stop; if ((1'h0 ? (W0044 >>> 6'sh0) : (W0044 >>> 6'sh01)) != 31'sh7fffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin W0304 <= ((127'sh00000000000000000000000000000001 >>> 8'shff) - 127'sh00000000000000000000000000000001); end always @(posedge clk) begin W0303 <= 111'sh6483041c277c0000000098007584; end always @(posedge clk) begin W0302 <= ((W0303[12-:13])==13'h0 ? 13'h0:((13'h0e56 << 5'h01) / W0303[12-:13])); end always @(posedge clk) begin W0301 <= W0304; end always @(posedge clk) begin if (W0301[W0302[12:7]] != 1'h1) if (check) $stop; if (2'h1 != 2'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin if (95'h0 != 95'h0) if (check) $stop; if (((- ((1'h0 ? 69'sh1f000000005f6fd955 : 69'sh0) <<< W0101)) & (((69'sh1fffffffff6a435651 >>> W0262))==69'h0 ? 69'sh0:(((69'sh1fffffffffffffffff >>> 8'sh01) >>> (8'sh01 >>> 4'sh0)) % (69'sh1fffffffff6a435651 >>> W0262)))) != 69'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0306 <= 79'sh53bf3d286da2ffffffff; end always @(posedge clk) begin W0305 <= (79'sh0000eac0ae48ceb2ae66 | (W0306 & ((79'sh0)==79'h0 ? 79'sh0:(79'sh150f00000000ffffffff / 79'sh0)))); end always @(posedge clk) begin if (W0305[$unsigned(6'sh0)] != 1'h0) if (check) $stop; if ((W0130 >>> 7'sh0) != 64'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0307 <= ((W0046)==1'h0 ? 1'h0:(W0102 % W0046)); end always @(posedge clk) begin if (W0035 != 32'sh0) if (check) $stop; if (W0307 != 1'h0) if (check) $stop; end //============================================================ always @(check or W0221 or W0061) begin : Block134 W0308 = (((~ ((55'sh0)==55'h0 ? 55'sh0:(55'sh00000000000001 / 55'sh0))))==55'h0 ? 55'sh0:(((55'sh0 >>> 7'sh0) <<< W0061) / (~ ((55'sh0)==55'h0 ? 55'sh0:(55'sh00000000000001 / 55'sh0))))); end always @(posedge clk) begin : Block134Check if ((~ W0221) != 32'hffffffff) if (check) $stop; if (W0308[54:54] != 1'h0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0309 <= 58'sh3ffffffffffffff; end always @(posedge clk) begin if ((W0131 >>> W0061) != 64'sh0) if (check) $stop; if (((W0117)==58'h0 ? 58'sh0:(W0309 / W0117)) != 58'sh0) if (check) $stop; end //============================================================ always @(check or W0095) begin : Block136 W0310 = ((((125'sh1fffffffffffffff94a937e4b63821d3 & 125'sh0) <<< ((8'sh01)==8'h0 ? 8'sh0:(8'sh0 / 8'sh01))))==125'h0 ? 125'sh0:(125'sh1fffffff000000012f126cb600000000 % ((125'sh1fffffffffffffff94a937e4b63821d3 & 125'sh0) <<< ((8'sh01)==8'h0 ? 8'sh0:(8'sh0 / 8'sh01))))); if (W0095 != 20'sh0) if (check) $stop; if (W0310[124:34] != 91'h0) if (check) $stop; end //============================================================ always @(check or W0064) begin : Block137 W0312 = (125'h1fffffffffffffffffffffffffffffff * 125'h014067caffffffffa912cb6200000001); W0311 = (W0312 << 8'h0); if (W0311[124:34] != 91'h7afe60d4000000015bb4d27) if (check) $stop; if (W0064 != 63'sh7fffffffffffffff) if (check) $stop; end //============================================================ always @(check or W0089 or W0037) begin : Block138 if (W0037 != 6'sh0) if (check) $stop; if (W0089 != 96'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0313 <= ((1'h1 ? (1'h0 ? 19'sh2e239 : 19'sh0) : ((19'sh0)==19'h0 ? 19'sh0:(19'sh667f0 / 19'sh0))) - (19'sh0b0f8 <<< W0037)); end always @(posedge clk) begin if (W0063 != 95'sh0) if (check) $stop; if (W0313 != 19'sh74f08) if (check) $stop; end //============================================================ always @(posedge clk) begin W0315 <= $signed(((87'sh7fffff000000011765b281 >>> 8'sh0) & (87'sh00000000000001eb9be7ba <<< 8'sh0))); end always @(posedge clk) begin W0314 <= (((105'sh1ff00000000ef0d900400000000)==105'h0 ? 105'sh0:((105'sh1ff00000000b2bf7412a1ac1787 >>> 8'sh0) % 105'sh1ff00000000ef0d900400000000)) * ((105'sh1ffffffffffffffffffffffffff <<< 8'shff) >>> (8'shff <<< 4'sh0))); end always @(posedge clk) begin if (W0314 != 105'sh0) if (check) $stop; if (W0315[86:86] != 1'h0) if (check) $stop; end //============================================================ always @(check or W0036 or W0114) begin : Block141 W0316 = (((~ 23'sh0) >>> W0036) <<< ((((6'sh01)==6'h0 ? 6'sh0:(6'sh3f % 6'sh01)))==6'h0 ? 6'sh0:(W0036 / ((6'sh01)==6'h0 ? 6'sh0:(6'sh3f % 6'sh01))))); if (W0316 != 23'sh7fffff) if (check) $stop; if (W0114 != 117'sh0058950000000000000001e74304cc) if (check) $stop; end //============================================================ always @(check) begin : Block142 if (31'sh7fffffff != 31'sh7fffffff) if (check) $stop; if (48'shffffffffffff != 48'shffffffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if (W0239 != 1'h1) if (check) $stop; if (83'h7ffffffffffffffffffff != 83'h7ffffffffffffffffffff) if (check) $stop; end //============================================================ always @(check or W0057 or W0221) begin : Block144 W0319 = 88'sh0; W0318 = W0319; W0317 = (128'hffffffffffffffffffffffffffffffff ^ 128'h0); end always @(posedge clk) begin : Block144Check if (((W0221)==32'h0 ? 32'h0:((W0317[98-:32] << W0318[87:82]) % W0221)) != 32'h0) if (check) $stop; if (W0057 != 2'sh0) if (check) $stop; end //============================================================ always @(posedge clk) begin W0320 <= 74'sh3ffffffffffffffffff; end always @(posedge clk) begin if (((56'sh0)==56'h0 ? 56'sh0:(56'sh324538ffffffff / 56'sh0)) != 56'sh0) if (check) $stop; if (W0320[73:73] != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0322 <= 116'sh000004a144132ffffffffffffffff; end always @(posedge clk) begin W0321 <= (((W0322[115:19])==97'h0 ? 97'h0:(97'h1ffffffffffffffffffffffff / W0322[115:19])) ^ {66'h0,31'sh0}); end always @(posedge clk) begin if ($unsigned((((21'sh0 | 21'sh000001) <<< W0037) <<< 6'sh3f)) != 21'h0) if (check) $stop; if (W0321[96:54] != 43'h0) if (check) $stop; end //============================================================ always @(check or W0130) begin : Block147 if (69'sh000000000000000001 != 69'sh000000000000000001) if (check) $stop; if (((W0130)==64'h0 ? 64'sh0:(64'sh7e2aefddd3bac6f5 / W0130)) != 64'sh0) if (check) $stop; end //============================================================ always @(check or W0110) begin : Block148 if ((W0110 >>> 8'sh0) != 67'sh0) if (check) $stop; if (32'shffffffff != 32'shffffffff) if (check) $stop; end //============================================================ always @(posedge clk) begin if (2'sh0 != 2'sh0) if (check) $stop; if (W0086 != 1'h1) if (check) $stop; end //============================================================ always @(posedge clk) begin W0325 <= 86'h0; end always @(posedge clk) begin W0324 <= 23'sh283d11; end always @(posedge clk) begin W0323 <= (W0324[4'h0] ? (20'h0 << 6'h0) : {15'h0,5'h0}); end always @(posedge clk) begin if ((W0323[19:19] && (W0044 >>> W0036)) != 1'h0) if (check) $stop; if (W0325 != 86'h0) if (check) $stop; end reg done; initial done=1'b0; reg ddone; initial ddone=1'b0; always @(posedge clk) begin if (check) begin done <= 1'b1; end if (done && !ddone) begin ddone <= 1'b1; $write("*-* All Finished *-*\n"); end end parameter [31:0] CYCLES /*verilator public*/ = 179; endmodule verilator-3.874/test_verilated/Makefile0000664000177100017500000000627312111011552020176 0ustar wsnyderwsnyder#***************************************************************************** # # DESCRIPTION: Verilator Example: Makefile for inside source directory # # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # # Copyright 2003 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. # #****************************************************************************/ default: test # This must point to the root of the VERILATOR kit VERILATOR_ROOT := $(shell pwd)/.. export VERILATOR_ROOT VERILATOR_NCVERILOG ?= ncverilog VERILATOR_VCS ?= vcs # Pick up PERL and other variable settings include $(VERILATOR_ROOT)/include/verilated.mk VERILATOR_SW += ifeq ($(VERILATOR_NO_DEBUG),) VERILATOR_SW += --debug --no-dump-tree endif PERL_PACKAGES_OK := $(shell $(PERL) -e 'eval "use Bit::Vector; print 1;";') ###################################################################### default: test ifneq ($(PERL_PACKAGES_OK),1) test:: nopackages else ifneq ($(VCS_HOME),) test:: vcs else test:: novcs endif ifneq ($(NC_ROOT),) test:: nc else test:: nonc endif test:: vlt endif vgen.v: ./vgen.pl $(PERL) vgen.pl $(VGEN_FLAGS) # We ulimit cpu time, as some cases make gcc 3.3.4 hang random: -rm -rf obj_dir/Vgen* obj_dir/simx $(PERL) vgen.pl --seed=0 --numops=1000 --depth=4 --raise=4 VERILATOR_NO_DEBUG=1 CPPFLAGS_ADD=-Wno-error VCS_HOME= NC_ROOT= bash -c "ulimit -t 120; $(MAKE) test" # $(MAKE) nc random_forever: while ( $(MAKE) random ) ; do \ echo ; \ done ###################################################################### nopackages: @echo "No perl Bit::Vector package installed." @echo "Not running regression test." novcs: @echo "No VCS simulator installed." @echo "Not running VCS regression test." vcs: vcs_passed.log simv: vgen.v sim_main.v vcs +cli -I +define+vcs+1 +v2k -q vgen.v sim_main.v vcs_passed.log : simv -rm -f vcs_passed.log ./simv -l sim.log grep -q Finished sim.log && grep Finished sim.log > vcs_passed.log ###################################################################### nonc: @echo "No NC-Verilog simulator installed." @echo "Not running NC-Verilog regression test." nc: nc_passed.log nc_passed.log: vgen.v sim_main.v $(VERILATOR_NCVERILOG) +licqueue +define+ncverilog=1 -q vgen.v sim_main.v -rm -f nc_passed.log grep -q Finished ncverilog.log && grep Finished ncverilog.log > nc_passed.log ###################################################################### vlt: prep compile vlt_passed.log prep: vgen.v $(VERILATOR_ROOT)/bin/verilator $(PERL) $(VERILATOR_ROOT)/bin/verilator $(VERILATOR_SW) --cc vgen.v compile: cd obj_dir ; $(MAKE) -j 3 -f ../Makefile_obj vlt_passed.log vlt_run: prep compile -rm -f vlt_passed.log sim.log obj_dir/simx | tee sim.log grep -q Finished sim.log && grep Finished sim.log > vlt_passed.log ###################################################################### maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_dir *.log *.dmp *.vpd simv* *.key vgen.v csrc INCA_libs verilator-3.874/Changes0000664000177100017500000023061012534631114015020 0ustar wsnyderwsnyderRevision history for Verilator The contributors that suggested a given feature are shown in []. [by ...] indicates the contributor was also the author of the fix; Thanks! * Verilator 3.873 2015-06-06 *** Add pkg-config .pc file, bug919. [Stefan Wallentowitz] **** Fix installing missing manpages, bug908. [Ahmed El-Mahmoudy] **** Fix sign extension in large localparams, bug910. [Mike Thyer] **** Fix core dump in sync-async warnings, bug911. [Sebastian Dressler] **** Fix truncation warning with -pins-bv, bug912. [Alfonso Martinez] **** Fix Cygwin uint32 compile, bug914. [Matthew Barr] **** Fix preprocessing stringified newline escapes, bug915. [Anton Rapp] **** Fix part-select in constant function, bug916. [Andrew Bardsley] **** Fix width extension on mis-width ports, bug918. [Patrick Maupin] **** Fix width propagation on sized casts, bug925. [Jonathon Donaldson] **** Fix MSVC++ compiler error, bug927. [Hans Tichelaar] * Verilator 3.872 2015-04-05 *** Add VerilatedVcdFile to allow real-time waveforms, bug890. [HyungKi Jeong] *** Add --clk and related optimizations, msg1533. [Jie Xu] *** Fix order of C style arrays. [Duraid Madina] **** Add --dump-treei-, bug894. [Jie Xu] **** Fix comma-instantiations with parameters, bug884. [Franck Jullien] **** Fix SystemC arrayed bit vectors, bug886. [David Poole] **** Fix compile error on MinGW, bug887. [HyungKi Jeong] * Verilator 3.870 2015-02-12 **** Suppress COMBDLY when inside always_latch, bug864. [Iztok Jeras] **** Support cast operator with expression size, bug865. [Iztok Jeras] **** Add warning on slice selection out of bounds, bug875. [Cong Van Nguyen]. **** Fix member select error broke in 3.868, bug867. [Iztok Jeras] **** Fix $sccanf from string, bug866. [David Pierce] **** Fix VM_PARALLEL_BUILDS broke in 3.868, bug870. [Hiroki Honda] **** Fix non-ANSI modport instantiations, bug868. [Kevin Thompson] **** Fix UNOPTFLAT change detect on multidim arrays, bug872. [Andrew Bardsley] **** Fix slice connections of arrays to ports, bug880. [Varun Koyyalagunta] **** Fix mis-optimizing gate assignments in unopt blocks, bug881. [Mike Thyer] **** Fix sign extension of pattern members, bug882. [Iztok Jeras] **** Fix clang compile warnings. * Verilator 3.868 2014-12-20 ** New verilator_coverage program added to replace SystemPerl's vcoverage. ** PSL support was removed, please use System Verilog assertions. ** SystemPerl mode is deprecated and now untested. *** Support enum.first/name and similar methods, bug460, bug848. *** Add 'string' printing and comparisons, bug746, bug747, etc. *** Inline C functions that are used only once, msg1525. [Jie Xu] *** Fix tracing SystemC signals with structures, bug858. [Eivind Liland] Note that SystemC traces will no longer show the signals in the wrapper, they can be seen one level further down. **** Add --stats-vars, bug851. [Jeremy Bennett] **** Fix bare generates in interfaces, bug789. [Bob Newgard] **** Fix underscores in real literals, bug863. [Jonathon Donaldson] * Verilator 3.866 2014-11-15 *** Fix +define+A+B to define A and B to match other simulators, bug847. [Adam Krolnik] *** Add optimization of wires from arrayed cells, msg1447. [Jie Xu] *** Add optimization of operators between concats, msg1447. [Jie Xu] *** Add public enums, bug833. [Jonathon Donaldson] *** Trace_off now operates on cells, bug826. [Lane Brooks] **** Fix public parameters in unused packages, bug804. [Jonathon Donaldson] **** Fix select when partially out-of-bound, bug823. [Cliffort Wolf] **** Fix generate unrolling with function call, bug830. [Steven Slatter] **** Fix cast-to-size context-determined sizing, bug828. [Geoff Barrett] **** Fix not tracing modules following primitives, bug837. [Jie Xu] **** Fix trace overflow on huge arrays, bug834. [Geoff Barrett] **** Fix quoted comment slashes in defines, bug845. [Adam Krolnik] * Verilator 3.864 2014-09-21 *** Support power operator with real, bug809. [Jonathon Donaldson] **** Improve verilator_profcfunc time attributions. [Jonathon Donaldson] **** Fix duplicate anonymous structures in $root, bug788. [Bob Newgard] **** Fix mis-optimization of bit-swap in wide signal, bug800. [Jie Xu] **** Fix error when tracing public parameters, bug722. [Jonathon Donaldson] **** Fix dpiGetContext in dotted scopes, bug740. [Geoff Barrett] **** Fix over-shift structure optimization error, bug803. [Jeff Bush] **** Fix optional parameter keyword in module #(), bug810. [Iztok Jeras] **** Fix $warning/$error multi-argument ordering, bug816. [Jonathon Donaldson] **** Fix clang warnings, bug818. [Iztok Jeras] **** Fix string formats under deep expressions, bug820. [Iztok Jeras] * Verilator 3.862 2014-06-10 *** Using command line -Wno-{WARNING} now overrides file-local lint_on. *** Add -P to suppress `line and blanks with preprocessing, bug781. [Derek Lockhart] *** Support SV 2012 package import before port list. **** Change SYMRSVDWORD to print as warning rather than error. **** Fix seg-fault with variable of parameterized interface, bug692. [Jie Xu] **** Fix false name conflict on cells in generate blocks, bug749. [Igor Lesik] **** Fix pattern assignment to basic types, bug767. [Jie Xu] **** Fix pattern assignment to conditionals, bug769. [Jie Xu] **** Fix shift corner-cases, bug765, bug766, bug768, bug772, bug774, bug776. [Clifford Wolf] **** Fix C compiler interpreting signing, bug773. [Clifford Wolf] **** Fix late constant division by zero giving X error, bug775. [Clifford Wolf] **** Fix gate primitives with arrays and non-arrayed pins. **** Fix DETECTARRAY error on packed arrays, bug770. [Jie Xu] **** Fix ENDLABEL warnings on escaped identifiers. **** Fix string corruption, bug780. [Derek Lockhart] * Verilator 3.860 2014-05-11 ** PSL is no longer supported, please use System Verilog assertions. ** Support '{} assignment pattern on arrays, bug355. ** Support streaming operators, bug649. [Glen Gibb] ** Fix expression problems with -Wno-WIDTH, bug729, bug736, bug737, bug759. Where WIDTH warnings were ignored this might result in different warning messages and results, though it should better match the spec. [Clifford Wolf] *** Add --no-trace-params. *** Add assertions on 'unique if', bug725. [Jeff Bush] *** Add PINCONNECTEMPTY warning. [Holger Waechtler] *** Support parameter arrays, bug683. [Jeremy Bennett] *** Fix begin_keywords "1800+VAMS", msg1211. **** Documentation fixes, bug723. [Glen Gibb] **** Support {} in always sensitivity lists, bug745. [Igor Lesik] **** Fix tracing of package variables and real arrays. **** Fix tracing of packed arrays without --trace-structs, bug742. [Jie Xu] **** Fix missing coverage line on else-if, bug727. [Sharad Bagri] **** Fix modport function import not-found error. **** Fix power operator calculation, bug730, bug735. [Clifford Wolf] **** Fix reporting struct members as reserved words, bug741. [Chris Randall] **** Fix change detection error on unions, bug758. [Jie Xu] **** Fix -Wno-UNOPTFLAT change detection with 64-bits, bug762. [Clifford Wolf] **** Fix shift-right optimization, bug763. [Clifford Wolf] **** Fix Mac OS-X test issues. [Holger Waechtler] **** Fix C++-2011 warnings. * Verilator 3.856 2014-03-11 *** Support case inside, bug708. [Jan Egil Ruud] *** Add parameters into trace files, bug706. [Alex Solomatnikov] **** Fix parsing "#0 'b0", bug256. **** Fix array bound checks on real variables. **** Fix --skip-identical mis-detecting on OS-X, bug707. **** Fix missing VL_SHIFTRS_IQI with WIDTH warning, bug714. [Fabrizio Ferrandi] **** Fix signed shift right optimization, bug715. [Fabrizio Ferrandi] **** Fix internal error on "input x =" syntax error, bug716. [Lane Brooks] **** Fix slice extraction from packed array, bug717. [Jan Egil Ruud] **** Fix inside statement EQWILD error, bug718. [Jan Egil Ruud] * Verilator 3.855 2014-01-18 *** Support modport import, bug696. [Jeremy Bennett] *** Add --trace-structs to show struct names, bug673. [Chris Randall] **** Fix tracing of packed structs, bug705. [Jie Xu] **** Fix --lint-only with MinGW, msg1283. [HyungKi Jeong] **** Fix some delayed assignments of typedefed unpacked arrays. **** Fix wire declarations with size and not range, bug466. [Alex Solomatnikov] **** Fix parameter pin vs. normal pin error, bug704. [Alex Solomatnikov] * Verilator 3.854 2013-11-26 *** Add UNPACKED warning to convert unpacked structs. [Jeremy Bennett] *** Add --compiler clang to work around compiler bug, bug694. [Stefan Ludwig] **** Support vpi_get of vpiSuppressVal, bug687. [Varun Koyyalagunta] **** Support vpi_get_time, bug688. [Varun Koyyalagunta] **** Fix evaluation of chained parameter functions, bug684. [Ted Campbell] **** Fix enum value extension of '1. **** Fix multiple VPI variable callbacks, bug679. [Rich Porter] **** Fix vpi_get of vpiSize, bug680. [Rich Porter] **** Fix vpi_remove_cb inside callback, bug689. [Varun Koyyalagunta] **** Fix crash with coverage of structures, bug691. [Eivind Liland] **** Fix array assignment from const var, bug693. [Jie Xu] * Verilator 3.853 2013-09-30 **** Add --no-order-clock-delay to work around bug613. [Charlie Brej] * Verilator 3.852 2013-09-29 *** Support named function and task arguments. [Chris Randall] *** Report SELRANGE warning for non-generate if, bug675. [Roland Kruse] **** Fix ordering of $fgetc, msg1229. [Frederic Requin] **** Fix --output-split-cfunc to count internal functions. [Chris Randall] **** Fix crash on 32-bit Ubuntu, bug670. [Mark Jackson Pulver] * Verilator 3.851 2013-08-15 *** Fix ordering of clock enables with delayed assigns, bug613. [Jeremy Bennett] *** Fix vpi_iterate on memory words, bug655. [Rich Porter] **** Fix final duplicate declarations when non-inlined, bug661. [Charlie Brej] **** Fix interface ports with comma lists, msg1058. [Ed Lander] **** Fix parameter real conversion from integer. **** Fix clang warnings, bug668. [Yutetsu Takatsukasa] * Verilator 3.850 2013-06-02 ** Support interfaces and modports, bug102. [Byron Bradley, Jeremy Bennett] *** Duplicate clock gate optimization on by default, bug621. **** Fix arrayed input compile error, bug645. [Krzysztof Jankowski] **** Fix GCC version runtime changes, bug651. [Jeremy Bennett] **** Fix packed array select internal error, bug652. [Krzysztof Jankowski] * Verilator 3.847 2013-05-11 *** Add ALWCOMBORDER warning. [KC Buckenmaier] *** Add --pins-sc-uint and --pins-sc-biguint, bug638. [Alex Hornung] **** Support "signal[vec]++". **** Fix simulation error when inputs and MULTIDRIVEN, bug634. [Ted Campbell] **** Fix module resolution with __, bug631. [Jason McMullan] **** Fix packed array non-zero right index select crash, bug642. [Krzysztof Jankowski] **** Fix nested union crash, bug643. [Krzysztof Jankowski] * Verilator 3.846 2013-03-09 ** IEEE 1800-2012 is now the default language. This adds 4 new keywords and updates the svdpi.h and vpi_user.h header files. *** Add --report-unoptflat, bug611. [Jeremy Bennett] *** Add duplicate clock gate optimization, msg980. [Varun Koyyalagunta] Disabled unless -OD or -O3 used, please try it as may get some significant speedups. *** Fix wrong dot resolution under inlining. [Art Stamness] **** Support pattern assignment features, bug616, bug617, bug618. [Ed Lander] **** Support bind in $unit, bug602. [Ed Lander] **** Support '() sized casts, bug628. [Ed Lander] **** Fix DETECTARRAY on packed structures, bug610. [Jeremy Bennett] **** Fix LITENDIAN on unpacked structures, bug614. [Wai Sum Mong] **** Fix 32-bit OS VPI scan issue, bug615. [Jeremy Bennett, Rich Porter] **** Fix opening a VerilatedVcdC file multiple times, msg1021. [Frederic Requin] **** Fix UNOPTFLAT circular array bounds crossing, bug630. [Jie Xu] * Verilator 3.845 2013/02/04 *** Fix nested packed arrays and struct, bug600. [Jeremy Bennett] Packed arrays are now represented as a single linear vector in Verilated models. This may affect packed arrays that are public or accessed via the VPI. *** Support wires with data types, bug608. [Ed Lander] *** Support bind, to module names only, bug602. [Ed Lander] *** Support VPI product info, warning calls, etc, bug588. [Rick Porter] *** Support $left, $right and related functions, bug448. [Iztok Jeras] *** Support inside expressions. *** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines. **** Fix pin width mismatch error, bug595. [Alex Solomatnikov] **** Fix implicit one bit parameter selection, bug603. [Jeremy Bennett] **** Fix signed/unsigned parameter misconversion, bug606. [Jeremy Bennett] **** Fix segfault on multidimensional dotted arrays, bug607. [Jie Xu] **** Fix per-bit array output connection error, bug414. [Jan Egil Ruud] **** Fix package logic var compile error. **** Fix enums with X values. * Verilator 3.844 2013/01/09 *** Support "unsigned int" DPI import functions, msg966. [Alex Lee] *** Fix package resolution of parameters, bug586. [Jeremy Bennett] **** Fix non-integer vpi_get_value, bug587. [Rich Porter] **** Fix task inlining under $display and case, bug589, bug598. [Holger Waechtler] **** Fix package import of non-localparam parameter, bug474, bug591. [Jeremy Bennett] **** Fix package import of package imports, partial bug592. [Jeremy Bennett] **** Fix package import preventing local var, bug599. [Jeremy Bennett] **** Fix array extraction of implicit vars, bug601. [Joe Eiler] * Verilator 3.843 2012/12/01 *** Add +1364-1995ext and similar language options, bug532. [Jeremy Bennett] **** Fix mis-optimized identical submodule subtract, bug581. [Charlie Brej] **** Fix crash on dotted references into dead modules, bug583. [Jeremy Bennett] **** Fix compile issues on MSVCC, bug571, bug577. [Amir Gonnen] **** Fix --debug overriding preceding --dump-treei, bug580. [Jeremy Bennett] * Verilator 3.842 2012/11/03 **** Add -x-initial-edge, bug570. [Jeremy Bennett] **** Fix parameter pins interspersed with cells broke in 3.840. [Bernard Deadman] **** Fix large shift error on large shift constants. [David Welch] **** Fix $display mangling on GCC 4.7 and speed up, msg927, bug373, bug574. [R Diez] **** Fix array of struct references giving false error, bug566. [Julius Baxter] **** Fix missing var access functions when no DPI, bug572. [Amir Gonnen] **** Fix name collision on unnamed blocks, bug567. [Chandan Egbert] **** Fix name collision on task inputs, bug569. [Chandan Egbert] * Verilator 3.841 2012/09/03 *** Add --savable to support model save/restore. [Jeremy Bennett] *** Support '{} assignment pattern on structures, part of bug355. **** Fix double-deep parameter cell WIDTHs, bug541. [Hiroki Honda] **** Fix imports under multiple instantiated cells, bug542. [Alex Solomatnikov] **** Fix defparam in generate broke in 3.840, bug543. [Alex Solomatnikov] **** Fix duplicate begin error broke in 3.840, bug548. [Alex Solomatnikov] **** Fix triangle symbol resolution error broke in 3.840, bug550. [Ted Campbell] * Verilator 3.840 2012/07/31 Beta ** Rewrote tristate handling; supports tri0, tri1, tristate bit selects, concatenates and pullup/pulldowns, bug395, bug56, bug54, bug51. [Alex Solomatnikov, Lane Brooks, et al] ** Support packed structures and unions, bug181. Note this was a major internal change that may lead to some instability. *** Support tri0 and tri1, bug462. [Alex Solomatnikov] *** Support nmos and pmos, bug488. [Alex Solomatnikov] *** Add INITIALDLY warning on initial assignments, bug478. [Alex Solomatnikov] *** Add PINMISSING and PINNOCONNECT lint checks. *** Add --converge-limit option. *** Fix generate operators not short circuiting, bug413. [by Jeremy Bennett] *** Fix parameters not supported in constant functions, bug474. [Alex Solomatnikov] **** Fix duplicate warnings/errors, bug516. [Alex Solomatnikov] **** Fix signed extending biops with WIDTH warning off, bug511. [Junji Hashimoto] **** Fix ITOD internal error on real conversions, bug491. [Alex Solomatnikov] **** Fix input and real loosing real data type, bug501. [Alex Solomatnikov] **** Fix imports causing symbol table error, bug490. [Alex Solomatnikov] **** Fix newlines in radix values, bug507. [Walter Lavino] **** Fix loop error message to report line, bug513. [Jeremy Bennett] **** Fix false UNUSED warning on file system calls. **** Fix GCC 4.7.0 compile warnings, bug530. [Jeremy Bennett] **** Fix svdpi.h compile error on Apple OS. **** Fix compile error under git submodules, bug534. [Aurelien Francillon] * Verilator 3.833 2012/04/15 *** Support += and -= in standard for loops, bug463. [Alex Solomatnikov] *** Fix processing unused parametrized modules, bug469, bug470. [Alex Solomatnikov] **** Add SELRANGE as warning instead of error, bug477. [Alex Solomatnikov] **** Add readme.pdf and internal.pdf and doxygen, bug483. [by Jeremy Bennett] **** Fix change detections on arrays, bug364. [John Stevenson, Alex Solomatnikov] **** Fix signed array warning, bug456. [Alex Solomatnikov] **** Fix genvar and begin under generate, bug461. [Alex Solomatnikov] **** Fix real constant parameter functions, bug475. [Alex Solomatnikov] **** Fix and document --gdb option, bug454. [Jeremy Bennett] **** Fix OpenSolaris compile error. [Sanjay Singh] * Verilator 3.832 2012/03/07 *** Fix memory delayed assignments from multiple clock domains. [Andrew Ling] *** Support arrayed SystemC I/O pins. [Christophe Joly] *** Report MULTIDRIVEN on memories set in multiple clock domains. *** Report ENDLABEL on mismatching end labels, bug450. [Iztok Jeras] **** Fix expansion of back-slashed escaped macros, bug441. [Alberto Del Rio] **** Fix inheriting real and signed type across untyped parameters. **** Fix core dump with over 100 deep UNOPTFLAT, bug432. [Joe Eiler] **** Fix false command not found warning in makefiles. [Ruben Diez] **** Fix hang when functions inside begin block. [David Welch] **** Fix hang on recursive substitution `defines, bug443. [Alex Solomatnikov] * Verilator 3.831 2012/01/20 ** Support SystemC 2.3.0 prerelease. This requires setting the new SYSTEMC_INCLUDE and SYSTEMC_LIBDIR variables in place of now deprecated SYSTEMC and SYSTEMC_ARCH. [Iztok Jeras] **** Suppress VARHIDDEN on dpi import arguments. [Ruben Diez] **** Support "generate for (genvar i=0; ...". [David Kravitz] **** Fix dpi exports with > 32 bit but < 64 bit args, bug423. [Chandan Egbert] **** Fix array of instantiations with sub-range output, bug414. [Jeremy Bennett] **** Fix BLKSEQ warnings on variables declared inside always. [Ruben Diez] * Verilator 3.830 2011/11/27 ** With "--language VAMS" support a touch of Verilog AMS. [Holger Waechtler] *** Add sc_bv attribute to force bit vectors, bug402. [by Stefan Wallentowitz] **** Search for user -y paths before default current directory. [Ruben Diez] **** Support constants in sensitivity lists, bug412. [Jeremy Bennett] **** Support $system. [Ruben Diez] **** Support $sscanf with %g. [Holger Waechtler] **** Indicate 'exiting due to errors' if errors, not warnings. [Ruben Diez] **** Fix bad result with if-else-return optimization, bug420. [Alex Solomatnikov] **** Fix reporting not found modules if generate-off, bug403. [Jeremy Bennett] **** Fix $display with %d following %g. [Holger Waechtler] * Verilator 3.824 2011/10/25 *** Fix "always @ (* )", bug403, bug404. [Walter Lavino] *** Add ASSIGNIN as suppressable error. [Jeremy Bennett] **** Fix 3.823 constructor core dump on Debian, bug401. [Ahmed El-Mahmoudy] * Verilator 3.823 2011/10/20 *** Support $ceil, $floor, etc. [Alex Solomatnikov] *** Add configure options for cc warnings and extended tests. [Ruben Diez] *** Add -Wall reporting ASSIGNDLY on assignment delays. [Ruben Diez] *** Fix UNDRIVEN warnings inside DPI import functions. [Ruben Diez] *** Fix --help output to go to stderr, not stdout, bug397. [Ruben Diez] **** Fix DPI import output of 64 bits, bug398. [Mike Denio] **** Fix DPI import false BLKSEQ warnings. [Alex Solomatnikov] **** Fix MSVC compile warning with trunc/round, bug394. [Amir Gonnen] **** Fix autoconf and Makefile warnings, bug396. [Ruben Diez] * Verilator 3.821 2011/09/14 **** Fix PowerPC runtime error, bug288. [Ahmed El-Mahmoudy] **** Fix internal error on integer casts, bug374. [Chandan Egbert] * Verilator 3.820 2011/07/28 ** Support 'real' numbers and related functions. *** Support 'const' variables in limited cases; similar to enums. [Alex Solomatnikov] *** Support disable for loop escapes. *** Support $fopen and I/O with integer instead of `verilator_file_descriptor. *** Support coverage in -cc and -sc output modes. [John Li] Note this requires SystemPerl 1.338 or newer. **** Fix vpi_register_cb using bad s_cb_data, bug370. [by Thomas Watts] **** Fix $display missing leading zeros in %0d, bug367. [Alex Solomatnikov] **** Use 'vluint64_t' for SystemC instead of (same sized) 'uint64' for MSVC++. * Verilator 3.813 2011/06/28 *** Support bit vectors > 64 bits wide in DPI import and exports. *** Fix out of memory on slice syntax error, bug354. [Alex Solomatnikov] **** Fix error on enum references to other packages, bug339. [Alex Solomatnikov] **** Fix DPI undeclared svBitVecVal compile error, bug346. [Chandan Egbert] **** Fix DPI bit vector compile errors, bug347, bug359. [Chandan Egbert] **** Fix CDCRSTLOGIC report showing endpoint flops without resets. **** Fix compiler warnings on SPARC, bug288. [Ahmed El-Mahmoudy] * Verilator 3.812 2011/04/06 *** Add --trace-max-width and --trace-max-array, bug319. [Alex Solomatnikov] *** Add --Wno-fatal to turn off abort on warnings. [by Stefan Wallentowitz] **** Support ${...} and $(...) env vars in .vc files. [by Stefan Wallentowitz] **** Support $bits(data_type), bug327. [Alex Solomatnikov] **** Support loop unrolling on width mismatches, bug333. [Joe Eiler] **** Support simple cast operators, bug335. [Alex Solomatnikov] **** Accelerate bit-selected inversions. **** Add error on circular parameter definitions, bug329. [Alex Solomatnikov] **** Fix concatenates and vectored bufif1, bug326. [Iztok Jeras] * Verilator 3.811 2011/02/14 **** Report errors on duplicated or empty pins, bug321. [Christian Leber] **** Report error on function call output tied to constant. [Bernard Deadman] **** Throw UNUSED/UNDRIVEN only once per net in a parametrized module. **** Fix internal error on functions called as SV tasks. [Bernard Deadman] **** Fix internal error on non-inlined inout pins. [Jeff Winston] **** Fix false BLKSEQ on non-unrolled for loop indexes. [Jeff Winston] **** Fix block comment not separating identifiers, bug311. [Gene Sullivan] **** Fix warnings to point to lowest net usage, not upper level ports. **** Fix error on constants connected to outputs, bug323. [Christian Leber] * Verilator 3.810 2011/01/03 ** Add limited support for VPI access to public signals, see docs. *** Add -F option to read relative option files, bug297. [Neil Hamilton] *** Support ++,--,+= etc as standalone statements. [Alex Solomatnikov] **** When running with VERILATOR_ROOT, optionally find binaries under bin. **** Suppress WIDTH warnings when adding/subtracting 1'b1. ** Add -Wall, -Wwarn-style, -Wno-style to enable code style warnings that have been added to this release, and disabled by default: *** With --Wall, add BLKSEQ warning on blocking assignments in seq blocks. *** With --Wall, add DECLFILENAME warning on modules not matching filename. *** With --Wall, add DEFPARAM warning on deprecated defparam statements. *** With --Wall, add IFDEPTH warning on deep if statements. *** With --Wall, add INCABSPATH warning on `include with absolute paths. *** With --Wall, add SYNCASYNCNET warning on mixed sync/async reset nets. *** With --Wall, add UNDRIVEN warning on undriven nets. *** With --Wall, add UNUSED warning on unused nets. *** The VARHIDDEN warning is now disabled by default, use -Wall to enable. * Verilator 3.805 2010/11/02 **** Add warning when directory contains spaces, msg378. [Salman Sheikh] **** Fix wrong filename on include file errors, bug289. [Brad Parker] **** Fix segfault on SystemVerilog "output wire foo=0", bug291. [Joshua Wise] **** Fix DPI export name not found, msg369. [Terry Chen] * Verilator 3.804 2010/09/20 *** Support tracing/coverage of underscore signals, bug280. [by Jason McMullan] **** Fix preprocessor `` of existing base define, bug283. [Usha Priyadharshini] **** Increase define recursions before error. [Paul Liu] **** On core dump, print debug suggestions. * Verilator 3.803 2010/07/10 *** Fix preprocessor preservation of newlines across macro substitutions. **** Fix preprocessor stringification of nested macros. **** Fix some constant parameter functions causing crash, bug253. [Nick Bowler] **** Fix do {...} while() not requiring final semicolon. * Verilator 3.802 2010/05/01 *** Support runtime access to public signal names. *** Add /*verilator public_flat_rw*/ for timing-specific public access. *** Fix word size to match uint64_t on -m64 systems, bug238. [Joe Eiler] **** Improve error handling on slices of arrays, bug226. [by Byron Bradley] **** Report errors when extra underscores used in meta-comments. **** Fix bit reductions on multi-packed dimensions, bug227. [by Byron Bradley] **** Fix removing $fscanf if assigned to unused var, bug248. [Ashutosh Das] **** Fix "make install" with configure outside srcdir. [Stefan Wallentowitz] **** Fix loop unroller out of memory; change --unroll-stmts. [Ashutosh Das] **** Fix trace files with empty modules crashing some viewers. **** Fix parsing single files > 2GB. [Jeffrey Short] **** Fix installing data files as non-executable, bug168. [by Ahmed El-Mahmoudy] * Verilator 3.801 2010/03/17 *** Support "break", "continue", "return". *** Support "`default_nettype none|wire". [Dominic Plunkett] **** Skip SystemC tests if not installed. [Iztok Jeras] **** Fix clock-gates with non-AND complex logic, bug220. [Ashutosh Das] **** Fix flushing VCD buffers on $stop. [Ashutosh Das] **** Fix Mac OS-X compile issues, bug217. [Joshua Wise, Trevor Williams] **** Fix make uninstall, bug216. [Iztok Jeras] **** Fix parametrized defines with empty arguments. * Verilator 3.800 2010/02/07 Application visible changes: ** SystemPerl is no longer required for tracing. Applications must use VerilatedVcdC class in place of SpTraceVcdC. ** SystemVerilog 1800-2009 is now the default language. Thus "global" etc are now keywords. See the --language option. New features: ** Support SystemVerilog types "byte", "chandle", "int", "longint", "shortint", "time", "var" and "void" in variables and functions. ** Support "program", "package", "import" and $unit. ** Support typedef and enum. [by Donal Casey] ** Support direct programming interface (DPI) "import" and "export". Includes an extension to map user $system PLI calls to the DPI. *** Support assignments of multidimensional slices, bug170. [by Byron Bradley] *** Support multidimensional inputs/outputs, bug171. [by Byron Bradley] *** Support "reg [1:0][1:0][1:0]" and "reg x [3][2]", bug176. [Byron Bradley] *** Support declarations in loop initializers, bug172. [by Byron Bradley] *** Support $test$plusargs and $value$plusargs, but see the docs! *** Support $sformat and $swrite. *** Support 1800-2009 define defaults and `undefineall. *** Add -CFLAGS, -LDFLAGS, .a, .o, and .so options. *** Speed compiles by avoiding including the STL iostream header. Application programs may need to include it themselves to avoid errors. *** Add experimental clock domain crossing checks. *** Add experimental --pipe-filter to filter all Verilog input. *** Add experimental config files to filter warnings outside of the source. *** Add VARHIDDEN warning when signal name hides module name. **** Support optional cell parenthesis, bug179. [by Byron Bradley] **** Support for loop i++, ++i, i--, --i, bug175. [by Byron Bradley] **** Support 1800-2009 /*comments*/ in define values. **** Add Makefile VM_GLOBAL_FAST, listing objects needed to link executables. **** Add --bbox-unsup option to black-box unsupported UDP tables. **** Add -Wno-MODDUP option to allow duplicate modules. Bug fixes: **** Fix implicit variable issues, bug196, bug201. [Byron Bradley] **** Fix 'for' variable typing, bug205. [by Byron Bradley] **** Fix tracing with --pins-bv 1, bug195. [Michael S] **** Fix MSVC++ 2008 compile issues, bug209. [Amir Gonnen] **** Fix MinGW compilation, bug184, bug214. [by Shankar Giri, Amir Gonnen] **** Fix Cygwin 1.7.x compiler error with uint32_t, bug204. [Ivan Djordjevic] **** Fix `define argument mis-replacing system task of same name, bug191. **** Fix Verilator core dump on wide integer divides, bug178. [Byron Bradley] **** Fix lint_off/lint_on meta comments on same line as warning. * Verilator 3.720 2009/10/26 ** Support little endian bit vectors ("reg [0:2] x;"). ** Support division and modulus of > 64 bit vectors. [Gary Thomas] *** Fix writing to out-of-bounds arrays writing element 0. **** Fix core dump with SystemVerilog var declarations under unnamed begins. **** Fix VCD files showing internal flattened hierarchy, broke in 3.714. **** Fix cell port connection to unsized integer causing false width warning. **** Fix erroring on strings with backslashed newlines, bug168. [Pete Nixon] * Verilator 3.714 2009/09/18 ** Add --bbox-sys option to blackbox $system calls. ** Support generate for var++, var--, ++var, --var. *** Improved warning when "do" used as identifier. **** Don't require SYSTEMPERL_INCLUDE if SYSTEMPERL/src exists. [Gary Thomas] **** Fix deep defines causing flex scanner overflows. [Brad Dobbie] **** Fix preprocessing commas in deep parameterized macros. [Brad Dobbie] **** Fix tracing escaped dotted identifiers, bug107. **** Fix $display with uppercase %M. **** Fix --error-limit option being ignored. * Verilator 3.713 2009/08/04 ** Support constant function calls for parameters. [many!] *** Support SystemVerilog "logic", bug101. [by Alex Duller] *** Name SYMRSVDWORD error, and allow disabling it, bug103. [Gary Thomas] **** Fix escaped preprocessor identifiers, bug106. [Nimrod Gileadi] * Verilator 3.712 2009/07/14 ** Patching SystemC is no longer required to trace sc_bvs. *** Support zero-width constants in concatenations. [Jeff Winston] *** Add verilator --pins-uint8 option to use sc_in. *** Add verilator -V option, to show verbose version. *** On WIDTH warnings, show variable name causing error. [Jeff Winston] **** Add BLKLOOPINIT error code, and describe --unroll-count. [Jeff Winston] * Verilator 3.711 2009/06/23 **** Support decimal constants of arbitrary widths. [Mark Marshall] **** Fix error on case statement with all duplicate items, bug99. [Gary Thomas] **** Fix segfault on unrolling for's with bad inits, bug90. [Andreas Olofsson] **** Fix tristates causing "Assigned pin is neither...". [by Lane Brooks] **** Fix compiler errors under Fedora release candidate 11. [Chitlesh Goorah] * Verilator 3.710 2009/05/19 ** Verilator is now licensed under LGPL v3 and/or Artistic v2.0. *** `__FILE__ now expands to a string, per draft SystemVerilog 2010(ish). **** The front end parser has been re-factored to enable more SV parsing. Code should parse the same, but minor parsing bugs may pop up. **** Verilator_includer is no longer installed twice, bug48. [Lane Brooks] **** Fix escaped identifiers with '.' causing conflicts, bug83. [J Baxter] **** Fix define formal arguments that contain newlines, bug84. [David A] * Verilator 3.703 2009/05/02 *** Fix $clog2 calculation error with powers-of-2, bug81. [Patricio Kaplan] **** Fix error with tasks that have output first, bug78. [Andrea Foletto] **** Fix "cloning" error with -y/--top-module, bug76. [Dimitris Nalbantis] **** Fix segfault with error on bad --top-module, bug79. [Dimitris Nalbantis] **** Fix "redefining I" error with complex includes. [Duraid Madina] **** Fix GCC 4.3.2 compile warnings. * Verilator 3.702 2009/03/28 *** Add --pins-bv option to use sc_bv for all ports. [Brian Small] *** Add SYSTEMPERL_INCLUDE envvar to assist RPM builds. [Chitlesh Goorah] **** Report errors when duplicate labels are used, bug72. [Vasu Kandadi] **** Fix the SC_MODULE name() to not include __PVT__. [Bob Fredieu] * Verilator 3.701 2009/02/26 ** Support repeat and forever statements. [Jeremy Bennett] *** Add --debugi- option, for internal debugging. [Dennis Muhlestein] **** Fix compile issues with GCC 4.3, bug47. [Lane Brooks] **** Fix VL_RANDom to better randomize bits. [Art Stamness] **** Fix error messages to consistently go to stderr. [Jeremy Bennett] **** Fix left associativity for ?: operators. * Verilator 3.700 2009/01/08 ** Add limited support for tristate inouts. Written by Lane Brooks, under support by Ubixum Inc. This allows common pad ring and tristate-mux structures to be Verilated. See the documentation for more information on supported constructs. ** Add --coverage_toggle for toggle coverage analysis. Running coverage now requires SystemPerl 1.301 or newer. *** Add /*verilator coverage_on/_off */ to bracket coverage regions. *** Optimize two-level shift and and/or trees, +23% on one test. *** Support posedge of bit-selected signals, bug45. [Rodney Sinclair] *** Line coverage now aggregates by hierarchy automatically. Previously this would be done inside SystemPerl, which was slower. **** Minor performance improvements of Verilator compiler runtime. **** Coverage of each parametarized module is counted separately. [Bob Fredieu] **** Fix creating parameterized modules when no parameter values are changed. **** Fix certain generate-if cells causing "clone" error. [Stephane Laurent] **** Fix line coverage of public functions. [Soon Koh] **** Fix SystemC 2.2 deprecated warnings about sensitive() and sc_start(). **** Fix arrayed variables under function not compiling, bug44. [Ralf Karge] **** Fix --output-split-cfuncs to also split trace code. [Niranjan Prabhu] **** Fix 'bad select range' warning missing some cases, bug43. [Lane Brooks] **** Fix internal signal names containing control characters (broke in 3.680). **** Fix compile error on Ubuntu 8.10. [Christopher Boumenot] **** Fix internal error on "output x; reg x = y;". **** Fix wrong result for read of delayed FSM signal, bug46. [Rodney Sinclair] * Verilator 3.681 2008/11/12 *** Add SystemVerilog unique and priority case. **** Include Verilog file's directory name in coverage reports. **** Fix 'for' under 'generate-for' causing error; bug38. [Rafael Shirakawa] **** Fix coverage hierarchy being backwards with inlining. [Vasu Arasanipalai] **** Fix GCC 4.3 compile error; bug35. [Lane Brooks] **** Fix MSVC compile error; bug42. [John Stroebel] * Verilator 3.680 2008/10/08 ** Support negative bit indexes. [Stephane Laurent] Tracing negative indexes requires latest Verilog-Perl and SystemPerl. *** Suppress width warnings between constant strings and wider vectors. [Rodney Sinclair] **** Ignore SystemVerilog timeunit and timeprecision. **** Expand environment variables in -f input files. [Lawrence Butcher] **** Report error if port declaration is missing; bug32. [Guy-Armand Kamendje] **** Fix genvars causing link error when using --public. [Chris Candler] * Verilator 3.671 2008/09/19 ** SystemC uint64_t pins are now the default instead of sc_bv<64>. Use --no-pins64 for backward compatibility. *** Support SystemVerilog "cover property" statements. *** When warnings are disabled on signals that are flattened out, disable the warnings on the signal(s) that replace it. *** Add by-design and by-module subtotals to verilator_profcfunc. *** Fix extra evaluation of pure combo blocks in SystemC output. **** Add IMPERFECTSCH warning, disabled by default. **** Support coverage under SystemPerl 1.285 and newer. **** Fix stack overflow on large ? : trees. [John Sanguinetti] **** Support arbitrary characters in identifiers. [Stephane Laurent] * Verilator 3.670 2008/07/23 ** Add --x-assign=fast option, and make it the default. This chooses performance over reset debugging. See the manual. ** Add --autoflush, for flushing streams after $display. [Steve Tong] ** Add CASEWITHX lint warning and if disabled fix handling of casez with Xs. *** Add $feof, $fgetc, $fgets, $fflush, $fscanf, $sscanf. [Holger Waechtler] *** Add $stime. [Holger Waechtler] *** Add $random. *** Add --Wfuture-, for improving forward compatibility. **** Fix verilator_includer not being installed properly. [Holger Waechtler] **** Fix IMPURE errors due to X-assignment temporary variables. [Steve Tong] **** Fix "lvalue" errors with public functions; bug25. [CY Wang] **** Add WIDTH warning to $fopen etc file descriptors. **** Internal changes to how $displays get compiled and executed. * Verilator 3.665 2008/06/25 **** Ignore "// verilator" comments alone on endif lines. [Rodney Sinclair] **** "Make install" now installs verilator_includer and verilator_profcfunc. **** Fix tracing missing changes on undriven public wires. [Rodney Sinclair] **** Fix syntax error when "`include `defname" is ifdefed. [John Dickol] **** Fix error when macro call has commas in concatenate. [John Dickol] **** Fix compile errors under Fedora 9, GCC 4.3.0. [by Jeremy Bennett] **** Fix Makefile to find headers/libraries under prefix. [by Holger Waechtler] * Verilator 3.664 2008/05/08 **** Fix missing file in kit. * Verilator 3.663 2008/05/07 **** Add DESTDIR to Makefiles to assist RPM construction. [Gunter Dannoritzer] **** Fix compiler warnings under GCC 4.2.1. **** Fix preprocessor `else after series of `elsif. [Mark Nodine] **** Fix parametrized defines calling define with comma. [Joshua Wise] **** Fix comma separated list of primitives. [by Bryan Brady] * Verilator 3.662 2008/04/25 *** Add Verilog 2005 $clog2() function. This is useful in calculating bus-widths from parameters. *** Support /**/ comments in -f option files. [Stefan Thiede] **** Add error message when modules have duplicate names. [Stefan Thiede] **** Support defines terminated in EOF, though against spec. [Stefan Thiede] **** Support optional argument to $finish and $stop. [by Stefan Thiede] **** Support ranges on gate primitive instantiations. [Stefan Thiede] **** Ignore old standard(ish) Verilog-XL defines. [by Stefan Thiede] **** Fix "always @ ((a) or (b))" syntax error. [by Niranjan Prabhu] **** Fix "output reg name=expr;" syntax error. [Martin Scharrer] **** Fix multiple .v files being read in random order. [Stefan Thiede] **** Fix internal error when params get non-constants. [Johan Wouters] **** Fix bug introduced in 3.661 with parametrized defines. * Verilator 3.661 2008/04/04 *** The --enable-defenv configure option added in 3.660 is now the default. This hard-codes a default for VERILATOR_ROOT etc in the executables. *** Add --language option for supporting older code. [Stefan Thiede] *** Add --top-module option to select between multiple tops. [Stefan Thiede] *** Unsized concatenates now give WIDTHCONCAT warnings. [Jonathan Kimmitt] Previously they threw fatal errors, which in most cases is correct according to spec, but can be incorrect in presence of parameter values. **** Support functions with "input integer". [Johan Wouters] **** Ignore delays attached to gate UDPs. [Stefan Thiede] **** Fix SystemVerilog parameterized defines with `` expansion, and fix extra whitespace inserted on substitution. [Vladimir Matveyenko] **** Fix no-module include files on command line. [Stefan Thiede] **** Fix dropping of backslash quoted-quote at end of $display. **** Fix task output pin connected to non-variables. [Jonathan Kimmitt] **** Fix missing test_v in install datadir. [Holger Waechtler] **** Fix internal error after MSB < LSB error reported to user. [Stefan Thiede] * Verilator 3.660 2008/03/23 *** Add support for hard-coding VERILATOR_ROOT etc in the executables, to enable easier use of Verilator RPMs. [Gunter Dannoritzer] *** Allow multiple .v files on command line. [Stefan Thiede] *** Convert re-defining macro error to warning. [Stefan Thiede] *** Add --error-limit option. [Stefan Thiede] *** Allow __ in cell names by quoting them in C. [Stefan Thiede] **** Fix genvar to be signed, so "< 0" works properly. [Niranjan Prabhu] **** Fix assignments to inputs inside functions/tasks. [Patricio Kaplan] **** Fix definitions in main file.v, referenced in library. [Stefan Thiede] **** Fix undefined assigns to be implicit warnings. [Stefan Thiede] * Verilator 3.658 2008/02/25 **** Fix unistd compile error in 3.657. [Patricio Kaplan, Jonathan Kimmitt] * Verilator 3.657 2008/02/20 **** Fix assignments of {a,b,c} = {c,b,a}. [Jonathan Kimmitt] **** Fix Perl warning with --lint-only. [by Ding Xiaoliang] **** Avoid creating obj_dir with --lint-only. [Ding Xiaoliang] **** Fix parsing of always @(*). [Patricio Kaplan] * Verilator 3.656 2008/01/18 **** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman] In such cases, a new {prefix}__Inlines.h file will be built and included. **** Fixed sign error when extracting from signed memory. [Peter Debacker] **** Fixed tracing of SystemC w/o SystemPerl. [Bernard Deadman, Johan Wouters] * Verilator 3.655 2007/11/27 *** Support "#delay ;" with associated STMTDLY warning. **** Fixed generate for loops with constant zero conditions. [Rodney Sinclair] **** Fixed divide-by-zero errors in constant propagator. [Rodney Sinclair] **** Fixed wrong result with obscure signed-shift underneath a "? :". **** Fixed many internal memory leaks, and added leak detector. * Verilator 3.654 2007/10/18 **** Don't exit early if many warnings but no errors are found. [Stan Mayer] **** Fixed parsing module #(parameter x,y) declarations. [Oleg Rodionov] **** Fixed parsing system functions with empty parens. [Oleg Rodionov] * Verilator 3.653 2007/8/1 **** Support SystemVerilog ==? and !=? operators. **** Fixed SC_LIBS missing from generated makefiles. [Ding Xiaoliang] * Verilator 3.652 2007/6/21 **** Report as many warning types as possible before exiting. **** Support V2K portlists with "input a,b,...". [Mark Nodine] **** Support V2K function/task argument lists. **** Optimize constant $display arguments. **** Fixed Preprocessor dropping some `line directives. [Mark Nodine] * Verilator 3.651 2007/5/22 *** Added verilator_profcfunc utility. [Gene Weber] *** Treat modules within `celldefine and `endcelldefine as if in library. *** Support functions which return integers. [Mark Nodine] **** Warn if flex is not installed. [Ralf Karge] **** Ignore `protect and `endprotect. **** Allow empty case/endcase blocks. * Verilator 3.650 2007/4/20 ** Add --compiler msvc option. This is now required when Verilated code is to be run through MSVC++. This also enables fixing MSVC++ error C1061, blocks nested too deeply. [Ralf Karge] ** Add --lint-only option, to lint without creating other output. *** Add /*verilator lint_save*/ and /*verilator lint_restore*/ to allow friendly control over re-enabling lint messages. [Gerald Williams] *** Support SystemVerilog .name and .* interconnect. *** Support while and do-while loops. *** Use $(LINK) instead of $(CXX) for Makefile link rules. [Gerald Williams] *** Add USER_CPPFLAGS and USER_LDFLAGS to Makefiles. [Gerald Williams] **** Fixed compile errors under Windows MINGW compiler. [Gerald Williams] **** Fixed dotted bit reference to local memory. [Eugene Weber] **** Fixed 3.640 `verilog forcing IEEE 1364-1995 only. [David Hewson] * Verilator 3.640 2007/3/12 *** Support Verilog 2005 `begin_keywords and `end_keywords. *** Updated list of SystemVerilog keywords to correspond to IEEE 1800-2005. *** Add /*verilator public_flat*/. [Eugene Weber] **** Try all +libext's in the exact order given. [Michael Shinkarovsky] **** Fixed elimination of public signals assigned to constants. [Eugene Weber] **** Fixed internal error when public for loop has empty body. [David Addison] **** Fixed "Loops detected" assertion when model exceeds 4GB. [David Hewson] **** Fixed display %m names inside named blocks. * Verilator 3.633 2007/2/7 *** Add --trace-depth option for minimizing VCD file size. [Emerson Suguimoto] *** With VL_DEBUG, show wires causing convergence errors. [Mike Shinkarovsky] **** Fixed isolate_assignments when many signals per always. [Mike Shinkarovsky] **** Fixed isolate_assignments across task/func temporaries. [Mike Shinkarovsky] **** Fixed $display's with array select followed by wide AND. [David Hewson] * Verilator 3.632 2007/1/17 *** Add /*verilator isolate_assignments*/ attribute. [Mike Shinkarovsky] * Verilator 3.631 2007/1/2 ** Support standard NAME[#] for cells created by arraying or generate for. This replaces the non-standard name__# syntax used in earlier versions. **** Fixed again dotted references into generate cells. [David Hewson] Verilator no longer accepts duplicated variables inside unique generate blocks as this is illegal according to the specification. **** Fixed $readmem* with filenames < 8 characters. [Emerson Suguimoto] * Verilator 3.630 2006/12/19 ** Support $readmemb and $readmemh. [Eugene Weber, Arthur Kahlich] *** Fixed configure and compiling under Solaris. [Bob Farrell] *** When dotted signal lookup fails, help the user by showing known scopes. *** Reduce depth of priority encoded case statements. [Eugene Weber] **** Fixed dotted references inside generated cells. [David Hewson] **** Fixed missed split optimization points underneath other re-split blocks. * Verilator 3.623 2006/12/05 *** Add --output-split-cfuncs for accelerating GCC compile. [Eugene Weber] **** Fixed $signed mis-extending when input has a WIDTH violation. [Eugene Weber] **** Add M32 make variable to support -m32 compiles. [Eugene Weber] * Verilator 3.622 2006/10/17 Stable **** Fixed --skip-identical without --debug, broken in 3.621. [Andy Meier] * Verilator 3.621 2006/10/11 Beta ** Add /*verilator no_inline_task*/ to prevent over-expansion. [Eugene Weber] *** Public functions now allow > 64 bit arguments. **** Remove .vpp intermediate files when not under --debug. **** Fixed link error when using --exe with --trace. [Eugene Weber] **** Fixed mis-optimization of wide concats with constants. **** Fixed core dump on printing error when not under --debug. [Allan Cochrane] * Verilator 3.620 2006/10/04 Stable *** Support simple inout task ports. [Eugene Weber] *** Allow overriding Perl, Flex and Bison versions. [by Robert Farrell] *** Optimize variables set to constants within basic blocks for ~3%. **** Default make no longer makes the docs; if you edit the documentation. sources, run "make info" to get them. **** Optimize additional boolean identities (a|a = a, etc.) **** Fixed coredump when dotted cross-ref inside task call. [Eugene Weber] **** Fixed dotted variables in always sensitivity lists. [Allan Cochrane] * Verilator 3.610 2006/09/20 Stable *** Verilator now works under DJGPP (Pentium GCC). [John Stroebel] **** Add default define for VL_PRINTF. [John Stroebel] **** Removed coverage request variable; see Coverage limitations in docs. **** Fixed DOS carriage returns in multiline defines. [Ralf Karge] **** Fixed printf format warnings on 64-bit linux. * Verilator 3.602 2006/09/11 Stable **** Fixed function references under top inlined module. [David Hewson] * Verilator 3.601 2006/09/06 Beta *** Added --inhibit-sim flag for environments using old __Vm_inhibitSim. *** Added `systemc_dtor for destructor extensions. [Allan Cochrane] *** Added -MP to make phony dependencies, ala GCC's. *** Changed how internal functions are invoked to reduce aliasing. Useful when using GCC's -O2 or -fstrict-aliasing, to gain another ~4%. **** Fixed memory leak when destroying modules. [John Stroebel] **** Fixed coredump when unused modules have unused cells. [David Hewson] **** Fixed 3.600 internal error with arrayed instances. [David Hewson] **** Fixed 3.600 internal error with non-unrolled function loops. [David Hewson] **** Fixed $display %m name not matching Verilog name inside SystemC modules. **** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate. * Verilator 3.600 2006/08/28 Beta ** Support dotted cross-hierarchy variable and task references. **** Lint for x's in generate case statements. **** Fixed line numbers being off by one when first file starts with newline. **** Fixed naming of generate for blocks to prevent non-inline name conflict. **** Fixed redundant statements remaining after table optimization. * Verilator 3.542 2006/08/11 Stable **** Fixed extraneous UNSIGNED warning when comparing genvars. [David Hewson] **** Fixed extra white space in $display %c. [by David Addison] **** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout. **** Add VL_CONST_W_24X macro. [Bernard Deadman] * Verilator 3.541 2006/07/05 Beta *** Fixed "// verilator lint_on" not re-enabling warnings. [David Hewson] *** Fixed 3.540's multiple memory assignments to same block. [David Hewson] **** Add warning on changeDetect to arrayed structures. [David Hewson] **** Fixed non-zero start number for arrayed instantiations. [Jae Hossell] **** Fixed GCC 4.0 header file warnings. * Verilator 3.540 2006/06/27 Beta **** Optimize combo assignments that are used only once, ~5-25% faster. **** Optimize delayed assignments to memories inside loops, ~0-5% faster. **** Fixed mis-width warning on bit selects of memories. [David Hewson] **** Fixed mis-width warning on dead generate-if branches. [Jae Hossell] * Verilator 3.533 2006/06/05 Stable *** Add PDF user manual, verilator.pdf. **** Fixed delayed bit-selected arrayed assignments. [David Hewson] **** Fixed execution path to Perl. [Shanshan Xu] **** Fixed Bison compile errors in verilog.y. [by Ben Jackson] * Verilator 3.531 2006/05/10 Stable *** Support $c routines which return 64 bit values. **** Fixed `include `DEFINE. **** Fixed Verilator core dump when have empty public function. [David.Hewson] * Verilator 3.530 2006/04/24 Stable ** $time is now 64 bits. The macro VL_TIME_I is now VL_TIME_Q, but calls the same sc_time_stamp() function to get the current time. * Verilator 3.523 2006/03/06 Stable **** Fixed error line numbers being off due to multi-line defines. [Mat Zeno] **** Fixed GCC sign extending (uint64_t)(a>>, $signed, $unsigned. [MANY!] ** Support multi-dimensional arrays. [Eugen Fekete] ** Add very limited support for the Property Specification Language (aka PSL or Sugar). The format and keywords are now very limited, but will grow with future releases. The --assert switch enables this feature. ** With --assert, generate assertions for synthesis parallel_case and full_case. **** Fixed generate if's with empty if/else blocks. [Mat Zeno] **** Fixed generate for cell instantiations with same name. [Mat Zeno] * Verilator 3.481 2005/10/12 Stable *** Add /*verilator tracing_on/off*/ for waveform control. **** Fixed split optimization reordering $display statements. * Verilator 3.480 2005/9/27 Beta ** Allow coverage of flattened modules, and multiple points per line. Coverage analysis requires SystemPerl 1.230 or newer. **** Add preprocessor changes to support meta-comments. **** Optimize sequential assignments of different bits of same bus; ~5% faster. **** Optimize away duplicate lookup tables. **** Optimize wide concatenates into individual words. [Ralf Karge] **** Optimize local variables from delayed array assignments. * Verilator 3.470 2005/9/6 Stable *** Optimize staging flops under reset blocks. *** Add '-Werror-...' to upgrade specific warnings to errors. **** Add GCC branch prediction hints on generated if statements. **** Fixed bad simulation when same function called twice in same expression. **** Fixed preprocessor substitution of quoted parameterized defines. * Verilator 3.464 2005/8/24 Stable *** Add `systemc_imp_header, for use when using --output-split. *** Add --stats option to dump design statistics. **** Fixed core dump with clock inversion optimizations. * Verilator 3.463 2005/8/5 Stable *** Fixed case defaults when not last statement in case list. [Wim Michiels] * Verilator 3.462 2005/8/3 Stable *** Fixed reordering of delayed assignments to same memory index. [Wim Michiels] **** Fixed compile error with Flex 2.5.1. [Jens Arm] **** Fixed multiply-instantiated public tasks generating non-compilable code. * Verilator 3.461 2005/7/28 Beta **** Fixed compile error with older versions of bison. [Jeff Dutton] * Verilator 3.460 2005/7/27 Beta ** Add -output-split option to enable faster parallel GCC compiles. To support --output-split, the makefiles now split VM_CLASSES into VM_CLASSES_FAST and VM_CLASSES_SLOW. This may require a change to local makefiles. ** Support -v argument to read library files. *** When issuing unoptimizable warning, show an example path. **** Fixed false warning when a clock is constant. **** Fixed X/Z in decimal numbers. [Wim Michiels] **** Fixed genvar statements in non-named generate blocks. **** Fixed core dump when missing newline in `define. [David van der bokke] **** Internal tree dumps now indicate edit number that changed the node. * Verilator 3.450 2005/7/12 ** $finish will no longer exit, but set Verilated::gotFinish(). This enables support for final statements, and for other cleanup code. If this is undesired, redefine the vl_user_finish routine. Top level loops should use Verilated::gotFinish() as a exit condition for their loop, and then call top->final(). To prevent a infinite loop, a double $finish will still exit; this may be removed in future releases. *** Add support for SystemVerilog keywords $bits, $countones, $isunknown, $onehot, $onehot0, always_comb, always_ff, always_latch, finish. **** Fixed "=== 1'bx" to always be false, instead of random. * Verilator 3.440 2005/6/28 Stable ** Add Verilog 2001 generate for/if/case statements. * Verilator 3.431 2005/6/24 Stable *** Fixed selection bugs introduced in 3.430 beta. * Verilator 3.430 2005/6/22 Beta ** Add Verilog 2001 variable part selects [n+:m] and [n-:m]. [Wim Michiels] * Verilator 3.422 2005/6/10 Stable *** Added Verilog 2001 power (**) operator. [Danny Ding] **** Fixed crash and added error message when assigning to inputs. [Ralf Karge] **** Fixed tracing of modules with public functions. * Verilator 3.421 2005/6/2 Beta **** Fixed error about reserved word on non-public signals. **** Fixed missing initialization compile errors in 3.420 beta. [Ralf Karge] * Verilator 3.420 2005/6/2 Beta *** Fixed case defaults when not last statement in case list. [Ralf Karge] **** Added error message when multiple defaults in case statement. **** Fixed crash when wire self-assigns x=x. ** Performance improvements worth ~20% ** Added -x-assign options; ~5% faster if use -x-assign=0. **** Optimize shifts out of conditionals and if statements. **** Optimize local 'short' wires. **** Fixed gate optimization with top-flattened modules. [Mahesh Kumashikar] * Verilator 3.411 2005/5/30 Stable **** Fixed compile error in GCC 2.96. [Jeff Dutton] * Verilator 3.410 2005/5/25 Beta ** Allow functions and tasks to be declared public. They will become public C++ functions, with appropriate C++ types. This allows users to make public accessor functions/tasks, instead of having to use public variables and `systemc_header hacks. *** Skip producing output files if all inputs are identical This uses timestamps, similar to make. Disable with --no-skip-identical. **** Improved compile performance with large case statements. **** Fixed internal error in V3Table. [Jeff Dutton] **** Fixed compile error in GCC 2.96, and with SystemC 1.2. [Jeff Dutton] * Verilator 3.400 2005/4/29 Beta ** Internal changes to support future clocking features. ** Verilog-Perl and SystemPerl are no longer required for C++ or SystemC output. If you want tracing or coverage analysis, they are still needed. *** Added --sc to create pure SystemC output not requiring SystemPerl. *** Added --pins64 to create 64 bit SystemC outputs instead of sc_bv<64>. *** The --exe flag is now required to produce executables inside the makefile. This was previously the case any time .cpp files were passed on the command line. *** Added -O3 and --inline-mult for performance tuning. [Ralf Karge] One experiment regained 5% performance, at a cost of 300% in compile time. *** Improved performance of large case/always statements with low fanin by converting to internal lookup tables (ROMs). *** Initialize SystemC port names. [S Shuba] **** Added Doxygen comments to Verilated includes. **** Fixed -cc pins 8 bits wide and less to be uint8_t instead of uint16_t. **** Fixed crash when Mdir has same name as .v file. [Gernot Koch] **** Fixed crash with size mismatches on case items. [Gernot Koch] * Verilator 3.340 2005/2/18 Stable *** Report misconnected pins across all modules, instead of just first error. **** Fixed over-active inlining, resulting in compile slowness. **** Improved large netlist compile times. **** Added additional internal assertions. * Verilator 3.332 2005/1/27 *** Added -E preprocess only flag, similar to GCC. *** Added CMPCONSTLR when comparison is constant due to > or < with all ones. **** Fixed loss of first -f file argument, introduced in 3.331. * Verilator 3.331 2005/1/18 ** The Verilog::Perl preprocessor is now C++ code inside of Verilator. This improves performance, makes compilation easier, and enables some future features. *** Support arrays of instantiations (non-primitives only). [Wim Michiels] **** Fixed unlinked error with defparam. [Shawn Wang] * Verilator 3.320 2004/12/10 ** NEWS is now renamed Changes, to support CPAN indexing. *** If Verilator is passed a C file, create a makefile link rule. This saves several user steps when compiling small projects. *** Added new COMBDLY warning in place of fatal error. [Shawn Wang] *** Fixed mis-simulation with wide-arrays under bit selects. [Ralf Karge] **** Added NC Verilog as alternative to VCS for reference tests. **** Support implicit wire declarations on input-only signals. (Dangerous, as leads to wires without drivers, but allowed by spec.) **** Fixed compile warnings on Suse 9.1 * Verilator 3.311 2004/11/29 ** Support implicit wire declarations (as a warning). [Shawn Wang] **** Fixed over-shift difference in Verilog vs C++. [Ralf Karge] * Verilator 3.310 2004/11/15 ** Support defparam. ** Support gate primitives: buf, not, and, nand, or, nor, xor, xnor. *** Ignore all specify blocks. * Verilator 3.302 2004/11/12 *** Support NAND and NOR operators. *** Better warnings when port widths don't match. **** Fixed internal error due to some port width mismatches. [Ralf Karge] **** Fixed WIDTH warnings on modules that are only used parameterized, not in 'default' state. **** Fixed selection of SystemC library on cygwin systems. [Shawn Wang] **** Fixed runtime bit-selection of parameter constants. * Verilator 3.301 2004/11/04 **** Fixed 64 bit [31:0] = {#{}} mis-simulation. [Ralf Karge] **** Fixed shifts greater then word width mis-simulation. [Ralf Karge] **** Work around GCC 2.96 negation bug. * Verilator 3.300 2004/10/21 ** New backend that eliminates most VL_ macros. Improves performance 20%-50%, depending on frequency of use of signals over 64 bits. GCC compile times with -O2 shrink by a factor of 10. **** Fixed "setting unsigned int from signed value" warning. * Verilator 3.271 2004/10/21 **** Fixed "loops detected" error with some negedge clocks. **** Cleaned up some output code spacing issues. * Verilator 3.270 2004/10/15 *** Support Verilog 2001 parameters in module headers. [Ralf Karge] **** Suppress numeric fault when dividing by zero. **** Faster code to support compilers not inlining all Verilated functions. * Verilator 3.260 2004/10/7 ** Support Verilog 2001 named parameter instantiation. [Ralf Karge] **** Return 1's when one bit wide extract indexes outside array bounds. **** Fixed compile warnings on 64-bit operating systems. **** Fixed incorrect dependency in .d file when setting VERILATOR_BIN. * Verilator 3.251 2004/9/9 **** Fixed parenthesis overflow in Microsoft Visual C++ [Renga Sundararajan] * Verilator 3.250 2004/8/30 ** Support Microsoft Visual C++ [Renga Sundararajan] *** SystemPerl 1.161+ is required. * Verilator 3.241 2004/8/17 ** Support ,'s to separate multiple assignments. [Paul Nitza] **** Fixed shift sign extension problem using non-GCC compilers. * Verilator 3.240 2004/8/13 ** Verilator now uses 64 bit math where appropriate. Inputs and outputs of 33-64 bits wide to the C++ Verilated model must now be uint64_t's; SystemC has not changed, they will remain sc_bv's. This increases performance by ~ 9% on x86 machines, varying with how frequently 33-64 bit signals occur. Signals 9-16 bits wide are now stored as 16 bit shorts instead of longs, this aids cache packing. **** Fixed SystemC compile error with feedthrus. [Paul Nitza] **** Fixed concat value error introduced in 3.230. * Verilator 3.230 2004/8/10 *** Added coverage output to test_sp example, SystemPerl 1.160+ is required. **** Fixed time 0 value of signals. [Hans Van Antwerpen] Earlier versions would not evaluate some combinatorial signals until posedge/negedge blocks had been activated. **** Fixed wide constant inputs to public submodules [Hans Van Antwerpen] **** Fixed wide signal width extension bug. Only applies when width mismatch warnings were overridden. * Verilator 3.220 2004/6/22 ** Many waveform tracing changes: *** Tracing is now supported on C++ standalone simulations. [John Brownlee] *** When tracing, SystemPerl 1.150 or newer is required. *** When tracing, Verilator must be called with the --trace switch. **** Added SystemPerl example to documentation. [John Brownlee] **** Various Cygwin compilation fixes. [John Brownlee] * Verilator 3.210 2004/4/1 ** Compiler optimization switches have changed See the BENCHMARKING section of the documentation. *** With Verilog-Perl 2.3 or newer, Verilator supports SystemVerilog preprocessor extensions. *** Added localparam. [Thomas Hawkins] *** Added warnings for SystemVerilog reserved words. * Verilator 3.203 2004/3/10 *** Notes and repairs for Solaris. [Fred Ma] * Verilator 3.202 2004/1/27 ** The beta version is now the primary release. See below for many changes. If you have many problems, you may wish to try release 3.125. *** Verilated::traceEverOn(true) must be called at time 0 if you will ever turn on tracing (waveform dumping) of signals. Future versions will need this switch to disable trace incompatible optimizations. **** Fixed several tracing bugs **** Added optimizations for common replication operations. * Verilator 3.201-beta 2003/12/10 ** BETA VERSION, USE 3.124 for stable release! ** Version 3.2XX includes a all new back-end. This includes automatic inlining, flattening of signals between hierarchy, and complete ordering of statements. This results in 60-300% execution speedups, though less pretty C++ output. Even better results are possible using GCC 3.2.2 (part of Redhat 9.1), as GCC has fixed some optimization problems which Verilator exposes. If you are using `systemc_ctor, beware pointers to submodules are now initialized after the constructor is called for a module, to avoid segfaults, move statements that reference subcells into initial statements. *** C++ Constructor that creates a verilog module may take a char* name. This name will be used to prefix any $display %m arguments, so users may distinguish between multiple Verilated modules in a single executable. * Verilator 3.125 2004/1/27 **** Optimization of bit replications * Verilator 3.124 2003/12/05 *** A optimized executable will be made by default, in addition to a debug executable. Invoking Verilator with --debug will pick the debug version. **** Many minor invisible changes to support the next version. * Verilator 3.123 2003/11/10 **** Wide bus performance enhancements. **** Fixed function call bug when width warning suppressed. [Leon Wildman] **** Fixed __DOT__ compile problem with funcs in last revision. [Leon Wildman] * Verilator 3.122 2003/10/29 *** Modules which are accessed from external code now must be marked with /*verilator public_module*/ unless they already contain public signals. To enforce this, private cell names now have a string prepended. **** Fixed replicated function calls in one statement. [Robert A. Clark] **** Fixed function call bug when width warning suppressed. [Leon Wildman] * Verilator 3.121 2003/09/29 *** Support multiplication over 32 bits. [Chris Boumenot] Also improved speed of addition and subtraction over 32 bits. *** Detect bit selection out of range errors. *** Detect integer width errors. **** Fixed width problems on function arguments. [Robert A. Clark] * Verilator 3.120 2003/09/24 *** $finish now exits the model (via vl_finish function). *** Support inputs/outputs in tasks. *** Support V2K "integer int = {INITIAL_VALUE};" *** Ignore floating point delay values. [Robert A. Clark] **** Ignore `celldefine, `endcelldefine, etc. [Robert A. Clark] **** New optimizations on reduction operators. **** Fixed converting "\ooo" into octal values. **** Fixed $display("%x"); * Verilator 3.112 2003/09/16 **** Fixed functions in continuous assignments. [Robert A. Clark] **** Fixed inlining of modules with 2-level deep outputs. * Verilator 3.111 2003/09/15 **** Fixed declaration of functions before using that module. [Robert A. Clark] **** Fixed module inlining bug with outputs. * Verilator 3.110 2003/09/12 ** Support Verilog 2001 style input/output declarations. [Robert A. Clark] *** Allow local vars in headers of function/tasks. [Leon Wildman] * Verilator 3.109 2003/08/28 ** Added support for local variables in named begin blocks. [Leon Wildman] * Verilator 3.108 2003/08/11 ** Added support for functions. *** Signals 8 bits and shorter are now stored as chars instead of uint32_t's. This improves Dcache packing and improves performance by ~7%. **** $display now usually results in a single VL_PRINT rather then many. **** Many optimizations involving conditionals (?:) * Verilator 3.107 2003/07/15 *** --private and --l2name are now the default, as this enables additional optimizations. Use --noprivate or --nol2name to get the older behavior. *** Now support $display of binary and wide format data. *** Added detection of incomplete case statements, and added related optimizations worth ~4%. **** Work around flex bug in Redhat 8.0. [Eugene Weber] **** Added some additional C++ reserved words. **** Additional constant optimizations, ~5% speed improvement. * Verilator 3.106 2003/06/17 ** $c can now take multiple expressions as arguments. For example $c("foo","bar(",32+1,");") will insert "foobar(33);" This makes it easier to pass the values of signals. ** Several changes to support future versions that may have signal-eliminating optimizations. Users should try to use these switch on designs, they will become the default in later versions. *** Added --private switch and /*verilator public*/ metacomment. This renames all signals so that compile errors will result if any signals referenced by C++ code are missing a /*verilator public*/ metacomment. *** With --l2name, the second level cell C++ cell is now named "v". Previously it was named based on the name of the verilog code. This means to get to signals, scope to "{topcell} ->v ->{mysignal}" instead of "{topcell} ->{verilogmod}. {mysignal}". This allows different modules to be substituted for the cell without requiring source changes. **** Several cleanups for Redhat 8.0. * Verilator 3.105 2003/05/08 **** Fixed more GCC 3.2 errors. [David Black] * Verilator 3.104 2003/04/30 *** Indicate direction of ports with VL_IN and VL_OUT. *** Allow $c32, etc, to specify width of the $c statement for VCS. **** Fixed false "indent underflow" error inside `systemc_ctor sections. **** Fixed missing ordering optimizations when outputs also used internally. *** Numerous performance improvements, worth about 25% **** Assign constant cell pins in initial blocks rather then every cycle. **** Promote subcell's combo logic to sequential evaluation when possible. **** Fixed GCC 3.2 compile errors. [Narayan Bhagavatula] * Verilator 3.103 2003/01/28 **** Fixed missing model evaluation when clock generated several levels of hierarchy across from where it is used as a clock. [Richard Myers] **** Fixed sign-extension bug introduced in 3.102. * Verilator 3.102 2003/01/24 **** Fixed sign-extension of X/Z's ("32'hx") * Verilator 3.101 2003/01/13 **** Fixed 'parameter FOO=#'bXXXX' [Richard Myers] **** Allow spaces inside numbers ("32'h 1234") [Sam Gladstone] * Verilator 3.100 2002/12/23 ** Support for simple tasks w/o vars or I/O. [Richard Myers] **** Ignore DOS carriage returns in Linux files. [Richard Myers] * Verilator 3.012 2002/12/18 **** Fixed parsing bug with casex statements containing case items with bit extracts of parameters. [Richard Myers] **** Fixed bug which could cause writes of non-power-of-2 sized arrays to corrupt memory beyond the size of the array. [Dan Lussier] **** Fixed bug which did not detect UNOPT problems caused by submodules. See the description in the verilator man page. [John Deroo] **** Fixed compile with threaded Perl. [Ami Keren] * Verilator 3.010 2002/11/3 *** Support SystemC 2.0.1. SystemPerl version 1.130 or newer is required. **** Fixed bug with inlined modules under other inlined modules. [Scott Bleiweiss] * Verilator 3.005 2002/10/21 **** Fixed X's in case (not casex/z) to constant propagate correctly. **** Fixed missing include. [Kurachi] * Verilator 3.004 2002/10/10 *** Added /* verilator module_inline */ and associated optimizations. *** Allow /* verilator coverage_block_off */ in place of `coverage_block_off. This prevents problems with Emacs AUTORESET. [Ray Strouble] **** Fixed `coverage_block_off also disabling subsequent blocks. **** Fixed unrolling of loops with multiple simple statements. **** Fixed compile warnings on newer GCC. [Kurachi] **** Additional concatenation optimizations. * Verilator 3.003 2002/09/13 *** Now compiles on Windows 2000 with Cygwin. **** Fixed bug with pin assignments to wide memories. **** Optimize wire assignments to constants. * Verilator 3.002 2002/08/19 ** First public release of version 3. * Verilator 3.000 2002/08/03 ** All new code base. Many changes too numerous to mention. *** Approximately 4 times faster then Verilator 2. *** Supports initial statements *** Supports correct blocking/nonblocking assignments *** Supports `defines across multiple modules *** Optimizes call ordering, constant propagation, and dead code elimination. * Verilator 2.1.8 2002/04/03 ** All applications must now link against include/verilated.cpp *** Paths specified to verilator_make should be absolute, or be formed to allow for execution in the object directory (prepend ../ to each path.) This allows relative filenames for makes which hash and cache dependencies. **** Added warning when parameter constants are too large. [John Deroo] **** Added warning when x/?'s used in non-casez statements. **** Added warning when blocking assignments used in posedge blocks. [Dan Lussier] **** Split evaluation function into clocked and non-clocked, 20% perf gain. * Verilator 2.1.5 2001/12/1 ** Added coverage analysis. In conjunction with SystemC provide line coverage reports, without SystemC, provide a hook to user written accumulation function. See --coverage option of verilator_make. *** Relaxed multiply range checking *** Support for constants up to 128 bits *** Randomize values used when assigning to X's. **** Added -guard option of internal testing. **** Changed indentation in emitted code to be automatically generated. **** Fixed corruption of assignments of signal over 32 bits with non-0 lsb. * Verilator 2.1.4 2001/11/16 ** Added $c("c_commands();"); for embedding arbitrary C code in Verilog. * Verilator 2.1.3 2001/11/03 ** Support for parameters. * Verilator 2.1.2 2001/10/25 ** Verilog Errors now reference the .v file rather then the .vpp file. *** Support strings in assignments: reg [31:0] foo = "STRG"; *** Support %m in format strings. Ripped out old $info support, use Verilog-Perl's vpm program instead. *** Convert $stop to call of v_stop() which user can define. **** Fixed bug where a==b==c would have wrong precedence rule. **** Fixed bug where XNOR on odd-bit-widths (~^ or ^~) had bad value. * Verilator 2.1.1 2001/5/17 ** New test_sp directory for System-Perl (SystemC) top level instantiation of the Verilated code, lower modules are still C++ code. (Experimental). ** New test_spp directory for Pure System-Perl (SystemC) where every module is true SystemC code. (Experimental) *** Input ports are now loaded by pointer reference into the sub-cell. This is faster on I-386 machines, as the stack must be used when there are a large number of parameters. Also, this simplifies debugging as the value of input ports exists for tracing. **** Many code cleanups towards standard C++ style conventions. * Verilator 2.1.0 2001/5/8 **** Many code cleanups towards standard C++ style conventions. * {Version history lost} * Verilator 1.8 1996/7/8 ** [Versions 0 to 1.8 were by Paul Wasson] **** Fixed single bit in concat from instance output incorrect offset bug. * Verilator 1.7 1996/5/20 **** Mask unused bits of DONTCAREs. * Verilator 1.6 1996/5/13 *** Added fasttrace script * Verilator 1.5 1996/1/9 *** Pass structure pointer into translated code, so multiple instances can use same functions. **** Fixed static value concat on casex items. * Verilator 1.1 1995/3/30 *** Bug fixes, added verimake_partial script, performance improvements. * Verilator 1.0c 1994/9/30 *** Initial release of Verilator * Verilator 0.0 1994/7/8 **** First code written. ---------------------------------------------------------------------- This uses outline mode in Emacs. See C-h m [M-x describe-mode]. Copyright 2001-2015 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. Local variables: mode: outline paragraph-separate: "[ \f\n]*$" end: verilator-3.874/README.pdf0000664000177100017500000032441212534631201015156 0ustar wsnyderwsnyder%PDF-1.4 %ÐÔÅØ 1 0 obj << /S /GoTo /D (section.2) >> endobj 4 0 obj (1 NAME) endobj 5 0 obj << /S /GoTo /D (section.3) >> endobj 8 0 obj (2 DISTRIBUTION) endobj 9 0 obj << /S /GoTo /D (section.4) >> endobj 12 0 obj (3 DESCRIPTION) endobj 13 0 obj << /S /GoTo /D (section.5) >> endobj 16 0 obj (4 SUPPORTED SYSTEMS) endobj 17 0 obj << /S /GoTo /D (section.6) >> endobj 20 0 obj (5 INSTALLATION) endobj 21 0 obj << /S /GoTo /D (section.11) >> endobj 24 0 obj (6 USAGE DOCUMENTATION) endobj 25 0 obj << /S /GoTo /D (section.12) >> endobj 28 0 obj (7 DIRECTORY STRUCTURE) endobj 29 0 obj << /S /GoTo /D (section.13) >> endobj 32 0 obj (8 LIMITATIONS) endobj 33 0 obj << /S /GoTo /D [34 0 R /Fit ] >> endobj 36 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ-ÁjÃ0 †ïy ãƒ˶d»·Ž¥‡Á.ÅôRz(´Ý ”–ן Bü?Hß÷‘»á@Ð{È ‘mñÅXÈ78÷'b_žÓu¥¹Þa ¾Åã¸ÿü[><§»ºä¯‚ @„‰ÙVl¡±ho0zߨ¿Ê†~]_»aض ÿj-’—Ò%ÌmO8/?Ž‘Síª¹¬!ÖFʼ• “X©Fë1RÍF‚´ª‡Ý˜»¼; endstream endobj 34 0 obj << /Type /Page /Contents 36 0 R /Resources 35 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> endobj 37 0 obj << /D [34 0 R /XYZ 121.4 736.262 null] >> endobj 38 0 obj << /D [34 0 R /XYZ 122.4 698.4 null] >> endobj 35 0 obj << /Font << /F16 39 0 R /F17 40 0 R /F15 41 0 R >> /ProcSet [ /PDF /Text ] >> endobj 53 0 obj << /Length 392 /Filter /FlateDecode >> stream xÚuRKO1¾ï¯è±=P;Ý>ŽËRÌXpÛ51ƃQLH@"’ø÷íRðž:I¿g§Ã]¡ –[% /¤ä9ÑRqc‘„grOo™AºÜ­Ö èž €nã°cÄœ"7:ïG¤­+G3—æñj½dar5FñCAp%ˆ¤\Í›àšà{dæBö–õW‚ÀW ä 4yÚd÷‚<Ç« ­!à† Ò\ÆiM|v“ û>ÒÈ9æJ~RÆðõÑvûÊ0VYÆCÐý{ *í ‚Ä±Z"XYЦ<ÔPšÊžôƒ„“ 7ª}hëaêyÃR ùxç«¶^œà…Å?ð„ÎÚw‹Å¼eVÑàF1N\Ž¿óÁÍ|$ƒê²W‘ØuãCÏ-§Óò qÊhDŒsnª­ó%CI¯]2Í«n7wPú–«¬Ž9/ØëÓÓ´® )þÝ1|h{é® ]奅ˆiÏ£˜$1­gõo㾸€‰õ÷CàQ¨@®œzüqŸD­ endstream endobj 52 0 obj << /Type /Page /Contents 53 0 R /Resources 51 0 R /MediaBox [0 0 612 792] /Parent 42 0 R /Annots [ 43 0 R 44 0 R 45 0 R 46 0 R 47 0 R 48 0 R 49 0 R 50 0 R ] >> endobj 43 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 653.57 174.359 662.438] /A << /S /GoTo /D (section.2) >> >> endobj 44 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 619.7 225.571 628.568] /A << /S /GoTo /D (section.3) >> >> endobj 45 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 585.829 219.927 594.697] /A << /S /GoTo /D (section.4) >> >> endobj 46 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 551.959 267.625 560.827] /A << /S /GoTo /D (section.5) >> >> endobj 47 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 518.088 225.045 526.956] /A << /S /GoTo /D (section.6) >> >> endobj 48 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 484.218 288.639 493.085] /A << /S /GoTo /D (section.11) >> >> endobj 49 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 450.347 285.125 459.215] /A << /S /GoTo /D (section.12) >> >> endobj 50 0 obj << /Type /Annot /Subtype /Link /Border[0 0 1]/H/I/C[0 0 1] /Rect [121.404 416.477 215.749 425.344] /A << /S /GoTo /D (section.13) >> >> endobj 54 0 obj << /D [52 0 R /XYZ 121.4 736.262 null] >> endobj 57 0 obj << /D [52 0 R /XYZ 122.4 678.574 null] >> endobj 51 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F28 56 0 R /F29 58 0 R >> /ProcSet [ /PDF /Text ] >> endobj 61 0 obj << /Length 1829 /Filter /FlateDecode >> stream xÚÛvÚFðÝ_Á[ű‘uIí&Ø!'¶)‚8>i„´†m„D¥UýúÎìŒ@8¤Íé šÙÛÎm¹™_\ßÚýNh†gЙ¿tlÇ1½Žï Ì t;ó´óÉøÐ \C”2‹»¶¡º=Û((»=×õ × |Aט‡oîÇßÊLt?Ïß]ߺV‹»ã†¦ë‹8ÃAÛ²,#ZL§³nàsd?~CL¢çh>¾ÏÅx~ñ×… ­Ž}PÒ5mËï$›‹OŸ­N [ï:–é†Ag§ 7wà›@Y'ºøýâ­u‚Ží™®7pŽæ‚Àô\Ÿ”²AÐÊx‚1Ú„YÐÍô}¨çkY‘¶ÍW{h-ù€Fiß©‚=¶“®_ºý¯ÄkßyÆ–ëeÂ$Ù§ê‚pσ›aUVõÍ$šÏ&7‹ùäñá¿U^£x¥¶¿^_ïv;ó+¢ â¶Û  ßÌ,ÊÕu³EÚcd^í¶ñŽã´Œê“Q¸ØlŽŠ-nîK¹Ù>z—Ër{Že÷ ]j‚ŸdV9ÁQŽgö©(Ínϳ|ðOßš V·dfËzÅÒTÁg·\àZ¡iÛ~xë–ù'¦ûÚtÔÌ?ãJˆ7Óò† ºØÚ1=ϘvžøçÇ™cy/ð})… ¨*^ŠÞáO\Šß`ÙöÀ'¨\M4IœPŠTVª”ËZé《vâ<½.XȆî3•/{–ªˆ¸ÎÁ¡´¤Ö,_‰rÃJ/ÍuÛ¶öd@ËaL§¸{XðlU…fŠc¸¹(ãŒi½ÌdÂä2yÅL8O*‰·®ë }Š×Ò¦’ÌoX*pÂkŽmÍû'7Ñðw Ç´0œpiNÄ[µ³éMš^ጽl-õ@‰^ ±N Wt¼ÉXËÅUµ¦YƒìdÜ•2B› ¨Î°TAÇkúqÈõ"ôNý@"é;ºD!—¬Ý/J‘y“ÐgláônÇzÁ]Þ=`û:Û÷‰D­ûDT|I­¸BÞ4}xWèô%†ëÉÐ-Q5`'¥ÒógZ‘Ç­ˆ_i!ă~¡ üö íÿv&à‚qƒ×0i3=R›Ê ¶*¥mr?ë˜lK¹‰Ë=!ì)@ô´ßŲ¦.Sc¦{N{¬nǂĂàýAв–™:wÇš?œ˜‰”¦1Ǥõ7¬NhÜÇIE;Qïão§‹‘9DE—²Ò½Ì5&<ÓÁ†ž¦aà„bÚ—jÎн˜ëØáuôƒjƒÊ{¾cÐD¶'´—ßz²Zº…Á`­‚Ó`”¢Ok/y¾K^Q~©hƒØ»ðŽËS]ìw-ð³iFûÕNæà“¾EuóÜÚ>ïÎáÙªÜw±¿Þ=¦'Lâ„ðÞ&/zˆj)8‘àí‡öwyL©–Œ|hv¾3—¤ªDC«.íÇY¿Ý‡ª#üw@£1€÷õhª(ü±¬€“4粋µF* v`ÃÓÒÉ1m/hþüŸÈ?½8•µ endstream endobj 60 0 obj << /Type /Page /Contents 61 0 R /Resources 59 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> endobj 62 0 obj << /D [60 0 R /XYZ 121.4 736.262 null] >> endobj 2 0 obj << /D [60 0 R /XYZ 122.4 698.4 null] >> endobj 6 0 obj << /D [60 0 R /XYZ 122.4 637.717 null] >> endobj 10 0 obj << /D [60 0 R /XYZ 122.4 429.476 null] >> endobj 14 0 obj << /D [60 0 R /XYZ 122.4 205.406 null] >> endobj 59 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F28 56 0 R /F31 63 0 R >> /ProcSet [ /PDF /Text ] >> endobj 66 0 obj << /Length 1950 /Filter /FlateDecode >> stream xÚ­X[oë¸~ϯ0²GÆÆ²DÝìSô!'ÔÛsNÐÄ]`±»È‘-Úf#K®HÙÉ¢?~g8CGN´-ZôÉCŠÎå›CšŸoÃd0õ§©HóÕ Â™HýÉ4Ì‹ÁÏÞÃIäÉF•ù0ôÌpz5ÍpE±ù“,F1òîo.¯¿Ü|«J9üuþÃø6 :ÚE–ú™˜ Òœ€² ¼Ùׇùp{—Ÿ?_âaóÙÝWÜ}v3?ûçY˃Ax4-òà ,·g?ÿ øôà ð£édp° ·ƒ(Í|R9x8ûÛÙ'ôÎ c?ŠSñêd:™øq”½š:S¦‚L_gÊ›0pÓϲ˜vߢÕuC¾oëF’TH“«RÓ@K‘°£høñtê²1f÷q<>þ"¾ŽÄ¢=™W—~=„Q³ï†0nêÈ¥Ñã½Äd@rLm§Çõ3j<«´ÉËRUëûEú)XÏçú¸]~˜EƒÄxÒ§Ù ÌÂ{ÁÃë–UÂ% ÖJtY„à¼jõ‚'Û?bn%ÙØ\à\Œê2VzzS·eA‹[-I0Vy¾Væœæ¶Òl(¼:×ô« ­ÃتRšSÃÑCH[úÓ$!ßL“/ñëeh‰6mòj-5DÄþ4H£xêÇÁ„öÌ7œ\ðFjCòwÊF«º¢ ÅIÏQý~˜$!_”¼77=PãØOÃì¿ÃÂ^ºÜð'ÑaøY½I´˜$~Ž… ”¯ O×VÇ¡*ë¼ +Í‹½ÇÝ úµæ«¦Þº}9/ÔÊÈ v¹*ˆ1 ¹¬·»Fj 2Atò2°0ºàÚ49TV"ïyÿÛŠ$çvƒ>î)ô¾YÿÖ‚‘Ó ˜w厨QÕ8 ð t„4Zm‘ŒâË6r{Eƒ_‚$Øk’5@I­7¨ÍÐÌÕ÷ߣ´Ðš]k`q‘‰ðŠ“@¿Skãøo ÛA‡¶»—} Bwª}”f“VY’9COˆE§ñGn,¨ÝLÓ.qB³ŽŸ¬Ž–¾SüPª¤,iîèÓº«±4‘ ?=Ìo¾\=b6gÀ,_¯>ÿýú†˜Â-æPçÜ7æ ¨»jY¶ ÕEÖÍ ):(´=—#¶9!…”ŒSX ¨2ˆÜ$cä&¯V~ž}ºžÝÓœµ’zjî~tæaê;Á<[R©Ψœ–‚¦ÆRDZß]YH¾†9Y:›/M³[K?/îþá¢d7h —å«s—÷¸çê/Ìc¨ `—L^øˆbgV”øiÊÜq„îaÉ€)Aö{6õÓ‰p°\•ò¹÷ªòEtdE´÷½¢p tv\³Pº®ú4§‰[õ†ÄôÑa ¤,úÈ øRøY²óÜ-‹¾’Ãîàx¯[ D ¼öTƵ ]làe.ÕCQÑEj·»{…z-fs>ëĨ“ŒT®Äq°ÉQï~Èwv­fVÏml7Á[˜%?¸¾f]³Iñq¯$…ÿ"ørO^ìÜB;xwî ¯µAÒ¥ž¡ œZ´ª,4ÉV ˶i¤£!ð*NR//[þ^¯XßÍýŒ›Ë»ûG‹ñ»»ùíqØŸ!ïÒ¯o.úŠj% ÞAR'ß ¹ÊÛÒðHQk‘ÿ Èg¹l öÈ1iæéš´›~\Ê[Þd‹”lûxkY7 0_`«c+ pú%ˆâuÛ@ê(öS?ЈÐÏBncC —šà»ïˆãζp»ÖU^ÒÔŠ[DD£0]8‹¸Ä_4;Æ‚*¸Âÿ¢i®i+ZtÌ­¥«šÏ¢þÁ*ÙHÚñ„mμÖì$ëCa_'!˜Ûúàlw­ñ˜ð2I=™keûœ•ÏDÛ`Ë–AÄ×ÕæUÈ~mmwë&/løF±˜z3óáxš®iͱlp°­µéÃÑÍ5uÉÅG*j븺kgô\êÖhLAìÔ$7doïÆNe‹Ú¨ÄåâÈ '7ÇIÛŠÄÝO®—ÆÍW-„±n 5fTgó;ô ê jìÏßv‡âŒ“,ñ¾£UŠÛ¸—ºåÖNo$a?jú]äzÓ>¸Èdµÿ£ãhþÏÄ—üßœ»Ô½}?†Z)¨ Ù×dÂs0“ÓÀ®§¹%cm<íÄë²^0W¨~% åôs¾Ì |ý$@-J?Ñ$7 mq ðÚÙ·ÌW؆XÓ>|®¯Hdš¦„XÆïâ}M6ð7ðŠþèbl—[{@âf?~á—Z[J=vïB,·ÅÇÿ„,¾ÅÚÊv-ÝLßÛŽŸ2…àïÿRöœ7 Âsì]azE`dú?¡‰Od«okÞi«Ô Ç*Å‘} Ÿ|·o{hEXŠj· Éš`_8¨9*kÅa,¤^6j!ûlê"Ü.v¨¼‘+õL3ã«ËëÇëÙÃ_ÝÃÓZÒŒ¿½?ÀŽþÅq‘lϹ~}±¢æÇñøüÛÑ–Næ/W¦ëý#w¬OÂþÁEûW|~N?Û¡FòJ9©TOoã¹ÂÐ@û±¯‹ƒÖ*J±µ>¼dÈ´Èý5õ;dª endstream endobj 65 0 obj << /Type /Page /Contents 66 0 R /Resources 64 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> endobj 67 0 obj << /D [65 0 R /XYZ 121.4 736.262 null] >> endobj 18 0 obj << /D [65 0 R /XYZ 122.4 698.4 null] >> endobj 69 0 obj << /D [65 0 R /XYZ 122.4 282.288 null] >> endobj 70 0 obj << /D [65 0 R /XYZ 122.4 194.746 null] >> endobj 64 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F28 56 0 R /F31 63 0 R /F32 68 0 R >> /ProcSet [ /PDF /Text ] >> endobj 73 0 obj << /Length 1722 /Filter /FlateDecode >> stream xÚåXYo7~÷¯Ð]Yj¹\îѾT‰Æic»¶ Hc¥¥¤…÷Pöð ÿ½3R‡½.‚¾öE;’3CÎ7õjv4yÃå(aI臣ÙrÄ}Ÿ£ÈYœˆÑ,}r>Žcá¨&/Ò1wº±Ëˆfì 8‚ÅQ€¤p.O¦ÇïOˆ~“jüeönòFx{Ò}Ÿ³(y$8Yžç9®¦c?v~7{Ï_xr6CµSü™‚¾sT|†2NfG_8HñF|k°`Ü‹F‹òèÓo”ÁÔ»‘ÇDîôÂr$ˆù@£«£¿Ž^áÉ…¿òÄc<à£0ŽY "2±Up`éK'¯Ú.-Šë¦®ÑÍ œ Ò¯§Ç×ǧWLnõ%uu3ù†|¶y]¹U_ÎUãö­Ê\ä§óúV}Ç“€5.ç,‘r«MU·¤ðãÉåéŸÓ™>öåõåùùŒø/ö,醄lµQUænRí«5Yz1ÅÁìí€É<¯~\Ð{-èìb:,«L+òûªÀ¯, $ȲP¾` Ü?[+r|¥î;¢êM7GË[âu5}:3èhѪˆÔsà? b^ÒlßæÕŠt[%uS¦fwûÐvª$N¹n1˜ÝÇÅéæjúj ë§K¼ã'ÁƒÄùÉgI߇ºoˆj× Íד-}çi»rÖóÚç\F’TÁMáÔ’è§ÿ¢r1¬‘MuµÌW}£~Ôñã´èTS¥]~‹Ñ¬À®öŽêž‹´2D]}öD õhFJòïiÔ­{Hí¼ƒ»ÜR›±‹Ò7=ÄB¯{¡“¶4WÖ-÷YäLJçüýìÃV(¢00kûÚtCpð=–ðèÿ½Îu7(ªQËüž8Ö]ês?žèŒuuz~6 ƒë3‚¨8¤Æ%@ˆHãpÀ÷w0ÂIR•RQèH-#Ëh¦±¸3Nö\Ƴ)æbWzÞ2½Ð…•pÀˆX,cc7Ê~ ´¨!¨H n«]™Þ …”0_„v‘µ`Q—,¡z°+ÀpcO€ð%K‚ÿlŽv`§(N&¡|ÆþÃPÉZÁ'rnLÙÔJF§˜º•QÈ8V¾>üƒ¹[XÆ,†­FýgÏ—ªJç…r ]€«šÝØøLF‘ݸ¬RSÖZa˜h3 ˆ#eêÏ¢Šo³^‹ÇÌ& pè,Ë]:9t ‡¶ee“ê[ºKé¤+eK™jÿP9š“.4êkŸ7ˆc\GÓ½¶æf1²x›œôþØÐa‚PE„*p°Â”‰™?ªiP²æÌ)Ãõ-5+º}ejI\ÊÔ2_qK’8=¨ë„ÝÁEEAìœd蛜úD\LwKí"M`¢ÎØú¹ð“¨7­Ój¥h¬& Ô\½-tît†hn  È8„JýÀ«Ðþ¢ßÚ´Ü|é5_Uè5¤ž¡$ŒÇŽéØ¿~ß:EH‡&¡‚@?ˆv9 Øÿ!Òye2xè ®ó&îЙ¶tªT46ò~nÌþ¬®Ãd'‹¦^5iÙÒD»®û"3´lµ”K¥s›7uU¾ó"ð„bÚäu´ÔÚ+¨âlmÅ9~ákŠg¾“dç*k,7ÈÉò¶kòyaóòó°Sàž£îÕ¢×Ñ ƒÃ&`B?LõØ ÀµÜ­sÊX´Ý4@aª2¢)= aÕCFmÛN¬:6^QR¡EçBÄ{- H™Äï7=0jMŽ-uC#hY‘qG³YMßt grÈ·±'Ÿ¦xÛ==Í–!ôFAbw ˜dìè§—ÑÓôO®,[ëœF3¦NŠ„I `Í—Ñ¡ bçÒæè ²àfÌ0¤¿æú̆ý⌜< =‚Îo±tZ4*ÍŒ¸¹©ŒzÐ5½¡°#Ã/=ö½îYž†D‘öEg‹Ý¶Ž~þ’RyZe6ÛßЭ˜¦²1¹þ0ä/1¾©GÄÇLkŸ(æU¡ËÈgоò€‰ ô©‹ Xâ…ÐðLv¯in^Ó‚Ók:Œv¯éć[K YîÌ<ÝÜG‘î±êRh@Ìi2j’½Í©}Ÿ‰Ý‘Í=aªl!\ÙÖÀ²¶NÐ×¢Ô–M… i@\®x¶ùµ¥qdþžÐ¡OOàünl£ MîæÙô‘[s.æÍ(Lñ²}Wg§yõ¨ï’bNžå¶ÔaÍ3PÖ¸°Øµu2ý[BYƒÇú$Ý\&21¯*ûWÇ?TP“t endstream endobj 72 0 obj << /Type /Page /Contents 73 0 R /Resources 71 0 R /MediaBox [0 0 612 792] /Parent 42 0 R >> endobj 74 0 obj << /D [72 0 R /XYZ 121.4 736.262 null] >> endobj 75 0 obj << /D [72 0 R /XYZ 122.4 644.381 null] >> endobj 76 0 obj << /D [72 0 R /XYZ 122.4 580.62 null] >> endobj 22 0 obj << /D [72 0 R /XYZ 122.4 230.589 null] >> endobj 71 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F32 68 0 R /F28 56 0 R >> /ProcSet [ /PDF /Text ] >> endobj 79 0 obj << /Length 816 /Filter /FlateDecode >> stream xÚU[o›0~ϯàVá`ln“V©MÓ)Õºj í4µÕDÀiPgÆIÛ¿c $©z{IÆç;ß¹ðÓx0<Çž¡Èw}#^Øu5×GaDŒ83nÍ+$&y‘XØ”–M†°lB¨IPPes:>9»kû> endobj 80 0 obj << /D [78 0 R /XYZ 121.4 736.262 null] >> endobj 26 0 obj << /D [78 0 R /XYZ 122.4 698.4 null] >> endobj 30 0 obj << /D [78 0 R /XYZ 122.4 472.061 null] >> endobj 77 0 obj << /Font << /F15 41 0 R /F30 55 0 R /F28 56 0 R /F32 68 0 R >> /ProcSet [ /PDF /Text ] >> endobj 81 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0´TÐ5W02S0µPH1ä*ä2 (˜™Be’s¹œ<¹ôÃ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. (\®ž\\&Q# endstream endobj 82 0 obj << /Length 162 /Filter /FlateDecode >> stream xÚ]± Â0†‡Â->‚ÿ˜ÄK…N…ZÁ ‚N⤎ŠÎú¨>‚c‡bMN8¤>È÷] çy’°ÈáÁü GGbŽÎÂO%ÎT2[0“YFK&¬p»ÞOdªõŽLƒÝS¨AZZFý¢HW 2"ÃòL}¦¾Tß©oþýï»­® ËÐ"І¾Öº?¦ endstream endobj 83 0 obj << /Length 175 /Filter /FlateDecode >> stream xÚµ± Â0DQXúKä'2Ò† á * D” ¨Ãh%#¤¤Âü#6HáWÜYòóMíÄÈà0žÃp œsº‘µf˜¹Øœ®Tz2{XKfÍ1¿Áãþ¼)·Käd*rdGò”R/¥RA-œ%¡a|¸½ݠЂ´V$‘Q¬ùµñžî†·êÞoÄ×e«ú¿U¿ïG+O;ú‚a endstream endobj 84 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚµ± Â0EQ Ýù €miCp¢ ” ¨“Ñ…(©0¾ó i~ñϧ{~37õ <& ¸ ~‰³¥9—Jƒ¹Ï“öJu }€s¤7©&¶xÜŸÒõnKºÁÑœ(4è^J©øåøqÄ^©.JùNQrŒ?)F#ŒPäëQ1H¢)3RŸ;™Ê;Ù˜J~.؆xCÙˆ?ZÚÓOYbÍ endstream endobj 85 0 obj << /Length 104 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UеP0¶TÐ5RH1ä*ä26 (˜A$’s¹œ<¹ôÃŒ¹ô≠ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿÏÄÿа—«'W *› endstream endobj 86 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04U02R06P05TH1ä*ä24Š(YB¥’s¹œ<¹ôà M¸ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ü òì?Ô¨ÿ„êÿØÿ‘ÿÃÿ‡¡ ÿ0ü`øÁøƒñóöìøØ7Ô7ügø.`àrõä äj'.ç endstream endobj 87 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0S0W0¶P01VH1ä*ä26Š(›%’s¹œ<¹ôÃŒ ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h –X.OæöX±ûŽììþ±ø÷Ÿýà¿ÿÇÿûÿüü?ûÿÿðÿÿÿ€ùÿÿÆÿÿêÿ€1ˆ ÉÔ€Ô‚õõ‚Ì™2—} ·p¹zrr«xSº endstream endobj 88 0 obj << /Length 116 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V0S01T01QH1ä*ä26ŠE-Àɹ\Nž\úá Ææ\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O† øA-Âþÿÿÿ€øÿ4‚Šv@  Ã¹\=¹¹emH™ endstream endobj 89 0 obj << /Length 136 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04UÐ54R0² R ¹ ¹ M€Â FÆ0¹ä\.'O.ýpC.} —¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ƒüûõ?€ðÚÿ‘ÿÃÿ‡áÆŒ?˜?°PààP—«'W ŸÒ,5 endstream endobj 90 0 obj << /Length 99 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F †† )†\…\@Ú$l‘IÎåròäÒ pé{€IO_…’¢ÒT.}§g ßE!¨'–ËÓEAžÁ¾¡þÀÿ0XÀ¾AžËÕ“+ ‰;“ endstream endobj 91 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0UÐ5W0¶T0µPH1ä*ä26 (˜™Bd’s¹œ<¹ôÃŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ì@ÌÀß#äÁHÌD؈:Q'þ€ˆ@Ì&> f0ñd˜82î>3Ñ dfâ ¸™¢Dp¹zrr@Ä:Õ endstream endobj 92 0 obj << /Length 107 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04F Æf )†\…\††@¾ˆ –IÎåròäÒW04äÒ÷ sé{ú*”•¦ré;8+E]¢zb¹<]äìêüƒõìäðì:¸\=¹¹{-= endstream endobj 93 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0V04S01T06QH1ä*ä26 (Z@d’s¹œ<¹ôÌ͹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. õÿÿÿÿÄÿ °‘§\®ž\\ºâAŠ endstream endobj 94 0 obj << /Length 145 /Filter /FlateDecode >> stream xÚ31Ö3µT0P04Q0²P0²T05WH1ä*ä !P"•œËåäÉ¥äré{Źô=}JŠJS¹ôœ ¹ô]¢  b¹<],jÿ0ÿaÿÁþÿ€|ƒ|ƒ=ƒCC þaø†ÿüðÿÃÿÿÔ¡ýûòØp¹zrrÇà/° endstream endobj 95 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 96 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0W04S06W02TH1ä*ä2 (˜B$’s¹œ<¹ôÃŒ,¹ô=L¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]êÿÿÿðÿÿÿ0 âs¹zrrå$~ endstream endobj 97 0 obj << /Length 117 /Filter /FlateDecode >> stream xÚ31Ö3µT0P°T02W06U05RH1ä*ä22 ()°Lr.—“'—~8P€KßLzú*”•¦ré;8+ré»(D*Äryº(Ø0È1Ôá†úl¸ž;¬c°ÇŠí Èl ärõä äÇ\+ß endstream endobj 98 0 obj << /Length 168 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.cs ßÄI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.Ovþ;¢ù†: ÁPƒNØÿÿÿÿÿÿF0Ø1ü`€uŒ@¢†ñQÄf ñƒù„Àf2ØJÆìó~ ñ€¿‚ñ;—«'W ÇžsË endstream endobj 99 0 obj << /Length 251 /Filter /FlateDecode >> stream xÚ…±JA†'\!Ls­ÝÎ èÞ±žšÆ…Á+­,ÄJ--íÄ;ðÅy‘µ²4åB–[çO"h£ÍWì¿üßÌì¹Ýf,•4²s n,Í¡ÜÖüÀÎéc%ûÍ:¹¹çIËöRœc{ªÏlÛ3yz|¾c;9?–šíT®j©®¹ fDT„¿P&E—{åh+ç•9G2ËÏD~þ>/BG¯Eðô$E7è~ }§ø¬€ŸK…ÑvmV›:¶¼«$ê,HŠ@•%¡j»}¦W”}þa³ÂzHõ‘ ¦OØ#b£¼A=ðb2ñßãà~|Òò0Ž endstream endobj 100 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚmÉ=‚` à’.žÀ߉1‘ÁD'㤎]…Ä‹‘8p n #¡~ $(}úö­ëL<ŸL²å¸6y6í-<¡Óvf{¶ÝÃÅšÅ\¶(â]Î׊p9% ED‹Ì-Æ4 ð•Óžgö&ëÉ{ô¼øâ!1îå¥qƒú?µ\ÀÜ P˜ùCÁµ#ýA“dZz–4Àu ×,iºÔu8‹q…/ÂaoM endstream endobj 101 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚÏ1NÃ@й°4¹¬—QY AÂTˆ (‘A‹ÃÍrÁå 3AzšWÌJÿ_¤ãæ”kN|y¹9á‡H/”–v¬¹Iû—û'Zun8-)\Ø™BwÉo¯ïVWg)¬ù6r}GÝšÅ3J•~ ZýôªýT™Mè¥Øa.åˆÊ)¥œ- ™oö̤Å/½ó`t™œÝÿ˜þRôø27ÈäVÖ¯½ifðöƒíh·¾hãÛ`+-·Rû¡ÔÑÒìNç]Ódvg9 endstream endobj 102 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.c ßÄI$çr9yré‡+[pé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿþÿÿD|?€bØ0ÿ ÿAD}°ò€ÿÁ&> f0ñH0b!þO ¶ƒn%Ørv¸ƒÀî³?sóˆ?À>û æË `Ÿs¹zrríÇG endstream endobj 103 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿÿÿÿÄÿ Øæ Œ„ † ‚ƒ`|$€lthv›bˆ)ØŒ‡6 ¢Žä£ÿQ Ø.WO®@.ÌŒ‡r endstream endobj 104 0 obj << /Length 145 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.c ßÄI$çr9yré‡+[pé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿÿÿâÿHìó"ˆ Á€ƒø$`@±ØCLÁmQDýÿ ÿ!Ä( ,ÆåêÉÈæxô endstream endobj 105 0 obj << /Length 227 /Filter /FlateDecode >> stream xÚÐ=NÃ@à±\¬4๬¥PY AÂT(PR$‚ÖÞŽkÍ ¸7eŠU†ÙI"QÒ|Åìß{;—Ý5袥ùŒº½´¸Á°ÐaC]8®<¿ár@ÿHaþVÇè‡;zß~¼¢_Þ_S‹~EO-5kVE*#TòÉPËŽaa¥'\¦BÙƒ°û‰«oè¹Ò\Qéõ4÷pf<á¢`2éß”²Oà$‡Ì˜gãßëíµúD> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿþÿùÿŸñÿ?cÀÀ€êÄÿÿÿ±4± Nàô%—«'W žˆ‡ä endstream endobj 107 0 obj << /Length 108 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bc SC…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§g ßE!ÚPÁ –ËÓE¡þÿÿÿÿÿÿà >ÿ†Áޱ¹›ËÕ“+ H¨X~ endstream endobj 108 0 obj << /Length 218 /Filter /FlateDecode >> stream xÚEÏ=nÂ@àE.,MÃvN€m M,ñ#ÅE¤P¥ˆR%)S€B‹9QPr„ø.]¬lÞÛÈ¢ØOš·ÒüLÒÑt¦±Žñ&c&ú•ÈFRf1K~|þÈ<—èMÓ™DÏH%Ê_ôw»û–hþºPÔK}O4þ|©…3EÓµ¦s|–Æ@F öÄAÖ¤ÃØÈHaÀž8pnÀ…\]Ï­GЈ-8¶j<ì\  8hP÷Ãýÿø­žHF¬é–=a…‹,oËÚ>“U.k¹9‰s endstream endobj 109 0 obj << /Length 123 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bCSC…C®B.cs ßÄI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿþÿÿ€L€Å˜ŒÁN|Œ?ˆ êÿÿÿÿã?*ûÀåêÉÈé f’ endstream endobj 110 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õøÿüÿÀ ÿBü`°ÿW$þð‰ü{ª1ˆy Ÿ‘‰ùŒ0¢Ÿñ1Œh†í͇ÄqÑ|¼F¼‡ï™aÄ Ñ𕨠‚l¢è·?`¿!°—«'W ±,ˆ endstream endobj 111 0 obj << /Length 194 /Filter /FlateDecode >> stream xÚUÏ-Â@à%ˆ&c¸Ì 迨¤”„ P‚$ޤu½Ö’[GEÓev›¶ æKÞ1Çî»hÑ8º&nL؃-;CF¹XïÀA_ í>¡ôpŠÇÃi º?!å—&+ŒRå"c¢(ɉ(§N+˜ÆµGÍSroˆ‰›‚W\¯Š‹"­àЬæüÏ ¦+éÕtI…–ðߣmÅ›h5|Ö ¸üˆ‹¢dXB]/†qsøº‰| endstream endobj 112 0 obj << /Length 170 /Filter /FlateDecode >> stream xÚÅ1 Â@ERÓx„Ìt³Ž)R-Än!he!VÆÒBÑÖä¨9‚¥EØq™Š†Wüßü7sžæe”ÓÄ”Ϩ¶xAæƘ‡æxÆÒ£Ù3šUŒÑø5Ý®÷šr³ ‹¦¢½¥ì€¾"h é`,ò‚T¤'ÀuID ˆ§x¸/„ˆ¶Hÿ ¡øÙ÷®î9 ƒ›Zª¯šëpéq‹o¡lª endstream endobj 113 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bSC…C®B.cs ÌI$çr9yré‡+›sé{E¹ô=}JŠJS¹ôœ€|…hCƒX.O…úÿÿ0üÿÿÿˆø"þ3Åþ70`øH؃þ@‚ýŒ`?€#^¬„ùŠ^°Q`Cƃ-YÉ ²œä fƒ€² Ô$êÿ700€ F"Àb\®ž\\æ„wN endstream endobj 114 0 obj << /Length 197 /Filter /FlateDecode >> stream xڕСÂ0à›jrfÐ{Ø::"#a‚‚ ‰€€îÞ e0‰XvtmC‚ùÄßöîOõh˜Ž)¦„Š´¦TÑ^á µ²aLiâOvGÌ ŒÖ¤FscT,èr¾0Ê–S²iNûf‹EN†`æÒY9†»Q‰¶3p‚qNÊNÙ3¼ÿ¶ßO0ïÉn‹ßè¶ ×ÄZ¿’J4½&}þ5tÊò›¦y+™A²ý ½-ؼ+Ô€³Wø2>z endstream endobj 115 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚu1NÄ@ E½Ú"’›a|˜„$ÕHË"‘ * D”H»$*â£å\!GØ2HQÌw€‰æÉãÿmÿ©«ãæT ©å¨”ºæDJÞsÕ ‰gõ­Ü?ñ¦åx#UÃñmŽí¥¼<¿>rÜ\IÉq+·¥wÜn…˜™åº2ûÐÌÌ4w„C0Mý€¤LúNÔéL”túAø ¨9ÁçÒ„Éa=tC¹6”8y€ÇF¢Ì›Ôa¥OÚ2éý/òaÁ<Ãô&ÄØùE>oùš¿åxv endstream endobj 116 0 obj << /Length 124 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b#SC…C®B.c˜ˆ ’HÎåròäÒW0¶äÒ÷Šré{ú*”•¦ré;8+ù. ц ±\ž. õÿÿÿÿÄÿÿ¡êêð@†H0 zÂþÿ(Qÿÿ—ËÕ“+ +òT¬ endstream endobj 117 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚeÌ;‚@€á!$Ópæº,‚Š1q ­,Œ•ZZh´.FÇ5¸”\5šo’2ã¹s? ›šqòò98^Ñ}G›|ç»9^0ÈväÈV2#kºßgdÑfAYL{NöELi iÛwÐw?>Í,À¨Ì Ìʰ ]’ xB˜i ¿´LHäÊ›1VÞL0óJRþa”…¢Vèu¦èZ À¥À-¾òVi endstream endobj 118 0 obj << /Length 197 /Filter /FlateDecode >> stream xÚϯ ÂPð#†Á)>‚çt»ºËÂœà‚ É &5mÂ.øb_CY°N wíztøo,È¿ðNøìvÓéE‚‚ì69‚æWh .-rZùe¶D/@sL¶@³Ï5šÁ€6ëíMoØ%n}šðÏŸÂ :ƒš–ßæ}v%Ö$@ö—F•´T÷iX°zÒûÓ[õñ¬¿VÎÉ!zyMŽì-¹ß+_ªX=”Ey>JÍ3CN™.°àï{ŒK endstream endobj 119 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚmÌ= Â@à Óx„¸ ‰‚Õ‚?` A+ ±RK E[“›™£ä)S,;Îh%Xìûfæùh<¥” }å:exÅ\³T¿:8^pV¢ÝQ>E»’m¹¦ûíqF;ÛÌ)C» }FéËEÜ$ s­´àXBט^H”ȃ©ÁÃ@ž?|be¨®ŸàzY©E—ƒâÿðTZ_Õq×-`öRÅ!a~…ˆƒ„®K<.KÜâj/\ endstream endobj 120 0 obj << /Length 187 /Filter /FlateDecode >> stream xÚŽ= Â@…g°¦ñ™˜„Ä"•#¸… •…X©¥…¢­ÉÑr”aË€!ãN;±˜æï½GÓY‡®âg!ŸBºR¤³@[]/”òw%ä¯Ü”|³æûíq&?Ý,ØõïÝåLƹ©¿+ðx•ƒ“À—´€"Ò¡@±y‰Rx Œ-¶0ª±éþ~Ð*ž?¢uîmÖ½rç!0±ƒe¥æ] ÔEÓ`ç%ÐÒЖÞ*Åsz endstream endobj 121 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚŽ1 Â@E¿¤¦Ik—9›°° Än!he!Vji¡h›äh%G°L2ΦÐÖ…}ðgÙ?of§óÇœêÅlS>'t#k5Ñ?œ®”;2{¶–ÌZ§d܆÷ç…L¾]rB¦àCÂñ‘\Á¤"iJzŒDˆÆ=á[5/”ÈjLAOåQ~Ñý‰ß¡@«B_ÕZ¯h4èÊJ—â5¡Î«µ^RMuZ9ÚѲuEJ endstream endobj 122 0 obj << /Length 193 /Filter /FlateDecode >> stream xڕα‚@ à’.<} L— &Þ`¢“ƒqRG®â›á£øŒ—;[pqÓᾤ½´ý 5)+ÊHñ+•9ís<¡’^&¥|ìŽXLפ*LçÜÅÔ,èr¾0­—S⺡MNÙMC±€Ä  ÿ$z1Ú1Þwxï!"Ëûâ>ô<æôZ™iá&³N°?â>cíH ãRa¸ÊÉHŽ'c Ë:ÇÑ´m™¸O,Î ®ð —ºYK endstream endobj 123 0 obj << /Length 201 /Filter /FlateDecode >> stream xÚmޱŠÂPEï’âÁ4ù„ÌìKˆ¬® ›BÐÊB¬Ôr‹mM>í}ÊûËâì}VÌ™;ܹ“ú³™i©“Ô¥ÖS=Tò'uÃù9&aÿ+óNüFëFü·â»¥žO—£øùêK+ñ ÝVZî¤[(²€ÂÐÛ f#2³;܃J>ÂPD´Cˆv@Z }•ˆ„‹÷c½C  ¤7¸¾Ð'Ð* 4u‘ö.æ7ú¹mp Ìb2ræcÀòÝÉZþI÷_þ endstream endobj 124 0 obj << /Length 154 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0asSC…C®B.cßÄ1’s¹œ<¹ôÃŒ¹ô=€¢\úž¾ %E¥©\úNÎ @¾‹B´¡‚A,—§‹ÿû@âÿÆÿÿ˜AûŸz ñHð?°*;&põÿÿÿš4A€Åðk£aÿÿÿ[~ `1.WO®@.òÅ^£ endstream endobj 125 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿ#E`š}!óšÄä”k.pž` A+ ±RK E»#›ÎÇðUò(y„”[,g‚²ìǰóÿÿÌÖÕÉzßòq¹áºâꜟJz¥º`;볟Öã íZÊï¸.(¿ÒwÊÛk~ûx¦|wsÁ%å{¾/¹x vÏ’€4¸ˆlnfxYé•DdöItÁ§S¶n\Å#7@efd=º`’El6X4jB*²`„éá¾fÀ}E_éh0‡íb•ôj“1SLÍ€,xÝ>v*‹Å!*:MÃö–Æ¢ó½:²?-y‰%Û§F‚Í@—-ÝÒ7ãè‚> endstream endobj 126 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcSC…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @¾‹B4Pe,—§‹Bý øÿ¬“Œ‘ò@dý ùóÿ? ùûÿ ùB~°o’äAdƒü ÉÀ$ÿÉ?Häz“õÿøÿÿÇÿÿIˆ8—«'W ƒzú endstream endobj 127 0 obj << /Length 132 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcKS#…C®B.cC ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ì ò ØþÃÄ@òx@ýÿ@ü€á?×C1;}pýÿÿþÿÿÿ†A|.WO®@.üØO) endstream endobj 128 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚÌ;‚@à%$Ópçò.¨H)L´²0Vji¡ÑV¸‰Wá(xŒ…[Æ_­Å~Éü³ó‡Á0ŠÑEŸ_ècäáÆƒ=’¹2Êb½ƒ4gA ΄Spò)§-8él„ôŒs˜ÃQ¹yÀ endstream endobj 129 0 obj << /Length 115 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0b e¨bÈUÈel䃹 ‰ä\.'O.ýpc.} (—¾§¯BIQi*—¾S€³ï¢m¨`Ëåé¢PÿÿÃÿÿ‰zÁÀ<Œˆúÿÿÿ7ñÿ,ÆåêÉÈî{\W endstream endobj 130 0 obj << /Length 171 /Filter /FlateDecode >> stream xÚ½Š= Â@…·[˜&GÈ\@7!Q°1#¸… •…X©¥…¢õ^,7ðæ[n±ì8šÎȃ÷WÃÑ3ä‚r„Å9œAl&’ø]ö'¨-˜\À,¤c—x½ÜŽ`êÕ s0 nå¹Û =œî=Cê¿bq䙣Ò1 S¥e¬”ö‰K•vI'ì’ö‡mrÿ/)Tžòì8R`ßû¾‡¹…5¼ízfÊ endstream endobj 131 0 obj << /Length 155 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úòþÿ¨ÿ$þÿ$ÿÿÏÀPÿD2þÿ`ß$ȃÈù@’Hþ“Èô&ëÿ?:ñÿÿÿÿ7 “q.WO®@.‹£ll endstream endobj 132 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ}Ž=‚@…‡XLÃvNàBL¬H·0ÑÊÂX©¥…F[Ù£íQ8¥…a†‚Îb^2ï}¹™KJ)*%³ K†w4÷Ò‹ó +‹ú@¦@½á)j»¥çãuE]íV”¡®é˜QzB[Ä_P¥ ¢:˜…ðá9o’.êAµ@9(¡dq%Ÿ»7@â'a¸ý/=ßµÓGÃ.^¬ÄTyhÆ ‰”pÁ A!\\[Üã>P: endstream endobj 133 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚ¥= Â@…g°¦ñ™ èfI"¦üSZYˆ•ZZ(ښͣä[.(w“€–‚S|Åæ½7q4HRYs_8Ö ù éL‘WCNâvµ?Ñ$#µá(%µp:©lÉ×ËíHj²š²&5ã­æpGÙŒs” V,ÈS*7;(& A‰]ƒt,¾à -À•ÇýGTÎÀµ@Û8×=ÓF–>¼®á ¡¯†¾$Úñ¼Ë_È¥÷ªùF­Ñ<£5½Þ¯ì endstream endobj 134 0 obj << /Length 158 /Filter /FlateDecode >> stream xÚ­É1 Â@ПJø—ðŸÀÝu£Äj!Fp A+ ±RKAEëõh9J¼AÊÁqc!Ú[̃™Ií`4-ØԈËÞð™m»îjw쎜{Vk±«y\Yù…\/·«|9ê½e_Hx’+5ÐCôÑ8´äÂ#‚$ÒRC®¡¹šˆ\õ¡ì¸ÿBÿ"¨¿xo<ó¼âõõIw endstream endobj 135 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚMË1 Â@ЋÀ4!s7q5Æ@T0… •…X©¥EÁÊÍÑrr‹ñ,,Þ2³óÿÔŽg©D’€MÅ&rŽùÆv‚=ê×þpºr^°Ù‹°Yã—M±‘Çýya“o³YÊ!–èÈÅRÈùr¨êGB®ù7 }Kïÿ´D#"×eZS¨¡W¡ÿ!§ˆ("P÷B Ca÷£}­¢9ª6A«ª=> stream xÚ31Ö3µT0P0bc 3…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€Àž¢þÿÿÿ @ü¿A€ÅH2…‚ù`€hàÀ ß €AþAý~ [@óÿ Œÿ€LxÀÀåêÉÈþ:B„ endstream endobj 137 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úÌÿþÿ`ÿ…¬ÿÁ $0ð()DÚÉ? õþÜÆðêdƒ=˜”ÿH2ÿcÿÏÀåêÉÈÄ£d> endstream endobj 138 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ5Í= Â0ÀñW:oéúN`ú¥ÐÅB­`A'qRGE7©…^Ì­×è êØ¡4¾Ø”É? ‰Âé,&žQ@áœÎ>Þ0ÔÍÓ[}pºb*Qì)ŒQ¬¹¢zÜŸévI>ŠŒ>yG”½•¥:ÅôJ•^ý›]ƒS |Á-,ZHZX:È^<rœ[CÂ×Á准’qÊz¤b&Õg¤aì¦QŒ¥À½†¿À•Äþ$›Lã endstream endobj 139 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ö3µT0P0bcc3…C®B.ßÄ1’s¹œ<¹ôÃL ¹ô=€¢\úž¾ %E¥©\úNÎ @Q…h ÊX.O…úÿ `Ôðÿ?ÃÙaCÄÙ00~ @2?ÀDv`²N2~¨+þߎ ¿#Èß``’ ?Ÿ‡“¿¿G#«¾g``¨?øA6 Hû†@Rž¡†ËÕ“+ Ém¢ endstream endobj 140 0 obj << /Length 202 /Filter /FlateDecode >> stream xÚEŒ; ÂPEoH!Lãœø£‚UÀ˜BÐÊB¬ÔÒBÑN!…Û²³t î@Ë!ãL@,ÞaæÌ»·µ{¸£¯Ûá¨ÏÛ™ lµÃfOÄܒ£¹©ZrÉŒOÇóŽÜp>âܘW!kJÆ‹/ŸLnRüQ;”H¡(Ô+€Øû­Üp{Íçh¼¯€/ O ¨.†êçê«oŸk> ¹¶´¬4¶ú…¥4Wè¬&F&ž”™äRŠ¢ª§ÚÑ$¡}¨xY& endstream endobj 141 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚEαjÃ@ àßdˆ‚ÁzöìØ)ÍCšB=Ò©CÉ”dÌÐÒnÆvÈÐ×jé‹:tÍ&É=Žûîî$%ñÍpÄ!ø:ºãdÀñ-¯"z¥X£!—Znh’‘yæxDæQâd²¿¿}¬ÉLæ÷‘™òKÄႲ)—Ö³µ[{²v§È­õöð+ïðOPy5À‘ Æ@®²äÌ©¤äUíð·-Gÿ[ùÙ;z¿Êßàµ[*ö‚l”ãŽBÉ;¥v\ɼHer”;åSú¾H‹R §Z88 ¾~íKôÑßÍa{ endstream endobj 142 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ}Ž1 ÂP †S2Y<‚9¯Å*B¡Vð ‚N⤎Š®­Gó(ï¤Ï¤c‡|?!?É'ãéœSžèä3>gt#Í”»Õ§+•žÜ^wrëŽ~ÃûóB®Ü.9#Wñ!ãôH¾â"Æ…ôPŒ‚¢x+š—"B I À/ >Š¡€i`˜¦$fà_£…$hŠ¡¨†¢Šj(ª¡D{£{-ÐÊÓŽ~æêb° endstream endobj 68 0 obj << /Type /Font /Subtype /Type3 /Name /F32 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -1 -19 45 58 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 21 /LastChar 125 /Widths 143 0 R /Encoding 144 0 R /CharProcs 145 0 R >> endobj 143 0 obj [43.59 0 0 0 0 0 0 0 0 0 0 0 0 43.59 43.59 43.59 0 0 43.59 0 0 43.59 43.59 43.59 43.59 43.59 43.59 0 0 0 0 0 0 0 0 0 0 43.59 0 0 43.59 43.59 0 0 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 43.59 43.59 0 43.59 43.59 0 0 0 0 0 0 0 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 0 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 43.59 ] endobj 144 0 obj << /Type /Encoding /Differences [21/a21 22/.notdef 34/a34/a35/a36 37/.notdef 39/a39 40/.notdef 42/a42/a43/a44/a45/a46/a47 48/.notdef 58/a58 59/.notdef 61/a61/a62 63/.notdef 65/a65 66/.notdef 67/a67/a68/a69/a70/a71/a72/a73 74/.notdef 75/a75/a76/a77/a78/a79/a80 81/.notdef 82/a82/a83/a84 85/.notdef 86/a86/a87 88/.notdef 95/a95/a96/a97/a98/a99/a100/a101/a102/a103/a104/a105 106/.notdef 107/a107/a108/a109/a110/a111/a112 113/.notdef 114/a114/a115/a116/a117/a118/a119/a120/a121/a122/a123/a124/a125] >> endobj 145 0 obj << /a21 96 0 R /a34 97 0 R /a35 98 0 R /a36 99 0 R /a39 86 0 R /a42 87 0 R /a43 88 0 R /a44 89 0 R /a45 95 0 R /a46 90 0 R /a47 91 0 R /a58 92 0 R /a61 93 0 R /a62 82 0 R /a65 100 0 R /a67 101 0 R /a68 102 0 R /a69 103 0 R /a70 104 0 R /a71 105 0 R /a72 106 0 R /a73 107 0 R /a75 108 0 R /a76 109 0 R /a77 110 0 R /a78 111 0 R /a79 112 0 R /a80 113 0 R /a82 114 0 R /a83 115 0 R /a84 116 0 R /a86 117 0 R /a87 118 0 R /a95 85 0 R /a96 94 0 R /a97 119 0 R /a98 120 0 R /a99 121 0 R /a100 122 0 R /a101 123 0 R /a102 124 0 R /a103 125 0 R /a104 126 0 R /a105 127 0 R /a107 128 0 R /a108 129 0 R /a109 130 0 R /a110 131 0 R /a111 132 0 R /a112 133 0 R /a114 134 0 R /a115 135 0 R /a116 136 0 R /a117 137 0 R /a118 138 0 R /a119 139 0 R /a120 140 0 R /a121 141 0 R /a122 142 0 R /a123 83 0 R /a124 81 0 R /a125 84 0 R >> endobj 146 0 obj << /Length 85 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3s…C®B.ˆMÎåròäÒW0çÒ÷ž¾ %E¥©\úNÎ †\ú. ц ±\ž. ÿ €ËÕ“+ hz¯ endstream endobj 147 0 obj << /Length 148 /Filter /FlateDecode >> stream xÚ31Ô35R0P0UÐ52T06W03RH1ä*ä26Š(XC¥’s¹œ<¹ôÃŒ ¹ô=€â\úž¾ %E¥©\úNÎ @Q…h ¦X.O ¶CÂu@\Å€ø3‚ðfáÌ ˜„ X„ Øžrãih4…ƃqs¹zrræŠH endstream endobj 148 0 obj << /Length 93 /Filter /FlateDecode >> stream xÚ32Ö30W0P°bC3cs…C®B.ˆOÎåròäÒW0çÒ÷ ré{ú*”•¦ré;8+ré»(D*Äryº(üƒì*ËåêÉÈžã: endstream endobj 149 0 obj << /Length 88 /Filter /FlateDecode >> stream xÚ32Ö30W0PaC3S …C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ“ ¸\=¹¹¢9K% endstream endobj 150 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚuŒ± ÂP ES:²ÔÑAh~@_¯K§B­`A'qRGEçöÓü”úBcZÜD.gÉÍ=.¥“£©%—Kéhñ‚.¦>É·9œ1/ÑlÉÅh–zFS®èv½ŸÐäë9Y4í,Å{, ‚¨_B‘:yDÂvA;ÿ5R`Àãÿd¬V«‹£Îã¬ñ¸ªýé~ðY”ª¹j2ÎúͰ}s Oö:\”¸Á5y\, endstream endobj 151 0 obj << /Length 179 /Filter /FlateDecode >> stream xÚ36Ó³4T0P0VÐ5T06U0¶TH1ä*ä2 (˜@e’s¹œ<¹ôÃŒ ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæ òÿ0ÔÿÀðÿÿÆÿÿÿ0!û†þ ò8€˜Á¾‚븈ÿ‘õÀ̱?ÀÀ4— h‡û†:ö?Ìÿ˜ÿÿÿtà[>€ÝÄþ‡ËÕ“+ ßrDª endstream endobj 152 0 obj << /Length 193 /Filter /FlateDecode >> stream xÚmŽ1‚@E?RL!G`. +¬šØH‚šHa¢•…±RK v8Gá”d×!R:Ékþäý=/BžpÄ£õŒõ‚¯!=HGNxÚo.wJRRGÖ©­Ä¤Ò¿žï©d¿âÔšORt¦tÍð 0@n ÇÚÒµ¶òZ¿ök·ñ+§ J´AO\ ‹e.d?:+°¦Ðaz²qw"–B…_c(/,]ã¹oÐé¹­¥¹„k@›”ô ÍUH endstream endobj 153 0 obj << /Length 234 /Filter /FlateDecode >> stream xÚ}±J1†ÿåŠÀ4y„Ì h6ç\·pžà‚Vr•ZZ(Úš> stream xÚ31Ò³T0P0bcs3…C®B.c4ƒH$çr9yré‡+pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þ100Ð3þaøÇÿ¿áŸüÿÿêÿ?ø÷ÿÿ‡ÿ?äüÀþãÿæÿ˜ÿüo`üóŸÿÑs¹zrr¦…{ endstream endobj 155 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bCSs…C®B. ×ĉ'çr9yré‡+Xpé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þC¨'p¹zrr4ö+³ endstream endobj 156 0 obj << /Length 128 /Filter /FlateDecode >> stream xÚ32Ò34Q0PÐ5UÐ54W04S05WH1ä*ä22PAs˜\r.—“'—~¸‚‘—¾P‚KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÿvD `ÿ0HÿƒùêüÿD õÿäÿ10ÿ`àrõä ä­TTÀ endstream endobj 157 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ½Î;‚@à%$Ópæ.bK‚˜¸…‰VÆJ--4Z³GÛx:)ã?ÁMöÛ×ìÌäÉ|Á ë̱$|NéFY†ótÔ‡Ó•JGvÏYFv[²nÃûóB¶Ü.9%[ñ!åäH®âÑ`ü›ÙÂD=ˆ;P´ n€x3‚8„„=ˆ:· h@í`'Òþ@ˆ|,oå…¿â‘EŒæ3µRxE ÅJ¤u#í TfÚP ­Ú¤™¨'<­íè 'µwÕ endstream endobj 158 0 obj << /Length 89 /Filter /FlateDecode >> stream xÚ3´Ô³0Q0P0bC3…C®B.s ×ĉ'çr9yré‡+˜sé{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þQ¸\=¹¹6VLÖ endstream endobj 159 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚÕL;‚@\BAòŽÀ; ! V$ˆ‰[˜hea¬ÐÒB£µ{´= GX;ÌŽ‹–žÀb2¿Ì”Åd>å”Ë)ç3>ft¡"÷þcÇ¢=S­Hî¸ÈI®|JR­ùv½ŸHÖ›g$ÞgœH5,‚—{ábèÂ%0´{ ŒžðªO[YtÑ`b BG:„ˆzè~¸rßï!Z*ÚÒK=Ù endstream endobj 160 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ31Ò³T0P0bcsc …C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.OÆ? ÿøÿ7ü“ÿà_ýÿÿþÿÿðÿ‡üÿØü?ÀüãóŸÿ Œþ3 ð?:`.WO®@.²dG endstream endobj 161 0 obj << /Length 190 /Filter /FlateDecode >> stream xÚ1‚PDÇPlÃØ èç †X‘ &R˜hea¬ÔÒB£­p4ŽÂ()Œëw-hm^1“™Mìd6刧<¶œDÏùdéJqêÄ諨s¼P^’Ùqœ’Y9™L¹æûíq&“olɼ·¨,Þ@ 5I ˆô‰¼œî¿‡ èPÕA‹¬„MV#hü¶rèOÀë\š×ÿ‹áV1$kQè*-×:H§éHTÒ¡4ÐhYÒ–>Yñ]] endstream endobj 162 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ­Î;‚@à!$Óp纋‹D+ÄD ­,Œ•ZZh´†£qŽ@IAvœ5cibóóü£ÉxNšb…1EšÌŒN!^Ñ©jšF}ëxÁ4Gµ#cP­¤Ž*_Óýö8£J7 Qe´I0ϼÀ,$\e®™à&i«@(0<+À vJ!ù…âû¿/Ë×7.ý®OÐ$KU»|²àìÐû­ÛË·øfswo endstream endobj 163 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ð36W0P0b#sc …C®B.#rAɹ\Nž\úá F\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O†Ø?üáÿðÇþßúþøûŸáï†ÿþ?`øŒþ3@Ñ?Š—«'W Ì“C¥ endstream endobj 164 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚMÍ; Â@à ir„Ìt³‰­"1‚)­,DÔÒBQ°r÷h{”!¥…dc¾æŸW¢£„"Š©¯)‰(ÓAããTˆ†]g¼Dµ¦8E5—U¹ ëåvD•/§¤Q´Ñm±,L¿Àg¶³ Eö)ðmž}À?Óɬ¨[¹† ½Ñ@€ÛP&ØÉ„ª/ÿg"vâk tìŒeÙ3²¶wžòÈÎJ\ánONØ endstream endobj 165 0 obj << /Length 133 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0TÐ5T0²P01WH1ä*ä22 (˜X@d’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. ŒˆÁÿÿÿÇÀÄê¥ÿch`üÇØÀðŸýÐR®ÿÏÀ`””ÀÀåêÉÈ|Q  endstream endobj 166 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚMÌ; Â@à?¤X˜&GØ=k ¢VÁ-­,ÄJ--m“ÜÄ›hŽ’#¤L¢³ ÂÂÌóŒæ£ÉBUÈÍlœCºQ4åºïØÁéJ‰!½WÑ”ôš»¤ÍF=îÏ éd»T!éTxóH&U_ ¨r@–ˆ‹’‘%rô2K7 j¯uð¿qðZ¿fD ´¢º>D”@ÞÃoËâÏ‹‘¸oKLjօV†vôg9Hã endstream endobj 167 0 obj << /Length 236 /Filter /FlateDecode >> stream xÚEαNÃ0à‹> stream xÚUÎ1jÃ@ÐoT¦Ñ4pVkYÄ®¢"W.B*'e »t’ä*{’ #¨T!”Ì®¬Ãò`g˜?“¯îkÎXó\ßsîß»¦#å…T3.–×Öá“6%©=ç©'©“*Ÿù|º|Ú¼<°&µåWÍÙ•[þ’¦Rë1õˆ©R‹ ž¤´BÜ¢f=¢n¤CÔGfWZ`ˆ= ðå‘iT‰L ý©Kñ·ãw"ê'dÏ ­kxš‰Øc]T •ìXù™!à2Kr×KÚÑ?§êVv endstream endobj 63 0 obj << /Type /Font /Subtype /Type3 /Name /F31 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -5 -21 60 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 46 /LastChar 121 /Widths 169 0 R /Encoding 170 0 R /CharProcs 171 0 R >> endobj 169 0 obj [23.07 41.52 0 0 0 0 0 0 0 0 0 0 23.07 0 0 0 0 0 0 0 0 0 0 0 0 0 0 23.07 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 39.9 0 36.91 0 36.91 0 41.52 42.9 19.84 22.14 40.6 19.84 65.97 42.9 41.52 42.9 0 28.37 31.83 29.99 0 38.29 56.74 0 38.29 ] endobj 170 0 obj << /Type /Encoding /Differences [46/a46/a47 48/.notdef 58/a58 59/.notdef 73/a73 74/.notdef 97/a97 98/.notdef 99/a99 100/.notdef 101/a101 102/.notdef 103/a103/a104/a105/a106/a107/a108/a109/a110/a111/a112 113/.notdef 114/a114/a115/a116 117/.notdef 118/a118/a119 120/.notdef 121/a121] >> endobj 171 0 obj << /a46 146 0 R /a47 147 0 R /a58 148 0 R /a73 149 0 R /a97 150 0 R /a99 151 0 R /a101 152 0 R /a103 153 0 R /a104 154 0 R /a105 155 0 R /a106 156 0 R /a107 157 0 R /a108 158 0 R /a109 159 0 R /a110 160 0 R /a111 161 0 R /a112 162 0 R /a114 163 0 R /a115 164 0 R /a116 165 0 R /a118 166 0 R /a119 167 0 R /a121 168 0 R >> endobj 172 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚ}бNÃ0€á‹ó[ñòŽ«í#•Ú[wж¾£¯Ïï7´«ûkÊÑ®é)§ìë5€Ú‚,ÝÇH‡Y˜1Fu˜EÃ1˜Û$Ì`„Ú³$ª] ½ciÕÝiÇ’˜¶MÓ6Òj T§Ä%˜0Òú©`t‰è)ßšô »µýÚ£Éî§ûì0„R7¡ ŒÇ’A¢«Ó\—þt‚‡dèC@ëf;„wÛ€75>à/G°ž% endstream endobj 173 0 obj << /Length 208 /Filter /FlateDecode >> stream xÚÑ= Â0àJ‡Â[rß LK©¥S¡V0ƒ “ƒ8©£ƒ¢s{4Ò#tìP“ö¥qj |ä‡÷Ã[Æ‹$Dõ^†Åx àQ¢Î¾>ê‡ó 2ü€Q|£n‹->¯+ðl·ÂxŽÇýˆ¥^oÇémIiTEí¸²êud=X4ƒi;87v¶LNó7މoò™üTÏŒêd²T}Xö÷_õ§—QOË^Wþo5Q;ŽG2Ê7öOõ×Ò<êq.ÖœÔWX ØÃuRÖä endstream endobj 174 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚ½‘=NÄ@ …¥ÉÍ!¾L"±ËnC¤e‘H¢J ´$GóQr„-·­ñŒ7qF}#[ãŸ÷–«Óõ9Õ´ “†–g´XÑsƒo¨¬Sxm™§WÜtî5áZúúxÿ|Á°¹½¤Öª±Û´ (E¸TV";§‘èYäepšÒ{ðJý¥9†~P(eÔRÂé™XföìdH-Ø ÌXq*óKÏíÄ8§ãþ/÷ü§~ÖbyœoƃÑöq?´}Ý`ôƒéáÁô©ÀôºÓïëØ0fW Ø';´¬jœô÷#˜©†úcŠÍªþyÄ< ^ux‡ß³ = endstream endobj 175 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚ37Ö32V0Pa3 Ss…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ@˜þ¥ÿÃè õ?ØÿÓp,ÿBóÿ‡ÐÌ@@4#P2Íðÿ„®ÿ€JÛÿ@£ÿ@hytúú?iBöÿAu?œ†ú«þª¿aá¥aá ?öÿ¨á[ÿþ°ø@‰Ÿ?P\®ž\\2oÉ™ endstream endobj 176 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚ}б Â0à+Â-}½'0­Út µ‚ÄI‡‚¯ì˜¡Û¤…¦VÇÇår~>ÅS hR(Šéâ#^ô¦-Ç &ÙŽ"ŽlUÜ"“kºßgdÉfA!²”ö!”)isÞÀKT •¡oéY<py~# ³ˆ?@Iæz­S=©Z¿ˆ¿‹Ah1s–Ì!oâ9)ù–¹ÁÓʦ«:#Ç¥Ä-~·Ê endstream endobj 177 0 obj << /Length 262 /Filter /FlateDecode >> stream xڽѱNÃ0à«2Dº%à{p<¸-“¥R$2 ÁÄ€˜€‘súh~”> stream xÚ36Ó32T0P0aSs…C®B.crAɹ\Nž\úá Æ\ú@Q.}O_…’¢ÒT.}§gC.}…h 1±\ž. ÿÿÿÿƒŒê0 uŒî'.WO®@.•õy9 endstream endobj 179 0 obj << /Length 138 /Filter /FlateDecode >> stream xÚ35×31V0PaScSs…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þVŠ¡þÃ0¤ØRüPŠ %BÙ£Põê?˜b„PÌŠÿ˜ªÿÝÿ8(.WO®@.‹† endstream endobj 180 0 obj << /Length 253 /Filter /FlateDecode >> stream xÚ}Ò±jÃ0à·è ì{‚ʦIëBÀ¦P…vÊP:µ;´´ÒÁ~°~?‚Æ &×S !HÁßIËwWÅÙÅœ :—[U4¿¤—ß±šI_„6|<¿á²A·¦j†îV^Ñ5wôùñõŠnyM%º=–T> stream xÚeѽJÄ@ÀñYR¦É#džÀMü¸\·pž` A+ ±RK EA±ˆ¾™¾I|ƒ³Sˆgwv/'W,üfþÅn³¿ÓìQEþ4»tÐÐuw8›Ë\ùÑ/®nqÑ¢=§Ùí±Ü¢mOèáþñíâôj´Kº¨©ºÄvIÌ@ƼÚÀ˜À èøU´Á;€é=zÅ‹¬ž'|+ž|1 #G”R (¤ø¹¤2))€RT¸58BÒ )*¤¨¢BŠ ˜0Dtc„㈒ß(rþTd¾†À¿á±<\B¹…"!OÈL¬ÑmÁ%”‚Á£è!ü)ä Y‚Ùµx†n«Äº endstream endobj 182 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚµ‘1NÃ@EQ Mã#ì\Ì*Š •¥$\D‚*J(SAíÍGñ\º°2üñÈ "JË»Ïþ£ïÿÍã]>‘{™Êm”,—éƒ|DÞr!B~ôÊzó’Ó¥d‘ÓÈœ– ùþúùätöú$Pçòϊ˹‘vdW¢º3Vª-p¥uèÁµ›/ˆ «Æ—=›:Ô`Nzº¸wÏèʼn¬8røöØ,œÍVÃpÚž£¯Ý¥xèçóœðdnÿ¿&8둉ç°;æb9©•ßÞ³µ0ÔrEÓªõUXîЂyjóÖA‡^ªýŸó:œŸŸ'?—üÆ¿°ÛÈI endstream endobj 183 0 obj << /Length 165 /Filter /FlateDecode >> stream xÚ33Õ3²P0P0b3Ss…C®B.S3 ÌI$çr9yré‡+˜šqé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒ˜ú¡þA¨ÿ õ?øÿQŒÿ€( Ä Êþ2%ÿ…úO&…b ª Pk!Ž€: ì@ˆ'@Ôõ¬q%vŠËÕ“+ 0¾ª( endstream endobj 184 0 obj << /Length 233 /Filter /FlateDecode >> stream xڥѽ Â0ð‡Â->Bï4bÛ­àØAÐÉAAëækù(>BG‡Ð3͇‚uP=¤òAYý‡Ú¯K]¹k̵ÚpÍ&ŽËœÛÈ…MšÊgd ŸÎoç°Úk|x–¯pÿ +‡Â@Zä/0ƒ´d73(Mº\5|¢³3¿WU =e0ƒ>¬ß endstream endobj 185 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚeϱNÃ@ à?êÉyƒÆ/iJ"•¥‘J‘È€D'ÄŒ X{÷hy”^åc¡¯êŠ™D5‡=îþÙü:þé§“ÎÇ|ñ_.þ(Ø_’ IŸ˜4B±±ÌCjÑz8½–nZ:Ð7¡6 endstream endobj 186 0 obj << /Length 152 /Filter /FlateDecode >> stream xÚ33Ó31V0Pa3cS3…C®B.SK ßÄI$çr9yré‡+˜Zré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿƒANúÃÿÌÿêi†úõ Zþ@ˆæ‡Ó5`šNW€ifœôýà˜fÄI3€i0™4?(pÓ\®ž\\wG³æ endstream endobj 187 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚíÑ1‚P Ð’.^@?'ILtr0Nêè ÑÍGã(ÑP[ˆ‰““£Cû_Û´Ë‚Á0$êûy4Šhïã CmJ9î&»#&š5…!š¹´Ñd ºœ¯4ÉrJ>š”6>y[ÌRbæ\æò €[B§øãgpq ‰¸þD¬…b¢ ¤û7 ›%é¸ÇXzÂ’¯²+pîC‘7 M=$¿©¯¬qÓ˜«ŽÀY†+|œ¼T endstream endobj 188 0 obj << /Length 220 /Filter /FlateDecode >> stream xÚÕÑ=ÊÂ@€á )„i¦ž§u‚;ì{¹ÛU«-2tsê{tyE—ýÑaÜ L‡” Ñ"¡x‰Ùˆ˜ù sñÀOh_ΊV!xéË eA”Ëáü©ŽYæ'ý@V4Сn.— B)€Æ´`š²˜¬QCS;¤QãiùV¾¿ñ°”ĸ¨pnp©r^!z£Íðkˆä'~Ž3œá?jz”ó endstream endobj 189 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31×37U0P0bCS…C®B.cc ßÄI$çr9yré‡+sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ä€ÀDübvQ$þÿG%úAüȨÿÿÿÁåêÉÈB•\ endstream endobj 190 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚmÏÏJÄ0ð¯,Ì%ÐZ%c‹ã7¢â!¿02I†ñ|ÜøÖÛz¿ü¾“éGÆ­…Vx|–í,ÍïGi®˜•f¾ö‡×ã“4Û› ßI³ó÷odÞy¸A# ÕŒJõ—&E½8]&”ÃRj ©Ð¤ šÙõKXÿ™"9ãØß°öC¯ú"‚ãƒùÊÞáN¤¶¶šàžç‚ +–o¨q‘Ô ™€ï@æF2ŠÌÏh.ÊpFmLF IÿA.g¹•OÕ¬—´ endstream endobj 191 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ}±JÄ@†ÿbaš> stream xڕϱ Â@ à– Yú6O`[¼Ò¥T¨¼AÐÉAœÔÑAQèP°ÖGé#tt«—ªtò $áB¢ÓyšpÄ :áDó%¦;騿‘¤Ò8ߨ0XÇnl•B³åçãu¥°Ø­ØVK>Ú/'2%;ŽãµÇÀ%|ÃAtG*èA0‡¬`/ºPu°½Fô19€9¬a{ÑíDíªb#úØj3XÃä5S¯øS… imhO_o`{ endstream endobj 193 0 obj << /Length 229 /Filter /FlateDecode >> stream xڅϱNÃ@ `G"yh_éüp’([+•"5:T #Ö^í%pcó»He``ùÛ÷û\·wm# iä¶”º’¦–ç’߸jQD¹ùéœ^yݱßKղߢ̾{”÷Ïöë§{)ÙoäPÊâÈÝFnˆ(ºžŠèF Ñ©j…Àd|ÉŒL@Àä6ììmБÜT /åˆõ¤sg`À|¸®Œ¿8c†Â¨Ò’5 MñÃÙâ—”i\Qn+ ¥yrŠevœEs¬á‡Žwü Ô4„s endstream endobj 194 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÏ=NÄ0à¥Mã#x.N´ŽV[YZ‰HPQ * ¤Aíp³%G0¢ÀE”a²» ÍgûYš¿<]6\±ç“š½çÆóCMÏ´XiXqÓì~îŸhÝ’»áÅŠÜ…ÆäÚK~}y{$·¾:ãšÜ†ok®î¨Ý0`2™€R¤Ó—é†r@ìŠI…ÀærBÈG£b¶dÅþ2lRÌ“V;äxFïò!#äSòÕI§gìµk4I±Yòžñ€;ý!þGøaÜbóžÝ¸óài^aÐeb_È»î+:‚¶‡ÑÚ(4¢ó–®é–•™ endstream endobj 195 0 obj << /Length 200 /Filter /FlateDecode >> stream xÚϱ ‚`ðáÁ{2As‰3È!¨©!šª±¡(hˆôÑzÁñĺïŒt©¡~Ãÿ8îÎûa@ ¨ç‘R0¤‡Gô=9›Îö€qŠîŠ|ÝÇè¦s:Ÿ.{tãÅ„8MhÍ3L®±â“+ÿ"dL-V¢K±x{°pprm î%@%*­!š¥ÞiÉfúÈ£ú1ƒÖºÕh¬´fG«£Ý¨ZŸFéȶ> stream xÚEÐ;N1 `G)Fr“#Œ/³£Ñj«HË"1Tˆ ()@PgŽ–£ä)S„{Aló)Çù“iw¹›iC]Œ4M4Oô2â;n÷²¸¡yþÝy~ÃÂÃm÷8ÜÈ2Ë-}~|½âp¸»¢‡#=Ž´yÂåH`xpœv ú$¸ä"¸,t¹?“”¬¥JIÏRÜsTR/´°vÌ „ –å6£#`f€ÀÁ3G&û-Û]\\ò\´Eõ«åV>R®ô­tŠUÌ?p¦²"ÅFÏ ¶ø¿Ìò¢!ÚS‚S¯`% ^/x?}Ï“… endstream endobj 58 0 obj << /Type /Font /Subtype /Type3 /Name /F29 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 2 -1 88 58 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 49 /LastChar 89 /Widths 197 0 R /Encoding 198 0 R /CharProcs 199 0 R >> endobj 197 0 obj [47.75 47.75 47.75 47.75 47.75 47.75 47.75 47.75 0 0 0 0 0 0 0 0 72.2 67.93 68.97 73.23 62.74 0 75.08 0 36.21 0 0 57.43 90.65 74.73 71.73 65.28 0 71.62 53.05 66.43 73.46 0 0 0 72.2 ] endobj 198 0 obj << /Type /Encoding /Differences [49/a49/a50/a51/a52/a53/a54/a55/a56 57/.notdef 65/a65/a66/a67/a68/a69 70/.notdef 71/a71 72/.notdef 73/a73 74/.notdef 76/a76/a77/a78/a79/a80 81/.notdef 82/a82/a83/a84/a85 86/.notdef 89/a89] >> endobj 199 0 obj << /a49 189 0 R /a50 190 0 R /a51 191 0 R /a52 192 0 R /a53 193 0 R /a54 194 0 R /a55 195 0 R /a56 196 0 R /a65 172 0 R /a66 173 0 R /a67 174 0 R /a68 175 0 R /a69 176 0 R /a71 177 0 R /a73 178 0 R /a76 179 0 R /a77 180 0 R /a78 181 0 R /a79 182 0 R /a80 183 0 R /a82 184 0 R /a83 185 0 R /a84 186 0 R /a85 187 0 R /a89 188 0 R >> endobj 200 0 obj << /Length 327 /Filter /FlateDecode >> stream xÚ•Ó¿j„0Àq%C ‹`ž *½B]®W¨C¡:”NmÇ-ív¨–GÉ#dt—&æ—?RiDø¨ ~ýi]_\V´¤;½×WôzGß*òIê’šMš ¯dß‘â‰Ö%)îôYRt÷ôûëçû‡Z‘â@Ÿõm^Hw ‰YmVìaܶb«Nß4RbÕXM›Î”\u®N›n•ònbÁý |ä± –mˆœbçÞ©¶‹LEæ´]$â±±7æ!3äi»ÈlŒzçÚ.2Ob'Þzº>¸Ñƒtî!ò¸´—Æ9™7Ê ×˜CîÒ.Ík&) 7L³Èʬ ¦k–üÓùì“ËõÁóÇ Á͹!¾·!×Kk¹KÛøÌ!×#°€Ü¥m<æá“ÆÌþçÎFkó(­°¿4J@?û¯ÉmGÉ/ðc ¥ endstream endobj 201 0 obj << /Length 267 /Filter /FlateDecode >> stream xÚµ“=nƒ@…Ç¢@šfà9Al%"’C$SX²+V*;eŠDI£pJ ÄzÖ°òÚîÌŠÕ·üì›y^çOÏ‘=“Jftˆñ“ˆìॽ±ÿÂEŽzKI„zÉWQç+úýùûD½X¿QŒ:£]LÑæ™óÑ@G¦j…ÌQ¨P¦˜ÚϘº§‰iz‚ÿVÈ8Jy›Ž¦<_’â­oSÈr¡ûºãJ^CoC¿âÁàK(®¥vR“ਾB,á|.ÅÝÚWK¥uÅÉ¡Ë`DuO6®KNý™‡‘¯6‘_i JGãT+É­”´ ç¤KP±„û²¡J¨ðÿ~ ßsÜà uÍyë endstream endobj 202 0 obj << /Length 338 /Filter /FlateDecode >> stream xÚÍ“?N…@ÆgC±É6½€QãÚ¸Éó™Ha¢•…±RK vF8Þä%^€’‚0Îì ‘¼Z ø-;;3|óqvrX”ºÐ§ú ÔÆhs¤ŸJõªL¡ù6Ç~çñEm*•ßiS¨üŠ^«¼ºÖïoÏ*ßÜ\èRå[}O‰TµÕ@W‚€dªR‰ˆ;Ȉ,Q–ˆG¨9ÛCi ì7rXKËä0—Aà@$ˆs;’²º:ñ>GOÔ11PV¨GG’ª à{ ré(µëÜ‘  J}1*7S(»$;SheIÙLõ>âoúCø¨^¥f­i0Ó¤ÚÙIñ™Î§ÉÌô¬ð§ Cœ4ôqú¢ŽHºèG®¹‹nJÛè°¬‰®³œcÔC +{ç7ZÛÎÛ¶>»ƒ Úà¿¢‹*E!¼Õe¥nÕ/ÙÏíã endstream endobj 203 0 obj << /Length 258 /Filter /FlateDecode >> stream xÚÕÓ1nƒ0`£ ‘ÞÂx'¨¡b€ ‰¦R"5S†ªSÛ±C¢d†£õ(9BF†ˆcWæGµR¦Z}lÀþ_ÇYÂ1§æÈSÎù#¡=e¹éÇ}·¿ñþEeEzÇYNzm®’®6|<œ>I—/Oœ^ñ«™æª‹kªo?nÁ‚>ƒíCK¹(Iç¸ÖªoïÐv^سs`'rVr\wƒ Iã‚—ý˼ÏÞ‹‘/ÞÁÈí¤íýênp=g¹ÇÍ?ôÿ;³†¸ÎØ—¹=Å  13èr…Ù‹ “E7™ÛòŒ™ÇZ€1µÓŒk kmªgjÖ.=W´¥€Ms³ endstream endobj 204 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚ•Ò= ð×t y G('«Æv3ñ#±ƒ‰NÆI4:—£õ(ÁÑIÓ¾ú¤H~…þi¿ÕE[ôLK;¶nc<`’˜ïgØìq˜¡\Š$A95½(³™8Ï;”ÃùHÄ(Çbe–Yc6º,wh*àúÀ´.9)"1RH HP+wh ¾yÅ›(¸/*±†øPè#qRDÒ¥LùSõÜ×õ¸c_ÿÿ½Ÿè擽®²éPèÒå[Ì+^« —& ÊIº ¬)J¢¢t*Jl)sŪJ¶SàN2\àîÀU\ endstream endobj 205 0 obj << /Length 349 /Filter /FlateDecode >> stream xÚÕ“±NÄ0 †]u¨”¥P¿´U‘®"‡D$˜02€`ny³ãMNâ¸ñ†ªÆIÜ»´EÀJ÷“ã8vâ?ÏŠã¢Â x”cµÀ²Àû\=©Ò83,OÜÊÝ£ZÖ*½Æ²Ré9»UZ_àËóëƒJ——§˜«t…79f·ª^!ðÒ û5D±Åˆˆ6XÖÌ;Ж©‡Æí¤uH@†cýN.|ÍŽrá.m@µÎ³Û¯F|Ž=›Mb¶š Ö´`]ƒÃœb{)Ð$èÀU2¤ئç¿ô' ÄcW˜¾|–rƬÇ,eŽ9sóýÃôOx^cf¥u=þÌzÆ.‡–{6œü‡·›òðÖS–1´Œ¸;ôAýe&oVýögÛ›ù`¦_#œˆ7ÄŸ¢)ÒNG¼¼ èöÝYmv¢M£Ù­è×Üf !ˆ&\oê¬VWê ?¦! endstream endobj 206 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ3±Ð31Q0P0bS #…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ÿA ÉÀþÿÃ(9THü±ÉåêÉÈ’:Õ° endstream endobj 207 0 obj << /Length 157 /Filter /FlateDecode >> stream xÚ3·Ô30T0P0bs #…C®B.3K ßÄI$çr9yré‡+˜Yré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü Ä0ø!Ô(c2~f0ÂH`0ãf°c0øáŒP†<Ãƨ‡1þCŒ0;ŒÁcÔCÌÀ¤ø Ãàrõä ä6n6 endstream endobj 208 0 obj << /Length 311 /Filter /FlateDecode >> stream xÚÔ±N„0Àñ’oé#´O ”\<'HÎ3‘ÁD'㤎ÝHàÉ ÆÁÑGð‘áBýú•Iû%)ð+,ÿ¦`ÊÕÑz­ ½ÂaJ£OJ}oà Œ9Æ™ÂÙ=º{„MùµÆyÈÏqòæB¿<¿>@¾¹<Õò­¾1º¸…f«­µ£ #q·8&ÏtáÞ3ûŸxž=%Ýüæ·õT]ˆ_¶'V1ü´± òÃîˆSï>8ƒ|º‹bGýx ²¦~Ù‡©¨_‰(Jê¯fÔß2L©Šcâ–# ןî8º~w‰¢[ÙstýJptýU,Ýr´,]ÿÄû±ž#öc},»=Ö3Ö³Tëc)íÛfôÑrLi‡G’vKA;+DEï ñß1¥]þ*Y÷‡¨ÄB8kà ~oˆ§L endstream endobj 209 0 obj << /Length 316 /Filter /FlateDecode >> stream xÚuÓ1NÃ0ÆqG"yÉâ¤êÐL–J‘È€bFÌé ¸Rc@n@G†*Æï9~ýÈðäßóò,×Õâdµ4•¡i³Z˜ûZ?é†öŠVÂÝ£^·º¼6ÍR—çþV—í…yy~}ÐåúòÔԺܘ›ÚT·ºÝçÜR*ñç<‚ÝV™s[¿(;(rOηì¼wþäpô(þàXð;¸áàŽÃуØr,¸çÎ8=ŠSpÂá`ÅáÉb æðdOæ°x§`Oæp4…ÄLáh }S8:S8šÂà^ìÃb öa±ƒb§`ûØx'îÜ·Ø‚ ~›à|Æ8'`5çlÁ8ŸqNÁ X‘‹½xúƒ> ¶àœÿµ>kõ•þJÔ@ endstream endobj 210 0 obj << /Length 325 /Filter /FlateDecode >> stream xÚÍ“±NÄ0 @ÝPÉK?¡þh H×›*‡D$˜02€`¾û´~J?¡c†ª&±ãrœNldH^âØŽ{U.+,p‰'%®Î°:ÇçÞ ºð‡ú…%O¯°n ¿÷_óÜÜàÇûç äëÛK,!ßàC‰Å#44~d´32DCÄšˆZAOÔ3%ä,F•¢b= _&gŒåË2‡½·dõÀ‚FL¤dtæ½Èêˆ^c;È“ºh†MZE=°p¡8È}ÃÚ‰âèÝ´1ª˜M¸Ótøµž°=Š[’l¥ÔýiÂþÿâìéñq<”3Mu;Ëúo˜ê†Ïš0Ñï÷q¯fUËȱ„±çšà:ëØ „Æåq’ñÌ×Ä·€•ZwÑ»¾$D#ÌB·HÜIè!iÐýh²Dåß W ÜÁxkD— endstream endobj 211 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ³°Ô³0U0P0b c #…C®B.s ßÄI$çr9yré‡+˜[pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÁëÿ8ëœõ¿ÎJóƒûÿ ,fn0‹¤ªÿcÙ5CXòÿ@Y ÂbGb}ÀÂúe1ceý¡ Ÿ½ìH,ln~÷å Ÿ#BBðPŒº`pÎb€±~ÀY 0SFYä± I—«'W TÛ4# endstream endobj 212 0 obj << /Length 290 /Filter /FlateDecode >> stream xÚµÓ±NÄ `H‡&ÿÒGèÿJk×NMÎ3±ƒ‰NÆIMÔèÜ{4¥ÀØá"R ÜßÈ%)ù ~ø¡Ùœo®°ÀK<+±©±¾À×>¡©Lcuåz^ÞaÛxĦqkšAtwøýõób{%ˆ>•X> stream xÚ}ѱJÄ@à?¤l“v_@“pÞ] !pž` A+ ±RK E;!÷hñMÎ7H¹à’qfwO ¦ù`vv23»œ•µ)ÍÒVf±0õÌÜWêIÍ%Xšú8œÜ=ªU«Šk3¯UqÎaU´æåùõA«ËSS©bmn*SÞªvm€| 82"‡7@бï, }8$´þtHIR2>JØÜJ =°MT;4[6ÿ±ùR׳éÄÄ~“û íD©Ï}~k£.:Âíì£6ʃH«¬Ï±¥DÎJ†wðkñ©8ÊÌ1ÁÛ‡=Iszÿ‚‰6üÑWÎBðJIľ7ìl¢:šÇa²hJ½Ý7ùCÞ¦ûßÍ8‘ÂýðˆþÝÆðâÞ5,φýkV›Ôqœ<ò Òöè÷Ã/™„µXY×dã|…ËvRJµêJ}áI± endstream endobj 214 0 obj << /Length 176 /Filter /FlateDecode >> stream xÚ³4Ô31W0P0b 3 C…C®B. rAɹ\Nž\úá \ú@Q.}O_…’¢ÒT.}§g ßE!ÚPÁ –ËÓEÁþ?ü!žu€¡þ?3õ‡Äb°ÿSÿÂâÿWÿÂbÿWÂbþWßa1þ«g€°Xu0V6V ŒeG,ëŒeÿÆ’'Åc1Œ²†%‹’œÍârõä äãCì< endstream endobj 215 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚ퓱 Â@ †S:Y|„æô]ª‚ÄIÝÄöÑú(>BGñLÓZD''—|ü¹ÿr7œÑ¦©;¤©M CA‡º>­ î0ðYÔÔmÕÃ՜՘eTÑ„ûãU8A5¤…!½ÄhH–ãàpɾe¨Û ä§P±þóï¸Vrÿ…{ÂÙŸy¹%ŸÞرWáÛ K¶¹Žp,ìŠ+¾ç¹&ûÂuaÏJNE±IÞM ºœ4y0犉%®Þ­àØ^žÃù ŽâAlæH 4È—¬6eOæ†E8Ã`ò| endstream endobj 216 0 obj << /Length 285 /Filter /FlateDecode >> stream xÚíÓ±NÃ0€a£ ‘nÉ#ÔO€›R iõ\/ÂfOõÙB?´ð vÎçñ4ÞØ<Áªs«íÌe¸ ¦»Ò¯/o`V×纳Öwa™{èÖÕR³pø©Ãn¯âpáЈ¯TMS¤]ôar%va;B,½‹~;1­°E_¸Sé)Ž\ ´0…ãíº§rC pPòArRSlœÌA”#Ac²Ÿã8‡ƒ²Éá8Îá ìQr8Žs8(%‡ß–äPPa?&oñcŸìð³ð×<+Ü ö…}r]¸’Ï‘ßPš†|Öÿ¹›ø¿õ¿0\tpß4­ endstream endobj 217 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚ…¿J1‡gÙ"0M!óº·`D«Ày‚[ZYˆ•ZZ(Úºy´}”<•aÇ™¹ãôP1|ðå—?üâéáIO :¢ƒžâ1ÅH=>cT¹Pc;÷O¸°»¡Øcw!»á’^_Þ±[^‘ØÝÊ™;Và8ƒŒ‘?dm˜gPÇj·\R…q :“dÄ„*Á |…Vbn¶;ƒg³Eó çd˜ö1Öo( Ø÷aãhDBÿcü³!ýD[Áo˜¬1¿En¥ ¹±¦ä%iêÝînª6N:ó\ÒZÛ` æ]H›_ÙI<ð?yë­œ endstream endobj 218 0 obj << /Length 184 /Filter /FlateDecode >> stream xÚíѱ‚@ à& &]xúÞÜHLtr0Nêè ÑUy´{ጃ „zwÀ¡Í×6ÿÔd4”’™JBG´ñ„qlfiG{Ø1+P¬)ŽQÌÍE± Ëùz@‘-§¢Èi’Üb‘¤‚˜µ©ÒÁc®|æÚ!P÷Æái à±®!`{èø.ÿT¼ÊV6ß¡ýAÓõ_°yÍÀ4Õ8+p…o âøš endstream endobj 219 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚµ‘±‚0†kHná¼Ђ±0’ &2˜èä`œÔÑA£3<šÂ#02Î^KL%!_sý{½þ¬æI‚!.qa¼@¥ðÁCT±Ý9ß +@P% 7º ²Øâóñº‚Ìv+Œ@æxŒ0> stream xÚ]Ð1NÃ@Ð¥°4¾;ÛŠBƒ¥$\ ‘ŠQ%Ú¬æ£ì\¦°v˜Y)¢yÒî·çÝT—ëk.¹æ‹Šë57 ¿UôIõJ/Kn®æäõƒ6O\¯¨¸×k*ºþþúy§bóxË[~®¸|¡nËXÊp8™ÎÙë…HDÑFä#ò°Ô々Ú~Àþ¨¨7ö'ÉQÈ”´^;LKZ+45qj@.dêtÜÇv“ù!¤¸Ç"iíÐÄÌôehÖ”ôÁjÛ]ˆÿdVçµ³½ÍSuž‡è ±ýõ?h©›ÓêgåcfKxýºëhG¿Á•¡Z endstream endobj 221 0 obj << /Length 186 /Filter /FlateDecode >> stream xÚ35Ô34S0P0RÐ5T01Q07SH1ä*ä21 (˜›Cd’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.O†ÀOþÁN2bÌH$;É&åÁ¤=˜¬“ÿA$3˜äÿÿÿÿ?†ÿ8H¨úANò7PJÊÃç‚”ÿÇ`$ÿƒHþÿ ÀØ`ÿð(Èþßÿ ýß E` q¹zrr:é“p endstream endobj 222 0 obj << /Length 137 /Filter /FlateDecode >> stream xÚ33Õ37W0P04¦æ æ )†\…\&f  ,“œËåäÉ¥®`bÆ¥ïæÒ÷ôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQ```c;0ùD0ƒI~0Y"ÙÿIæÿ ò?&ù¤æDå(I²ôÿÿà"¹\=¹¹VI¢” endstream endobj 223 0 obj << /Length 301 /Filter /FlateDecode >> stream xÚ}ÑMJÅ0à)Y²é’Ø–G_]x>Á.]¹WêÒ…¢ëôh=JŽe¥ãüˆ? Ú¯if¦“tߟ ChÞ¯6 §á±s/®ßÑ\¦¼ððì£knC¿sÍ%½uÍxÞ^ߟ\s¸>kŽá® í½Ào@£B,D¸'€DdZš"-š,-ÚB/6¨3"x‰š¢äç”™œ®—ÓÊ®k‰í ƒËpÞ7q|Ì$pãFúæš¿È »ùdíL™@ÚAvüZ´H¥ÙFÓ¬¦YM«5Þk|,ZdÖìI³eb4Ðj`Môä³g!@Tt¶«`[ÈBÍ».àA8ã²EþõËwÌ•b«ÔŠW¢’üÉü'îbt7î}tû” endstream endobj 224 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚ‘½N„@LJlA² À¼€ÅgErž‰&ZY+µ´ÐhÍ=Ú> @IA烋 á·ì|ýgf.ëK xQá®Âz¯•ÿð!ðe‰õ•Y^Þý¡õÅ#†à‹[¾öE{‡_Ÿßo¾8Ü_cå‹#>UX>ûöˆ)Eà§£‰¿ŽˆN£ÈGG#›"ˆqhfHøÔ8¾ÏéäfEÊAEIÅÈ=¿ÿ„Å-ˆÎ’%$©#쵂H\ÀÕWèfä¹  Íhg™…™cgݺi†¹8iZþG«`©s+´¤É,25×ô\iÜ`2[Ì[¸¨ÈE3)Dä/ˆþbZÁ1.8Gƒ ƒ•I¬³éUuužR¯áÍ:îXÔ&¼oÝ´í]Ö¯"MºÎÝß´þÁÿéýëo endstream endobj 225 0 obj << /Length 225 /Filter /FlateDecode >> stream xڽнjÃ0ð ‚[ôº'ˆìPÛt±!têP2µ;´4›qüh~?‚G‚$ÎýÅC»õ@ú¡Bw—&ó,㈮+]pöÈo1}R2æ¢ñ8^¼~в$ÿÌIF~{Í’/wüýu|'¿Ü¯8&¿æ—˜£•kžnûLMÔÐ@;ÑÁž&žEõD-twñ>‡5 pU/jh:ØŠ¶,PW+D5À^Ôh ma#:ôYÀVpÔ=ìDÓŠºb~9¬a€g‰æ/ÌÿŸuøÿwiSÒ]]Óq endstream endobj 226 0 obj << /Length 285 /Filter /FlateDecode >> stream xڭѽJÄ@ðY l“Gȼ€&áH¢ ç ¦´²+µ´P´N-²°`“b¹u>r‡"X?²ÙLæ¿Ó6']‡¶x\c[awŠOµ}µÍšéñLß<¾ØMoË;lÖ¶¼¢e[ö×øþöñlËÍÍÖ¶Üâ}Õƒí·hF8ˆs0;àÛ¤Ž¡+*³¯Lʨ€•Yñ ‘ iþŸŒk›àäï!%Nó¹4tíaà(.JÚ‚bÒî> stream xÚ’=NÄ0…'ÚÂ’›!sHRd ‘–E"Tˆ ()@ Qa-GÙ#¤Lyxcó´‘•Oòóx~ž×ÍaÛrÅ Ô¼®¹=âûÚ>Ù¦ÁfÅíqRîí¦·å57-ϱmËþ‚_ž_l¹¹<åÚ–[¾©¹ºµý–‰ÈÒOdÀ%2…È ¸9SQväTòÔy2ÙSÁ Tà» 2NXFvY òŒø_ȹèíC!š‹"Þˆº%R­î/ºQ‘‰(Œ¶"!×V$ÞMÀ x#$“0"»W ­ ÎˆPrÂ(¨ì$Ó7´Ày?â Âîßèö"^Ò\æ%òˆI‘Éd¾«^EÀ€AíÈRɯiP7ë@tÊê4F¦¾Ã}œÒ·  CÔGƒÉžõöÊ~†\ö endstream endobj 228 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­Ò±jÃ0`™[ü¾he…ÚÎTAš@=š)Cé”dÌÐnÁò£ùQü5˜8²þ@mp CoÐ'¸ÓJ“§,ã˜3~Tœ>óLñVÑ’Ô%cžMq³ÙÓ<'¹æ$%ùæÒ$ówþ>þìHÎ?^Y‘\ð§âø‹òGÂGT‚ ´%ð1Šîs °à< (G˜®Ï‹(ºnhÄÉõ<œA홀°OîÐÂS€ÆiüX+ÒÃé"¬]ö1¨Õö n\PrÀ䚇cDôÆÞ§ý+Á"ZlÎ`eºúý1´ÌiEWÂÁL endstream endobj 229 0 obj << /Length 339 /Filter /FlateDecode >> stream xÚU‘1NÄ0E'JÉMŽ`_²)²ÊÒ²H¤@‚ŠQ-” ¨£…›øéHayøcARäIñÿù?ûî¼ïÍÎtæ¬5ûÖôæ¹UoªëðqgúË|rzU‡A5¦ëTsƒÏªnÍÇûç‹jwW¦UÍÑ<¶f÷¤†£!*y"<–Þ3Dà‰ê@¼àȓơ©ŠD,#DQÄc!C<– S 1¹©úŸ`}½EØ fðŠQæjÙÀM5ÏA°˜øcÁ²¦Ç.%ó‚Í€€ %‚Æ ç œ9æd’QÿÅœrè™’t‘pI#xÙï$u_"E`—-5KˆfXÊz‘ qv, /&Áy¹6:)z…‹©veÒuFµA¹EøÅ”àVxXVˆ;Õ³]äß‘^KFƒùa9 ÔjcªG²ëÜY•ëAEJ˜¨ëAÝ«D© endstream endobj 56 0 obj << /Type /Font /Subtype /Type3 /Name /F28 /FontMatrix [0.00836 0 0 0.00836 0 0] /FontBBox [ 2 -1 121 84 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 49 /LastChar 116 /Widths 230 0 R /Encoding 231 0 R /CharProcs 232 0 R >> endobj 230 0 obj [65.77 65.77 65.77 65.77 65.77 65.77 65.77 65.77 0 0 0 0 0 0 0 0 99.31 93.5 95.01 100.81 86.31 0 103.39 0 48.44 0 0 79.01 124.77 102.84 98.78 89.85 0 97.76 73.08 91.47 101.07 0 0 0 99.31 0 0 0 0 0 0 0 0 0 0 0 59.81 0 0 0 0 0 0 0 0 73.08 65.77 0 0 0 51.89 51.16 ] endobj 231 0 obj << /Type /Encoding /Differences [49/a49/a50/a51/a52/a53/a54/a55/a56 57/.notdef 65/a65/a66/a67/a68/a69 70/.notdef 71/a71 72/.notdef 73/a73 74/.notdef 76/a76/a77/a78/a79/a80 81/.notdef 82/a82/a83/a84/a85 86/.notdef 89/a89 90/.notdef 101/a101 102/.notdef 110/a110/a111 112/.notdef 115/a115/a116] >> endobj 232 0 obj << /a49 222 0 R /a50 223 0 R /a51 224 0 R /a52 225 0 R /a53 226 0 R /a54 227 0 R /a55 228 0 R /a56 229 0 R /a65 200 0 R /a66 201 0 R /a67 202 0 R /a68 203 0 R /a69 204 0 R /a71 205 0 R /a73 206 0 R /a76 207 0 R /a77 208 0 R /a78 209 0 R /a79 210 0 R /a80 211 0 R /a82 212 0 R /a83 213 0 R /a84 214 0 R /a85 215 0 R /a89 216 0 R /a101 217 0 R /a110 218 0 R /a111 219 0 R /a115 220 0 R /a116 221 0 R >> endobj 233 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÐÁjÂ@à ƒ4׊ÁSµ`B{êAA{,ØÒž“GË£ôrô ngvÜ]vù˜]Øaþb:™Î•QOt ·O9~ᬠڕüpüÄe‰ú]Í ÔºE]nÕÏ÷ïêåëJå¨×j—+³Çr­€Ö€Ç(àYXU€õ‰zj&®|’€aOÃd pèùcš1uÔŽ¸Æ-1H[7c(< ¤bÆgá Xk;®>É÷èN`$ŸŽ³„Ö:¢‹ -åomc)¾ŠZ¶ç†/%¾á?OFi° endstream endobj 234 0 obj << /Length 266 /Filter /FlateDecode >> stream xÚÐÁJÃ@àYh`Í ”f^@“[ …ZÁ zò ‚ …* =É£åQò9î!tÝ™¤‡âAO;»³Ìü¶8-Î)£‚NÎhaÉô’›wcm(f´È‡›ç7³*MzOÖšô&”MZnèóãëÕ¤«Û+ ç5=ä”=šrM¢“@åë) ¼oç\SÝ%´Ø}‡«³ØqÝKK䄸´ã‡PËFïF왎»m4â„øˆ¤cž´ÂRÀ1Uó'~¤þú@õ›h`"[bzÄ ÉOv˜ÙJ:Y³åœ ¨°»®‡8!áÎy¥»@ì4÷h? î%<$ü¹.ÍùD‰pj endstream endobj 235 0 obj << /Length 241 /Filter /FlateDecode >> stream xÚѽnƒ0àC"ÝÂ#pOƒ(TLH ‘ÂP©:D™ÚŒZ53<Â#02 ßÙ$i¤(Aœ>l#ÝÓxñSHiLÉ+}GøƒIfÖ!/ùàë€ËÕ'%ªÙEU¾Ñßïqjù¾¢UAۈ–A¥µîÄÑ©kó¡~ÍF AkóæpÖ³Þ`…Ñ9EåÌkð&Çkkpk ³Éá9ç“\SþX¿·ù}iúžõÙÀõ,3ÐðO®ùZ®)g{I!9ÅÎê·VÓ®ÈQ5’Fb´)e¬<îþR‚gJàëàÛ‘)›gpò-áºÄ<[?—Ò endstream endobj 236 0 obj << /Length 230 /Filter /FlateDecode >> stream xÚmпJÄ@ð „´bæ ÜD؈ œ'˜B8+ µT´5y´> stream xÚ…Ð?JÄPð/¤ b.°ìÎ4‰°‚XW0Å‚Vb¥–ŠÂ²ÉÑr”=BÊ!Ï™I\ˆ ¾æG&óþÌ—¥§IÆ1/ù䌳”Ós~NèR-Æœ%ß§WZÝsšQt#eŠŠ ¼¾P´º½bù^óCÂñ#kôð…ÜUà9·µæµs`Ñàâ(+Ìw€z;#h¿GØÈž‹½œÐ!¯ éW¤øñze«»e0Òá¹TV<%× ä‘Êú_ÜHõ'Ëèo@Ûííeõ7®²)Àˆ%pÀb9 czCr™&!j.Ç; w¶³‘¶uØùÍLÚœ«ô$ – ]tGßPÄ< endstream endobj 238 0 obj << /Length 161 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0bc Ss…C®B.cS ßÄI$çr9yré‡+›ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ìÿÿ!êAC=3Ø€õ`¢ñL0`'ÁÄ?3˜øƒƒ`?pü`âBL<ÀAØ£úA€=ÿÿÿñDp¹zrr¾aZ¡ endstream endobj 239 0 obj << /Length 196 /Filter /FlateDecode >> stream xڅн Â0Àñ ‚…Côï LC[T?À ‚N⤎Š‚›>šÒGèØAŒEl ù‘Ëø'ªÙ¡"ÞIDI‹Ö wÛYh¯öaµÅ¾F9§¸ƒrÌS”zB‡ýqƒ²?B9¤…¢p‰zHp6&øÌÕžp¾|b¿-j8 endstream endobj 240 0 obj << /Length 305 /Filter /FlateDecode >> stream xÚmÑ¿KÃ@ðxT³r¹X4íT¨Ì èä B :Š?Ð9'þ[·uô_ˆ®f’Áó½k›Úá¾|ÞÝÁ»Éá^¼/•ìÓôåA"¯c|ÀdHµâ’¦·8N1ºÉ£šÅ(=•OÏ7ÏŽdŒÑD^ÆR]a:‘[ Âþ’LK> "@ÎÚª(î ŠÖw­wVÞÒ¬¤˜nÐŒä5z+WñJ¥ð×ÕiÄ µì:yNÅR½ RN@WP!Ége¬Ë„¦­<½.#Òv­.©#ÍéFÝZ½ÊI»åÔ[Ê6È,,iÁ‡vR|Ÿ¶­¯•üŸZx¬ûZøsà!‰¥J¥“G*œh;‰¿ÜÚBamÅòi'> stream xÚeÑAK„@Àñ' Èk‡Àù©Úv¶ ò°P§KTÇ`‹:;}³‰û ó òèÁvzÏ]Å=èüFaü;“ON&S™ÈSºòs™ÉÇ_0Ïhžð”_<<ã¬ÄøVæÆWôãr!ß^ߟ0ž]_Èã¹\¦2¹Ãr.¡²„µjÀÊ5ƒn¡rh„߯á‡à3¾Û1¾ÖÒè}Z‡ÂCÑG¨tc‚P…ÙG¢zŒ°é1Ž Ú>#é ÖcxÖ,¬ ‹³ŠA•ºwÐÅÆ!2´EÕ *kíÐ8;´âAqÂ2¨À³jØGÅXmÁ Á'ñÎmA?N¼i¿ƒÞ/K¼Á¨‡xƒ endstream endobj 242 0 obj << /Length 262 /Filter /FlateDecode >> stream xÚ…‘1NÅ0 †]e¨ä%Gˆ/m©xS¤ÇC¢L ˆ ßð¬´GëQz„ŒªÛdè"Jò)ËþÓ^žû+ªiGgÔzò;zmð„Þ³XSÛüܼqßaõHÞcuË2VÝ}¼¾aµ¿¿&>è©¡ú»€]@ƺ¼›ÙN¢ff¹üÒYÌ*˜à('‰’ ü‚Q‚ BФùŠ Id“!Ù‹¥T$·pÓa“¨èÿ‡6U.ÃοÀÅ~‹I2FE?h+(¸QÊ©š[/¹UöB–€éÃÄ oÄ\öLrƒD’Š5éßÑð¦ÃüÖ¼ˆ„ endstream endobj 243 0 obj << /Length 207 /Filter /FlateDecode >> stream xڅϱ‚0à# $·ðÜX0)ÆÉD1‘ÁD'㤎áÑxÑP¯GIt0 Í—»¶×¿:è„bšòÒsÒ3º$xGrÛÒnœo¸ÌQH§¨6ÜE•oéùx]Q-w+JPetä1'Ì3‚ÂÓ€Ðõ˜ÀTPÔ\–6Bðæf ~ËxŽî3à9º:ð^vì@+ð{B#pˆ€‰*ɱpqä”íý‚>{È{ wƈõ( G5Já(ÿâ9Ò‡ýÂ6qã?¾}O endstream endobj 244 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚнNÃ0`G,Ý@¡÷à8UÚ2E*E"L ¨tìPsüh~”> stream xÚuнNÃ0ðä¡Ò-YÙz/IÀTt!R)`b@LÀˆ&PãGó£øÌV¤¨æÎa¨øÈðS|gûîlg{Í×lywŸíœç|×ÐY+Ášg͘¹} EGÕ[KÕ™„©êÎùåùõžªÅÅ ËzÉ× ×7Ô-0j`šÜ#ЧQ æ#ÀD¼LÚ€Òc0u(e ‹+9í1ü´ _¬E—ÿÿrùŠ4ê²A)'RòÐvd/Ú”F½¶™¢”NI/ÏJB7™,ú|z’5[%°m_‰«¾}תŒ¦£G9Ð;}ŒÞ£tøŒúBq)[m0”:˜Ï}ÐiG—ôy?x endstream endobj 246 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ…ÐÍ ‚@àÂyõ 5OÐ*h&‚ä!¨S‡‚êØ¡¨³>šâ#tô°d»µDFäÀð1?00~8r(9ôÈhïâ }OÔŽ,å`wÄ8E¶"ßC6]déœ.çëY¼˜‹,¡µKÎÓ„ŒZÿ¢‚¬Ô¹Y@T7sɸ z‚l»õbô¤ãÔ x³ýÄR I´;Èø‡®à­ŠªSqk¥¯([‰Å²µ\ÑŧÅy£NS\âwpmõ endstream endobj 247 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚ}ÐÁJÃ@à ¸0HsõPè¼€nHLO…ZÁ=yBA= * ÞÌ£åQò9öP:Îvô 9}à 3Uœ5gœ|Zp5çòœsz¥²ÒnÆå<ŽžiÙ»ã²"w¥}rÍ5¿¿}<‘[Þ\pNnÅ÷9gkjV,"­ùVöFZે˜áÀ&²WŽG˜"‰ì”“jØÈVÉFxA”Í=f‘^éþÇtXD:¥ýƒ$‚ߨÀQ`¢uþõÓ@ ¤ºú3 çØF«d@âma5_³óÙjέ ñ"btÙÐ-}”^p endstream endobj 248 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚÎÍJÃ@ð ƒØko™'p7…Øô¨ÌAГ ­GAEÏÙGÛGYñ ‚ôP2îÇH=沿ÝÿÎ s1;Ÿ5¤©Òþ˜kªç´­ðë…Ä?ãÏæ—ª{ª¨®}Œª»¡÷·'TËÛKªP­è¡"ýˆÝŠ˜ dwthÙåì g ïDŸõAs´ u<ñ–¾öTœŠw²ÐâÚ[l2 æd&™Cã8ÈÎÄ0Ö/b¦bí틸N:m?Å/-¿!ù“œ âAÜ'‹?w’ÕÉü±¦õ )§¾žÙŠæŸxÕáþZmà endstream endobj 249 0 obj << /Length 214 /Filter /FlateDecode >> stream xÚeνŠÂ@à Ñ6…ûN²1’NðL!hµÅ"v·\6ŠÖæM|ßDÁÒBϱÐÂóÁ{¦—t³µÇ¤šõõ'‘•¤9æ˜#ß2,Ä~jš‹âVl1ÓÍzû+v8i"v¬_‰ÆK)Æjpª'gÄ#> N ý$"òOÜÝ#ð÷$ Ò$á 6&')Éx5ðÍ“éĤ47tGü4HÓxWtAN*²sÎ] î‚¿\ÌÁ‹ó;mçN/dRÈB\ endstream endobj 250 0 obj << /Length 242 /Filter /FlateDecode >> stream xÚuϱJAà± ¢­•7/ {›Üy¸Dð A+ „ÄRPQ°òÖ7[ð|ûW¦8¼Ì$Ml¾…ÙÝf w\9ç>rQpYòÜÑ3*)æ\V››Ù#k²7<ªÈ^H™l}ɯ/odÇWvd§|ë8¿£zÊØKdiÐ"ëû¤D%(€ï;¥œ”Û<)÷ÿ‘”Ø_ŒïOIY Ó~0-Î`> stream xÚ]Ð1NÄ0Ð¥ˆ4à¹$Ù]C*,-‹D $¨¶@T@I‚aÍ7 ¥ â)]D˜I²H@᧑ǶþxUï›W|À{ ^6†ojº§e#››Ã¹s}Gë–Ê-/*Oe›ÊöŒžn©\ŸsMå†/k®®¨Ý0€$«HЩ"² òŠNjòÚ ‚Cñ52 ûëEÿƒšèÝYý‘:èÏa_ñ ûŽ#Ø7yÑFyÛö‚“APÁ¹9ãgô/þc'‚ûË‹Lã'Ü8—…¤Þ‘ME(/YUPA2KÈ,Ÿ‘†)4@'-]Ð70¥oÈ endstream endobj 252 0 obj << /Length 260 /Filter /FlateDecode >> stream xÚm±JÄ@†ÿ°E`š}ƒd^@s¹\ˆ…8O0…àUb¥–Š‚ÅAòhû(û[¦7Î(‚,|Åìÿ;ì¦>m×¼â–OÖ¼i¸mù©¦Wj:ê¸û¹y|¡í@Õ7U×:¦j¸á÷·gª¶·—\SµãûšW4ìÈ€þ¨™à’ȃ‹ðÈ á˜q|êùEú‹Ù"³…«‘EȤ y€D?aœK`\TÖ‹&K‰€—  ˆ*2›yY€b5–2eɛ™"“  ‰ªèã…¶£z|.Îóü¾¡‘|2@kÞP@U”ú”Ê|„³/€Øg”Ú¡«öôé8p endstream endobj 55 0 obj << /Type /Font /Subtype /Type3 /Name /F30 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ 2 -2 83 60 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 52 /LastChar 89 /Widths 253 0 R /Encoding 254 0 R /CharProcs 255 0 R >> endobj 253 0 obj [41.52 41.52 41.52 0 41.52 0 0 0 0 0 0 0 0 62.28 0 59.97 63.43 56.51 0 65.16 0 29.99 0 0 51.9 76.12 62.28 64.58 56.51 0 61.12 46.13 59.97 62.28 0 0 0 62.28 ] endobj 254 0 obj << /Type /Encoding /Differences [52/a52/a53/a54 55/.notdef 56/a56 57/.notdef 65/a65 66/.notdef 67/a67/a68/a69 70/.notdef 71/a71 72/.notdef 73/a73 74/.notdef 76/a76/a77/a78/a79/a80 81/.notdef 82/a82/a83/a84/a85 86/.notdef 89/a89] >> endobj 255 0 obj << /a52 249 0 R /a53 250 0 R /a54 251 0 R /a56 252 0 R /a65 233 0 R /a67 234 0 R /a68 235 0 R /a69 236 0 R /a71 237 0 R /a73 238 0 R /a76 239 0 R /a77 240 0 R /a78 241 0 R /a79 242 0 R /a80 243 0 R /a82 244 0 R /a83 245 0 R /a84 246 0 R /a85 247 0 R /a89 248 0 R >> endobj 256 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ1 Â@E°L¡70sÝì ’@°ˆÜBÐÊB„€ZZ( 9ZŽ’#XZ:IV›t«þ 3ïOÌØÄrÄ#²‰xjø¨éBºN%7nt8SjImYǤ–’“²+¾]ï'RézΚTÆ;ÍážlÆ@TðJô ø@ ðhxÁ«jze/¨ š]aöåÙáýÝ;¿íÇÎAdDÉ/ak+ÚÎ?i¶¥”T“‚RSÊ"§…¥ }G«@ endstream endobj 257 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚ1 Â@E¿¤L/ :ÐÍ®A"ˆEŒà‚Vb¥–‚Š‚…EŽ–£äÁÍ$±ÐNxÕÌgæý¡˜1‡qß„l">hº.§!Ǧ^íO”XRÖcR 7'e—|»Þ¤’ÕŒ5©”·šÃÙ”s Î@ t€h~//i¹ÝKxO`L®Ð“tIVãçßxÅ?üÞù¼¨>ö‡©(=C±uÚ•¿/ñ@ªÅRÓr•iniMoEËBs endstream endobj 258 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. Œ?øØ¾á„ËüýóƒðÚcyn€8£žáÐ@§Ô­ÿÏ¡A|8X¤¤^þ}ÜÇÿ& ð…(¼À…ã.WO®@.QåXÙ endstream endobj 259 0 obj << /Length 174 /Filter /FlateDecode >> stream xÚ31Ô35R0P0SÐ52T06S03RH1ä*ä2²Š(XC¥’s¹œ<¹ôÃŒ,¹ô=€â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. þ```ÿÀÀÀâÔ±=700ȃ0P’ŸøÐ aþäy û]ɃÔÔƒôÑÃ} p…(\ìàN9~ ×r¹zrr°Wß endstream endobj 260 0 obj << /Length 103 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0WÐ5´T2u MR ¹ ¹L @Ð*•œËåäÉ¥®`jÀ¥ï¡`Â¥ïé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢PÿÀäÿP *ÈåêÉÈ- +´ endstream endobj 261 0 obj << /Length 130 /Filter /FlateDecode >> stream xÚ-ɱ Â0…á gð 2œ'0¹-¥™k3:9ˆ TGAEçæÑòfÚ¢|Ûÿ—ÕÒ7ôlXUÔÀ:ð¢x@='eý;ý m„;P=ÜfÌpqË×ó}…kw+*\Ç£ÒŸ;Zä“Fy2d›åÏd“L*R!s™ÉB¬¹ËY°ŽØã ,P#Œ endstream endobj 262 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ33Ñ3µP0P0UÐ5S03P0±PH1ä*ä25 …M 2ɹ\Nž\úá@.}0éé«PRTšÊ¥ïà¬`È¥ï¢m¨`Ëåé¢ÀÀÀ`ÀC‰ú ÔÐô—«'W —á)Ð endstream endobj 263 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ-É1 Â@EÑ?^á ¦xЙ‰‰mŒà‚V"ÑRPÑ:³´Ù™&Nwo¾\ø’ž%红V\ó¦xA=y1žö:À¨n×w¸°ççý½ÃÕ‡ ®áYé/ ­tò‹½4è’M22ÉD³˜ÉT&2+•<å*ØñBÛ#´ endstream endobj 264 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsK…C®B.K Ïȉ&çr9yré‡+Xré{€O_…’¢ÒT.}§gC.}…hCƒX.O†z†ÿ 0XÏ ÃÀåêÉÈ[\w endstream endobj 265 0 obj << /Length 153 /Filter /FlateDecode >> stream xڅ̽AÅñ ɉ¨ŠóÌ—eëµSH¨"‘ ” ôÍ£xw³ÓN¦ø5çæþgvZ8œ8K¿àÜñbñ€·²–>žÎ7TzOo¡×²C‡ _Ï÷ºÚ.)k̓<j*¥zÑP ¢±‰R˜è.NÑO|[ƧÕmÈÜÏdSéL6•Îeé\6•NdV;üxÔ*Æ endstream endobj 266 0 obj << /Length 101 /Filter /FlateDecode >> stream xÚ32Ö30W0PaCsc3…C®B.K ×ĉ'çr9yré‡+Xré{¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]dêþ7À`=ƒ 1S—«'W fp"¸ endstream endobj 267 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ32Ö30W0P0WÐ54S0´P06SH1ä*ä24PAS#¨Tr.—“'—~¸‚¡—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEA†¡žá Ö3È0຀`ý™ PÈx€±±¹™¨Ò‚¡€!ËÕ“+ &,• endstream endobj 268 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚMÉ=@PEáþ®â®À¼™x¨ý$^!¡Rˆ ¥‚°{ äTß±4J2:*5¡Å4嬨`ö¢£ÿÆ´"žfšû¹@ò¶ BJJ7"”¼ï몀Ði ‹ endstream endobj 269 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ31Ô35R0P°T0²T06V0µTH1ä*ä22 (Ce’s¹œ<¹ôÃŒŒ¹ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž. 5 5ÿþýg„" Õ1ü*Êl*,,0‘ƒ—«'W /¨67 endstream endobj 270 0 obj << /Length 263 /Filter /FlateDecode >> stream xÚUÏAJÃPà‘Y13Ð4i»j³tåBA] * ]”vB.{b yÐ ÜdÞsJDìâÛüÃ{ÿÌqt”ô¹Ç &yÐ燈^(Ž4ìñ`ØMîŸhœSxÍqDá¹ÆæüöúþHáøò”5ð¾¹¥|€ü`aaÇ9Áïeå­ ã—R(£L¥(û3”]µ7EÉÛ`±¥EiÕÔêN-6Vj-pâW©|gÁÓíªÀ9£Ãpã«\ª²,~‰UsퟻNöŸívI ÊìN=k¿jF(uŠE}€¥ññ£òÖŸÚg\ غ]ÑYNWô_Z endstream endobj 271 0 obj << /Length 295 /Filter /FlateDecode >> stream xÚ¥Q±JÄ@}a‹ÀîÚÁìh6± œ'˜B8+ j)DQlDîÓ⟠ø)-qf·ÑÚdáM^&/oÞlª“º±ÎÖö¸´ÁS{_ÒÕ•Î3úæî‘¶×¶®¨¸šŠîÒ¾<¿>P±ÝŸÙ’н)­»¥ng³@¯|a…Yn b Ä=Z F˜Á-µ;C4 ¬`Ú £ FŠhj…x‘†¹1føo8ý}}‹Èà¢IDœ3Ö솘sÓ{Hûõø ØC6æb‰“BKú¿à›i°”ªÁœSµÛr£æßØé(_Ó ƒ}NìÇ\F?t"@!„°Bzéï>a3û„óÉ'¼tíìס²¡é¼£+ú®E}d endstream endobj 272 0 obj << /Length 172 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bSK…C®B.# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ø0Aý? Áøƒ½ýãù† ö@CÿùA2þ€’@5@’±D‚!™dþÀðPI¸ùÌCdþÃÀþƒ¡þÿƒÿÿ “\®ž\\^åˆÓ endstream endobj 273 0 obj << /Length 154 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bSK…C®B.# ßÄI$çr9yré‡+˜qé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]øÿ0AýÿÆÌذIù~ iÏ"ëÈ?P¨†ñ3õÈÿ@€JR×|Z“ÌÀ0ù Çÿÿ@&¹\=¹¹)“ endstream endobj 274 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚmÐÁj1à é^=;OÐd-‘õ$¨…îAhO=”‚ÐöX¨ÒÞ„Í£í£ø{ô°˜N"¸Q6>fB&?™Nî'izàmf4Õô™ãáZûÒ||ã¢DõJÆ zâ.ªrM¿»¿/T‹ç%å¨Vô–“~ÇrEP@X×ìû8õ \²²IU{ó˜»ùÁ3ÌbÆYã¥1Ezôè$æ'i=SË©†LÂB„p6Pu Ž–8ç:R†£ ²Ž÷›[4ß9Þ²áéí…ÃŽ&ÎÈ&üZÚú'­ãXήÁÇ_ð%°m¼ endstream endobj 275 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ•±‚0†0Üâ#pO`Amd3ALd0ÑÉÁ8©£ƒFgúh< ÀÈ@¨…«Ú´_®íÝýýe4fÐÜ,¹ ¹¤kˆ”µÓ„íÅåŽqŠâH2@±5§(Ò½žïŠx¿¦EB§‚3¦ i3 €5C8ZA–›À/:LÊ^ÕÁ­ûpšôXpžÛôkÚF¶­±bIF°Ü2ÕéqžËUœNÐC¨™E>ª_…ñ÷c‹ð+v·d¯ó¯åínÔâ&Å~VŸP endstream endobj 276 0 obj << /Length 260 /Filter /FlateDecode >> stream xڭѱJÄ@à? LaZ áæ4‰Üª[-œ'˜BÐÊB¬ÔRPÑÖÌ›ø*¾‰yË+Äuv²g!–Bà#“ÍÌî¿ÎïúnÙñÎ;ÇÎóMG4÷Zly¿›¾\ßÑ¢§æ‚çžš-SÓŸòÓãó-5‹³#Ö÷%_vÜ^Q¿d ˆRPDZT†¸R´öR ÊOÔµ þ@ù*˜(ÞAWEÁ],øR‚º˜IµRê5ú7P­Ñ&?”2oÆ(~#FLØàgÈü5=dF#ïzv¢L;mf–Ä&,—mXJ[°Ìa Þ#å }Rº:%e-vÁvS½•Ô=U:î霾šes– endstream endobj 277 0 obj << /Length 194 /Filter /FlateDecode >> stream xÚ33Ö31V0PaS Ss…C®B.S ßÄI$çr9yré‡+˜špé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÁõBýc``üßD@.ƒý0ÅÿL1ÿSŒÀÃ?UBÙ7@¨`JJ=SüPêŠýê (<ö¡9ÅñP¯@=ómrüC%h˜ACž  !@ y`> stream xÚuб Â0Ð  ·ô¼/0­ µ‚Dª£ƒ¢³ý4?Å/iLsqˆð’»INÍÆª œ&vª)©9 ¼¢‹åý¶O4¬4Ê©åÊFQê5Ýo3Êj³ ­ioK¨k2ýè D˜ÒÀ€§dFLƤ1’(­C8^Qˆ€„ÉÆDð¹ïɰ|pÃ1ÆÛ½Ó.þ"bøÿyÒ€Œ)™gëºk¸×¿àRã?UŸ’~ endstream endobj 279 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚ35Ñ3R0P0bSCSs…C®B.s ßÄI$çr9yré‡+˜˜sé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þƒÀd’ñƒü†ÿ Œ`’ᘬ“6`R‰äÁAòI68ÉØ€L2`%™‘Hv0)"ÿÿG'!âP5Ⱥ‰ A€J$ãÿ `G@%¹\=¹¹Mÿx× endstream endobj 280 0 obj << /Length 254 /Filter /FlateDecode >> stream xڭѱJÄ@à?l˜&yM"&`µpž` A+ ±:--­7`ákMgé+ä ¼òŠãÖÙÍ& XšæKf’Íì¿]{Üt\ó)p×p{Æ =SŠu¨ÄÎæ‰V=U·ÜvT]j™ªþŠ__Þ©Z]Ÿ³>¯ù®áúžú5ð(ü6S¬ßü`À쑊-Ì— oÕ¶¸áÖë¥d‡ˆ¾¯ I¾Sòý03a‘™LlB".€¿Ñ!1ÍúOx½&ÂpcÄJÂ&ÆHù‹¸£…¸Û…˜„rI)¥ÌÜ” _ò,v0Ÿšõù{lØtéT–‰é¢§úî”Û endstream endobj 281 0 obj << /Length 125 /Filter /FlateDecode >> stream xÚ33Ò3²P0P0bSKSs…C®B.SS ßÄI$çr9yré‡+˜šré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÏøÿÿ?TŠñó bü78) À¤¯s‘)hèb y.WO®@.!»¥7 endstream endobj 282 0 obj << /Length 106 /Filter /FlateDecode >> stream xÚ3²Ô³´T0P0aKSs…C®B.#3 ßÄI$çr9yré‡+™qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿ†€ˆ¡¾aècWüÅåêÉÈ3v\‚ endstream endobj 283 0 obj << /Length 140 /Filter /FlateDecode >> stream xÚ35Ô³T0P0bKSs…C®B.S ßÄI$çr9yré‡+˜˜ré{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]þÿÿÿ€™dü€þ3 eR/i& 0È ò‚d“Ì`’LÊ?`üßÀðÿÁ@!¹\=¹¹Afl÷ endstream endobj 284 0 obj << /Length 244 /Filter /FlateDecode >> stream xÚuÑ?kÂPð{<0p² Þ'ð%œÿ€ ur(Ávt°ÔÙ€«ê•]ÝÌGÈè|½¨X#yîøÝ=8. [~›< 8¢€:½û¸Ä°ËµW”ÅÇ|ýÕ”Â.ª1wQÅÏôõ¹ú@ÕjH¯>yoÉà瘣1 ýƒ¸ 8hFãx‡]Ê*ñ›1æ•øá8§¾yºØTBŸ¤,a P³ —À“M õ2Ü< œ fepÒˆ\$ÀIÂÖ5+zÛG4÷V¸Y5D NZ@fWðí¤'c´ÔÒÇýoÊÀQŒü¦Â! endstream endobj 285 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚUпJÄ@ð/.0…ûfŸÀMNÖ?óSge!Vji¡hkRù\AKÁTÖ©$EØuwöŠM1üøf`Šï`¹·<’…Üw£¥>”w%=’Ö.>úÃí­jRWRkRçnKª¾ÏO/÷¤V›SY’ZËëR7T¯¥µ@fµm óÀ¦‡í¼ÅÏ0 à{d¾¦˜üۘÎ=õ4]LÕ3ùȦ€aÒ@b·´liº@ÏT|`Ä“MLjbËÀ¾Å4ŸLõ“ÿ1ÂÄdtFÀœW$®Gœ á*Ã.|ר™±ÕtIÿ6D†c endstream endobj 286 0 obj << /Length 239 /Filter /FlateDecode >> stream xÚ­‘±‚0†Ï8˜ÜÂ#ô^@D'ÔDŒ“::htGáxWÚœmš~éÝßöú_LÂyÒxJsNgoô(ò»ÌéŠIŠîžÂÝ5‡ÑM7ô¸?/è&Ûñ~IŸ¼#¦K¶ Cµ¥ Ô¼*x1F%¨À)dBœÃè ñ‘Š…¬ªA«ÑŸ8çEÅjGîU…Ò(ßNk¼ûÈ4ª,— ~ÐjÔ…}Á<ÛC¿2[|Žþfa?­-ÈÖžÆ3ë ñ“­oŒ×œÈ¾}°]Ñ=ÂUŠ;ü”K‰É endstream endobj 287 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚ35Ó35T0P0bS#Ss…C®B.K ßÄI$çr9yré‡+˜Xré{E¹ô=}JŠJS¹ôœ ¹ô]¢ÆÄryº(ü‚ ê„úÏÀÀø¿,ÊÀ ÿLñSÌ? Ô0Åø™adªT Y;ªÑPû ¶CÝuP7ÈÙÿÀÔˆ ƒ™….ĵ˜—«'W ŽK€¿ endstream endobj 288 0 obj << /Length 221 /Filter /FlateDecode >> stream xڕѽ Â0ð–‚ì#x/ i*Uœ ~€ÄIí£ù(}„ŽJãÙK Í"&…äHrÿt¢F*ÄÇ8 q¢0šâYÁ È€f4ãÊé óäžê ×´ 2Ùàãþ¼€œo¨@.ñ 08B²D­uåÐ uf,HW§‚ ô¥lüfëç¬(ºz¥eõ§Ö~ûüæÞ¦Øô§¹_Qš@™ñÍëõ6Ò+L®6ŸñeålóZ¹šÿ«›v,X¿ÕKéP~ï‡ÞEÔºe¯Ö©úN=â’¹«vð™<›Â endstream endobj 289 0 obj << /Length 256 /Filter /FlateDecode >> stream xÚUϱNÄ0 à¿Ê)K¡~h{=îÄB¤ãè€Ó ˆ @°!ZÞ̉èF%Psw ²|Jì8¶ç‹Ãª¦’æt0£ùŒŽŽé®r®^j°¤EµËÜ>¸U㊠ÕKWœkØÍ=?½Ü»buyJz_ÓuEåkÖ?€ÆŒ!òÎf°l#>Ù3ZÎ;@Î'€ç7Àîx ïÉ&Œ&È–Nm9ƒR0—!¡G/aEïFD+E$½ÑŒµ²MX‰¿„^É>a‡-úÆü‘Mˆÿèû=¦×:upÇ´–¤-µiÞ}õèGŒˆA§Š^{s¦ywÖ¸+÷=Ÿ†# endstream endobj 290 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ3µÔ³4W0P0bSsJ1ä*ä2ñÁ" Fr.—“'—~¸‚©1—¾P”KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÁþ?<@£0ÿg`ÇÀøùA ˆbüP¢>€©T*L`¥€)‹`J+ŦF Åþ¿Hʃ‚ârõä äWÎr° endstream endobj 291 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚåÐ= Â@àÑÖBÈ\@7‰¬ÆJðL!he!Vj)¨h«9šGÉ,SˆëlÅ3X,ßòf˜âu¢VsÀmnFlzlº¼ é@ÆH¸¤˜¬w4HH/ØÒ‰I'S>Ï[ÒƒÙCÒ#^†¬(±µÊ>ñl \3X~ZPCAù©J'BEH?4€þ—ºôuâ7{©-'¿ROrï%ËxºVÝ™‹Ã·¹CÙ ï qBszØxaº endstream endobj 292 0 obj << /Length 240 /Filter /FlateDecode >> stream xÚmÐ1jÃ0Æñg1> stream xÚuÑ1KÄ0àW „ãºv8ÈûÚôÎb ç vtrá@ÿ…?'â)ΤC¹ø’£âMHøH^ÂK^Yì/Pá÷æX.°8ÄÛ\<ˆR¡ëÅÑvçæ^,k‘]b©DvJË"«ÏðéñùNdËócÌE¶Â«Õµ¨WhíÀ­í"kÿ·ä@öŒæ¤àmDâ$f~¤#; Hl ¿¥½8@£ÁŠwdFUšì¨%[pù¤^q(é`J7)¯Iˆ’›ÑMk¯T¢äRÙñRI JN%}¤½Ö<=“Dt2l¥IÜ©yÑÑ&ôFš:Uï; ôAš9ÉOŠ} ô5*¡¿­ºÿÄÿ‰°­ ÄœŒE'"'íEÑ<´¾¦®_g'µ¸ßÑÆ©Ñ endstream endobj 294 0 obj << /Length 279 /Filter /FlateDecode >> stream xÚ]ÑAJÄ0àC»…МÀ¦Ç.„Â8‚]ãÊ…êÒ…¢ëöÁ«ô&æuW°ôù’<3‹ôãÑ¿ù».OËÊXSÒZ[svnž ýªIkÂè_<¾èM£ó;šu~žÍyûxÖùfwi oÍ}aìƒn¶¦E„'8p…@ë@Òµ1Ù±=™Ž h¨ $«3,ØÄ+N¼€ÝŠ­‚moƒµÛ³.˜ }0ý颿Q…£’x(`ÜO‡b<¾£âkˆç|ŽÑ4ºPS0á€%»â€ ¢–ƒöàØÞW¾œÌÈCeàË  »ä›PIÂ{Á7™½]øоiՈݱúªÑ·úR}Ý endstream endobj 295 0 obj << /Length 231 /Filter /FlateDecode >> stream xÚÍαJAàYÈÁL›"y÷.p1©b¯L•BAS¦P´Î=’p²2EÈ8»n@ô,†ofgÙ§“ËÉŒK®´¦×WüRÑ+ÕsË8ÆÅó– ¹5×sr·zJ®¹ã÷· ¹Åý5Wä–ü 7©Y²È ð~k%…öÒvìT²Z^{ÓcÝÙ³ ÷ÃâôU«o²CÕ0Ë–*¤ÅSTB¶‹ú`ζÑñÞ&‡í%‹ãE¶Ÿ´§QÒÈ0›b4è3¾Ýe}÷¿Íÿô"Ý_馡}Èl® endstream endobj 296 0 obj << /Length 204 /Filter /FlateDecode >> stream xÚmÌ; Â@à . ´Vf. ›´1àL!he!Vji¡(X›£å({„”Á8ë£—åø‡ùÝéÅQ—Úš’˜º}Úi<"ÏÈŃ÷f{ÀQ†jÅ{T3ŽQes:Ÿ.{T£Å˜4ª ­5EÌ&¡€º6äü¥…°%/_x÷/PAP02gøýÁ0Ò¦–yp&îî¬dBw›:Œ+0ðÁüâ}¨AT¾yóMÞ6Ó¢5lö–¢.Ë5²Ài†K|¤øT£ endstream endobj 297 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01V0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃT‚D0S$ê00|`ÇÀü¹A¾ù;ÿæ ì˜ÿå˜00þ* àÄ?8Q"êI&êPMÊøbÛ½`Ëßœq ä ã ò Ìê˜þÿ:]þ—«'W ÈckA endstream endobj 298 0 obj << /Length 182 /Filter /FlateDecode >> stream xÚÎA ‚`à'?( ‘œ ”ýüºÌ A­ZD«jXÔ.Ì£yàÒ…Tcu€ßæ 7f: 5ÙðP³™° ø éL¦ %¿—ý‰â”ü MþBbòÓ%_/·#ùñjÆ’&¼•ÎŽÒ„¡ZÀ{ÈUe5ÈTÆ©¬Ö-Õ‡W¨6êÀj@-ÐÉÅóOù¯Ó‰;*`{ú^‰ž[bàTd7“ý w§”§ÍSZÓ»= endstream endobj 299 0 obj << /Length 198 /Filter /FlateDecode >> stream xÚ31Ó34V0P0VÐ5T01Q0µPH1ä*ä21PASKˆLr.—“'—~¸‚‰—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEÿó‚ÁþT‚zó !ÿHÔ±÷`øÁøþó†ú쀶¤ „|P±=˜i«‡u âÉDª)öph‘<„ÚkrF=ÈAï?0þ`<ÿŸ¡†½ÿ?ƒü?þÿ ì@‡s¹zrroXhI endstream endobj 300 0 obj << /Length 189 /Filter /FlateDecode >> stream xÚ]Î1 Â@Ð\˜B/ 8ÐM²(ÚЦ´²+µT´“èÑr”!åbI qáÁ23ü;èö9änÀ¶ÏvÈû€ÎdC)úlGUgw¤IBfÍ6$3—2™dÁ×Ëí@f²œr@&æm)‰Ú¸·2Ï©\^¡sϵ2¸Î÷¯HÅøQ‰RñþQÖOþø—Ö5ÉQÑJrµìhè M£íÂá„TårL¼@³„Vô½£@ endstream endobj 301 0 obj << /Length 141 /Filter /FlateDecode >> stream xÚ32Õ36W0P0bcSK…C®B.# ÌI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢*c¹<]ê˜ÿ70ð|À ßþ€ÁžÿCÿ`ÆÌ00ŠÿÿÿÇäè§3ÿa`¨ÿÿ޹\=¹¹¢&[ endstream endobj 302 0 obj << /Length 237 /Filter /FlateDecode >> stream xÚ¿J1Æ¿00…ñ v^@³9ïäŠÃ…ó·´²+µT´[¸}´> stream xÚ31Ó34V0P0bS …C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ì€à?É&™iN‚ìaþ`ÿD~°’È700nà?ÀÀüDþ“ØÀÈä‡$Ù€‚ëÿÿƒÿÿ7 “\®ž\\y endstream endobj 304 0 obj << /Length 122 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS3…C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜ø0È@A@ 8~Àüá? ±q©ŽØ0üÿ‚¸\=¹¹(CE` endstream endobj 305 0 obj << /Length 150 /Filter /FlateDecode >> stream xÚ32Õ36W0PÐ5QÐ54W0´P05SH1ä*ä22 (˜Ãä’s¹œ<¹ôÃŒ ¹ô=€\úž¾ %E¥©\úNÎ @Q…h ®X.OÆ ìø   P?`üÁð†Ø€¸ôE6Œ?êügüðŸ‚üc?PÃ~À†Ÿÿó.WO®@.ÿ§Wõ endstream endobj 306 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚµÍ1 Â@Еir3'p.#˜BÐÊB¬ÔRPQ°ÍÑr±0EÈ:? êdÙ³3ó7èuÂ.{Œô¸òʧãH‰ÆrCqJzÆGz$¯¤Ó1öÇ5éx2`ŸtÂsŸ½¥ […RÊüâë?´LõºæÝ3Ø‚ærÁÊkm‚¨„;xÔÂ3êH†Kv¤Ø@%¯â.êýoÔ nn—**ŒÉù@Ô¦ôDr endstream endobj 307 0 obj << /Length 108 /Filter /FlateDecode >> stream xÚ32Ö30W0P0aCS …C®B.C ßÄI$çr9yré‡+Zpé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?0ü‡!þ ̃±ÿ`øÿÿq¹zrrÆ‚Q. endstream endobj 308 0 obj << /Length 177 /Filter /FlateDecode >> stream xÚ3³Ô3R0Pa3scs…C®B.3 ßÄI$çr9yré‡+˜™pé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]˜?ð`Àðÿƒý†ú@úƒ=ãƒ:†ÿÈ77Ø3ðnà?Î ßÀüÿˆþÇÀDÿa`ÿÁÀNÿ``ÿ€þÀÀþ`Ð O€âÿÿƒÿÿ7ÿÿNs¹zrr#߈ endstream endobj 309 0 obj << /Length 147 /Filter /FlateDecode >> stream xÚ31Ó34V0P0bcs…C®B.C ßÄI$çr9yré‡+˜ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. Ìø?00üÿ`ÿD~°’È70ðnà?ÀÀüDþ“ØÀÈä‡$Ù0½ñÿÿÁÿÿI.WO®@.‡e% endstream endobj 310 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚŽ1‚@E¿¡ ™†#0Ðeƒ6 &na¢•…±RK v9Gá”Tâd)H¬ÌN^fþîþù‘žÌ¦ð”Çš£€Ã9Ÿ5Ý(ŒE”qÑßœ®”R{cRk‘I™ ?îÏ ©l»dM*çƒæàH&g8^W‰S­œQƒdHàVðá•R¾ ò!J*¨- Ài~ nNû/†ooñkg»Íîõ$AéÖHåŠ> éáwlzZÚÑIKÚ endstream endobj 311 0 obj << /Length 196 /Filter /FlateDecode >> stream xÚα Â@ àH†B¡y½ž­uj;:9ˆ“::(ºÚ>Z¥p"ØŠç]qÐQ |CB’?Šû2ä€Ü“1G!‡#ÞI:R°«aøm”d$V$f¶O"›óùtÙ“H–$R^K6”¥ŒÊ¯À¨\ƒ¹UW0÷Â/¼º%>Á«°T¨5*è´4hy~“ÿÌ÷ö²¥ý¦Ýß> stream xÚ31Ö³0R0P0VÐ54S01Q06WH1ä*ä21PASc¨Tr.—“'—~¸‚‰—¾PœKßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEùÃùŒêØ0üa<|€ùÃãìÊð?`0?À€Áþ€> stream xÚ36Ò35R0PacCcs…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]ØÈ3üPàÿÃÇþ?nÿÀÿœýó3 ~Äo˜0ÿah`þÁÀ€‚?P³Íüÿÿs¹zrrjÙF„ endstream endobj 314 0 obj << /Length 195 /Filter /FlateDecode >> stream xÚ=αJÄ@à¶X˜fßÀÌ x{›`TñSwÕ‡•Z * Wî£í£ÄÊ6`“"8Î%GŠ™ùÿfŠ|q~ÆK.ø4p¡ó‚½R^j¨çåÔ<> stream xÚ36Ò3²T0P0TÐ5T0²P05TH1ä*ä22 (˜Ad’s¹œ<¹ôÌ̸ô=€Â\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  Ø W á Œ@Ì Äì@,ÿÿ?Ã(f„ÊQ „þ0‚pC sC3ƒ=;ÿ?°f.WO®@.uH– endstream endobj 316 0 obj << /Length 153 /Filter /FlateDecode >> stream xÚ31Ó34V0P0RÐ5T01Q06WH1ä*ä21 ([@d’s¹œ<¹ôÃL ¹ô=€Â\úž¾ %E¥©\úNÎ @Q…h žX.Oæ ìþ`üJò`À‘p’ƒºBþ`°ÀÀðƒ¡üÆçÿì™Iùÿí@’ùÐ.WO®@.1c endstream endobj 317 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚU̱ ‚PÆñ#‘k[çêªWJ'Á rjjˆ ¨Æ†¢¶ˆûh>Š`›Ph—º—jù ÿ¾@ BŸ\ò©ïQà“ÒÎÃ#ŠHE—Äè³l˜dÈ—$"äS•‘g3:Ÿ.{äÉ|Lò”V¹kÌRj×_œ œÒ.Á.X ,g0i)à <¡¥©¡pƒ¶&†®A†=éjœ|c(v‘kØ]þb=ÀÐ(Ô¿áúO¨ÁI† |F£?ê endstream endobj 318 0 obj << /Length 233 /Filter /FlateDecode >> stream xÚUÎ=KÃPÅñs Xx³v(æùzËíËb ­`A' ÖQ|A7©‘|±€Ð~Lïx‡`¼7UÓN?8gù«áá°Ï!ñAÄjÀÝÏ"z$¥ìr·¿~nîh”¼d¥HžÚ™drÆÏO/·$GçcŽHNø*âðš’ WUPñ÷6¾Aß´4æðŠ5¹§q ‘þ" bxØ%âtÇq¿Á_ù®cùGˆÅ²h;²š÷L€ Ëtè5Â<þfúOk…2·|âµÁ+ñ–ZlECÝdÑ ±ï(°ç˜ÂÑIBô¥Y_™ endstream endobj 319 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚMν Â@ ð)(¡«ƒÐ> stream xÚUÎÁjÂ@àYi® Î èn²Zõ$¨sÚSE¨GÁ½‰æÑöQ|„x ‰³²Iéå;üÃüü=ÝF¤(¢N8 ^DúÖ!þ qª¨¯ÝiµÅIŒò‹ôåœs”ñ‚ö¿‡ ÊÉÇ”B”3úI-1žQY¦ãâàAægà//7ˆœŽ4gËZŽvª*Ì 0‰Ã¿˜Š+ã]S‡¸CEÉ@QsüϰFÕì,IqSn/¼'¶’gCþbŸ^m‘mjg`ç1øã'>ÚŸKø endstream endobj 321 0 obj << /Length 183 /Filter /FlateDecode >> stream xÚ%Î1 Â@„á‘@„‡$|'0‰+AA¢‚)­,D¨¥ ¢æQ<‚eŠ`œÅ_ìì·°&î# µÇL_M¬‡H.bìÚ£½ØŸ$I%ب‰$Xp• ]êíz?J¬¦Êu¦[>ÙI:ÓIU•uO§Ã)Fh~ðß!;£ó:còÌÛዬQÖ‘‚ôŸÿ)HÿåpIëH]R·YÀ#õH[¤mé(œ²âl2Oe-?uàC endstream endobj 322 0 obj << /Length 188 /Filter /FlateDecode >> stream xÚµ1 Â@EH!L“#d. ›ÍºˆBŒ` A+ ±RK EÁBb޶GÉR¦R×l´6¯˜˜ÿþPtÌ+îǬƬ5$Ii;ŒXÜf¢$#±a¥I,ì˜D¶äëåv$‘¬f,I¤¼•í(K~ |[äj¿„W¢‚opGÏà ÀÄ!´—S‹¢E¦ /‹òèzù´ÌO¾6x+Ó¸YÛ~åÕÎÜuдñí…æ­éÂÕ`ú endstream endobj 323 0 obj << /Length 121 /Filter /FlateDecode >> stream xÚ31Ô35R0P0bc3SS…C®B.# ßÄI$çr9yré‡+Ypé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<]0001;Ëñÿ ÿaX*6T°ý†úÿÿ?À0—«'W ¾NÚ endstream endobj 324 0 obj << /Length 228 /Filter /FlateDecode >> stream xÚmαJÄ@ÆñoÙ"0M^ป'p÷WóSZYˆ ¨¥ ¢`eòh>JáÊ+ŽŒóé5‚E~°;ÿY²¬šc­té_^iÓèC-/’³Ÿ+9¸’u'éZs–tî·’º }{}”´¾<ÕZÒFoj­n¥Û(Ê-€~‚Ù€8¶#J^ÎQì0CÜc…0áùîÈDÌ_úŸžÓÁïø:ßsöNüaçü™r$_΂[-> ³À,°ˆ, %‡s„'äƒlÏ"³ÈÌñ¥™aAZÒ›M°¿ÈY'Wò TŸc| endstream endobj 325 0 obj << /Length 235 /Filter /FlateDecode >> stream xÚuÐ1NÄ0ЉRXšß`3', ZiY$R AE¨€ ´ØGóQr„”[¬0¼„‰"OÊŒóÇ“ãîÈ/¥•^—ÒŸ‰÷òØñ+÷ÅVüɾóðÌëÝ­ôžÝ%Êì†+yûxb·¾>—ŽÝFî:iïyØ™-­2È9QµµÕ EëPõE6‚f¤LÍôV»&‘ÆàðÌÔb&e6‚€§Ñf“õÕŽó‘òY (yâ/ifU ý°Å_ cBüÔ¨M>Õ‹ý‚¸Ÿ™°y¥ÿ€‚޵¸2_ |ÃßÇ›jh endstream endobj 326 0 obj << /Length 188 /Filter /FlateDecode >> stream xڕν Â@ ð+ At-(˜'ð®¶µkotr¡P?ÁQðÅ_ÄÇè èý‹­³ù‘äIàõÃ+FŠÃ!¯=Ú“™º,ñ‘o)Ñ$ìG$'¦KROùt8oH&³{$S^z¬V¤SBĢ⊠ØÀ©iƒèA«äf°1ë€h‚.p;»Áö`¯Z  \2ðoóŠß›ÿÂy™³54Ö4§òý`ö endstream endobj 327 0 obj << /Length 226 /Filter /FlateDecode >> stream xÚ•Ï¿jAðïnaÜ ˆÎ ˜½s=b!j W¦J!‚`R ìnÍG¹G°´8ÜÌœEH:›_1;ödÏyŸSp¯ÏnÈyΟíÉ9)¦œ¿Ü_6[šd?Ø9²oR&[Ìùð}ü";YL9#;ãeÆéŠŠÇÀŒÇæÒºÂ„ÐpQ*Å+j .+xsº7á”xÄ•‘Íç–Üð‘\ƒ }µrÓþ† ”¿ø´•R þ/:tK­¬uéîNTc¨'Û¼‰Ä'ò¡jìiT”2ƒ®D¥×‚Þé+XÑ endstream endobj 328 0 obj << /Length 197 /Filter /FlateDecode >> stream xڕα Â@ àHÁB}Ѽ€Þ]õ¤“…ª`A'uª(¸ÙGóQî|ƒšTZèàà‘û†?$w#3°i²ÔhdÈŽéhð‚CË!Çá·s8cœ ÚÐТZpŒ*YÒíz?¡ŠWS2¨f´5¤w˜ÌHŸP˜Qžç®ÎëY’ 4aÐ:B@à ¸Ç8 ‚—1¾ìn -¡SQ¼üRá-8­ð d“_Ñ®Ó+ÈJ¢_<ÿ!’¯tùâ<Á5~lúQ- endstream endobj 329 0 obj << /Length 265 /Filter /FlateDecode >> stream xÚMÁJÃ@Eo˜ÅÀ[8мÐ$A„ÒB­`B]¹WêÒ…¢ÐEÁù´ù” ;#Ç›*ÖÍyóî{wæÎquÔLµÔZ§ZŸjÓè}%OR7KmN~&w²l¥¸Öº‘₲í¥¾<¿>H±\Ÿi%ÅJo*-o¥])L OÄ[ À`;d1ëa¶°3X`LpÀM6{ä{xÖSÏœ˜°Hpžî|tO¥0£1l¹6Ì ùi4ÈþÓ,ìÀe3zŸÓáw™gRÒô¦SÅß@v伕+ùÿcå endstream endobj 41 0 obj << /Type /Font /Subtype /Type3 /Name /F15 /FontMatrix [0.01204 0 0 0.01204 0 0] /FontBBox [ -4 -21 83 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 28 /LastChar 125 /Widths 330 0 R /Encoding 331 0 R /CharProcs 332 0 R >> endobj 330 0 obj [46.13 46.13 0 0 0 0 41.52 0 41.52 0 0 23.07 32.29 32.29 0 64.58 23.07 27.68 23.07 41.52 41.52 41.52 41.52 41.52 41.52 41.52 0 41.52 41.52 0 23.07 23.07 0 0 0 0 64.58 62.28 58.82 59.97 63.43 56.51 54.2 65.16 62.28 29.99 0 0 51.9 76.12 62.28 64.58 56.51 0 61.12 46.13 59.97 62.28 62.28 85.34 62.28 62.28 0 0 0 0 0 64.58 0 41.52 46.13 36.91 46.13 36.91 25.37 41.52 46.13 23.07 25.37 43.82 23.07 69.2 46.13 41.52 46.13 43.82 32.52 32.75 32.29 46.13 43.82 59.97 43.82 43.82 36.91 41.52 0 41.52 ] endobj 331 0 obj << /Type /Encoding /Differences [28/a28/a29 30/.notdef 34/a34 35/.notdef 36/a36 37/.notdef 39/a39/a40/a41 42/.notdef 43/a43/a44/a45/a46/a47/a48/a49/a50/a51/a52/a53 54/.notdef 55/a55/a56 57/.notdef 58/a58/a59 60/.notdef 64/a64/a65/a66/a67/a68/a69/a70/a71/a72/a73 74/.notdef 76/a76/a77/a78/a79/a80 81/.notdef 82/a82/a83/a84/a85/a86/a87/a88/a89 90/.notdef 95/a95 96/.notdef 97/a97/a98/a99/a100/a101/a102/a103/a104/a105/a106/a107/a108/a109/a110/a111/a112/a113/a114/a115/a116/a117/a118/a119/a120/a121/a122/a123 124/.notdef 125/a125] >> endobj 332 0 obj << /a28 272 0 R /a29 273 0 R /a34 269 0 R /a36 270 0 R /a39 261 0 R /a40 256 0 R /a41 257 0 R /a43 262 0 R /a44 263 0 R /a45 268 0 R /a46 264 0 R /a47 265 0 R /a48 322 0 R /a49 323 0 R /a50 324 0 R /a51 325 0 R /a52 326 0 R /a53 327 0 R /a55 328 0 R /a56 329 0 R /a58 266 0 R /a59 267 0 R /a64 271 0 R /a65 274 0 R /a66 275 0 R /a67 276 0 R /a68 277 0 R /a69 278 0 R /a70 279 0 R /a71 280 0 R /a72 281 0 R /a73 282 0 R /a76 283 0 R /a77 284 0 R /a78 285 0 R /a79 286 0 R /a80 287 0 R /a82 288 0 R /a83 289 0 R /a84 290 0 R /a85 291 0 R /a86 292 0 R /a87 293 0 R /a88 294 0 R /a89 295 0 R /a95 260 0 R /a97 296 0 R /a98 297 0 R /a99 298 0 R /a100 299 0 R /a101 300 0 R /a102 301 0 R /a103 302 0 R /a104 303 0 R /a105 304 0 R /a106 305 0 R /a107 306 0 R /a108 307 0 R /a109 308 0 R /a110 309 0 R /a111 310 0 R /a112 311 0 R /a113 312 0 R /a114 313 0 R /a115 314 0 R /a116 315 0 R /a117 316 0 R /a118 317 0 R /a119 318 0 R /a120 319 0 R /a121 320 0 R /a122 321 0 R /a123 258 0 R /a125 259 0 R >> endobj 333 0 obj << /Length 95 /Filter /FlateDecode >> stream xÚ32×3°P0PaCKC…C®B. ‚†‰ä\.'O.ýp ŸKßLzú*”•¦ré;8+ré»(D*Äryº(È1Ô7Ô7ü? ¶—«'W Ë endstream endobj 334 0 obj << /Length 166 /Filter /FlateDecode >> stream xÚ3±Ð37U0P0UÐ52U01QòR ¹ ¹Œ-€¢ †0¹ä\.'O.ýpc .}—¾§¯BIQi*—¾S€³‚!—¾‹B´¡‚A,—§‹ðÀ !',@„ˆ( pâˆ8#ÁD` 0‚D°Á >\–!ì¡…e8=…×2„=ø-ã#2Ñ,Ãå)êX†7¸\=¹¹(o0› endstream endobj 335 0 obj << /Length 105 /Filter /FlateDecode >> stream xÚ32×3°P0PaCKc…C®B.CrAɹ\Nž\úá †\ú@Q.}O_…’¢ÒT.}§gC.}…hCƒX.O9†ú†ú†ÿ Ä–c `3ËÕ“+ ö…( endstream endobj 336 0 obj << /Length 94 /Filter /FlateDecode >> stream xÚ36Ò3U0P0T0´P0"…C®B.#3  ‚D"9—ËÉ“K?\ÁÈŒKßCHxú*”•¦ré;8+ré»(D*Äryº(üÿÿÿ6ÌåêÉÈ#ˆ'ï endstream endobj 337 0 obj << /Length 210 /Filter /FlateDecode >> stream xÚuÏ1jÃ0àg<þÅ7ˆÿ 4²‘ã1'…z(¤S‡$ MH×XGÓQ|„ŒJÝW\(TˆôúŸ 7uN3uúk‘i1Ó}.Gq%CËáf÷&u#öU])ö‰±ØæYϧƒØzµÐ\ìR×¹fi–Šè €éÆWà‚Op_ÝPIÓ!õ I@Ò*¤#f %×#ý¸~á,üK{ÇT#ç¼³¶,„ΰq`É(°nìYÜsLøâ¾Þ–ÇF^䃷V2 endstream endobj 338 0 obj << /Length 275 /Filter /FlateDecode >> stream xÚ¿NÃ0Æ?+C$/~„Ü @pK§V*E"L02€`«÷ÉÈ£Dâ`ž”7Ѭ$7ëãî¨d¸¬*¦ ¯:}§¿$ X endstream endobj 339 0 obj << /Length 167 /Filter /FlateDecode >> stream xÚÍα Â@ à;:ò’'ðzxµ: µ‚7:9ˆ“: *:{ÖGñ;œs]úÈù“!¹éë3pç‡cÜk8ƒ‰YǸØ¡´ Öh PsNAÙ^/·¨r9E ªÂÆl ¶BéuL[“Vùeˆ¦T³½ôÉŽdÞø@ú‡`_µ¬‹’wV| ýÿšð‡äˆš …oafaosKƒ endstream endobj 340 0 obj << /Length 125 /Filter /FlateDecode >> stream xÚ32×3°P0P0b#S3s…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒØ€ÿ‚ˆ¥ˆŒþÃûæ? : æ ÿÿÿ€ .WO®@.»P endstream endobj 341 0 obj << /Length 110 /Filter /FlateDecode >> stream xÚ32×3°P0P0b#S3K…C®B.#C ßÄI$çr9yré‡+ré{E¹ô=}JŠJS¹ôœ€¢. Ñ@-±\ž. ŒþÃûæ? ŒC 1ÿcøÿÿq¹zrrp^Ú endstream endobj 342 0 obj << /Length 209 /Filter /FlateDecode >> stream xÚ= Â@…GR¦É2ÐMtý©bSZYˆ•ZZ(Ú‰ÉÑr2EH|›((vÂðí̛ݷ«Ga_<éIÛ=Ý—½Ï'Ö]ˆžQêÎîÈAÄj-ºËj™U´Ëùz`,§â³ eã‹·å(¢8!"«Ê@'-À1¹à4r²Sjed=L A Ñ‹]l»ÓŒßÄñ V0ùee˜þǯÛ̬äsnãÄ…«òíž ²Áœ¬Ì”/óÍKÝ´í*ëßàYÄ+~PûZ> endstream endobj 343 0 obj << /Length 218 /Filter /FlateDecode >> stream xڭнŽÂ0 p[*yé#à€4"€øè€t7Ýpº ‘Á }4¥Ð±CHpH'n¼[~ƒ­8{`zzÄ9÷¹«Ç<Ðl o5É„jÎÃ~ÛÚìiVúb3"µ’:©bÍçÓeGjö1gMjÁßšó*Œ6±Þf¾'i%°ôQ|”p”Þ´Dй£+”7Y´¦Ñ&˜Dí»èþêï™ñÇÖºÍã^ÙÜ+­džF˰ÅU6ºƒ´uÒˆ“¬;Ò‰wþÛĽoÞ¤eAŸô$”Šš endstream endobj 344 0 obj << /Length 144 /Filter /FlateDecode >> stream xÚ36׳4R0P0a3…C®B.c˜ˆ ’HÎåròäÒW06âÒ÷Šré{ú*”•¦ré;8+ré»(D*Äryº(0ÿ`þðÿ‡üŸÿ?lìþÿ(¨gÿñà?óÏÿ6ügü  u@lÃøŸñþC{Ì ´÷ÿÿpÌåêÉÈÈöPê endstream endobj 345 0 obj << /Length 160 /Filter /FlateDecode >> stream xÚ36׳4R0P0RÐ5T06V03TH1ä*ä26PA3#ˆLr.—“'—~¸‚±—¾P˜KßÓW¡¤¨4•Kß)ÀYÁKßE!ÚPÁ –ËÓEó¡a9$lÄuPüˆÙXþÿÿÿ¡$N#ÌC®ca¨gc{ ùù ì00þ?À”àrõä äùJm endstream endobj 346 0 obj << /Length 202 /Filter /FlateDecode >> stream xÚ]Í= Â@àYÑ6sݬ®+Á0… •…‚Z *Z»G²´ÌQr„”!ënÄ5Ø|Å›7¼¾èȈBêR[ìÑ^àË0$)?—ÝG1òÉùÌÄÈã9]/·òÑbLù„Ö‚Â ÆÒ:c:¯êk€{ê-Ŭ`m8ë¦8•u¨ t&p2 l©µ™Bâ̘ÑϘúê½> stream xÚeɱJÄ@…á; $p ¤M!æ¾€ÎdÍF 1°®` A+ ÔÒBÑv362°eЏãì]X'ñqι>­g¤iF'5TŸÑk…ØÌè©®÷ÏË;.:TÔÌQ݆UwG_Ÿßo¨÷×T¡ZÒSEú»%yïB­7ÿ‘zÈ· CÇD`AlÙ`Áï^Ѓ\ƒ„Fö´&i!‰QÚ¤5#+§È]VÚ‚QäS¤›"wš¡Ó)ä ÓÍŠ±’SˆÑÉÁ2¬8`ܼ?†aàÏè€ÁÅhÖŒ+.Æ1À%ãˆûÞtø€¿ƒ}z= endstream endobj 348 0 obj << /Length 207 /Filter /FlateDecode >> stream xÚ½½ ÂP F¿Ò¡¥Ð¼€ÞVn«“‚?`A'qRGE7Áúf}”>BÇÅšÞ‚Šè*3$|9º×î†ì³æV‡uÈQÄÛ€¤}®+ê5“Íž†1©%kŸÔTڤ⟎ç©á|Ä©1¯öר8Ux·èã”À*à%V7±38©“ÂÎ \Aî&°rOP ådeyÜ¿¡>Xý ?c\%éý#øë£æË'q¶(I£©fÔ‰µNšÄ´ ƒ…) endstream endobj 349 0 obj << /Length 131 /Filter /FlateDecode >> stream xÚ3±Ð37U0P°bC33…C®B.c# ßÄI$çr9yré‡+qé{E¹ô=}JŠJS¹ôœ ¹ô]¢  b¹<] >00013Ëñÿ ÿAø9³ùà óÿúóCýÿÿÿa˜ËÕ“+ Ìt^@ endstream endobj 350 0 obj << /Length 259 /Filter /FlateDecode >> stream xÚ]ÐÁJ…@ÆñOf!"·."ç åÚÍE0p»A.‚Zµˆ ¨vµ ôÑ|Á¥‹ËÎgH0?˜ñ?p´¬NÎNmn¹ÊÒ®×ö¹wYUºÏ¹å‹§7ÙÔâîìªw¥§âêkûùñõ"nssa q[{_ØüAê­…ÙÈB´aD4%;˜>Ú#îp¨§Ýà{%*eÌdl”鈧W”]èHÿ‹ùOË·ž¦…dfä 3Âױt¢KÒ‡óF¼oæû¼³MØfl=³oÂ,"†EÌ"pLΉ~WІh–Fš¥F³*Ö4×€& !Œ3ž´DWþËZnåÎvj endstream endobj 351 0 obj << /Length 238 /Filter /FlateDecode >> stream xڭбJÄ@à?ìÂ4y1󺉗‹[8O0… •…‚Z *Úš<Ú>Ê=BÊKÖD¸Òæ+f™™¶ö‡Ç+.yÅG\×Ü4üPÑ -½Knü÷Ëý­;r×¼ôäÎ¥L®»à·×÷GrëËS®Èmø¦âò–º ÁØ`#úÁ¦” ÌJT&e« 0m´ã?H‚M¦ÈF3âC‚ …P J°@¤#ßJ“ÿ2 ‹_â.N”^‘v2%5+w:ù‹gY9–º×Cbì)û@;ä@¯ùf,B‘M¥—B‘~2ÑYGWô îøeß endstream endobj 352 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚuпJÄ@ðoÙ"0…y!óšDr1•óSZ)ˆ ¨¥ ¢­É£åQò[¦X2ÎæN¼²ð[˜ý÷ÍÕñéŠ3.øè„‹—%?çôNEÆa”Õvåé•Ö ¥·\d”^j™ÒæŠ??¾^(]_ŸsNé†ïsΨÙ0yµ("=¬·¢I 5p‡oI—àu·ë~ѽvŒ§ œÚ§î´„©5âÐF‡à rˆ¤“ q/ošAz½ ¹FÅÌxé¶`Úcο¤ý=!õ‚)Ùa¦$¼ï°ãÜ ¹Ðï íkÙkRý—:ô5±Œ€•ðš†.º¡Ö̈% endstream endobj 40 0 obj << /Type /Font /Subtype /Type3 /Name /F17 /FontMatrix [0.01004 0 0 0.01004 0 0] /FontBBox [ 1 -25 68 75 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 45 /LastChar 119 /Widths 353 0 R /Encoding 354 0 R /CharProcs 355 0 R >> endobj 353 0 obj [32.5 27.08 48.75 48.75 48.75 48.75 0 0 48.75 48.75 0 0 0 27.08 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 43.33 0 48.75 54.17 27.08 0 0 27.08 0 0 48.75 54.17 0 37.92 0 37.92 0 51.46 70.42 ] endobj 354 0 obj << /Type /Encoding /Differences [45/a45/a46/a47/a48/a49/a50 51/.notdef 53/a53/a54 55/.notdef 58/a58 59/.notdef 101/a101 102/.notdef 103/a103/a104/a105 106/.notdef 108/a108 109/.notdef 111/a111/a112 113/.notdef 114/a114 115/.notdef 116/a116 117/.notdef 118/a118/a119] >> endobj 355 0 obj << /a45 336 0 R /a46 333 0 R /a47 334 0 R /a48 348 0 R /a49 349 0 R /a50 350 0 R /a53 351 0 R /a54 352 0 R /a58 335 0 R /a101 337 0 R /a103 338 0 R /a104 339 0 R /a105 340 0 R /a108 341 0 R /a111 342 0 R /a112 343 0 R /a114 344 0 R /a116 345 0 R /a118 346 0 R /a119 347 0 R >> endobj 356 0 obj << /Length 96 /Filter /FlateDecode >> stream xÚ36×31R0P0F¦ :Å« Ì ƒYɹ\Nž\úá@—¾˜ôôU()*MåÒw pV0äÒwQˆ6T0ˆåòtQàg°?Pÿàÿ¬`€ŸËÕ“+ è±"g endstream endobj 357 0 obj << /Length 368 /Filter /FlateDecode >> stream xÚÔMJÄ0à„,YL/0ØœÀ¶ƒè ÆìBЕ q¥.…Qܵ7ð^¥7±G˜å,¤1_R¦ŸŒ¡-ORZxßþyqœŸÊ\žè}q&‹¼…x‹™^ÈíÜœzx«Jd·r1Ù¥YYu%ß^ߟD¶º>—z¾–w…ÌïEµ–ÄŒ„Äñ—ÓwÙvݶÚ4U»èoÜìë'ú7Oúhp> stream xÚÕÔ±nƒ0`"¤[xî jÈÐ )M¥2Tj§ U¦´c‡FéLGá,\Û´ç“rJÒn±„õÙHðý.òùÍòs,íe±,ñµ€(vœ»¡»±{‡U jƒåÔƒU?âaÿùjõt‡¨5¾˜o¡^£ñ­l›h»ÀÁOkÛ5£cå&RóeûÌqfÚ_FMOôýÄTã‘83ÄÈ=í‡MK¬:bÖSƘhbÌ8ÝrÇt+ ´/!±#V2{‰ãpŽZbúŽ×Àÿ}ÿ;Ãå”·EÞB¶ÇlçM{º`äâbÕÇÊ“‘Õ/+pVö, ¦ Á¡´Ä!C‰–¢9ÅÔ‡7ñá ‘fA?Ž8üQ÷5<Ã7ã  endstream endobj 359 0 obj << /Length 243 /Filter /FlateDecode >> stream xÚ¥Ó½jÃ0ð 7Ä/Pð=Aew± …@šB<š)CÈÔv,¤¥…nî£åQô;T+&ÿPŽB‚ßIè®.®ËÉ¥ò½’º’§‚_¹¬û8÷¡Ÿx|áYÃf-eÍfѲi–òþöñÌföp'›¹l É·ÜÌÅÛ׸Èý‘òš~÷¢Ìí);HCtR M¡ J¡$ ’=JEŠþ£Ý ]¼(F]œ¤¡J¡vOPŒN+þì’NSÝ¥w>ÿ“H]! —ëªFõ©nL* %¥øaÔB΢¢,ªÌ•§³¨Æý¸ø¾áÿÃ# endstream endobj 360 0 obj << /Length 202 /Filter /FlateDecode >> stream xÚÝѽ Â0à“ …[úöžÀ´vh],Ô vtr'utPtÕ>ªáP¬MmO„¨õg2pỄäÎ÷ZŸl*¢M¹®ÑsóÜV©º˜¯0ŒQNÈsQòS”ñ¶›Ýe8ꑃ2¢©Cö ㈲r¥ð\ Lµ§\p8X…,–Á,ÐiÏêjÔÔÈb™5e|!‘<ÖQ+€Õ¨)Á2X&ËbeW©©ÕÑíÅÝ/¦¦šx»gøµàï•V XY–T(§öBØqŒ˜Wê‡ endstream endobj 361 0 obj << /Length 316 /Filter /FlateDecode >> stream xÚÔ±JÄ0Àñ„ ½¨4O`µÐ[,œ'ØAð&qRG¡ŠâØn¾V|‚ƒëmÞp\üò¥Šp9óÚä—–JôÁá~q¤r5…KëBMKu«åƒÔy;¹µ}ts/gµÌ.ìËì ¶eVŸ«§Çç;™Í.N”–Ù\]i•_Ëz®ŒY37RcºÿµUØupû•]ì™Q/ë-%öu;>ƒj{ªPÑkPé%„G“*K¸0IX‘ S†Å]¦Æ'æÂ aÞ„a¢Ž Ì$˜W&¦ˆ>a˜’"ÌÔø…a’ ïI‚0QGdl‡ LLÌ M¦¤ 254A¦a§Ú·ž¨ê£#*ýbDM6~ÿ,> stream xÚÅÔ±NÃ0Ы×ÎÒ×@êÊÁ0·Ì=ÌãS,,D¿ uÇê‡Í+u|mÇêŠï‹ÛOö³ëîDîOæE;Y—ðЊÙDê3i S%wÎû3cH˜€ ;›<$érò”¯Ùét ?F7êðºÂ{ü‡ñ,\ endstream endobj 363 0 obj << /Length 374 /Filter /FlateDecode >> stream xÚÓ1KÃ@Àñ 7´_ Øûš¤CI P¨Ì èÔAœÔQ¨¢s#~±lý·¹IÆ !ÏÜ»{w5‰Ö Ç—„ð?.qŸEs‰™8‰4i"bþÌS5ŒD™[÷O|•ñp#Ò9/Õœ‡Ù•x}y{äáêú\Ä<\‹ÛXDw<[ ¨™ºvÿ1ÈÑc(Ù²A2¿-õ#ÌkgSrí̪öC›wYÉX@–­ÁÙ7öŠ®skÏØÏ».БÕÒy§=ê¹DŸ¨e©=AW=/Ô2ÕNе³ ÞöÜPºÇ¯›ø{Ro0åR¼¶öó¾ J7ñÞ=Œ7ÆàÑ€KgŒŸW/´1>1®1x;à†ÒM¼4†Ÿö$.ÊÕñd¬s».(ãM.Æ[·Á£A—ÎmüdÐ¥c|b];·ÁÛA7”ŽñÒíYû@¹ÊïÖ|äÃÞ[3Ø3çOçÝ×/nœéþËæØ÷<.;Çí=ó‹ŒßðoZÎ) endstream endobj 364 0 obj << /Length 287 /Filter /FlateDecode >> stream xڕѽNÃ0à‹> stream xÚ‘±J1†'lq0…ûÞ¼€f̰pžà‚Vb¥–Š‚]òhy”}„-¯86ÎL¢œ‡• Ù/Ìü;“üq«Ó5äè¤%×QwFO-¾¢kHfçræñ×Ú;r Ú+£®éýíãíúæ‚Z´ºo©yÀaCÕ 2–i¤´å¯™5º˜À€z„>‚¬%k<&rš¥,«¶`vŒìd+q3Ëß’1«^+ü ô\úoxE<@ØG*Ðqˆ ÷ù/|AüýoŒÙ¸=˜¨×,¨¢8U(`‡Ø´ fA-©‘pœûžçÚŸ¹Ú¤Pjí"ê{mœ¤ÔIš€‘ƒã倷øYRŽ endstream endobj 366 0 obj << /Length 142 /Filter /FlateDecode >> stream xÚ36×31R0P0bcCKS…C®B.#ßÄ1’s¹œ<¹ôÃŒL¹ô=€¢\úž¾ %E¥©\úNÎ †\ú. ц ±\ž.  Œÿ˜ÿ30°ÿoÀŠAr 5 µTì ü@;þ£af f€áú!Žÿ``üÿè¯ÿ ȘËÕ“+ > stream xÚ36×31R0P0bc#C…C®B.#3 €˜’JÎåròäÒW02ãÒ÷ sé{ú*”•¦ré;8+ré»(D*Äryº(0°70ðÿo`ø†™˜†ëG1Õñÿ ŒÿÃúÿdÌåêÉȸ§‰ô endstream endobj 368 0 obj << /Length 249 /Filter /FlateDecode >> stream xÚ­‘±NÃ@ †}êÉK!~¸5Ç©©*ÁÔ1#æÜ£õQú3T9l× êÈÝIßɾü±‡Ûë5•TÓUEá†Âš^+üÀ:p°¤PŸ3/ï¸éÐï©è·Fßíèëóû ýæáŽ*ô-=UT>c×€Kxåiôi$Þ«Š@v”#W@Áø!ç'=rå4à8 E\)™æGCÎ †B1Š:‹6ŠÓ½bê¥:wZ¹KÿŠ??²"XÖi=Ì1w«½fùbpêYœ4?Í]óšeä[›ƒã©ÄßÙÄt~xßá#þ°´”ð endstream endobj 369 0 obj << /Length 185 /Filter /FlateDecode >> stream xÚÝÏ? ÂP ð¯,d°«ƒÐœÀ×ÚVt*øì èä ‚ Ž‚ŠÎ¯GëQzÇNÆ÷:ˆƒx‡üÈ—@ i¿—Drj*ñ æCDJb“Cíb¢qNjÍILjn¦¤òß®÷#©ñr©)oÌ™-åS†¯†/ž–ÂX¥ˆSeF·Ô•+^¡+ˆkÛª»d%ôA¢è3ðv×X}Xþ´øÅ~äÈö"õ7i–ÓŠ^¤Ds. endstream endobj 370 0 obj << /Length 191 /Filter /FlateDecode >> stream xÚ35Ò31T0P0RÐ5T01U°°PH1ä*ä21 (XXBd’s¹œ<¹ôÃLŒ¸ô=€Â\úž¾ %E¥©\úNÎ †\ú. Ñ@ƒb¹<] @€ò>’ƒdF"Ù‘H~$RLÚƒÉz0ùD2ƒIþÿ@ÀðƒD1aˆ’Œ¨L²ÿ``n@'Ù˜ÿ0°3€H~`¼ücà1ƒ(¸l@Aÿà(ÀáÍþÿ8¸\=¹¹~@‡Ø endstream endobj 371 0 obj << /Length 328 /Filter /FlateDecode >> stream xÚ’±JÄ@†'¤XØ&oàÎ h.r98œ'˜BÐÊB¬ÔÒBQ°2y´{”<•[„Œ»ó¯ÁÂòÁÌÎÏ?›¿>;Yò‚k>>åºâõ’+ûbW±¸àuÎóݶ¶¼åÕÒ–—¡lËöŠß^ߟl¹½>çÊ–;¾«xqoÛ¡ø4rßLd¢X鉜ÏdZ=5¡ù Dá-FÊBÁL”‡v.dú8šÐQOöÅx…ºÁMÿEãÙ  Hÿ…žÔÍOs˜Q¡¶ åZDæç3½è „EÊ!Iàösiãçg’‰ä,¹þÞ¡K€™óÍoø9\˜`5àFøøÿ¡ñºUÀ PSÍá–6ð¹ù#Àá) ˆF>hP2Ć&˜7·t>«Ç¸!|ºH‡kÕ`Ú‹ÖÞØ/U=Å¡ endstream endobj 372 0 obj << /Length 246 /Filter /FlateDecode >> stream xÚÍÒÁJÄ0€á† sè¾@©yÓ¢]+ÖìAГÙÓêQ¨¢°7û&¾JßÄ>Bž\ó´¸wÂÇ$2™ŸëLÛ5?Ò§…¾ËåQŠrÌ3›ÚƒÍƒ,k17º(Å\Œ»bêKýüôr/fyu¦s1+}›ël-õJ6† ø©Âpb„³‰ø:q÷[õî ½oÎÈË}1¦˜`…[lpÀÞ©0ì°uF^úŽ1Å+ÜbƒöN…a‡­3òò>1¦˜`…%68`ïT8–q¶ÎÈËf˜b‚–Øà€;Ý>ÿš÷qñÁÿúüž³í·Ý§œ×r-_³c·Å endstream endobj 373 0 obj << /Length 257 /Filter /FlateDecode >> stream xÚ½ÑÁJÃ@à-9æ`^ ˜yÝDL×@h ­`‚ž<ˆ'õXh‹…œj-²c¥uÍþ-f¡<8—f–º¼æˆ_\ñ áTñ[LsJ”IFœ¦¶ò:¥QAò‰EòΤI÷ü±X¾“=Œ9&9á瘣*&|&lœÃpo×p×FuÌÜ*ºnáæà°½­YëLÜ´6&c¢§am*&<èWPXh­¿íà –p†aKOÃÚêA³ú88Ò‡,q½ÐÝ6žvÚ8íÇÐYA‡Ž+Ç-Ü ý½½ë®þ ƒ†ÍïæôóŸÌ±¦°þ¹º-葾YïšÓ endstream endobj 374 0 obj << /Length 380 /Filter /FlateDecode >> stream xÚ’¿NÃ0ÆÏò`ÉK!~HƒÚ N‘J‘È€bF¬M-’GðèÁÄÜw.*$D駞Ͼᄏæôxé®qG'®©ÝzéjûlW.ܺÉ'÷OvÓÙêÆ­–¶ºà°­ºK÷úòöh«ÍÕ™«mµu·µ[ÜÙnëˆt"üÊä”"!–5Q¥‘&|ÔdÑŽ9‡?5“â1p·'ÍYœf€r0#0@ñ…˜JÀüñS¾'KŸ ß(‡b΀ò–L ɤ ’5º‹¤¸;–¬ÒLÚ£Y‚Ö>‰º6MÜ"v(™Þ÷Nì}N~˜U¤ÿÍù •UTã[¤²Tä°ðµåçfñ‹SUÄ•AT §H#ä°dÈQ)÷ž¼Ò{ˆ£6´R2ô"@¤òX:î!rTŒ¿Aÿ\§ü¦ú„ÔS^ªë¬EŽj,òp ŸÇdØïŠtÌS‘Ž'BZIÌÊë¦òò±â®,¦=ïìµýÖYÙá endstream endobj 39 0 obj << /Type /Font /Subtype /Type3 /Name /F16 /FontMatrix [0.00697 0 0 0.00697 0 0] /FontBBox [ 2 -2 115 101 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 46 /LastChar 116 /Widths 375 0 R /Encoding 376 0 R /CharProcs 377 0 R >> endobj 375 0 obj [37.42 0 0 0 0 67.4 67.4 0 0 67.4 67.4 0 0 0 0 0 0 0 0 101.06 0 0 102.96 91.72 87.98 0 0 0 0 0 0 123.54 0 0 0 0 99.22 0 0 0 101.06 0 0 0 0 0 0 0 0 0 0 67.4 0 0 0 59.9 0 0 0 37.42 0 0 37.42 0 0 67.4 0 0 52.41 0 52.41 ] endobj 376 0 obj << /Type /Encoding /Differences [46/a46 47/.notdef 51/a51/a52 53/.notdef 55/a55/a56 57/.notdef 65/a65 66/.notdef 68/a68/a69/a70 71/.notdef 77/a77 78/.notdef 82/a82 83/.notdef 86/a86 87/.notdef 97/a97 98/.notdef 101/a101 102/.notdef 105/a105 106/.notdef 108/a108 109/.notdef 111/a111 112/.notdef 114/a114 115/.notdef 116/a116] >> endobj 377 0 obj << /a46 356 0 R /a51 371 0 R /a52 372 0 R /a55 373 0 R /a56 374 0 R /a65 357 0 R /a68 358 0 R /a69 359 0 R /a70 360 0 R /a77 361 0 R /a82 362 0 R /a86 363 0 R /a97 364 0 R /a101 365 0 R /a105 366 0 R /a108 367 0 R /a111 368 0 R /a114 369 0 R /a116 370 0 R >> endobj 42 0 obj << /Type /Pages /Count 6 /Kids [34 0 R 52 0 R 60 0 R 65 0 R 72 0 R 78 0 R] >> endobj 378 0 obj << /Type /Outlines /First 3 0 R /Last 31 0 R /Count 8 >> endobj 31 0 obj << /Title 32 0 R /A 29 0 R /Parent 378 0 R /Prev 27 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 378 0 R /Prev 23 0 R /Next 31 0 R >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 378 0 R /Prev 19 0 R /Next 27 0 R >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 378 0 R /Prev 15 0 R /Next 23 0 R >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 378 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 378 0 R /Prev 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 378 0 R /Prev 3 0 R /Next 11 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R /Parent 378 0 R /Next 7 0 R >> endobj 379 0 obj << /Names [(Doc-Start) 38 0 R (Item.10) 76 0 R (Item.7) 69 0 R (Item.8) 70 0 R (Item.9) 75 0 R (page.1) 37 0 R] /Limits [(Doc-Start) (page.1)] >> endobj 380 0 obj << /Names [(page.2) 54 0 R (page.3) 62 0 R (page.4) 67 0 R (page.5) 74 0 R (page.6) 80 0 R (section*.1) 57 0 R] /Limits [(page.2) (section*.1)] >> endobj 381 0 obj << /Names [(section.11) 22 0 R (section.12) 26 0 R (section.13) 30 0 R (section.2) 2 0 R (section.3) 6 0 R (section.4) 10 0 R] /Limits [(section.11) (section.4)] >> endobj 382 0 obj << /Names [(section.5) 14 0 R (section.6) 18 0 R] /Limits [(section.5) (section.6)] >> endobj 383 0 obj << /Kids [379 0 R 380 0 R 381 0 R 382 0 R] /Limits [(Doc-Start) (section.6)] >> endobj 384 0 obj << /Dests 383 0 R >> endobj 385 0 obj << /Type /Catalog /Pages 42 0 R /Outlines 378 0 R /Names 384 0 R /PageMode/UseOutlines/PageLabels<>1<>]>> /OpenAction 33 0 R >> endobj 386 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.10)/Keywords() /CreationDate (D:20150606134849-04'00') /ModDate (D:20150606134849-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-1.40.10-2.2 (TeX Live 2009/Debian) kpathsea version 5.0.0) >> endobj xref 0 387 0000000000 65535 f 0000000015 00000 n 0000005440 00000 n 0000099597 00000 n 0000000060 00000 n 0000000084 00000 n 0000005495 00000 n 0000099513 00000 n 0000000129 00000 n 0000000161 00000 n 0000005552 00000 n 0000099427 00000 n 0000000206 00000 n 0000000238 00000 n 0000005610 00000 n 0000099339 00000 n 0000000284 00000 n 0000000322 00000 n 0000007970 00000 n 0000099251 00000 n 0000000368 00000 n 0000000401 00000 n 0000010343 00000 n 0000099163 00000 n 0000000448 00000 n 0000000488 00000 n 0000011568 00000 n 0000099075 00000 n 0000000535 00000 n 0000000575 00000 n 0000011624 00000 n 0000099000 00000 n 0000000622 00000 n 0000000654 00000 n 0000000971 00000 n 0000001193 00000 n 0000000704 00000 n 0000001079 00000 n 0000001137 00000 n 0000097725 00000 n 0000090255 00000 n 0000082700 00000 n 0000098832 00000 n 0000001935 00000 n 0000002085 00000 n 0000002234 00000 n 0000002385 00000 n 0000002536 00000 n 0000002687 00000 n 0000002839 00000 n 0000002991 00000 n 0000003259 00000 n 0000001759 00000 n 0000001287 00000 n 0000003143 00000 n 0000062025 00000 n 0000054327 00000 n 0000003201 00000 n 0000043092 00000 n 0000005668 00000 n 0000005274 00000 n 0000003365 00000 n 0000005382 00000 n 0000034623 00000 n 0000008142 00000 n 0000007804 00000 n 0000005774 00000 n 0000007912 00000 n 0000027058 00000 n 0000008026 00000 n 0000008084 00000 n 0000010401 00000 n 0000010062 00000 n 0000008260 00000 n 0000010170 00000 n 0000010228 00000 n 0000010286 00000 n 0000011682 00000 n 0000011402 00000 n 0000010507 00000 n 0000011510 00000 n 0000011788 00000 n 0000011964 00000 n 0000012206 00000 n 0000012461 00000 n 0000012712 00000 n 0000012896 00000 n 0000013124 00000 n 0000013375 00000 n 0000013571 00000 n 0000013787 00000 n 0000013966 00000 n 0000014203 00000 n 0000014390 00000 n 0000014580 00000 n 0000014805 00000 n 0000014988 00000 n 0000015171 00000 n 0000015368 00000 n 0000015616 00000 n 0000015947 00000 n 0000016212 00000 n 0000016511 00000 n 0000016775 00000 n 0000017003 00000 n 0000017229 00000 n 0000017537 00000 n 0000017738 00000 n 0000017927 00000 n 0000018226 00000 n 0000018430 00000 n 0000018688 00000 n 0000018963 00000 n 0000019214 00000 n 0000019469 00000 n 0000019747 00000 n 0000020064 00000 n 0000020269 00000 n 0000020539 00000 n 0000020817 00000 n 0000021089 00000 n 0000021357 00000 n 0000021620 00000 n 0000021894 00000 n 0000022176 00000 n 0000022411 00000 n 0000022745 00000 n 0000022987 00000 n 0000023200 00000 n 0000023479 00000 n 0000023675 00000 n 0000023927 00000 n 0000024163 00000 n 0000024427 00000 n 0000024708 00000 n 0000024947 00000 n 0000025213 00000 n 0000025449 00000 n 0000025678 00000 n 0000025945 00000 n 0000026200 00000 n 0000026483 00000 n 0000026801 00000 n 0000027308 00000 n 0000027786 00000 n 0000028301 00000 n 0000029135 00000 n 0000029301 00000 n 0000029530 00000 n 0000029704 00000 n 0000029873 00000 n 0000030137 00000 n 0000030397 00000 n 0000030671 00000 n 0000030986 00000 n 0000031208 00000 n 0000031384 00000 n 0000031593 00000 n 0000031870 00000 n 0000032040 00000 n 0000032286 00000 n 0000032504 00000 n 0000032775 00000 n 0000033045 00000 n 0000033259 00000 n 0000033528 00000 n 0000033742 00000 n 0000034005 00000 n 0000034322 00000 n 0000034873 00000 n 0000035132 00000 n 0000035434 00000 n 0000035773 00000 n 0000036110 00000 n 0000036399 00000 n 0000036743 00000 n 0000037020 00000 n 0000037285 00000 n 0000037628 00000 n 0000037810 00000 n 0000038029 00000 n 0000038363 00000 n 0000038705 00000 n 0000039035 00000 n 0000039281 00000 n 0000039595 00000 n 0000039939 00000 n 0000040172 00000 n 0000040449 00000 n 0000040750 00000 n 0000040953 00000 n 0000041265 00000 n 0000041583 00000 n 0000041852 00000 n 0000042162 00000 n 0000042478 00000 n 0000042759 00000 n 0000043339 00000 n 0000043539 00000 n 0000043780 00000 n 0000044128 00000 n 0000044536 00000 n 0000044884 00000 n 0000045303 00000 n 0000045642 00000 n 0000045951 00000 n 0000046381 00000 n 0000046567 00000 n 0000046805 00000 n 0000047197 00000 n 0000047594 00000 n 0000048000 00000 n 0000048290 00000 n 0000048661 00000 n 0000049088 00000 n 0000049345 00000 n 0000049659 00000 n 0000050025 00000 n 0000050350 00000 n 0000050615 00000 n 0000050927 00000 n 0000051267 00000 n 0000051534 00000 n 0000051752 00000 n 0000052134 00000 n 0000052520 00000 n 0000052826 00000 n 0000053192 00000 n 0000053587 00000 n 0000053907 00000 n 0000054576 00000 n 0000054856 00000 n 0000055169 00000 n 0000055587 00000 n 0000055901 00000 n 0000056248 00000 n 0000056570 00000 n 0000056881 00000 n 0000057232 00000 n 0000057474 00000 n 0000057751 00000 n 0000058137 00000 n 0000058503 00000 n 0000058846 00000 n 0000059134 00000 n 0000059464 00000 n 0000059811 00000 n 0000060090 00000 n 0000060411 00000 n 0000060734 00000 n 0000061029 00000 n 0000061352 00000 n 0000061684 00000 n 0000062272 00000 n 0000062447 00000 n 0000062696 00000 n 0000062979 00000 n 0000063249 00000 n 0000063518 00000 n 0000063776 00000 n 0000064031 00000 n 0000064215 00000 n 0000064426 00000 n 0000064612 00000 n 0000064824 00000 n 0000064999 00000 n 0000065233 00000 n 0000065415 00000 n 0000065636 00000 n 0000065811 00000 n 0000066014 00000 n 0000066358 00000 n 0000066734 00000 n 0000066987 00000 n 0000067221 00000 n 0000067537 00000 n 0000067827 00000 n 0000068168 00000 n 0000068443 00000 n 0000068705 00000 n 0000068952 00000 n 0000069287 00000 n 0000069493 00000 n 0000069680 00000 n 0000069901 00000 n 0000070226 00000 n 0000070550 00000 n 0000070870 00000 n 0000071118 00000 n 0000071420 00000 n 0000071757 00000 n 0000071988 00000 n 0000072260 00000 n 0000072581 00000 n 0000072969 00000 n 0000073329 00000 n 0000073641 00000 n 0000073926 00000 n 0000074205 00000 n 0000074468 00000 n 0000074747 00000 n 0000075017 00000 n 0000075239 00000 n 0000075557 00000 n 0000075793 00000 n 0000075996 00000 n 0000076227 00000 n 0000076504 00000 n 0000076693 00000 n 0000076951 00000 n 0000077179 00000 n 0000077448 00000 n 0000077725 00000 n 0000078008 00000 n 0000078229 00000 n 0000078505 00000 n 0000078737 00000 n 0000078971 00000 n 0000079235 00000 n 0000079549 00000 n 0000079840 00000 n 0000080140 00000 n 0000080404 00000 n 0000080673 00000 n 0000080875 00000 n 0000081184 00000 n 0000081500 00000 n 0000081769 00000 n 0000082076 00000 n 0000082354 00000 n 0000082950 00000 n 0000083459 00000 n 0000084007 00000 n 0000085017 00000 n 0000085193 00000 n 0000085440 00000 n 0000085626 00000 n 0000085801 00000 n 0000086092 00000 n 0000086448 00000 n 0000086696 00000 n 0000086902 00000 n 0000087093 00000 n 0000087383 00000 n 0000087682 00000 n 0000087907 00000 n 0000088148 00000 n 0000088431 00000 n 0000088758 00000 n 0000089046 00000 n 0000089258 00000 n 0000089598 00000 n 0000089917 00000 n 0000090504 00000 n 0000090753 00000 n 0000091040 00000 n 0000091334 00000 n 0000091511 00000 n 0000091960 00000 n 0000092326 00000 n 0000092650 00000 n 0000092933 00000 n 0000093330 00000 n 0000093724 00000 n 0000094179 00000 n 0000094547 00000 n 0000094895 00000 n 0000095118 00000 n 0000095322 00000 n 0000095652 00000 n 0000095918 00000 n 0000096190 00000 n 0000096599 00000 n 0000096926 00000 n 0000097264 00000 n 0000097975 00000 n 0000098210 00000 n 0000098556 00000 n 0000098926 00000 n 0000099668 00000 n 0000099831 00000 n 0000099995 00000 n 0000100177 00000 n 0000100281 00000 n 0000100378 00000 n 0000100416 00000 n 0000100582 00000 n trailer << /Size 387 /Root 385 0 R /Info 386 0 R /ID [<87AF42789729012CBFF38265229601EB> <87AF42789729012CBFF38265229601EB>] >> startxref 100908 %%EOF verilator-3.874/configure.ac0000664000177100017500000001407212534631136016021 0ustar wsnyderwsnyder# DESCRIPTION: Process this file with autoconf to produce a configure script. # # Copyright 2003-2015 by Wilson Snyder. Verilator 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. #AC_INIT([Verilator],[#.### YYYY-MM-DD]) #AC_INIT([Verilator],[#.### devel]) AC_INIT([Verilator],[3.874 2015-06-06]) AC_CONFIG_HEADER(src/config_build.h) AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc) AC_MSG_RESULT([configuring for $PACKAGE_STRING]) # Special Substitutions - CFG_WITH_DEFENV AC_MSG_CHECKING(whether to disable hardcoded paths) AC_ARG_ENABLE([defenv], [AS_HELP_STRING([--disable-defenv], [disable using some hardcoded data paths extracted from some default environment variables (the default is to use hardcoded paths)])], [case "${enableval}" in yes) CFG_WITH_DEFENV=yes ;; no) CFG_WITH_DEFENV=no ;; *) AC_MSG_ERROR([bad value ${enableval} for --disable-defenv]) ;; esac], CFG_WITH_DEFENV=yes) AC_SUBST(CFG_WITH_DEFENV) AC_MSG_RESULT($CFG_WITH_DEFENV) # Special Substitutions - CFG_WITH_CCWARN AC_MSG_CHECKING(whether to show and stop on compilation warnings) AC_ARG_ENABLE([ccwarn], [AS_HELP_STRING([--enable-ccwarn], [enable showing and stopping on compilation warnings])], [case "${enableval}" in yes) CFG_WITH_CCWARN=yes ;; no) CFG_WITH_CCWARN=no ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-ccwarn]) ;; esac], [case "x${VERILATOR_AUTHOR_SITE}" in x) CFG_WITH_CCWARN=no ;; *) CFG_WITH_CCWARN=yes ;; esac] ) AC_SUBST(CFG_WITH_CCWARN) AC_MSG_RESULT($CFG_WITH_CCWARN) # Special Substitutions - CFG_WITH_LONGTESTS AC_MSG_CHECKING(whether to run long tests) AC_ARG_ENABLE([longtests], [AS_HELP_STRING([--enable-longtests], [enable running long developer tests])], [case "${enableval}" in yes) CFG_WITH_LONGTESTS=yes ;; no) CFG_WITH_LONGTESTS=no ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-longtests]) ;; esac], [case "x${VERILATOR_AUTHOR_SITE}" in x) CFG_WITH_LONGTESTS=no ;; *) CFG_WITH_LONGTESTS=yes ;; esac] ) AC_SUBST(CFG_WITH_LONGTESTS) AC_MSG_RESULT($CFG_WITH_LONGTESTS) # Compiler flags CFLAGS=-I${includedir} CPPFLAGS=-I${includedir} CXXFLAGS=-I${includedir} LDFLAGS=-L${libdir} # Checks for programs. AC_PROG_CC AC_PROG_CXX AC_PROG_INSTALL AC_LANG_PUSH(C++) AC_MSG_CHECKING([that C++ compiler can compile simple program]) AC_RUN_IFELSE( [AC_LANG_SOURCE([int main() { return 0; }])], AC_MSG_RESULT(yes), AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]), AC_MSG_RESULT(yes)) AC_PATH_PROG(PERL,perl) if test "x$PERL" = "x" ; then AC_MSG_ERROR([Cannot find "perl" in your PATH, please install it]) fi AC_PATH_PROG(LEX,flex) if test "x$LEX" = "x" ; then AC_MSG_ERROR([Cannot find "flex" in your PATH, please install it]) fi AC_PATH_PROG(YACC,bison) if test "x$YACC" = "x" ; then AC_MSG_ERROR([Cannot find "bison" in your PATH, please install it]) fi # Checks for libraries. # Checks for typedefs, structures AC_CHECK_TYPE(size_t,unsigned int) AC_TYPE_SIZE_T # Checks for compiler characteristics. AC_C_INLINE AC_DEFUN([_MY_CXX_CHECK_OPT], [# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS $2 -Werror" AC_MSG_CHECKING([whether $CXX accepts $2]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([],[])], [_my_result=yes if test -s conftest.err; then if grep -e "$2" conftest.err >/dev/null; then _my_result=no fi fi], [_my_result=no]) AC_MSG_RESULT($_my_result) if test "$_my_result" = "yes" ; then $1="$$1 $2" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" ])# _MY_CXX_CHECK_OPT # Flags for compiling Verilator internals including parser _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-char-subscripts) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments) AC_SUBST(CFG_CXXFLAGS_SRC) # Flags for compiling Verilator parser _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-null-conversion) AC_SUBST(CFG_CXXFLAGS_PARSER) # Flags for Verilated makefile # For example, -Wno-div-by-zero isn't in 4.1.2 _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-char-subscripts) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality) # Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn # without this flag, even though there's a conditional to prevent the divide. # We still don't add no-div-by-zero as it throws message to stdout, though doesn't die. #_MY_CXX_CHECK_OPT(-Wno-div-by-zero) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096) _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments) AC_SUBST(CFG_CXXFLAGS_NO_UNUSED) # Checks for library functions. # Checks for system services # Other install directories pkgdatadir=${datadir}/verilator AC_SUBST(pkgdatadir) pkgconfigdir=${datadir}/pkgconfig AC_SUBST(pkgconfigdir) AC_OUTPUT AC_MSG_RESULT([]) AC_MSG_RESULT([Now type 'make' (or sometimes 'gmake') to build Verilator.]) AC_MSG_RESULT([]) verilator-3.874/test_v/0000775000177100017500000000000012534632371015035 5ustar wsnyderwsnyderverilator-3.874/test_v/t.v0000664000177100017500000000166612436231574015501 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. module t (/*AUTOARG*/ // Outputs passed, // Inputs clk, fastclk, reset_l ); input clk /*verilator sc_clock*/; input fastclk /*verilator sc_clock*/; input reset_l; output passed; reg [31:0] count_c; reg [31:0] count_f; always @ (posedge clk) begin if (!reset_l) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops count_c <= 32'h0; // End of automatics end else begin count_c <= count_c + 1; end end always @ (posedge fastclk) begin if (!reset_l) begin /*AUTORESET*/ // Beginning of autoreset for uninitialized flops count_f <= 32'h0; passed <= 1'h0; // End of automatics end else begin count_f <= count_f + 1; if (count_f == 5) passed <= 1'b1; end end endmodule verilator-3.874/test_v/input.vc0000664000177100017500000000011412111011552016501 0ustar wsnyderwsnyder +librescan +libext+.v -y ../test_v +incdir+../test_v +incdir+../include verilator-3.874/test_v/top.v0000664000177100017500000000166612436231574016040 0ustar wsnyderwsnyder// DESCRIPTION: Verilator: Verilog Test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2003 by Wilson Snyder. `timescale 1 ns/ 1ns module top (/*AUTOARG*/ // Outputs passed, out_small, out_quad, out_wide, // Inputs clk, fastclk, reset_l, in_small, in_quad, in_wide ); output passed; input clk; input fastclk; input reset_l; output [1:0] out_small; output [39:0] out_quad; output [69:0] out_wide; input [1:0] in_small; input [39:0] in_quad; input [69:0] in_wide; wire [1:0] out_small = in_small | {2{reset_l}}; wire [39:0] out_quad = in_quad | {40{reset_l}}; wire [69:0] out_wide = in_wide | {70{reset_l}}; initial begin $write("Hello World!\n"); end // Example sub module t t (/*AUTOINST*/ // Outputs .passed (passed), // Inputs .clk (clk), .fastclk (fastclk), .reset_l (reset_l)); endmodule verilator-3.874/mkinstalldirs0000664000177100017500000000123412111011551016312 0ustar wsnyderwsnyder#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here verilator-3.874/Artistic0000664000177100017500000002156112111011551015221 0ustar wsnyderwsnyderArtistic License 2.0 Copyright (c) 2000-2006, The Perl Foundation. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble ******** This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software. You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement. Definitions *********** "Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package. "Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures. "You" and "your" means any person who would like to copy, distribute, or modify the Package. "Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version. "Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization. "Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees. "Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder. "Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder. "Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future. "Source" form means the source code, documentation source, and configuration files for the Package. "Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form. Permission for Use and Modification Without Distribution ******************************************************** (1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version. Permissions for Redistribution of the Standard Version ****************************************************** (2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package. (3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License. Distribution of Modified Versions of the Package as Source ********************************************************** (4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following: (a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version. (b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version. (c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under (i) the Original License or (ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed. Distribution of Compiled Forms of the Standard Version or Modified ****************************************************************** Versions without the Source *************************** (5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license. (6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version. Aggregating or Linking the Package ********************************** (7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation. (8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package. Items That are Not Considered Part of a Modified Version ******************************************************** (9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license. General Provisions ****************** (10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. (11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. (12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. (13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. verilator-3.874/install-sh0000664000177100017500000001272012111011551015512 0ustar wsnyderwsnyder#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 verilator-3.874/verilator.html0000664000177100017500000053435112534631201016430 0ustar wsnyderwsnyder Verilator - Convert Verilog code to C++/SystemC



NAME

Verilator - Convert Verilog code to C++/SystemC


SYNOPSIS

    verilator --help
    verilator --version
    verilator --cc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so]
    verilator --sc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so]
    verilator --lint-only    [top_level.v]...


DESCRIPTION

Verilator converts synthesizable (not behavioral) Verilog code, plus some Synthesis, SystemVerilog and a small subset of Verilog AMS assertions, into C++ or SystemC code. It is not a complete simulator, but a compiler.

Verilator is invoked with parameters similar to GCC, Cadence Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog code, lints it, and optionally adds coverage and waveform tracing code. For C++ and SystemC formats, it outputs .cpp and .h files.

The files created by Verilator are then compiled with C++. The user writes a little C++ wrapper file, which instantiates the top level module, and passes this filename on the command line. These C files are compiled in C++, and linked with the Verilated files.

The resulting executable will perform the actual simulation.

To get started, jump down to "EXAMPLE C++ EXECUTION".


ARGUMENT SUMMARY

This is a short summary of the arguments to Verilator. See the detailed descriptions in the next sections for more information.

    {file.v}                    Verilog top level filenames
    {file.c/cc/cpp}             Optional C++ files to compile in
    {file.a/o/so}               Optional C++ files to link in
     +1364-1995ext+<ext>        Use Verilog 1995 with file extension <ext>
     +1364-2001ext+<ext>        Use Verilog 2001 with file extension <ext>
     +1364-2005ext+<ext>        Use Verilog 2005 with file extension <ext>
     +1800-2005ext+<ext>        Use SystemVerilog 2005 with file extension <ext>
     +1800-2009ext+<ext>        Use SystemVerilog 2009 with file extension <ext>
     +1800-2012ext+<ext>        Use SystemVerilog 2012 with file extension <ext>
    --assert                    Enable all assertions
    --autoflush                 Flush streams after all $displays
    --bbox-sys                  Blackbox unknown $system calls
    --bbox-unsup                Blackbox unsupported language features
    --bin <filename>            Override Verilator binary
     -CFLAGS <flags>            C++ Compiler flags for makefile
    --cc                        Create C++ output
    --cdc                       Clock domain crossing analysis
    --clk <signal-name>         Mark specified signal as clock
    --compiler <compiler-name>  Tune for specified C++ compiler
    --converge-limit <loops>    Tune convergence settle time
    --coverage                  Enable all coverage
    --coverage-line             Enable line coverage
    --coverage-toggle           Enable toggle coverage
    --coverage-user             Enable SVL user coverage
    --coverage-underscore       Enable coverage of _signals
     -D<var>[=<value>]          Set preprocessor define
    --debug                     Enable debugging
    --debug-check               Enable debugging assertions
    --debugi <level>            Enable debugging at a specified level
    --debugi-<srcfile> <level>  Enable debugging a source file at a level
    --default-language <lang>   Default language to parse
     +define+<var>=<value>      Set preprocessor define
    --dump-tree                 Enable dumping .tree files
    --dump-treei <level>        Enable dumping .tree files at a level
    --dump-treei-<srcfile> <level>  Enable dumping .tree file at a source file at a level
     -E                         Preprocess, but do not compile
    --error-limit <value>       Abort after this number of errors
    --exe                       Link to create executable
     -F <file>                  Parse options from a file, relatively
     -f <file>                  Parse options from a file
    --gdb                       Run Verilator under GDB interactively
    --gdbbt                     Run Verilator under GDB for backtrace
    --help                      Display this help
     -I<dir>                    Directory to search for includes
    --if-depth <value>          Tune IFDEPTH warning
     +incdir+<dir>              Directory to search for includes
    --inhibit-sim               Create function to turn off sim
    --inline-mult <value>       Tune module inlining
     -LDFLAGS <flags>           Linker pre-object flags for makefile
     -LDLIBS <flags>            Linker library flags for makefile
    --language <lang>           Default language standard to parse
     +libext+<ext>+[ext]...     Extensions for finding modules
    --lint-only                 Lint, but do not make output
    --MMD                       Create .d dependency files
    --MP                        Create phony dependency targets
    --Mdir <directory>          Name of output object directory
    --mod-prefix <topname>      Name to prepend to lower classes
    --no-clk <signal-name>      Prevent marking specified signal as clock
    --no-pins64                 Don't use vluint64_t's for 33-64 bit sigs
    --no-skip-identical         Disable skipping identical output
     +notimingchecks            Ignored
     -O0                        Disable optimizations
     -O3                        High performance optimizations
     -O<optimization-letter>    Selectable optimizations
     -o <executable>            Name of final executable
    --no-order-clock-delay      Disable ordering clock enable assignments
    --output-split <bytes>      Split .cpp files into pieces
    --output-split-cfuncs <statements>   Split .cpp functions
    --output-split-ctrace <statements>   Split tracing functions
     -P                         Disable line numbers and blanks with -E
    --pins-bv <bits>            Specify types for top level ports
    --pins-sc-uint              Specify types for top level ports
    --pins-sc-biguint           Specify types for top level ports
    --pins-uint8                Specify types for top level ports
    --pipe-filter <command>     Filter all input through a script
    --prefix <topname>          Name of top level class
    --profile-cfuncs            Name functions for profiling
    --private                   Debugging; see docs
    --public                    Debugging; see docs
    --report-unoptflat          Extra diagnostics for UNOPTFLAT
    --savable                   Enable model save-restore
    --sc                        Create SystemC output
    --stats                     Create statistics file
    --stats-vars                Provide statistics on variables
     -sv                        Enable SystemVerilog parsing
     +systemverilogext+<ext>    Synonym for +1800-2012ext+<ext>
    --top-module <topname>      Name of top level input module
    --trace                     Enable waveform creation
    --trace-depth <levels>      Depth of tracing
    --trace-max-array <depth>   Maximum bit width for tracing
    --trace-max-width <width>   Maximum array depth for tracing
    --trace-params              Enable tracing parameters
    --trace-structs             Enable tracing structure names
    --trace-underscore          Enable tracing of _signals
     -U<var>                    Undefine preprocessor define
    --unroll-count <loops>      Tune maximum loop iterations
    --unroll-stmts <stmts>      Tune maximum loop body size
    --unused-regexp <regexp>    Tune UNUSED lint signals
     -V                         Verbose version and config
     -v <filename>              Verilog library
     +verilog1995ext+<ext>      Synonym for +1364-1995ext+<ext>
     +verilog2001ext+<ext>      Synonym for +1364-2001ext+<ext>
     -Werror-<message>          Convert warning to error
     -Wfuture-<message>         Disable unknown message warnings
     -Wno-<message>             Disable warning
     -Wno-lint                  Disable all lint warnings
     -Wno-style                 Disable all style warnings
     -Wno-fatal                 Disable fatal exit on warnings
    --x-assign <mode>           Initially assign Xs to this value
    --x-initial-edge            Enable initial X->0 and X->1 edge triggers
     -y <dir>                   Directory to search for modules


ARGUMENTS

{file.v}

Specifies the Verilog file containing the top module to be Verilated.

{file.c/.cc/.cpp/.cxx}

Specifies optional C++ files to be linked in with the Verilog code. If any C++ files are specified in this way, Verilator will include a make rule that generates a module executable. Without any C++ files, Verilator will stop at the module__ALL.a library, and presume you'll continue linking with make rules you write yourself. See also the -CFLAGS option.

{file.a/.o/.so}

Specifies optional object or library files to be linked in with the Verilog code, as a shorthand for -LDFLAGS "<file>". If any files are specified in this way, Verilator will include a make rule that uses these files when linking the module executable. This generally is only useful when used with the --exe option.

+1364-1995ext+ext
+1364-2001ext+ext
+1364-2005ext+ext
+1800-2005ext+ext
+1800-2009ext+ext
+1800-2012ext+ext

Specifies the language standard to be used with a specific filename extension, ext.

For compatibility with other simulators, see also the synonyms +verilog1995ext+ext, +verilog2001ext+ext, and +systemverilogext+ext.

For any source file, the language specified by these options takes precedence over any language specified by the --default-language or --language options.

These options take effect in the order they are encountered. Thus the following would use Verilog 1995 for a.v and Verilog 2001 for b.v.

    verilator ... +1364-1995ext+v a.v +1364-2001ext+v b.v

These flags are only recommended for legacy mixed language designs, as the preferable option is to edit the code to repair new keywords, or add appropriate `begin_keywords.

Note `begin_keywords is a SystemVerilog construct, which specifies only which the set of keywords is to be recognized. Whatever set is chosen, the semantics will be those of SystemVerilog. By contrast +1364-1995ext+ etc. specify both the syntax and semantics to be used.

--assert

Enable all assertions.

See also --x-assign and --x-initial-edge; setting "--x-assign unique" and/or "--x-initial-edge" may be desirable.

--autoflush

After every $display or $fdisplay, flush the output stream. This insures that messages will appear immediately but may reduce performance; for best performance call "fflush(stdout)" occasionally in the main C loop. Defaults off, which will buffer output as provided by the normal C stdio calls.

--bbox-sys

Black box any unknown $system task or function calls. System tasks will be simply NOPed, and system functions will be replaced by unsized zero. Arguments to such functions will be parsed, but not otherwise checked. This prevents errors when linting in the presence of company specific PLI calls.

--bbox-unsup

Black box some unsupported language features, currently UDP tables and the cmos and tran gate primitives. This may enable linting the rest of the design even when unsupported constructs are present.

--bin filename

Rarely needed. Override the default filename for Verilator itself. When a dependency (.d) file is created, this filename will become a source dependency, such that a change in this binary will have make rebuild the output files.

-CFLAGS flags

Add specified C compiler flags to the generated makefiles. When make is run on the generated makefile these will be passed to the C++ compiler (gcc/g++/msvc++).

--cc

Specifies C++ without SystemC output mode; see also --sc.

--cdc

Experimental. Perform some clock domain crossing checks and issue related warnings (CDCRSTLOGIC) and then exit; if warnings other than CDC warnings are needed make a second run with --lint-only. Additional warning information is also written to the file {prefix}__cdc.txt.

Currently only checks some items that other CDC tools missed; if you have interest in adding more traditional CDC checks, please contact the authors.

--clk signal-name

Sometimes it is quite difficult for Verilator to distinguish clock signals from other data signals. Occasionally the clock signals can end up in the checking list of signals which determines if further evaluation is needed. This will heavily degrade the performance of verilated model.

With --clk <signal-name>, user can specified root clock into the model, then Verilator will mark the signal as clocker and propagate the clocker attribute automatically to other signals derived from that. In this way, Verilator will try to avoid taking the clocker signal into checking list.

Note signal-name is specified by the RTL hiearchy path. For example, v.foo.bar. If the signal is the input to top-module, the directly the signal name. If you find it difficult to find the exact name, try to use /*verilator clocker*/ in RTL file to mark the signal directly.

--compiler compiler-name

Enables tunings and work-arounds for the specified C++ compiler.

clang

Tune for clang. This may reduce execution speed as it enables several workarounds to avoid silly hardcoded limits in clang. This includes breaking deep structures as for msvc as described below.

gcc

Tune for Gnu C++, although generated code should work on almost any compliant C++ compiler. Currently the default.

msvc

Tune for Microsoft Visual C++. This may reduce execution speed as it enables several workarounds to avoid silly hardcoded limits in MSVC++. This includes breaking deeply nested parenthesized expressions into sub-expressions to avoid error C1009, and breaking deep blocks into functions to avoid error C1061.

--converge-limit <loops>

Rarely needed. Specifies the maximum number of runtime iterations before creating a model failed to converge error. Defaults to 100.

--coverage

Enables all forms of coverage, alias for "--coverage-line --coverage-toggle --coverage-user".

--coverage-line

Specifies basic block line coverage analysis code should be inserted.

Coverage analysis adds statements at each code flow change point, which are the branches of IF and CASE statements, a super-set of normal Verilog Line Coverage. At each such branch a unique counter is incremented. At the end of a test, the counters along with the filename and line number corresponding to each counter are written into logs/coverage.pl.

Verilator automatically disables coverage of branches that have a $stop in them, as it is assumed $stop branches contain an error check that should not occur. A /*verilator coverage_block_off*/ comment will perform a similar function on any code in that block or below, or /*verilator coverage_on/coverage_off*/ will disable coverage around lines of code.

Note Verilator may over-count combinatorial (non-clocked) blocks when those blocks receive signals which have had the UNOPTFLAT warning disabled; for most accurate results do not disable this warning when using coverage.

--coverage-toggle

Specifies signal toggle coverage analysis code should be inserted.

Every bit of every signal in a module has a counter inserted. The counter will increment on every edge change of the corresponding bit.

Signals that are part of tasks or begin/end blocks are considered local variables and are not covered. Signals that begin with underscores, are integers, or are very wide (>256 bits total storage across all dimensions) are also not covered.

Hierarchy is compressed, such that if a module is instantiated multiple times, coverage will be summed for that bit across ALL instantiations of that module with the same parameter set. A module instantiated with different parameter values is considered a different module, and will get counted separately.

Verilator makes a minimally-intelligent decision about what clock domain the signal goes to, and only looks for edges in that clock domain. This means that edges may be ignored if it is known that the edge could never be seen by the receiving logic. This algorithm may improve in the future. The net result is coverage may be lower than what would be seen by looking at traces, but the coverage is a more accurate representation of the quality of stimulus into the design.

There may be edges counted near time zero while the model stabilizes. It's a good practice to zero all coverage just before releasing reset to prevent counting such behavior.

A /*verilator coverage_off/on */ comment pair can be used around signals that do not need toggle analysis, such as RAMs and register files.

--coverage-underscore

Enable coverage of signals that start with an underscore. Normally, these signals are not covered. See also --trace-underscore.

--coverage-user

Enables user inserted functional coverage. Currently, all functional coverage points are specified using SVA which must be separately enabled with --assert.

For example, the following statement will add a coverage point, with the comment "DefaultClock":

   DefaultClock: cover property (@(posedge clk) cyc==3);
-Dvar=value

Defines the given preprocessor symbol, without allowing. Similar to +define; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility.

--debug

Select the debug built image of Verilator (if available), and enable more internal assertions (equivelent to --debug-check), debugging messages (equivelent to --debugi 4), and intermediate form dump files (equivilent to --dump-treei 3).

--debug-check

Rarely needed. Enable internal debugging assertion checks, without changing debug verbosity. Enabled automatically when --debug specified.

--debugi <level>
--debugi-<srcfile> <level>

Rarely needed - for developer use. Set internal debugging level globally to the specified debug level (1-10) or set the specified Verilator source file to the specified level (e.g. --debugi-V3Width 9). Higher levels produce more detailed messages.

--default-language value

Select the language to be used by default when first processing each Verilog file. The language value must be "1364-1995", "1364-2001", "1364-2005", "1800-2005", "1800-2009" or "1800-2012".

Any language associated with a particular file extension (see the various +langext+ options) will be used in preference to the language specified by --default-language.

The --default-language flag is only recommended for legacy code using the same language in all source files, as the preferable option is to edit the code to repair new keywords, or add appropriate `begin_keywords. For legacy mixed language designs, the various +langext+ options should be used.

If no language is specified, either by this flag or +langext+ options, then the latest SystemVerilog language (IEEE 1800-2012) is used.

+define+var=value
+define+var=value+var2=value2...

Defines the given preprocessor symbol, or multiple symbols if separated by plusses. Similar to -D; +define is fairly standard across Verilog tools while -D is an alias for GCC compatibility.

--dump-tree

Rarely needed. Enable writing .tree debug files with dumping level 3, which dumps the standard critical stages. For details on the format see the Verilator Internals manual. --dump-tree is enabled automatically with --debug, so "--debug --no-dump-tree" may be useful if the dump files are large and not desired.

--dump-treei <level>
--dump-treei-<srcfile> <level>

Rarely needed - for developer use. Set internal tree dumping level globally to a specific dumping level or set the specified Verilator source file to the specified tree dumping level (e.g. --dump-treei-V3Order 9). Level 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9 enables dumping of every stage.

-E

Preprocess the source code, but do not compile, as with 'gcc -E'. Output is written to standard out. Beware of enabling debugging messages, as they will also go to standard out.

--error-limit <value>

After this number of errors or warnings are encountered, exit. Defaults to 50.

--exe

Generate an executable. You will also need to pass additional .cpp files on the command line that implement the main loop for your simulation.

-F file

Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the directory containing the specified file. See also -f. Note -F is fairly standard across Verilog tools.

-f file

Read the specified file, and act as if all text inside it was specified as command line parameters. Any relative paths are relative to the current directory. See also -F. Note -f is fairly standard across Verilog tools.

The file may contain // comments which are ignored to the end of the line. Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment variable.

--gdb

Run Verilator underneath an interactive GDB (or VERILATOR_GDB environment variable value) session. See also --gdbbt.

--gdbbt

If --debug is specified, run Verilator underneath a GDB process and print a backtrace on exit, then exit GDB immediately. Without --debug or if GDB doesn't seem to work, this flag is ignored. Intended for easy creation of backtraces by users; otherwise see the --gdb flag.

--help

Displays this message and program version and exits.

-Idir

See -y.

--if-depth value

Rarely needed. Set the depth at which the IFDEPTH warning will fire, defaults to 0 which disables this warning.

+incdir+dir

See -y.

--inhibit-sim

Rarely needed. Create a "inhibitSim(bool)" function to enable and disable evaluation. This allows an upper level testbench to disable modules that are not important in a given simulation, without needing to recompile or change the SystemC modules instantiated.

--inline-mult value

Tune the inlining of modules. The default value of 2000 specifies that up to 2000 new operations may be added to the model by inlining, if more than this number of operations would result, the module is not inlined. Larger values, or a value <= 1 will inline everything, will lead to longer compile times, but potentially faster runtimes. This setting is ignored for very small modules; they will always be inlined, if allowed.

-LDFLAGS flags

Add specified C linker flags to the generated makefiles. When make is run on the generated makefile these will be passed to the C++ linker (ld) *after* the primary file being linked. This flag is called -LDFLAGS as that's the traditional name in simulators; it's would have been better called LDLIBS as that's the Makefile variable it controls. (In Make, LDFLAGS is before the first object, LDLIBS after. -L libraries need to be in the Make variable LDLIBS, not LDFLAGS.)

--language value

A synonym for --default-langauge, for compatibility with other tools and earlier versions of Verilator.

+libext+ext+ext...

Specify the extensions that should be used for finding modules. If for example module x is referenced, look in x.ext. Note +libext+ is fairly standard across Verilog tools. Defaults to .v and .sv.

--lint-only

Check the files for lint violations only, do not create any other output.

You may also want the -Wall option to enable messages that are considered stylistic and not enabled by default.

If the design is not to be completely Verilated see also the --bbox-sys and --bbox-unsup options.

--MMD

Enable creation of .d dependency files, used for make dependency detection, similar to gcc -MMD option. On by default, use --no-MMD to disable.

--MP

When creating .d dependency files with --MMD, make phony targets. Similar to gcc -MP option.

--Mdir directory

Specifies the name of the Make object directory. All generated files will be placed in this directory. If not specified, "obj_dir" is used. The directory is created if it does not exist and the parent directories exist; otherwise manually create the Mdir before calling Verilator.

--mod-prefix topname

Specifies the name to prepend to all lower level classes. Defaults to the same as --prefix.

--no-clk <signal-name>

Prevent the specified signal from being marked as clock. See --clk.

--no-pins64

Backward compatible alias for "--pins-bv 33".

--no-skip-identical

Rarely needed. Disables skipping execution of Verilator if all source files are identical, and all output files exist with newer dates.

+notimingchecks

Ignored for compatibility with other simulators.

-O0

Disables optimization of the model.

-O3

Enables slow optimizations for the code Verilator itself generates (as opposed to "-CFLAGS -O3" which effects the C compiler's optimization. -O3 may reduce simulation runtimes at the cost of compile time. This currently sets --inline-mult -1.

-Ooptimization-letter

Rarely needed. Enables or disables a specific optimizations, with the optimization selected based on the letter passed. A lowercase letter disables an optimization, an upper case letter enables it. This is intended for debugging use only; see the source code for version-dependent mappings of optimizations to -O letters.

-o <executable>

Specify the name for the final executable built if using --exe. Defaults to the --prefix if not specified.

--no-order-clock-delay

Rarely needed. Disables a bug fix for ordering of clock enables with delayed assignments. This flag should only be used when suggested by the developers.

--output-split bytes

Enables splitting the output .cpp/.sp files into multiple outputs. When a C++ file exceeds the specified number of operations, a new file will be created at the next function boundary. In addition, any slow routines will be placed into __Slow files. This accelerates compilation by as optimization can be disabled on the slow routines, and the remaining files can be compiled on parallel machines. Using --output-split should have only a trivial impact on performance. With GCC 3.3 on a 2GHz Opteron, --output-split 20000 will result in splitting into approximately one-minute-compile chunks.

--output-split-cfuncs statements

Enables splitting functions in the output .cpp/.sp files into multiple functions. When a generated function exceeds the specified number of operations, a new function will be created. With --output-split, this will enable GCC to compile faster, at a small loss in performance that gets worse with decreasing split values. Note that this option is stronger than --output-split in the sense that --output-split will not split inside a function.

--output-split-ctrace statements

Enables splitting trace functions in the output .cpp/.sp files into multiple functions. Defaults to same setting as --output-split-cfuncs.

-P

With -E, disable generation of `line markers and blank lines, similar to GCC -P flag.

--pins64

Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64.

--pins-bv width

Specifies SystemC inputs/outputs of greater than or equal to width bits wide should use sc_bv's instead of uint32/vluint64_t's. The default is "--pins-bv 65". Versions before Verilator 3.671 defaulted to "--pins-bv 33". The more sc_bv is used, the worse for performance. Use the "/*verilator sc_bv*/" attribute to select specific ports to be sc_bv.

--pins-sc-uint

Specifies SystemC inputs/outputs of greater than 2 bits wide should use sc_uint between 2 and 64. When combined with the "--pins-sc-biguint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512.

--pins-sc-biguint

Specifies SystemC inputs/outputs of greater than 65 bits wide should use sc_biguint between 65 and 512, and sc_bv from 513 upwards. When combined with the "--pins-sc-uint" combination, it results in sc_uint being used between 2 and 64 and sc_biguint being used between 65 and 512.

--pins-uint8

Specifies SystemC inputs/outputs that are smaller than the --pins-bv setting and 8 bits or less should use uint8_t instead of uint32_t. Likewise pins of width 9-16 will use uint16_t instead of uint32_t.

--pipe-filter command

Rarely needed and experimental. Verilator will spawn the specified command as a subprocess pipe, to allow the command to perform custom edits on the Verilog code before it reaches Verilator.

Before reading each Verilog file, Verilator will pass the file name to the subprocess' stdin with 'read_verilog "<filename>"'. The filter may then read the file and perform any filtering it desires, and feeds the new file contents back to Verilator on stdout with 'Content-Length'. Output to stderr from the filter feeds through to Verilator's stdout and if the filter exits with non-zero status Verilator terminates. See the t/t_pipe_filter test for an example.

To debug the output of the filter, try using the -E option to see preprocessed output.

--prefix topname

Specifies the name of the top level class and makefile. Defaults to V prepended to the name of the --top-module switch, or V prepended to the first Verilog filename passed on the command line.

--profile-cfuncs

Modify the created C++ functions to support profiling. The functions will be minimized to contain one "basic" statement, generally a single always block or wire statement. (Note this will slow down the executable by ~5%.) Furthermore, the function name will be suffixed with the basename of the Verilog module and line number the statement came from. This allows gprof or oprofile reports to be correlated with the original Verilog source statements.

--private

Opposite of --public. Is the default; this option exists for backwards compatibility.

--public

This is only for historical debug use. Using it may result in mis-simulation of generated clocks.

Declares all signals and modules public. This will turn off signal optimizations as if all signals had a /*verilator public*/ comments and inlining. This will also turn off inlining as if all modules had a /*verilator public_module*/, unless the module specifically enabled it with /*verilator inline_module*/.

--report-unoptflat

Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the 10 widest variables in the loop, and the 10 most fanned out variables in the loop. These are candidates for splitting into multiple variables to break the loop.

In addition produces a GraphViz DOT file of the entire strongly connected components within the source associated with each loop. This is produced irrespective of whether --dump-tree is set. Such graphs may help in analyzing the problem, but can be very large indeed.

Various commands exist for viewing and manipulating DOT files. For example the dot command can be used to convert a DOT file to a PDF for printing. For example:

    dot -Tpdf -O Vt_unoptflat_simple_2_35_unoptflat.dot

will generate a PDF Vt_unoptflat_simple_2_35_unoptflat.dot.pdf from the DOT file.

--savable

Enable including save and restore functions in the generated model.

The user code must create a VerilatedSerialize or VerilatedDeserialze object then calling the << or >> operators on the generated model and any other data the process needs saved/restored. For example:

    void save_model(const char* filenamep) {
        VerilatedSave os;
        os.open(filenamep);
        os << main_time;  // user code must save the timestamp, etc
        os << *topp;
    }
    void restore_model(const char* filenamep) {
        VerilatedRestore os;
        os.open(filenamep);
        os >> main_time;
        os >> *topp;
    }
--sc

Specifies SystemC output mode; see also --cc.

--stats

Creates a dump file with statistics on the design in {prefix}__stats.txt.

--stats-vars

Creates more detailed statistics including a list of all the variables by size (plain --stats just gives a count). See --stats, which is implied by this.

-sv

Specifies SystemVerilog language features should be enabled; equivalent to "--language 1800-2005". This option is selected by default, it exists for compatibility with other simulators.

+systemverilogext+ext

A synonym for +1800-2012ext+ext.

--top-module topname

When the input Verilog contains more than one top level module, specifies the name of the top level Verilog module to become the top, and sets the default for if --prefix is not used. This is not needed with standard designs with only one top.

--trace

Adds waveform tracing code to the model. Verilator will generate additional {prefix}__Trace*.cpp files that will need to be compiled. In addition verilated_vcd_sc.cpp (for SystemC traces) or verilated_vcd_c.cpp (for both) must be compiled and linked in. If using the Verilator generated Makefiles, these will be added as source targets for you. If you're not using the Verilator makefiles, you will need to add these to your Makefile manually.

Having tracing compiled in may result in some small performance losses, even when waveforms are not turned on during model execution.

--trace-depth levels

Specify the number of levels deep to enable tracing, for example --trace-level 1 to only see the top level's signals. Defaults to the entire model. Using a small number will decrease visibility, but greatly improve runtime and trace file size.

--trace-max-array depth

Rarely needed. Specify the maximum array depth of a signal that may be traced. Defaults to 32, as tracing large arrays may greatly slow traced simulations.

--trace-max-width width

Rarely needed. Specify the maximum bit width of a signal that may be traced. Defaults to 256, as tracing large vectors may greatly slow traced simulations.

--no-trace-params

Disable tracing of parameters.

--trace-structs

Enable tracing to show the name of packed structure, union, and packed array fields, rather than a simgle combined packed bus. Due to VCD file format constraints this may result in significantly slower trace times and larger trace files.

--trace-underscore

Enable tracing of signals that start with an underscore. Normally, these signals are not output during tracing. See also --coverage-underscore.

-Uvar

Undefines the given preprocessor symbol.

--unroll-count loops

Rarely needed. Specifies the maximum number of loop iterations that may be unrolled. See also BLKLOOPINIT warning.

--unroll-stmts statements

Rarely needed. Specifies the maximum number of statements in a loop for that loop to be unrolled. See also BLKLOOPINIT warning.

--unused-regexp regexp

Rarely needed. Specifies a simple regexp with * and ? that if a signal name matches will suppress the UNUSED warning. Defaults to "*unused*". Setting it to "" disables matching.

-V

Shows the verbose version, including configuration information compiled into Verilator. (Similar to perl -V.)

-v filename

Read the filename as a Verilog library. Any modules in the file may be used to resolve cell instantiations in the top level module, else ignored. Note -v is fairly standard across Verilog tools.

+verilog1995ext+ext
+verilog2001ext+ext

Synonyms for +1364-1995ext+ext and +1364-2001ext+ext respectively

-Wall

Enable all warnings, including code style warnings that are normally disabled by default.

-Werror-message

Convert the specified warning message into an error message. This is generally to discourage users from violating important site-wide rules, for example -Werror-NOUNOPTFLAT.

-Wfuture-message

Rarely needed. Suppress unknown Verilator comments or warning messages with the given message code. This is used to allow code written with pragmas for a later version of Verilator to run under a older version; add -Wfuture- arguments for each message code or comment that the new version supports which the older version does not support.

-Wno-message

Disable the specified warning message. This will override any lint_on directives in the source, i.e. the warning will still not be printed.

-Wno-lint

Disable all lint related warning messages, and all style warnings. This is equivalent to "-Wno-ALWCOMBORDER -Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEWITHX -Wno-CMPCONST -Wno-ENDLABEL -Wno-IMPLICIT -Wno-LITENDIAN -Wno-PINCONNECTEMPTY -Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED -Wno-WIDTH" plus the list shown for Wno-style.

It is strongly recommended you cleanup your code rather than using this option, it is only intended to be use when running test-cases of code received from third parties.

-Wno-style

Disable all code style related warning messages (note by default they are already disabled). This is equivalent to "-Wno-DECLFILENAME -Wno-DEFPARAM -Wno-INCABSPATH -Wno-PINCONNECTEMPTY -Wno-PINNOCONNECT -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNUSED -Wno-VARHIDDEN".

-Wno-fatal

When warnings are detected, print them, but do not exit the simulator.

Having warning messages in builds is sloppy. It is strongly recommended you cleanup your code, use inline lint_off, or use -Wno-... flags rather than using this option.

-Wwarn-message

Enables the specified warning message.

-Wwarn-lint

Enable all lint related warning messages (note by default they are already enabled), but do not affect style messages. This is equivalent to "-Wwarn-ALWCOMBORDER -Wwarn-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX -Wwarn-CMPCONST -Wwarn-ENDLABEL -Wwarn-IMPLICIT -Wwarn-LITENDIAN -Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED -Wwarn-WIDTH".

-Wwarn-style

Enable all code style related warning messages. This is equivalent to "-Wwarn ASSIGNDLY -Wwarn-DECLFILENAME -Wwarn-DEFPARAM -Wwarn-INCABSPATH -Wwarn-PINNOCONNECT -Wwarn-SYNCASYNCNET -Wwarn-UNDRIVEN -Wwarn-UNUSED -Wwarn-VARHIDDEN".

--x-assign 0
--x-assign 1
--x-assign fast (default)
--x-assign unique

Controls the two-state value that is replaced when an assignment to X is encountered. --x-assign=fast, the default, converts all Xs to whatever is best for performance. --x-assign=0 converts all Xs to 0s, and is also fast. --x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more likely to find reset bugs as active high logic will fire. --x-assign=unique will call a function to determine the value, this allows randomization of all Xs to find reset bugs and is the slowest, but safest for finding reset bugs in code.

If using --x-assign unique, you may want to seed your random number generator such that each regression run gets a different randomization sequence. Use the system's srand48() or for Windows srand() function to do this. You'll probably also want to print any seeds selected, and code to enable rerunning with that same seed so you can reproduce bugs.

Note. This option applies only to variables which are explicitly assigned to X in the Verilog source code. Initial values of clocks are set to 0 unless --x-initial-edge is specified. Initial values of all other state holding variables are set as though --x-assign unique had been specified.

--x-initial-edge

Enables emulation of event driven simulators which generally trigger an edge on a transition from X to 1 (posedge) or X to 0 (negedge). Thus the following code, where rst_n is uninitialized would set res_n to 1'b1 when rst_n is first set to zero:

    reg  res_n = 1'b0;
    always @(negedge rst_n) begin
       if (rst_n == 1'b0) begin
          res_n <= 1'b1;
       end
    end

In Verilator, by default, uninitialized clocks are given a value of zero, so the above always block would not trigger.

While it is not good practice, there are some designs that rely on X → 0 triggering a negedge, particularly in reset sequences. Using --x-initial-edge with Verilator will replicate this behavior. It will also ensure that X → 1 triggers a posedge.

Note. Some users have reported that using this option can affect convergence, and that it may be necessary to use --converge-limit to increase the number of convergence iterations. This may be another indication of problems with the modelled design that should be addressed.

-y dir

Add the directory to the list of directories that should be searched for include files or libraries. The three flags -y, +incdir and -I have similar effect; +incdir and +y are fairly standard across Verilog tools while -I is an alias for GCC compatibility.

Verilator defaults to the current directory ("-y .") and any specified --Mdir, though these default paths are used after any user specified directories. This allows '-y "$(pwd)"' to be used if absolute filenames are desired for error messages instead of relative filenames.


EXAMPLE C++ EXECUTION

We'll compile this example into C++.

    mkdir test_our
    cd test_our
    cat <<EOF >our.v
      module our;
         initial begin $display("Hello World"); $finish; end
      endmodule
    EOF
    cat <<EOF >sim_main.cpp
      #include "Vour.h"
      #include "verilated.h"
      int main(int argc, char **argv, char **env) {
          Verilated::commandArgs(argc, argv);
          Vour* top = new Vour;
          while (!Verilated::gotFinish()) { top->eval(); }
          delete top;
          exit(0);
      }
    EOF

If you installed Verilator from sources, or a tarball, but not as part of your operating system (as an RPM), first you need to point to the kit:

    export VERILATOR_ROOT=/path/to/where/verilator/was/installed
    export PATH=$VERILATOR_ROOT/bin:$PATH

Now we run Verilator on our little example.

    verilator -Wall --cc our.v --exe sim_main.cpp

We can see the source code under the "obj_dir" directory. See the FILES section below for descriptions of some of the files that were created.

    ls -l obj_dir

We then can compile it

    cd obj_dir
    make -j -f Vour.mk Vour

(Verilator included a default compile rule and link rule, since we used --exe and passed a .cpp file on the Verilator command line. You can also write your own compile rules, as we'll show in the SYSTEMC section.)

And now we run it

    cd ..
    obj_dir/Vour

And we get as output

    Hello World
    - our.v:2: Verilog $finish

Really, you're better off writing a Makefile to do all this for you. Then, when your source changes it will automatically run all of these steps. See the test_c directory in the distribution for an example.


EXAMPLE SYSTEMC EXECUTION

This is an example similar to the above, but using SystemC.

    mkdir test_our_sc
    cd test_our_sc
    cat <<EOF >our.v
      module our (clk);
         input clk;  // Clock is required to get initial activation
         always @ (posedge clk)
            begin $display("Hello World"); $finish; end
      endmodule
    EOF
    cat <<EOF >sc_main.cpp
      #include "Vour.h"
      int sc_main(int argc, char **argv) {
          Verilated::commandArgs(argc, argv);
          sc_clock clk ("clk",10, 0.5, 3, true);
          Vour* top;
          top = new Vour("top");   // SP_CELL (top, Vour);
          top->clk(clk);           // SP_PIN  (top, clk, clk);
          while (!Verilated::gotFinish()) { sc_start(1, SC_NS); }
          delete top; 
          exit(0);
      }
    EOF

If you installed Verilator from sources, or a tarball, but not as part of your operating system (as an RPM), first you need to point to the kit:

    export VERILATOR_ROOT=/path/to/where/verilator/was/installed
    export PATH=$VERILATOR_ROOT/bin:$PATH

Now we run Verilator on our little example.

    verilator -Wall --sc our.v

We then can compile it

    make -j -f Vour.mk Vour__ALL.a
    make -j -f Vour.mk ../sc_main.o verilated.o

And link with SystemC. Note your path to the libraries may vary, depending on the operating system.

    export SYSTEMC_LIBDIR=/path/to/where/libsystemc.a/exists
    export LD_LIBRARY_PATH=$SYSTEMC_LIBDIR:$LD_LIBRARY_PATH
    # Might be needed if SystemC 2.3.0
    export SYSTEMC_CXX_FLAGS=-pthread
    g++ -L$SYSTEMC_LIBDIR ../sc_main.o Vour__ALL*.o verilated.o \
              -o Vour -lsystemc

And now we run it

    cd ..
    obj_dir/Vour

And we get the same output as the C++ example:

    Hello World
    - our.v:2: Verilog $finish

Really, you're better off using a Makefile to do all this for you. Then, when your source changes it will automatically run all of these steps. See the test_sc directory in the distribution for an example.


BENCHMARKING & OPTIMIZATION

For best performance, run Verilator with the "-O3 --x-assign=fast --noassert" flags. The -O3 flag will require longer compile times, and --x-assign=fast may increase the risk of reset bugs in trade for performance; see the above documentation for these flags.

Minor Verilog code changes can also give big wins. You should not have any UNOPTFLAT warnings from Verilator. Fixing these warnings can result in huge improvements; one user fixed their one UNOPTFLAT warning by making a simple change to a clock latch used to gate clocks and gained a 60% performance improvement.

Beyond that, the performance of a Verilated model depends mostly on your C++ compiler and size of your CPU's caches.

By default, the lib/verilated.mk file has optimization turned off. This is for the benefit of new users, as it improves compile times at the cost of runtimes. To add optimization as the default, set one of three variables, OPT, OPT_FAST, or OPT_SLOW lib/verilated.mk. Or, use the -CFLAGS and/or -LDFLAGS option on the verilator command line to pass the flags directly to the compiler or linker. Or, just for one run, pass them on the command line to make:

    make OPT_FAST="-O2" -f Vour.mk Vour__ALL.a

OPT_FAST specifies optimizations for those programs that are part of the fast path, mostly code that is executed every cycle. OPT_SLOW specifies optimizations for slow-path files (plus tracing), which execute only rarely, yet take a long time to compile with optimization on. OPT specifies overall optimization and affects all compiles, including those OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2", and link with "-static". Nearly the same results can be had with much better compile times with OPT_FAST="-O1 -fstrict-aliasing". Higher optimization such as "-O3" may help, but gcc compile times may be excessive under O3 on even medium sized designs. Alternatively, some larger designs report better performance using "-Os".

Unfortunately, using the optimizer with SystemC files can result in compiles taking several minutes. (The SystemC libraries have many little inlined functions that drive the compiler nuts.)

For best results, use GCC 3.3 or newer. GCC 3.2 and earlier have optimization bugs around pointer aliasing detection, which can result in 2x performance losses.

If you will be running many simulations on a single compile, investigate feedback driven compilation. With GCC, using -fprofile-arcs, then -fbranch-probabilities will yield another 15% or so.

Modern compilers also support link-time optimization (LTO), which can help especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in both compilation and link. Note LTO may cause excessive compile times on large designs.

If you are using your own makefiles, you may want to compile the Verilated code with -DVL_INLINE_OPT=inline. This will inline functions, however this requires that all cpp files be compiled in a single compiler run.

You may uncover further tuning possibilities by profiling the Verilog code. Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run either oprofile or gprof to see where in the C++ code the time is spent. Run the gprof output through verilator_profcfunc and it will tell you what Verilog line numbers on which most of the time is being spent.

When done, please let the author know the results. I like to keep tabs on how Verilator compares, and may be able to suggest additional improvements.


FILES

All output files are placed in the output directory name specified with the -Mdir option, or "obj_dir" if not specified.

Verilator creates the following files in the output directory:

    {prefix}.mk                         // Make include file for compiling
    {prefix}_classes.mk                 // Make include file with class names

For -cc and -sc mode, it also creates:

    {prefix}.cpp                        // Top level C++ file
    {prefix}.h                          // Top level header
    {prefix}{each_verilog_module}.cpp   // Lower level internal C++ files
    {prefix}{each_verilog_module}.h     // Lower level internal header files

In certain optimization modes, it also creates:

    {prefix}__Dpi.h                     // DPI import and export declarations
    {prefix}__Inlines.h                 // Inline support functions
    {prefix}__Slow.cpp                  // Constructors and infrequent routines
    {prefix}__Syms.cpp                  // Global symbol table C++
    {prefix}__Syms.h                    // Global symbol table header
    {prefix}__Trace.cpp                 // Wave file generation code (--trace)
    {prefix}__cdc.txt                   // Clock Domain Crossing checks (--cdc)
    {prefix}__stats.txt                 // Statistics (--stats)

It also creates internal files that can be mostly ignored:

    {each_verilog_module}.vpp           // Post-processed verilog (--debug)
    {prefix}.flags_vbin                 // Verilator dependencies
    {prefix}.flags_vpp                  // Pre-processor dependencies
    {prefix}__verFiles.dat              // Timestamps for skip-identical
    {prefix}{misc}.d                    // Make dependencies (-MMD)
    {prefix}{misc}.dot                  // Debugging graph files (--debug)
    {prefix}{misc}.tree                 // Debugging files (--debug)

After running Make, the C++ compiler should produce the following:

    {prefix}                            // Final executable (w/--exe argument)
    {prefix}__ALL.a                     // Library of all Verilated objects
    {prefix}{misc}.o                    // Intermediate objects


ENVIRONMENT

LD_LIBRARY_PATH

A generic Linux/OS variable specifying what directories have shared object (.so) files. This path should include SystemC and any other shared objects needed at runtime.

OBJCACHE

Optionally specifies a caching or distribution program to place in front of all runs of the C++ Compiler. For example, "objcache --read --write", or "ccache". If using distcc, it would generally be run under either objcache or ccache; see the documentation for those programs.

SYSTEMC

Deprecated. Used only if SYSTEMC_INCLUDE or SYSTEMC_LIBDIR is not set. If set, specifies the directory containing the SystemC distribution. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled).

SYSTEMC_ARCH

Deprecated. Used only if SYSTEMC_LIBDIR is not set. Specifies the architecture name used by the SystemC kit. This is the part after the dash in the lib-{...} directory name created by a 'make' in the SystemC distribution. If not set, Verilator will try to intuit the proper setting, or use the default optionally specified at configure time (before Verilator was compiled).

SYSTEMC_CXX_FLAGS

Specifies additional flags that are required to be passed to GCC when building the SystemC model. System 2.3.0 may need this set to "-pthread".

SYSTEMC_INCLUDE

If set, specifies the directory containing the systemc.h header file. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/include.

SYSTEMC_LIBDIR

If set, specifies the directory containing the libsystemc.a library. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled), or computed from SYSTEMC/lib-SYSTEMC_ARCH.

VCS_HOME

If set, specifies the directory containing the Synopsys VCS distribution. When set, a 'make test' in the Verilator distribution will also run VCS baseline regression tests.

VERILATOR_BIN

If set, specifies an alternative name of the Verilator binary. May be used for debugging and selecting between multiple operating system builds.

VERILATOR_GDB

If set, the command to run when using the --gdb option, such as "ddd". If not specified, it will use "gdb".

VERILATOR_ROOT

Specifies the directory containing the distribution kit. This is used to find the executable, Perl library, and include files. If not specified, it will come from a default optionally specified at configure time (before Verilator was compiled). It should not be specified if using a pre-compiled Verilator RPM as the hardcoded value should be correct.


CONNECTING TO C++

Verilator creates a .h and .cpp file for the top level module and all modules under it. See the test_c directory in the kit for an example.

After the modules are completed, there will be a module.mk file that may be used with Make to produce a module__ALL.a file with all required objects in it. This is then linked with the user's top level to create the simulation executable.

The user must write the top level of the simulation. Here's a simple example:

        #include <verilated.h>          // Defines common routines
        #include "Vtop.h"               // From Verilating "top.v"
        Vtop *top;                      // Instantiation of module
        vluint64_t main_time = 0;       // Current simulation time
        // This is a 64-bit integer to reduce wrap over issues and
        // allow modulus.  You can also use a double, if you wish.
        double sc_time_stamp () {       // Called by $time in Verilog
            return main_time;           // converts to double, to match
                                        // what SystemC does    
        }
        int main(int argc, char** argv) {
            Verilated::commandArgs(argc, argv);   // Remember args
            top = new Vtop;             // Create instance
            top->reset_l = 0;           // Set some inputs
            while (!Verilated::gotFinish()) {
                if (main_time > 10) {
                    top->reset_l = 1;   // Deassert reset
                }
                if ((main_time % 10) == 1) {
                    top->clk = 1;       // Toggle clock
                }
                if ((main_time % 10) == 6) {
                    top->clk = 0;
                }
                top->eval();            // Evaluate model
                cout << top->out << endl;       // Read a output
                main_time++;            // Time passes...
            }
            top->final();               // Done simulating
            //    // (Though this example doesn't get here)
            delete top;
        }

Note signals are read and written as member variables of the lower module. You call the eval() method to evaluate the model. When the simulation is complete call the final() method to wrap up any SystemVerilog final blocks, and complete any assertions.


CONNECTING TO SYSTEMC

Verilator will convert the top level module to a SC_MODULE. This module will plug directly into a SystemC netlist.

The SC_MODULE gets the same pinout as the Verilog module, with the following type conversions: Pins of a single bit become bool. Pins 2-32 bits wide become uint32_t's. Pins 33-64 bits wide become sc_bv's or vluint64_t's depending on the --no-pins64 switch. Wider pins become sc_bv's. (Uints simulate the fastest so are used where possible.)

Lower modules are not pure SystemC code. This is a feature, as using the SystemC pin interconnect scheme everywhere would reduce performance by an order of magnitude.


DIRECT PROGRAMMING INTERFACE (DPI)

Verilator supports SystemVerilog Direct Programming Interface import and export statements. Only the SystemVerilog form ("DPI-C") is supported, not the original Synopsys-only DPI.

DPI Example

In the SYSTEMC example above, if you wanted to import C++ functions into Verilog, put in our.v:

   import "DPI-C" function integer add (input integer a, input integer b);
   initial begin
      $display("%x + %x = %x", 1, 2, add(1,2));
   endtask

Then after Verilating, Verilator will create a file Vour__Dpi.h with the prototype to call this function:

    extern int add (int a, int b);

From the sc_main.cpp file (or another .cpp file passed to the Verilator command line, or the link), you'd then:

    #include "svdpi.h"
    #include "Vour__Dpi.h"
    int add (int a, int b) { return a+b; }

DPI System Task/Functions

Verilator extends the DPI format to allow using the same scheme to efficiently add system functions. Simply use a dollar-sign prefixed system function name for the import, but note it must be escaped.

   export "DPI-C" function integer \$myRand;
   initial $display("myRand=%d", $myRand());

Going the other direction, you can export Verilog tasks so they can be called from C++:

   export "DPI-C" task publicSetBool;
   task publicSetBool;
      input bit in_bool;
      var_bool = in_bool;
   endtask

Then after Verilating, Verilator will create a file Vour__Dpi.h with the prototype to call this function:

    extern bool publicSetBool(bool in_bool);

From the sc_main.cpp file, you'd then:

    #include "Vour__Dpi.h"
    publicSetBool(value);

Or, alternatively, call the function under the design class. This isn't DPI compatible but is easier to read and better supports multiple designs.

    #include "Vour__Dpi.h"
    Vour::publicSetBool(value);
    // or top->publicSetBool(value);

Note that if the DPI task or function accesses any register or net within the RTL, it will require a scope to be set. This can be done using the standard functions within svdpi.h, after the module is instantiated, but before the task(s) and/or function(s) are called.

For example, if the top level module is instantiated with the name "dut" and the name references within tasks are all hierarchical (dotted) names with respect to that top level module, then the scope could be set with

    #include "svdpi.h"
    ...
    svSetScope (svGetScopeFromName ("dut"));

(Remember that Verilator adds a "V" to the top of the module hierarchy.)

Scope can also be set from within a DPI imported C function that has been called from Verilog by querying the scope of that function. See the sections on DPI Context Functions and DPI Header Isolation below and the comments within the svdpi.h header for more information.

DPI Display Functions

Verilator allows writing $display like functions using this syntax:

   import "DPI-C" function void
         \$my_display (input string formatted /*verilator sformat*/ );

The /*verilator sformat*/ indicates that this function accepts a $display like format specifier followed by any number of arguments to satisfy the format.

DPI Context Functions

Verilator supports IEEE DPI Context Functions. Context imports pass the simulator context, including calling scope name, and filename and line number to the C code. For example, in Verilog:

   import "DPI-C" context function int dpic_line();
   initial $display("This is line %d, again, line %d\n", `line, dpic_line());

This will call C++ code which may then use the svGet* functions to read information, in this case the line number of the Verilog statement that invoked the dpic_line function:

   int dpic_line() {
       // Get a scope:  svScope scope = svGetScope();
       const char* scopenamep = svGetNameFromScope(scope);
       assert(scopenamep);
       const char* filenamep = "";
       int lineno = 0;
       if (svGetCallerInfo(&filenamep, &lineno)) {
           printf("dpic_line called from scope %s on line %d\n",
              scopenamep, lineno);
           return lineno;
       } else {
           return 0;
       }
   }

See the IEEE Standard for more information.

DPI Header Isolation

Verilator places the IEEE standard header files such as svdpi.h into a separate include directory, vltstd (VeriLaTor STandarD). When compiling most applications $VERILATOR_ROOT/include/vltstd would be in the include path along with the normal $VERILATOR_ROOT/include. However, when compiling Verilated models into other simulators which have their own svdpi.h and similar standard files with different contents, the vltstd directory should not be included to prevent picking up incompatible definitions.

Public Functions

Instead of DPI exporting, there's also Verilator public functions, which are slightly faster, but less compatible.


VERIFICATION PROCEDURAL INTERFACE (VPI)

Verilator supports a very limited subset of the VPI. This subset allows inspection, examination, value change callbacks, and depositing of values to public signals only.

To access signals via the VPI, Verilator must be told exactly which signals are to be accessed. This is done using the Verilator public pragmas documented below.

Verilator has an important difference from an event based simulator; signal values that are changed by the VPI will not immediately propagate their values, instead the top level header file's eval() method must be called. Normally this would be part of the normal evaluation (IE the next clock edge), not as part of the value change. This makes the performance of VPI routines extremely fast compared to event based simulators, but can confuse some test-benches that expect immediate propagation.

Note the VPI by it's specified implementation will always be much slower than accessing the Verilator values by direct reference (structure->module->signame), as the VPI accessors perform lookup in functions at runtime requiring at best hundreds of instructions, while the direct references are evaluated by the compiler and result in only a couple of instructions.

VPI Example

In the below example, we have readme marked read-only, and writeme which if written from outside the model will have the same semantics as if it changed on the specified clock edge.

    module t;
       reg readme   /*verilator public_flat_rd*/;
       reg writeme  /*verilator public_flat_rw @(posedge clk) */;
    endmodule

There are many online tutorials and books on the VPI, but an example that accesses the above would be:

void read_and_check() { vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.readme", NULL); if (!vh1) { error... } const char* name = vpi_get_str(vpiName, vh1); printf("Module name: %s\n"); // Prints "readme"

    s_vpi_value v;
    v.format = vpiIntVal;
    vpi_get_value(vh1, &v);
    printf("Value of v: %d\n", v.value.integer);  // Prints "readme"
}


CROSS COMPILATION

Verilator supports cross-compiling Verilated code. This is generally used to run Verilator on a Linux system and produce C++ code that is then compiled on Windows.

Cross compilation involves up to three different OSes. The build system is where you configured and compiled Verilator, the host system where you run Verilator, and the target system where you compile the Verilated code and run the simulation.

Currently, Verilator requires the build and host system type to be the same, though the target system type may be different. To support this, ./configure and make Verilator on the build system. Then, run Verilator on the host system. Finally, the output of Verilator may be compiled on the different target system.

To support this, none of the files that Verilator produces will reference any configure generated build-system specific files, such as config.h (which is renamed in Verilator to config_build.h to reduce confusion.) The disadvantage of this approach is that include/verilatedos.h must self-detect the requirements of the target system, rather than using configure.

The target system may also require edits to the Makefiles, the simple Makefiles produced by Verilator presume the target system is the same type as the build system.

Cadence NC-SystemC Models

Similar to compiling Verilated designs with gcc, Verilated designs may be compiled inside other simulators that support C++ or SystemC models. One such simulator is Cadence's NC-SystemC, part of their Incisive Verification Suite. (Highly recommended.)

Using the example files above, the following command will build the model underneath NC:

   cd obj_dir
   ncsc_run \
        sc_main.cpp \
        Vour__ALLcls.cpp \
        Vour__ALLsup.cpp \
        verilated.cpp

For larger designs you'll want to automate this using makefiles, which pull the names of the .cpp files to compile in from the make variables generated in obj_dir/Vour_classes.mk.


CONFIGURATION FILES

In addition to the command line, warnings and other features may be controlled by configuration files, typically named with the .vlt extension. An example:

  `verilator_config
  lint_off -msg WIDTH
  lint_off -msg CASEX  -file "silly_vendor_code.v"

This disables WIDTH warnings globally, and CASEX for a specific file.

Configuration files are parsed after the normal Verilog preprocessing, so `ifdefs, `defines, and comments may be used as if it were normal Verilog code.

The grammar of configuration commands is as follows:

`verilator_config

Take remaining text up the the next `verilog mode switch and treat it as Verilator configuration commands.

coverage_off [-file "<filename>" [-lines <line> [ - <line> ]]]

Disable coverage for the specified filename (or wildcard with '*' or '?', or all files if omitted) and range of line numbers (or all lines if omitted). Often used to ignore an entire module for coverage analysis purposes.

lint_off [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]

Disables the specified lint warning, in the specified filename (or wildcard with '*' or '?', or all files if omitted) and range of line numbers (or all lines if omitted).

Using '*' will override any lint_on directives in the source, i.e. the warning will still not be printed.

If the -msg is omitted, all lint warnings are disabled. This will override all later lint warning enables for the specified region.

tracing_off [-file "<filename>" [-lines <line> [ - <line> ]]]

Disable waveform tracing for all future signals declared in the specified filename (or wildcard with '*' or '?', or all files if omitted) and range of line numbers (or all lines if omitted).


LANGUAGE STANDARD SUPPORT

Verilog 2001 (IEEE 1364-2001) Support

Verilator supports most Verilog 2001 language features. This includes signed numbers, "always @*", generate statements, multidimensional arrays, localparam, and C-style declarations inside port lists.

Verilog 2005 (IEEE 1364-2005) Support

Verilator supports most Verilog 2005 language features. This includes the `begin_keywords and `end_keywords compiler directives, $clog2, and the uwire keyword.

SystemVerilog 2005 (IEEE 1800-2005) Support

Verilator supports ==? and !=? operators, ++ and -- in some contexts, $bits, $countones, $error, $fatal, $info, $isunknown, $onehot, $onehot0, $unit, $warning, always_comb, always_ff, always_latch, bit, byte, chandle, const, do-while, enum, export, final, import, int, interface, logic, longint, modport, package, program, shortint, struct, time, typedef, union, var, void, priority case/if, and unique case/if.

It also supports .name and .* interconnection.

Verilator partially supports concurrent assert and cover statements; see the enclosed coverage tests for the syntax which is allowed.

SystemVerilog 2012 (IEEE 1800-2012) Support

Verilator implements a full SystemVerilog 2012 preprocessor, including function call-like preprocessor defines, default define arguments, `__FILE__, `__LINE__ and `undefineall.

Verilator currently has some support for SystemVerilog synthesis constructs. As SystemVerilog features enter common usage they are added; please file a bug if a feature you need is missing.

Verilog AMS Support

Verilator implements a very small subset of Verilog AMS (Verilog Analog and Mixed-Signal Extensions) with the subset corresponding to those VMS keywords with near equivalents in the Verilog 2005 or SystemVerilog 2009 languages.

AMS parsing is enabled with "--language VAMS" or "--language 1800+VAMS".

At present Verilator implements ceil, exp, floor, ln, log, pow, sqrt, string, and wreal.

Synthesis Directive Assertion Support

With the --assert switch, Verilator reads any "//synopsys full_case" or "//synopsys parallel_case" directives. The same applies to any "//ambit synthesis", "//cadence" or "//pragma" directives of the same form.

When these synthesis directives are discovered, Verilator will either formally prove the directive to be true, or failing that, will insert the appropriate code to detect failing cases at runtime and print an "Assertion failed" error message.

Verilator likewise also asserts any "unique" or "priority" SystemVerilog keywords on case statement, as well as "unique" on if statements. However, "priority if" is currently simply ignored.


LANGUAGE EXTENSIONS

The following additional constructs are the extensions Verilator supports on top of standard Verilog code. Using these features outside of comments or `ifdef's may break other tools.

`__FILE__

The __FILE__ define expands to the current filename as a string, like C++'s __FILE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!)

`__LINE__

The __LINE__ define expands to the current filename as a string, like C++'s __LINE__. This was incorporated into to the 1800-2009 standard (but supported by Verilator since 2006!)

`error string

This will report an error when encountered, like C++'s #error.

$c(string, ...);

The string will be embedded directly in the output C++ code at the point where the surrounding Verilog code is compiled. It may either be a standalone statement (with a trailing ; in the string), or a function that returns up to a 32-bit number (without a trailing ;). This can be used to call C++ functions from your Verilog code.

String arguments will be put directly into the output C++ code. Expression arguments will have the code to evaluate the expression inserted. Thus to call a C++ function, $c("func(",a,")") will result in 'func(a)' in the output C++ code. For input arguments, rather than hard-coding variable names in the string $c("func(a)"), instead pass the variable as an expression $c("func(",a,")"). This will allow the call to work inside Verilog functions where the variable is flattened out, and also enable other optimizations.

If you will be reading or writing any Verilog variables inside the C++ functions, the Verilog signals must be declared with /*verilator public*/.

You may also append an arbitrary number to $c, generally the width of the output. [signal_32_bits = $c32("...");] This allows for compatibility with other simulators which require a differently named PLI function name for each different output width.

$display, $write, $fdisplay, $fwrite, $sformat, $swrite

Format arguments may use C fprintf sizes after the % escape. Per the Verilog standard, %x prints a number with the natural width, and %0x prints a number with minimum width. Verilator extends this so %5x prints 5 digits per the C standard (it's unspecified in Verilog).

`coverage_block_off

Specifies the entire begin/end block should be ignored for coverage analysis. Same as /* verilator coverage_block_off */.

`systemc_header

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the output .h file's header. Despite the name of this macro, this also works in pure C++ code.

`systemc_ctor

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class constructor. Despite the name of this macro, this also works in pure C++ code.

`systemc_dtor

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class destructor. Despite the name of this macro, this also works in pure C++ code.

`systemc_interface

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class interface. Despite the name of this macro, this also works in pure C++ code.

`systemc_imp_header

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the header of all files for this C++ class implementation. Despite the name of this macro, this also works in pure C++ code.

`systemc_implementation

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into a single file of the C++ class implementation. Despite the name of this macro, this also works in pure C++ code.

If you will be reading or writing any Verilog variables in the C++ functions, the Verilog signals must be declared with /*verilator public*/. See also the public task feature; writing an accessor may result in cleaner code.

`SYSTEMVERILOG

The SYSTEMVERILOG, SV_COV_START and related standard defines are set by default when --language is 1800-*.

`VERILATOR
`verilator
`verilator3

The VERILATOR, verilator and verilator3 defines are set by default so you may `ifdef around compiler specific constructs.

`verilator_config

Take remaining text up the the next `verilog mode switch and treat it as Verilator configuration commands.

`verilog

Switch back to processing Verilog code after a `systemc_... mode switch. The Verilog code returns to the last language mode specified with `begin_keywords, or SystemVerilog if none were specified.

/*verilator clock_enable*/

Used after a signal declaration to indicate the signal is used to gate a clock, and the user takes responsibility for insuring there are no races related to it. (Typically by adding a latch, and running static timing analysis.) For example:

   reg enable_r /*verilator clock_enable*/;
   wire gated_clk = clk & enable_r;
   always_ff @ (posedge clk)
      enable_r <= enable_early;

The clock_enable attribute will cause the clock gate to be ignored in the scheduling algorithm, sometimes required for correct clock behavior, and always improving performance. It's also a good idea to enable the IMPERFECTSCH warning, to insure all clock enables are properly recognized.

/*verilator clocker*/
/*verilator no_clocker*/

Used after a signal declaration to indicate the signal is used as clock or not. This information is used by Verilator to mark the signal as clocker and propagate the clocker attribute automatically to derived signals. See --clk for more information.

/*verilator coverage_block_off*/

Specifies the entire begin/end block should be ignored for coverage analysis purposes.

/*verilator coverage_off*/

Specifies that following lines of code should have coverage disabled. Often used to ignore an entire module for coverage analysis purposes.

/*verilator coverage_on*/

Specifies that following lines of code should have coverage re-enabled (if appropriate --coverage flags are passed) after being disabled earlier with /*verilator coverage_off*/.

/*verilator inline_module*/

Specifies the module the comment appears in may be inlined into any modules that use this module. This is useful to speed up simulation time with some small loss of trace visibility and modularity. Note signals under inlined submodules will be named submodule__DOT__subsignal as C++ does not allow "." in signal names. When tracing such signals the tracing routines will replace the __DOT__ with the period.

/*verilator isolate_assignments*/

Used after a signal declaration to indicate the assignments to this signal in any blocks should be isolated into new blocks. When there is a large combinatorial block that is resulting in a UNOPTFLAT warning, attaching this to the signal causing a false loop may clear up the problem.

IE, with the following

    reg splitme /* verilator isolate_assignments*/;
    // Note the placement of the semicolon above
    always @* begin
      if (....) begin
         splitme = ....;
         other assignments
      end
    end

Verilator will internally split the block that assigns to "splitme" into two blocks:

It would then internally break it into (sort of):

    // All assignments excluding those to splitme
    always @* begin
      if (....) begin
         other assignments
      end
    end
    // All assignments to splitme
    always @* begin
      if (....) begin
         splitme = ....;
      end
    end
/*verilator lint_off msg*/

Disable the specified warning message for any warnings following the comment.

/*verilator lint_on msg*/

Re-enable the specified warning message for any warnings following the comment.

/*verilator lint_restore*/

After a /*verilator lint_save*/, pop the stack containing lint message state. Often this is useful at the bottom of include files.

/*verilator lint_save*/

Push the current state of what lint messages are turned on or turned off to a stack. Later meta-comments may then lint_on or lint_off specific messages, then return to the earlier message state by using /*verilator lint_restore*/. For example:

    // verilator lint_save
    // verilator lint_off SOME_WARNING
    ...  // code needing SOME_WARNING turned off
    // verilator lint_restore

If SOME_WARNING was on before the lint_off, it will now be restored to on, and if it was off before the lint_off it will remain off.

/*verilator no_inline_task*/

Used in a function or task variable definition section to specify the function or task should not be inlined into where it is used. This may reduce the size of the final executable when a task is used a very large number of times. For this flag to work, the task and tasks below it must be pure; they cannot reference any variables outside the task itself.

/*verilator public*/ (typedef enum)

Used after an enum typedef declaration to indicate the emitted C code should have the enum values visible. Due to C++ language restrictions, this may only be used on 64-bit or narrower integral enumerations.

    typedef enum logic [2:0] { ZERO = 3'b0 } pub_t /*verilator public*/;
/*verilator public*/ (variable)

Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will also declare this module public, otherwise use /*verilator public_flat*/.

Instead of using public variables, consider instead making a DPI or public function that accesses the variable. This is nicer as it provides an obvious entry point that is also compatible across simulators.

/*verilator public*/ (task/function)

Used inside the declaration section of a function or task declaration to indicate the function or task should be made into a C++ function, public to outside callers. Public tasks will be declared as a void C++ function, public functions will get the appropriate non-void (bool, uint32_t, etc) return type. Any input arguments will become C++ arguments to the function. Any output arguments will become C++ reference arguments. Any local registers/integers will become function automatic variables on the stack.

Wide variables over 64 bits cannot be function returns, to avoid exposing complexities. However, wide variables can be input/outputs; they will be passed as references to an array of 32-bit numbers.

Generally, only the values of stored state (flops) should be written, as the model will NOT notice changes made to variables in these functions. (Same as when a signal is declared public.)

You may want to use DPI exports instead, as it's compatible with other simulators.

/*verilator public_flat*/ (variable)

Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will not declare this module public, which means the name of the signal or path to it may change based upon the module inlining which takes place.

/*verilator public_flat_rd*/ (variable)

Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat (see above), but read-only.

/*verilator public_flat_rw @(<edge_list>) */ (variable)

Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat_rd (see above), and also writable, where writes should be considered to have the timing specified by the given sensitivity edge list.

/*verilator public_module*/

Used after a module statement to indicate the module should not be inlined (unless specifically requested) so that C code may access the module. Verilator automatically sets this attribute when the module contains any public signals or `systemc_ directives. Also set for all modules when using the --public switch.

/*verilator sc_clock*/

Rarely needed. Used after an input declaration to indicate the signal should be declared in SystemC as a sc_clock instead of a bool. This was needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require clock pins to be sc_clocks and this is no longer needed.

/*verilator sc_bv*/

Used after a port declaration. It sets the port to be of sc_bv<width> type, instead of bool, vluint32_t or vluint64_t. This may be useful if the port width is parametrized and different of such modules interface a templated module (such as a transactor) or for other reasons. In general you should avoid using this attribute when not necessary as with increasing usage of sc_bv the performance increases significantly.

/*verilator sformat*/

Attached to the final input of a function or task "input string" to 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.

/*verilator tracing_off*/

Disable waveform tracing for all future signals that are declared in this module, or cells below this module. Often this is placed just after a primitive's module statement, so that the entire module and cells below it are not traced.

/*verilator tracing_on*/

Re-enable waveform tracing for all future signals or cells that are declared.


LANGUAGE LIMITATIONS

There are some limitations and lack of features relative to a commercial simulator, by intent. User beware.

It is strongly recommended you use a lint tool before running this program. Verilator isn't designed to easily uncover common mistakes that a lint program will find for you.

Synthesis Subset

Verilator supports only the Synthesis subset with a few minor additions such as $stop, $finish and $display. That is, you cannot use hierarchical references, events or similar features of the Verilog language. It also simulates as Synopsys's Design Compiler would; namely a block of the form:

        always @ (x)   y = x & z;

This will recompute y when there is even a potential for change in x or a change in z, that is when the flops computing x or z evaluate (which is what Design Compiler will synthesize.) A compliant simulator would only calculate y if x changes. Use verilog-mode's /*AS*/ or Verilog 2001's always @* to reduce missing activity items. Avoid putting $displays in combo blocks, as they may print multiple times when not desired, even on compliant simulators as event ordering is not specified.

Bind

Verilator only supports "bind" to a target module name, not an instance path.

Dotted cross-hierarchy references

Verilator supports dotted references to variables, functions and tasks in different modules. However, references into named blocks and function-local variables are not supported. The portion before the dot must have a constant value; for example a[2].b is acceptable, while a[x].b is not.

References into generated and arrayed instances use the instance names specified in the Verilog standard; arrayed instances are named {cellName}[{instanceNumber}] in Verilog, which becomes {cellname}__BRA__{instanceNumber}__KET__ inside the generated C++ code.

Verilator creates numbered "genblk" when a begin: name is not specified around a block inside a generate statement. These numbers may differ between other simulators, but the Verilog specification does not allow users to use these names, so it should not matter.

If you are having trouble determining where a dotted path goes wrong, note that Verilator will print a list of known scopes to help your debugging.

Floating Point

Floating Point (real) numbers are supported.

Latches

Verilator is optimized for edge sensitive (flop based) designs. It will attempt to do the correct thing for latches, but most performance optimizations will be disabled around the latch.

Structures and Unions

Verilator only presently supports packed structs and packed unions. Rand and randc tags on members are simply ignored. All structures and unions are represented as a single vector, which means that generating one member of a structure from blocking, and another from non-blocking assignments is unsupported.

Time

All delays (#) are ignored, as they are in synthesis.

Unknown states

Verilator is mostly a two state simulator, not a four state simulator. However, it has two features which uncover most initialization bugs (including many that a four state simulator will miss.)

Identity comparisons (=== or !==) are converted to standard ==/!== when neither side is a constant. This may make the expression result differ from a four state simulator. An === comparison to X will always be false, so that Verilog code which checks for uninitialized logic will not fire.

Assigning a variable to a X will actually assign the variable to a random value (see the --x-assign switch.) Thus if the value is actually used, the random value should cause downstream errors. Integers also randomize, even though the Verilog 2001 specification says they initialize to zero.

All variables are randomly initialized using a function. By running several random simulation runs you can determine that reset is working correctly. On the first run, the function initializes variables to zero. On the second, have it initialize variables to one. On the third and following runs have it initialize them randomly. If the results match, reset works. (Note this is what the hardware will really do.) In practice, just setting all variables to one at startup finds most problems.

Note. --x-assign applies to variables explicitly initialized or assigned to X. Uninitialized clocks are initialized to zero, while all other state holding variables are initialized to a random value.

Event driven simulators will generally trigger an edge on a transition from X to 1 (posedge) or X to 0 (negedge). However, by default, since clocks are initialized to zero, Verilator will not trigger an initial negedge. Some code (particulary for reset) may rely on X->0 triggering an edge. Verilator provides a switch (see --x-initial-edge) to enable this behavior. Comparing runs with and without this switch will find such problems.

Tri/Inout

Verilator converts some simple tristate structures into two state. Pullup, pulldown, bufif0, bufif1, notif0, notif1, pmos, nmos, tri0 and tri1 are also supported. Simple comparisons with === 1'bz are also supported.

An assignment of the form:

    inout driver;
    wire driver = (enable) ? output_value : 1'bz;

Will be converted to

    input driver;       // Value being driven in from "external" drivers
    output driver__en;  // True if driven from this module
    output driver__out; // Value being driven from this module

External logic will be needed to combine these signals with any external drivers.

Tristate drivers are not supported inside functions and tasks; an inout there will be considered a two state variable that is read and written instead of a four state variable.

Functions & Tasks

All functions and tasks will be inlined (will not become functions in C.) The only support provided is for simple statements in tasks (which may affect global variables).

Recursive functions and tasks are not supported. All inputs and outputs are automatic, as if they had the Verilog 2001 "automatic" keyword prepended. (If you don't know what this means, Verilator will do what you probably expect -- what C does. The default behavior of Verilog is different.)

Generated Clocks

Verilator attempts to deal with generated and enabled clocks correctly, however some cases cause problems in the scheduling algorithm which is optimized for performance. The safest option is to have all clocks as primary inputs to the model, or wires directly attached to primary inputs. For proper behavior clock enables may also need the /*verilator clock_enable*/ attribute.

Ranges must be big-bit-endian

Bit ranges must be numbered with the MSB being numbered greater or the same as the LSB. Little-bit-endian busses [0:15] are not supported as they aren't easily made compatible with C++.

Gate Primitives

The 2-state gate primitives (and, buf, nand, nor, not, or, xnor, xor) are directly converted to behavioral equivalents. The 3-state and MOS gate primitives are not supported. Tables are not supported.

Specify blocks

All specify blocks and timing checks are ignored.

Array Initialization

When initializing a large array, you need to use non-delayed assignments. Verilator will tell you when this needs to be fixed; see the BLKLOOPINIT error for more information.

Array Out of Bounds

Writing a memory element that is outside the bounds specified for the array may cause a different memory element inside the array to be written instead. For power-of-2 sized arrays, Verilator will give a width warning and the address. For non-power-of-2-sizes arrays, index 0 will be written.

Reading a memory element that is outside the bounds specified for the array will give a width warning and wrap around the power-of-2 size. For non-power-of-2 sizes, it will return a unspecified constant of the appropriate width.

Assertions

Verilator is beginning to add support for assertions. Verilator currently only converts assertions to simple "if (...) error" statements, and coverage statements to increment the line counters described in the coverage section.

Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. (Arguably SEREs are much of the point, but one must start somewhere.)

Language Keyword Limitations

This section describes specific limitations for each language keyword.

`__FILE__, `__LINE__, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `begin_keywords, `define, `else, `elsif, `end_keywords, `endif, `error, `ifdef, `ifndef, `include, `line, `systemc_ctor, `systemc_dtor, `systemc_header, `systemc_imp_header, `systemc_implementation, `systemc_interface, `timescale, `undef, `verilog

Fully supported.

always, always_comb, always_ff, always_latch, and, assign, begin, buf, byte, case, casex, casez, default, defparam, do-while, else, end, endcase, endfunction, endgenerate, endmodule, endspecify, endtask, final, for, function, generate, genvar, if, initial, inout, input, int, integer, localparam, logic, longint, macromodule, module, nand, negedge, nor, not, or, output, parameter, posedge, reg, scalared, shortint, signed, supply0, supply1, task, time, tri, typedef, var, vectored, while, wire, xnor, xor

Generally supported.

++, -- operators

Increment/decrement can only be used as standalone statements or in for loops. They cannot be used as side effect operators inside more complicate expressions ("a = b++;").

'{} operator

Assignment patterns with order based, default, constant integer (array) or member identifier (struct/union) keys are supported. Data type keys and keys which are computed from a constant expression are not supported.

cast operator

Casting is supported only between simple scalar types, signed and unsigned, not arrays nor structs.

chandle

Treated as a "longint"; does not yet warn about operations that are specified as illegal on chandles.

disable

Disable statements may be used only if the block being disabled is a block the disable statement itself is inside. This was commonly used to provide loop break and continue functionality before SystemVerilog added the break and continue keywords.

inside

Inside expressions may not include unpacked array traversal or $ as an upper bound. Case inside and case matches are also unsupported.

interface

Interfaces and modports, including with generated data types are supported. Generate blocks around modports are not supported, nor are virtual interfaces nor unnamed interfaces.

priority if, unique if

Priority and unique if's are treated as normal ifs and not asserted to be full nor unique.

specify specparam

All specify blocks and timing checks are ignored.

string

String is supported only to the point that they can be assigned, concatenated, compared, and passed to DPI imports. Standard method calls on strings are not supported.

timeunit, timeprecision

All timing control statements are ignored.

uwire

Verilator does not perform warning checking on uwires, it treats the uwire keyword as if it were the normal wire keyword.

$bits, $countones, $error, $fatal, $finish, $info, $isunknown, $onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time, $unsigned, $warning.

Generally supported.

$display, $write, $fdisplay, $fwrite, $swrite

$display and friends must have a constant format string as the first argument (as with C's printf). The rare usage which lists variables standalone without a format is not supported.

$displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc

The sized display functions are rarely used and so not supported. Replace them with a $write with the appropriate format specifier.

$finish, $stop

The rarely used optional parameter to $finish and $stop is ignored.

$fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fscanf, $fwrite

File descriptors passed to the file PLI calls must be file descriptors, not MCDs, which includes the mode parameter to $fopen being mandatory.

$fscanf, $sscanf

Only integer formats are supported; %e, %f, %m, %r, %v, and %z are not supported.

$fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal, $setup, $setuphold, $skew, $timeskew, $width

All specify blocks and timing checks are ignored.

$random

$random does not support the optional argument to set the seed. Use the srand function in C to accomplish this, and note there is only one random number generator (not one per module).

$readmemb, $readmemh

Read memory commands should work properly. Note Verilator and the Verilog specification does not include support for readmem to multi-dimensional arrays.

$test$plusargs, $value$plusargs

Supported, but the instantiating C++/SystemC testbench must call

    Verilated::commandArgs(argc, argv);

to register the command line before calling $test$plusargs or $value$plusargs.

$timeformat

Not supported as Verilator needs to determine all formatting at compile time. Generally you can just ifdef them out for no ill effect. Note also VL_TIME_MULTIPLER can be defined at compile time to move the decimal point when displaying all times, model wide.


ERRORS AND WARNINGS

Warnings may be disabled in two ways. First, when the warning is printed it will include a warning code. Simply surround the offending line with a warn_off/warn_on pair:

        // verilator lint_off UNSIGNED
        if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
        // verilator lint_on UNSIGNED

Warnings may also be globally disabled by invoking Verilator with the -Wno-warning switch. This should be avoided, as it removes all checking across the designs, and prevents other users from compiling your code without knowing the magic set of disables needed to successfully compile your design.

List of all warnings:

ALWCOMBORDER

Warns that an always_comb block has a variable which is set after it is used. This may cause simulation-synthesis mismatches, as not all commercial simulators allow this ordering.

    always_comb begin
       a = b;
       b = 1;
    end

Ignoring this warning will only suppress the lint check, it will simulate correctly.

ASSIGNIN

Error that an assignment is being made to an input signal. This is almost certainly a mistake, though technically legal.

    input a;
    assign a = 1'b1;

Ignoring this warning will only suppress the lint check, it will simulate correctly.

ASSIGNDLY

Warns that you have an assignment statement with a delayed time in front of it, for example:

    a <= #100 b;
    assign #100 a = b;

Ignoring this warning may make Verilator simulations differ from other simulators, however at one point this was a common style so disabled by default as a code style warning.

BLKANDNBLK

BLKANDNBLK is an error that a variable comes from a mix of blocked and non-blocking assignments. Generally, this is caused by a register driven by both combo logic and a flop:

      always @ (posedge clk)  foo[0] <= ...
      always @* foo[1] = ...

Simply use a different register for the flop:

      always @ (posedge clk)  foo_flopped[0] <= ...
      always @* foo[0] = foo_flopped[0];
      always @* foo[1] = ...

This is good coding practice anyways.

It is also possible to disable this error when one of the assignments is inside a public task.

Ignoring this warning may make Verilator simulations differ from other simulators.

BLKSEQ

This indicates that a blocking assignment (=) is used in a sequential block. Generally non-blocking/delayed assignments (<=) are used in sequential blocks, to avoid the possibility of simulator races. It can be reasonable to do this if the generated signal is used ONLY later in the same block, however this style is generally discouraged as it is error prone.

      always @ (posedge clk)  foo = ...

Disabled by default as this is a code style warning; it will simulate correctly.

BLKLOOPINIT

This indicates that the initialization of an array needs to use non-delayed assignments. This is done in the interest of speed; if delayed assignments were used, the simulator would have to copy large arrays every cycle. (In smaller loops, loop unrolling allows the delayed assignment to work, though it's a bit slower than a non-delayed assignment.) Here's an example

        always @ (posedge clk)
            if (~reset_l) begin
                for (i=0; i<`ARRAY_SIZE; i++) begin
                    array[i] = 0;        // Non-delayed for verilator
                end

This message is only seen on large or complicated loops because Verilator generally unrolls small loops. You may want to try increasing --unroll-count (and occasionally --unroll-stmts) which will raise the small loop bar to avoid this error.

CASEINCOMPLETE

Warns that inside a case statement there is a stimulus pattern for which there is no case item specified. This is bad style, if a case is impossible, it's better to have a "default: $stop;" or just "default: ;" so that any design assumption violations will be discovered in simulation.

Ignoring this warning will only suppress the lint check, it will simulate correctly.

CASEOVERLAP

Warns that inside a case statement you have case values which are detected to be overlapping. This is bad style, as moving the order of case values will cause different behavior. Generally the values can be respecified to not overlap.

Ignoring this warning will only suppress the lint check, it will simulate correctly.

CASEX

Warns that it is simply better style to use casez, and ? in place of x's. See http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf

Ignoring this warning will only suppress the lint check, it will simulate correctly.

CASEWITHX

Warns that a case statement contains a constant with a x. Verilator is two-state so interpret such items as always false. Note a common error is to use a X in a case or casez statement item; often what the user instead intended is to use a casez with ?.

Ignoring this warning will only suppress the lint check, it will simulate correctly.

CDCRSTLOGIC

With --cdc only, warns that asynchronous flop reset terms come from other than primary inputs or flopped outputs, creating the potential for reset glitches.

CLKDATA

Warns that clock signal is mixed used with/as data signal. The checking for this warning is enabled only if user has explicitly marked some signal as clocker using command line option or in-source meta comment (see --clk).

The warning can be disabled without affecting the simulation result. But it is recommended to check the warning as this may degrade the performance of the Verilated model.

CMPCONST

Warns that you are comparing a value in a way that will always be constant. For example "X > 1" will always be true when X is a single bit wide.

Ignoring this warning will only suppress the lint check, it will simulate correctly.

COMBDLY

Warns that you have a delayed assignment inside of a combinatorial block. Using delayed assignments in this way is considered bad form, and may lead to the simulator not matching synthesis. If this message is suppressed, Verilator, like synthesis, will convert this to a non-delayed assignment, which may result in logic races or other nasties. See http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf

Ignoring this warning may make Verilator simulations differ from other simulators.

DECLFILENAME

Warns that a module or other declaration's name doesn't match the filename with path and extension stripped that it is declared in. The filename a modules/interfaces/programs is declared in should match the name of the module etc. so that -y directory searching will work. This warning is printed for only the first mismatching module in any given file, and -v library files are ignored.

Disabled by default as this is a code style warning; it will simulate correctly.

DEFPARAM

Warns that the "defparam" statement was deprecated in Verilog 2001 and all designs should now be using the #(...) format to specify parameters.

Disabled by default as this is a code style warning; it will simulate correctly.

DETECTARRAY

Error when Verilator tries to deal with a combinatorial loop that could not be flattened, and which involves a datatype which Verilator cannot handle, such as an unpacked struct or a large unpacked array. This typically ocurrs when -Wno-UNOPTFLAT has been used to override an UNOPTFLAT warning (see below).

The solution is to break the loop, as described for UNOPTFLAT.

ENDLABEL

Warns that a label attached to a "end"-something statement does not match the label attached to the block start.

Ignoring this warning will only suppress the lint check, it will simulate correctly.

GENCLK

Warns that the specified signal is generated, but is also being used as a clock. Verilator needs to evaluate sequential logic multiple times in this situation. In somewhat contrived cases having any generated clock can reduce performance by almost a factor of two. For fastest results, generate ALL clocks outside in C++/SystemC and make them primary inputs to your Verilog model. (However once need to you have even one, don't sweat additional ones.)

Ignoring this warning may make Verilator simulations differ from other simulators.

IFDEPTH

Warns that if/if else statements have exceeded the depth specified with --if-depth, as they are likely to result in slow priority encoders. Unique and priority if statements are ignored. Solutions include changing the code to a case statement, or a SystemVerilog 'unique if' or 'priority if'.

Disabled by default as this is a code style warning; it will simulate correctly.

IMPERFECTSCH

Warns that the scheduling of the model is not absolutely perfect, and some manual code edits may result in faster performance. This warning defaults to off, and must be turned on explicitly before the top module statement is processed.

IMPLICIT

Warns that a wire is being implicitly declared (it is a single bit wide output from a sub-module.) While legal in Verilog, implicit declarations only work for single bit wide signals (not buses), do not allow using a signal before it is implicitly declared by a cell, and can lead to dangling nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for Emacs, available from http://www.veripool.org/

Ignoring this warning will only suppress the lint check, it will simulate correctly.

IMPURE

Warns that a task or function that has been marked with /*verilator no_inline_task*/ references variables that are not local to the task. Verilator cannot schedule these variables correctly.

Ignoring this warning may make Verilator simulations differ from other simulators.

INCABSPATH

Warns that an `include filename specifies an absolute path. This means the code will not work on any other system with a different file system layout. Instead of using absolute paths, relative paths (preferably without any directory specified whatever) should be used, and +incdir used on the command line to specify the top include source directories.

Disabled by default as this is a code style warning; it will simulate correctly.

INITIALDLY

Warns that you have a delayed assignment inside of an initial or final block. If this message is suppressed, Verilator will convert this to a non-delayed assignment. See also the COMBDLY warning.

Ignoring this warning may make Verilator simulations differ from other simulators.

LITENDIAN

Warns that a packed vector is declared with little endian bit numbering (i.e. [0:7]). Big endian bit numbering is now the overwhelming standard, and little numbering is now thus often due to simple oversight instead of intent.

Ignoring this warning will only suppress the lint check, it will simulate correctly.

MODDUP

Error that a module has multiple definitions. Generally this indicates a coding error, or a mistake in a library file and it's good practice to have one module per file to avoid these issues. For some gate level netlists duplicates are unavoidable, and this error may be disabled.

MULTIDRIVEN

Warns that the specified signal comes from multiple always blocks. This is often unsupported by synthesis tools, and is considered bad style. It will also cause longer runtimes due to reduced optimizations.

Ignoring this warning will only slow simulations, it will simulate correctly.

MULTITOP

Error that there are multiple top level modules, that is modules not instantiated by any other module. Verilator only supports a single top level, if you need more, create a module that wraps all of the top modules.

Often this error is because some low level cell is being read in, but is not really needed. The best solution is to insure that each module is in a unique file by the same name. Otherwise, make sure all library files are read in as libraries with -v, instead of automatically with -y.

PINCONNECTEMPTY

Warns that a cell instantiation has a pin which is connected to .pin_name(), e.g. not another signal, but with an explicit mention of the pin. It may be desirable to disable PINCONNECTEMPTY, as this indicates intention to have a no-connect.

Disabled by default as this is a code style warning; it will simulate correctly.

PINMISSING

Warns that a module has a pin which is not mentioned in a cell instantiation. If a pin is not missing it should still be specified on the cell declaration with a empty connection, using "(.pin_name())".

Ignoring this warning will only suppress the lint check, it will simulate correctly.

PINNOCONNECT

Warns that a cell instantiation has a pin which is not connected to another signal.

Disabled by default as this is a code style warning; it will simulate correctly.

REALCVT

Warns that a real number is being implicitly rounded to an integer, with possible loss of precision.

REDEFMACRO

Warns that you have redefined the same macro with a different value, for example:

    `define MACRO def1
    //...
    `define MACRO otherdef

The best solution is to use a different name for the second macro. If this is not possible, add a undef to indicate the code is overriding the value:

    `define MACRO def1
    //...
    `undef MACRO
    `define MACRO otherdef
SELRANGE

Warns that a selection index will go out of bounds:

    wire vec[6:0];
    initial out = vec[7];  // There is no 7

Verilator will assume zero for this value, instead of X. Note that in some cases this warning may be false, when a condition upstream or downstream of the access means the access out of bounds will never execute or be used.

    wire vec[6:0];
    initial begin
        seven = 7;
        ...
        if (seven != 7) out = vec[seven];  // Never will use vec[7]
STMTDLY

Warns that you have a statement with a delayed time in front of it, for example:

    #100 $finish;

Ignoring this warning may make Verilator simulations differ from other simulators.

SYMRSVDWORD

Warning that a symbol matches a C++ reserved word and using this as a symbol name would result in odd C compiler errors. You may disable this warning, but the symbol will be renamed by Verilator to avoid the conflict.

SYNCASYNCNET

Warns that the specified net is used in at least two different always statements with posedge/negedges (i.e. a flop). One usage has the signal in the sensitivity list and body, probably as an async reset, and the other usage has the signal only in the body, probably as a sync reset. Mixing sync and async resets is usually a mistake. The warning may be disabled with a lint_off pragma around the net, or either flopped block.

Disabled by default as this is a code style warning; it will simulate correctly.

TASKNSVAR

Error when a call to a task or function has a output from that task tied to a non-simple signal. Instead connect the task output to a temporary signal of the appropriate width, and use that signal to set the appropriate expression as the next statement. For example:

      task foo; output sig; ... endtask
      always @* begin
           foo(bus_we_select_from[2]);   // Will get TASKNSVAR error
      end

Change this to:

      reg foo_temp_out;
      always @* begin
           foo(foo_temp_out);
           bus_we_select_from[2] = foo_temp_out;
      end

Verilator doesn't do this conversion for you, as some more complicated cases would result in simulator mismatches.

UNDRIVEN

Warns that the specified signal is never sourced. Verilator is fairly liberal in the usage calculations; making a signal public, or loading only a single array element marks the entire signal as driven.

Disabled by default as this is a code style warning; it will simulate correctly.

UNOPT

Warns that due to some construct, optimization of the specified signal or block is disabled. The construct should be cleaned up to improve runtime.

A less obvious case of this is when a module instantiates two submodules. Inside submodule A, signal I is input and signal O is output. Likewise in submodule B, signal O is an input and I is an output. A loop exists and a UNOPT warning will result if AI & AO both come from and go to combinatorial blocks in both submodules, even if they are unrelated always blocks. This affects performance because Verilator would have to evaluate each submodule multiple times to stabilize the signals crossing between the modules.

Ignoring this warning will only slow simulations, it will simulate correctly.

UNOPTFLAT

Warns that due to some construct, optimization of the specified signal is disabled. The signal specified includes a complete scope to the signal; it may be only one particular usage of a multiply instantiated block. The construct should be cleaned up to improve runtime; two times better performance may be possible by fixing these warnings.

Unlike the UNOPT warning, this occurs after netlist flattening, and indicates a more basic problem, as the less obvious case described under UNOPT does not apply.

Often UNOPTFLAT is caused by logic that isn't truly circular as viewed by synthesis which analyzes interconnection per-bit, but is circular to simulation which analyzes per-bus:

      wire [2:0] x = {x[1:0],shift_in};

This statement needs to be evaluated multiple times, as a change in "shift_in" requires "x" to be computed 3 times before it becomes stable. This is because a change in "x" requires "x" itself to change value, which causes the warning.

For significantly better performance, split this into 2 separate signals:

      wire [2:0] xout = {x[1:0],shift_in};

and change all receiving logic to instead receive "xout". Alternatively, change it to

      wire [2:0] x = {xin[1:0],shift_in};

and change all driving logic to instead drive "xin".

With this change this assignment needs to be evaluated only once. These sort of changes may also speed up your traditional event driven simulator, as it will result in fewer events per cycle.

The most complicated UNOPTFLAT path we've seen was due to low bits of a bus being generated from an always statement that consumed high bits of the same bus processed by another series of always blocks. The fix is the same; split it into two separate signals generated from each block.

The UNOPTFLAT warning may also be due to clock enables, identified from the reported path going through a clock gating cell. To fix these, use the clock_enable meta comment described above.

The UNOPTFLAT warning may also occur where outputs from a block of logic are independent, but occur in the same always block. To fix this, use the isolate_assignments meta comment described above.

To assist in resolving UNOPTFLAT, the option --report-unoptflat can be used, which will provide suggestions for variables that can be split up, and a graph of all the nodes connected in the loop. See the Arguments section for more details.

Ignoring this warning will only slow simulations, it will simulate correctly.

UNPACKED

Warns that unpacked structs and unions are not supported.

Ignoring this warning will make Verilator treat the structure as packed, which may make Verilator simulations differ from other simulators.

UNSIGNED

Warns that you are comparing a unsigned value in a way that implies it is signed, for example "X < 0" will always be true when X is unsigned.

Ignoring this warning will only suppress the lint check, it will simulate correctly.

UNUSED

Warns that the specified signal is never sinked. Verilator is fairly liberal in the usage calculations; making a signal public, a signal matching --unused-regexp ("*unused*") or accessing only a single array element marks the entire signal as used.

Disabled by default as this is a code style warning; it will simulate correctly.

A recommended style for unused nets is to put at the bottom of a file code similar to the following:

    wire _unused_ok = &{1'b0,
                        sig_not_used_a,
                        sig_not_used_yet_b,  // To be fixed
                        1'b0};

The reduction AND and constant zeros mean the net will always be zero, so won't use simulation time. The redundant leading and trailing zeros avoid syntax errors if there are no signals between them. The magic name "unused" (-unused-regexp) is recognized by Verilator and suppresses warnings; if using other lint tools, either teach to tool to ignore signals with "unused" in the name, or put the appropriate lint_off around the wire. Having unused signals in one place makes it easy to find what is unused, and reduces the number of lint_off pragmas, reducing bugs.

VARHIDDEN

Warns that a task, function, or begin/end block is declaring a variable by the same name as a variable in the upper level module or begin/end block (thus hiding the upper variable from being able to be used.) Rename the variable to avoid confusion when reading the code.

Disabled by default as this is a code style warning; it will simulate correctly.

WIDTH

Warns that based on width rules of Verilog, two operands have different widths. Verilator generally can intuit the common usages of widths, and you shouldn't need to disable this message like you do with most lint programs. Generally other than simple mistakes, you have two solutions:

If it's a constant 0 that's 32 bits or less, simply leave it unwidthed. Verilator considers zero to be any width needed.

Concatenate leading zeros when doing arithmetic. In the statement

        wire [5:0] plus_one = from[5:0] + 6'd1 + carry[0];

The best fix, which clarifies intent and will also make all tools happy is:

        wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]};

Ignoring this warning will only suppress the lint check, it will simulate correctly.

WIDTHCONCAT

Warns that based on width rules of Verilog, a concatenate or replication has an indeterminate width. In most cases this violates the Verilog rule that widths inside concatenates and replicates must be sized, and should be fixed in the code.

    wire [63:0] concat = {1,2};

An example where this is technically legal (though still bad form) is:

    parameter PAR = 1;
    wire [63:0] concat = {PAR,PAR};

The correct fix is to either size the 1 ("32'h1"), or add the width to the parameter definition ("parameter [31:0]"), or add the width to the parameter usage ("{PAR[31:0],PAR[31:0]}".

The following describes the less obvious errors:

Internal Error

This error should never occur first, though may occur if earlier warnings or error messages have corrupted the program. If there are no other warnings or errors, submit a bug report.

Unsupported: ....

This error indicates that you are using a Verilog language construct that is not yet supported in Verilator. See the Limitations chapter.

Verilated model didn't converge

Verilator sometimes has to evaluate combinatorial logic multiple times, usually around code where a UNOPTFLAT warning was issued, but disabled. For example:

   always @ (a)  b=~a;
   always @ (b)  a=b

will toggle forever and thus the executable will give the didn't converge error to prevent an infinite loop.

To debug this, run Verilator with --profile-cfuncs. Run make on the generated files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in your main.cpp.

This will cause each change in a variable to print a message. Near the bottom you'll see the code and variable that causes the problem. For the program above:

        CHANGE: filename.v:1: b
        CHANGE: filename.v:2: a


FAQ/FREQUENTLY ASKED QUESTIONS

Does it run under Windows?

Yes, using Cygwin. Verilated output should also compile under Microsoft Visual C++ Version 7 or newer, but this is not tested by the author.

Can you provide binaries?

Verilator is available as a RPM for SuSE, Fedora, and perhaps other systems; this is done by porters and may slightly lag the primary distribution. If there isn't a binary build for your distribution, how about you set one up? Please contact the authors for assistance.

Note people sometimes request binaries when they are having problems with their C++ compiler. Alas, binaries won't help this, as in the end a fully working C++ compiler is required to compile the output of Verilator.

How can it be faster than (name-the-simulator)?

Generally, the implied part of the question is "... with all of their manpower they can put into it."

Most commercial simulators have to be Verilog compliant, meaning event driven. This prevents them from being able to reorder blocks and make netlist-style optimizations, which are where most of the gains come from.

Non-compliance shouldn't be scary. Your synthesis program isn't compliant, so your simulator shouldn't have to be -- and Verilator is closer to the synthesis interpretation, so this is a good thing for getting working silicon.

Will Verilator output remain under my own license?

Yes, it's just like using GCC on your programs; this is why Verilator uses the "GNU *Lesser* Public License Version 3" instead of the more typical "GNU Public License". See the licenses for details, but in brief, if you change Verilator itself or the header files Verilator includes, you must make the source code available under the GNU Lesser Public License. However, Verilator output (the Verilated code) only "include"s the licensed files, and so you are NOT required to release any output from Verilator.

You also have the option of using the Perl Artistic License, which again does not require you release your Verilog or generated code, and also allows you to modify Verilator for internal use without distributing the modified version. But please contribute back to the community!

One limit is that you cannot under either license release a commercial Verilog simulation product incorporating Verilator without making the source code available.

As is standard with Open Source, contributions back to Verilator will be placed under the Verilator copyright and LGPL/Artistic license. Small test cases will be released into the public domain so they can be used anywhere, large tests under the LGPL/Artistic, unless requested otherwise.

Why is Verilation so slow?

Verilator needs more memory than the resulting simulator will require, as Verilator creates internally all of the state of the resulting simulator in order to optimize it. If it takes more than a minute or so (and you're not using --debug since debug is disk bound), see if your machine is paging; most likely you need to run it on a machine with more memory. Verilator is a full 64-bit application and may use more than 4GB, but about 1GB is the maximum typically needed.

How do I generate waveforms (traces) in C++?

See the next question for tracing in SystemC mode.

Add the --trace switch to Verilator, and in your top level C code, call Verilated::traceEverOn(true). Then create a VerilatedVcdC object, and in your main loop call "trace_object->dump(time)" every time step, and finally call "trace_object->close()". For an example, see below and the test_c/sim_main.cpp file of the distribution.

You also need to compile verilated_vcd_c.cpp and add it to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag.

Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file.

    #include "verilated_vcd_c.h"
    ...
    int main(int argc, char **argv, char **env) {
        ...
        Verilated::traceEverOn(true);
        VerilatedVcdC* tfp = new VerilatedVcdC;
        topp->trace (tfp, 99);
        tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd");
        ...
        while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
            main_time += #;
            tfp->dump (main_time);
        }
        tfp->close();
    }
How do I generate waveforms (traces) in SystemC?

Add the --trace switch to Verilator, and in your top level C sc_main code, include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then create a VerilatedVcdSc object as you would create a normal SystemC trace file. For an example, see the call to VerilatedVcdSc in the test_sc/sc_main.cpp file of the distribution, and below.

Alternatively you may use the C++ trace mechanism described in the previous question, however the timescale and timeprecision will not inherited from your SystemC settings.

You also need to compile verilated_vcd_sc.cpp and verilated_vcd_c.cpp and add them to your link, preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule. This is done for you if using the Verilator --exe flag.

Note you can also call ->trace on multiple Verilated objects with the same trace file if you want all data to land in the same output file.

    #include "verilated_vcd_sc.h"
    ...
    int main(int argc, char **argv, char **env) {
        ...
        Verilated::traceEverOn(true);
        VerilatedVcdSc* tfp = new VerilatedVcdSc;
        topp->trace (tfp, 99);
        tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd");
        ...
        sc_start(1);
        ...
        tfp->close();
    }
How do I view waveforms (traces)?

Verilator makes standard VCD (Value Change Dump) files. They are viewable with the public domain Dinotrace or GtkWave programs, or any of the many commercial offerings.

How do I reduce the size of large waveform (trace) files?

First, instead of calling VerilatedVcdC->open at the beginning of time, delay calling it until the time stamp where you want to tracing to begin. Likewise you can also call VerilatedVcdC->open before the end of time (perhaps a short period after you detect a verification error.)

Next, add /*verilator tracing_off*/ to any very low level modules you never want to trace (such as perhaps library cells). Finally, use the --trace-depth option to limit the depth of tracing, for example --trace-depth 1 to see only the top level signals.

Also be sure you write your trace files to a local disk, instead of to a network disk. Network disks are generally far slower.

How do I do coverage analysis?

Verilator supports both block (line) coverage and user inserted functional coverage.

First, run verilator with the --coverage option. If you're using your own makefile, compile the model with the GCC flag -DVM_COVERAGE (if using Verilator's, it will do this for you.)

Run your tests in different directories. Each test will create a logs/coverage.pl file.

After running all of your tests, verilator_coverage is executed. Verilator_coverage reads the logs/coverage.pl file(s), and creates an annotated source code listing showing code coverage details.

For an example, after running 'make test' in the Verilator distribution, see the test_sc/logs directory. Grep for lines starting with '%' to see what lines Verilator believes need more coverage.

Where is the translate_off command? (How do I ignore a construct?)

Translate on/off pragmas are generally a bad idea, as it's easy to have mismatched pairs, and you can't see what another tool sees by just preprocessing the code. Instead, use the preprocessor; Verilator defines the "VERILATOR" define for you, so just wrap the code in an ifndef region:

   `ifndef VERILATOR
      Something_Verilator_Dislikes;
   `endif
Why do I get "unexpected `do'" or "unexpected `bit'" errors?

Do, bit, ref, return, and other words are now SystemVerilog keywords. You should change your code to not use them to insure it works with newer tools. Alternatively, surround them by the Verilog 2005/SystemVerilog begin_keywords pragma to indicate Verilog 2001 code.

   `begin_keywords "1364-2001"
      integer bit; initial bit = 1;
   `end_keywords

If you want the whole file to be parsed as Verilog 2001, just create a file with

   `begin_keywords "1364-2001"

and add it before other Verilog files on the command line. (Note this will also change the default for --prefix, so if you're not using --prefix, you will now need to.)

How do I prevent my assertions from firing during reset?

Call Verilated::assertOn(false) before you first call the model, then turn it back on after reset. It defaults to true. When false, all assertions controlled by --assert are disabled.

Why do I get "undefined reference to `sc_time_stamp()'"?

In C++ (non SystemC) code you need to define this function so that the simulator knows the current time. See the "CONNECTING TO C++" examples.

Why do I get "undefined reference to `VL_RAND_RESET_I' or `Verilated::...'"?

You need to link your compiled Verilated code against the verilated.cpp file found in the include directory of the Verilator kit. This is one target in the $(VK_GLOBAL_OBJS) make variable, which should be part of your Makefile's link rule.

Is the PLI supported?

Only somewhat. More specifically, the common PLI-ish calls $display, $finish, $stop, $time, $write are converted to C++ equivalents. You can also use the "import DPI" SystemVerilog feature to call C code (see the chapter above). There is also limited VPI access to public signals.

If you want something more complex, since Verilator emits standard C++ code, you can simply write your own C++ routines that can access and modify signal values without needing any PLI interface code, and call it with $c("{any_c++_statement}").

How do I make a Verilog module that contain a C++ object?

You need to add the object to the structure that Verilator creates, then use $c to call a method inside your object. The test_regress/t/t_extend_class files show an example of how to do this.

How do I get faster build times?

Between GCC 3.0 to 3.3, each compiled progressively slower, thus if you can use GCC 2.95, or GCC 3.4 you'll have faster builds. Two ways to cheat are to compile on parallel machines and avoid compilations altogether. See the --output-split option, and the web for the ccache, distcc and icecream packages. ccache will skip GCC runs between identical source builds, even across different users. You can use the OBJCACHE environment variable to use these CC wrappers.

Why do so many files need to recompile when I add a signal?

Adding a new signal requires the symbol table to be recompiled. Verilator uses one large symbol table, as that results in 2-3 less assembly instructions for each signal access. This makes the execution time 10-15% faster, but can result in more compilations when something changes.

How do I access functions/tasks in C?

Use the SystemVerilog Direct Programming Interface. You write a Verilog function or task with input/outputs that match what you want to call in with C. Then mark that function as an external function. See the DPI chapter in the manual.

How do I access signals in C?

The best thing is to make a SystemVerilog "export DPI task" or function that accesses that signal, as described in the DPI chapter in the manual and DPI tutorials on the web. This will allow Verilator to better optimize the model and should be portable across simulators.

If you really want raw access to the signals, declare the signals you will be accessing with a /*verilator public*/ comment before the closing semicolon. Then scope into the C++ class to read the value of the signal, as you would any other member variable.

Signals are the smallest of 8-bit chars, 16-bit shorts, 32-bit longs, or 64-bit long longs that fits the width of the signal. Generally, you can use just uint32_t's for 1 to 32 bits, or vluint64_t for 1 to 64 bits, and the compiler will properly up-convert smaller entities.

Signals wider than 64 bits are stored as an array of 32-bit uint32_t's. Thus to read bits 31:0, access signal[0], and for bits 63:32, access signal[1]. Unused bits (for example bit numbers 65-96 of a 65-bit vector) will always be zero. if you change the value you must make sure to pack zeros in the unused bits or core-dumps may result. (Because Verilator strips array bound checks where it believes them to be unnecessary.)

In the SYSTEMC example above, if you had in our.v:

    input clk /*verilator public*/;
    // Note the placement of the semicolon above

From the sc_main.cpp file, you'd then:

    #include "Vour.h"
    #include "Vour_our.h"
    cout << "clock is " << top->v->clk << endl;

In this example, clk is a bool you can read or set as any other variable. The value of normal signals may be set, though clocks shouldn't be changed by your code or you'll get strange results.

Should a module be in Verilog or SystemC?

Sometimes there is a block that just interconnects cells, and have a choice as to if you write it in Verilog or SystemC. Everything else being equal, best performance is when Verilator sees all of the design. So, look at the hierarchy of your design, labeling cells as to if they are SystemC or Verilog. Then:

A module with only SystemC cells below must be SystemC.

A module with a mix of Verilog and SystemC cells below must be SystemC. (As Verilator cannot connect to lower-level SystemC cells.)

A module with only Verilog cells below can be either, but for best performance should be Verilog. (The exception is if you have a design that is instantiated many times; in this case Verilating one of the lower modules and instantiating that Verilated cells multiple times into a SystemC module *may* be faster.)


BUGS

First, check the the coding limitations section.

Next, try the --debug switch. This will enable additional internal assertions, and may help identify the problem.

Finally, reduce your code to the smallest possible routine that exhibits the bug. Even better, create a test in the test_regress/t directory, as follows:

    cd test_regress
    cp -p t/t_EXAMPLE.pl t/t_BUG.pl
    cp -p t/t_EXAMPLE.v t/t_BUG.v

There are many hits on how to write a good test in the driver.pl documentation which can be seen by running:

    cd $VERILATOR_ROOT  # Need the original distribution kit
    test_regress/driver.pl --help

Edit t/t_BUG.pl to suit your example; you can do anything you want in the Verilog code there; just make sure it retains the single clk input and no outputs. Now, the following should fail:

    cd $VERILATOR_ROOT  # Need the original distribution kit
    cd test_regress
    t/t_BUG.pl  # Run on Verilator
    t/t_BUG.pl --debug # Run on Verilator, passing --debug to Verilator
    t/t_BUG.pl --vcs  # Run on a commercial simulator
    t/t_BUG.pl --nc|--iv|--ghdl  # Likewise on other simulators

The test driver accepts a number of options, many of which mirror the main Verilator option. For example the previous test could have been run with debugging enabled. The full set of test options can be seen by running driver.pl --help as shown above.

Finally, report the bug using the bug tracker at http://www.veripool.org/verilator. The bug will become publicly visible; if this is unacceptable, mail the bug report to wsnyder@wsnyder.org.


HISTORY

Verilator was conceived in 1994 by Paul Wasson at the Core Logic Group at Digital Equipment Corporation. The Verilog code that was converted to C was then merged with a C based CPU model of the Alpha processor and simulated in a C based environment called CCLI.

In 1995 Verilator started being used also for Multimedia and Network Processor development inside Digital. Duane Galbi took over active development of Verilator, and added several performance enhancements. CCLI was still being used as the shell.

In 1998, through the efforts of existing DECies, mainly Duane Galbi, Digital graciously agreed to release the source code. (Subject to the code not being resold, which is compatible with the GNU Public License.)

In 2001, Wilson Snyder took the kit, and added a SystemC mode, and called it Verilator2. This was the first packaged public release.

In 2002, Wilson Snyder created Verilator3 by rewriting Verilator from scratch in C++. This added many optimizations, yielding about a 2-5x performance gain.

In 2009, major SystemVerilog and DPI language support was added.

Currently, various language features and performance enhancements are added as the need arises. Verilator is now about 3x faster than in 2002, and is faster than many popular commercial simulators.


AUTHORS

When possible, please instead report bugs to http://www.veripool.org/.

Wilson Snyder <wsnyder@wsnyder.org>

Major concepts by Paul Wasson, Duane Galbi and Jie Xu.


CONTRIBUTORS

Many people have provided ideas and other assistance with Verilator.

The major corporate sponsors of Verilator, by providing significant contributions of time or funds include include Atmel Corporation, Cavium Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc., and SiCortex Inc.

The people who have contributed major functionality are Byron Bradley, Jeremy Bennett, Jie Xu, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers include Jeff Dutton, Jonathon Donaldson, Ralf Karge, David Hewson, Iztok Jeras, Wim Michiels, Alex Solomatnikov, Sebastien Van Cauwenberghe, Gene Weber, and Clifford Wolf.

Some of the people who have provided ideas and feedback for Verilator include: Yves Mathieu, David Addison, Nikana Anastasiadis, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad Bagri, Andrew Bardsley, Geoff Barrett, J Baxter, Julius Baxter, Jeremy Bennett, Michael Berman, David Binderman, David Black, Daniel Bone, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Charlie Brej, Lane Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Ted Campbell, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike Denio, John Deroo, Philip Derrick, John Dickol, R. Diez, Ruben Diez, Danny Ding, Ivan Djordjevic, Jonathon Donaldson, Alex Duller, Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete, Fabrizio Ferrandi, Andrea Foletto, Bob Fredieu, Christian Gelinek, Glen Gibb, Shankar Giri, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Junji Hashimoto, Thomas Hawkins, David Hewson, Hiroki Honda, Alex Hornung, Jae Hossell, Ben Jackson, Krzysztof Jankowski, HyungKi Jeong, Iztok Jeras, James Johnson, Christophe Joly, Franck Jullien, Mike Kagen, Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Sobhan Klnv, Gernot Koch, Soon Koh, Steve Kolecki, Brett Koonce, Wojciech Koszek, Varun Koyyalagunta, David Kravitz, Roland Kruse, Ed Lander, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber, Igor Lesik, John Li, Eivind Liland, Charlie Lind, Andrew Ling, Paul Liu, Derek Lockhart, Arthur Low, Stefan Ludwig, Dan Lussier, Fred Ma, Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Wai Sum Mong, Sean Moore, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Bob Newgard, Cong Van Nguyen, Paul Nitza, Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, David Pierce, Dominic Plunkett, David Poole, Rich Porter, Niranjan Prabhu, Usha Priyadharshini, Mark Jackson Pulver, Prateek Puri, Chris Randall, Frederic Requin, Alberto Del Rio, Oleg Rodionov, Jan Egil Ruud, John Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Steven Slatter, Brian Small, Wilson Snyder, Alex Solomatnikov, Art Stamness, John Stevenson, Todd Strader, John Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu Takatsukasa, Peter Tengstrand, Stefan Thiede, Gary Thomas, Kevin Thompson, Mike Thyer, Steve Tong, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston, Joshua Wise, Clifford Wolf, Johan Wouters, Ding Xiaoliang, Jie Xu, and Amir Yazdanbakhsh.

Thanks to them, and all those we've missed including above.


DISTRIBUTION

The latest version is available from http://www.veripool.org/.

Copyright 2003-2015 by Wilson Snyder. Verilator is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.


SEE ALSO

verilator_coverage, verilator_profcfunc, make,

verilator --help which is the source for this document,

and internals.txt in the distribution.

verilator-3.874/internals.txt0000664000177100017500000007373012534631201016272 0ustar wsnyderwsnyderNAME Verilator Internals INTRODUCTION This file discusses internal and programming details for Verilator. It's the first for reference for developers and debugging problems. See also the Verilator internals presentation at http://www.veripool.org. CODE FLOWS Verilator Flow The main flow of Verilator can be followed by reading the Verilator.cpp process() function: First, the files specified on the command line are read. Reading involves preprocessing, then lexical analysis with Flex and parsing with Bison. This produces an abstract syntax tree (AST) representation of the design, which is what is visible in the .tree files described below. Verilator then makes a series of passes over the AST, progressively refining and optimizing it. Cells in the AST first linked, which will read and parse additional files as above. Functions, variable and other references are linked to their definitions. Parameters are resolved and the design is elaborated. Verilator then performs many additional edits and optimizations on the hierarchical design. This includes coverage, assertions, X elimination, inlining, constant propagation, and dead code elimination. References in the design are then pseudo-flattened. Each module's variables and functions get "Scope" references. A scope reference is an occurrence of that un-flattened variable in the flattened hierarchy. A module that occurs only once in the hierarchy will have a single scope and single VarScope for each variable. A module that occurs twice will have a scope for each occurrence, and two VarScopes for each variable. This allows optimizations to proceed across the flattened design, while still preserving the hierarchy. Additional edits and optimizations proceed on the pseudo-flat design. These include module references, function inlining, loop unrolling, variable lifetime analysis, lookup table creation, always splitting, and logic gate simplifications (pushing inverters, etc). Verilator orders the code. Best case, this results in a single "eval" function which has all always statements flowing from top to bottom with no loops. Verilator mostly removes the flattening, so that code may be shared between multiple invocations of the same module. It localizes variables, combines identical functions, expands macros to C primitives, adds branch prediction hints, and performs additional constant propagation. Verilator finally writes the C++ modules. Key Classes Used in the Verilator Flow "AstNode" The AST is represented at the top level by the class "AstNode". This abstract class has derived classes for the individual components (e.g. "AstGenerate" for a generate block) or groups of components (e.g. "AstNodeFTask" for functions and tasks, which in turn has "AstFunc" and "AstTask" as derived classes). Each "AstNode" has pointers to up to four children, accessed by the "op1p" through "op4p" methods. These methods are then abstracted in a specific Ast* node class to a more specific name. For example with the "AstIf" node (for "if" statements), "ifsp" calls "op2p" to give the pointer to the AST for the "then" block, while "elsesp" calls "op3p" to give the pointer to the AST for the "else" block, or NULL if there is not one. "AstNode" has the concept of a next and previous AST - for example the next and previous statements in a block. Pointers to the AST for these statements (if they exist) can be obtained using the "back" and "next" methods. It is useful to remember that the derived class "AstNetlist" is at the top of the tree, so checking for this class is the standard way to see if you are at the top of the tree. By convention, each function/method uses the variable "nodep" as a pointer to the "AstNode" currently being processed. "AstNVisitor" The passes are implemented by AST visitor classes (see "Visitor Functions"). These are implemented by subclasses of the abstract class, "AstNVisitor". Each pass creates an instance of the visitor class, which in turn implements a method to perform the pass. "V3Graph" A number of passes use graph algorithms, and the class "V3Graph" is provided to represent those graphs. Graphs are directed, and algorithms are provided to manipulate the graphs and to output them in *GraphViz* dot format (see ). "V3Graph.h" provides documentation of this class. "V3GraphVertex" This is the base class for vertices in a graph. Vertices have an associated "fanout", "color" and "rank", which may be used in algorithms for ordering the graph. A generic "user"/"userp" member variable is also provided. Virtual methods are provided to specify the name, color, shape and style to be used in dot output. Typically users provide derived classes from "V3GraphVertex" which will reimplement these methods. Iterators are provided to access in and out edges. Typically these are used in the form: for (V3GraphEdge *edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { "V3GraphEdge" This is the base class for directed edges between pairs of vertices. Edges have an associated "weight" and may also be made "cutable". A generic "user"/"userp" member variable is also provided. Accessors, "fromp" and "top" return the "from" and "to" vertices respectively. Virtual methods are provided to specify the label, color and style to be used in dot output. Typically users provided derived classes from "V3GraphEdge" which will reimplement these methods. "V3GraphAlg" This is the base class for graph algorithms. It implements a "bool" method, "followEdge" which algorithms can use to decide whether an edge is followed. This method returns true if the graph edge has weight greater than one and a user function, "edgeFuncp" (supplied in the constructor) returns "true". A number of predefined derived algorithm classes and access methods are provided and documented in "V3GraphAlg.cpp". Verilated Flow The evaluation loop outputted by Verilator is designed to allow a single function to perform evaluation under most situations. On the first evaluation, the Verilated code calls initial blocks, and then "settles" the modules, by evaluating functions (from always statements) until all signals are stable. On other evaluations, the Verilated code detects what input signals have changes. If any are clocks, it calls the appropriate sequential functions (from always @ posedge statements). Interspersed with sequential functions it calls combo functions (from always @*). After this is complete, it detects any changes due to combo loops or internally generated clocks, and if one is found must reevaluate the model again. For SystemC code, the eval() function is wrapped in a SystemC SC_METHOD, sensitive to all inputs. (Ideally it would only be sensitive to clocks and combo inputs, but tracing requires all signals to cause evaluation, and the performance difference is small.) If tracing is enabled, a callback examines all variables in the design for changes, and writes the trace for each change. To accelerate this process the evaluation process records a bitmask of variables that might have changed; if clear, checking those signals for changes may be skipped. CODING CONVENTIONS Indentation style To match the indentation of Verilator C++ sources, use 4 spaces per level, and leave tabs at 8 columns, so every other indent level is a tab stop. All files should contain the magic header to insure standard indentation: // -*- mode: C++; c-file-style: "cc-mode" -*- This sets indentation to the cc-mode defaults. (Verilator predates a CC-mode change of several years ago which overrides the defaults with GNU style indentation; the c-set-style undoes that.) The "astgen" script Some of the code implementing passes is extremely repetitive, and must be implemented for each sub-class of "AstNode". However, while repetitive, there is more variability than can be handled in C++ macros. In Verilator this is implemented by using a Perl script, "astgen" to pre-process the C++ code. For example in "V3Const.cpp" this is used to implement the "visit()" functions for each binary operation using the TREEOP macro. The original C++ source code is transformed into C++ code in the "obj_opt" and "obj_dbg" sub-directories (the former for the optimized version of Verilator, the latter for the debug version). So for example "V3Const.cpp" into "V3Const__gen.cpp". Visitor Functions Verilator uses the *Visitor* design pattern to implement its refinement and optimization passes. This allows separation of the pass algorithm from the AST on which it operates. Wikipedia provides an introduction to the concept at . As noted above, all visitors are derived classes of "AstNVisitor". All derived classes of "AstNode" implement the "accept" method, which takes as argument a reference to an instance or a "AstNVisitor" derived class and applies the visit method of the "AstNVisitor" to the invoking AstNode instance (i.e. "this"). One possible difficulty is that a call to "accept" may perform an edit which destroys the node it receives as argument. The "acceptSubtreeReturnEdits" method of "AstNode" is provided to apply "accept" and return the resulting node, even if the original node is destroyed (if it is not destroyed it will just return the original node). The behavior of the visitor classes is achieved by overloading the "visit" function for the different "AstNode" derived classes. If a specific implementation is not found, the system will look in turn for overloaded implementations up the inheritance hierarchy. For example calling "accept" on "AstIf" will look in turn for: void visit (AstIf* nodep, AstNUser* vup) void visit (AstNodeIf* nodep, AstNUser* vup) void visit (AstNodeStmt* nodep, AstNUser* vup) void visit (AstNode* nodep, AstNUser* vup) There are three ways data is passed between visitor functions. 1. A visitor-class member variable. This is generally for passing "parent" information down to children. "m_modp" is a common example. It's set to NULL in the constructor, where that node ("AstModule" visitor) sets it, then the children are iterated, then it's cleared. Children under an "AstModule" will see it set, while nodes elsewhere will see it clear. If there can be nested items (for example an "AstFor" under an "AstFor") the variable needs to be save-set-restored in the "AstFor" visitor, otherwise exiting the lower for will lose the upper for's setting. 2. User attributes. Each "AstNode" (Note. The AST node, not the visitor) has five user attributes, which may be accessed as an integer using the "user1()" through "user5()" methods, or as a pointer (of type "AstNUser") using the "user1p()" through "user5p()" methods (a common technique lifted from graph traversal packages). A visitor first clears the one it wants to use by calling "AstNode::user#ClearTree()", then it can mark any node's user() with whatever data it wants. Readers just call "nodep->user()", but may need to cast appropriately, so you'll often see "nodep->userp()->castSOMETYPE()". At the top of each visitor are comments describing how the "user()" stuff applies to that visitor class. For example: // NODE STATE // Cleared entire netlist // AstModule::user1p() // bool. True to inline this module This says that at the "AstNetlist" "user1ClearTree()" is called. Each "AstModule"'s "user1()" is used to indicate if we're going to inline it. These comments are important to make sure a "user#()" on a given "AstNode" type is never being used for two different purposes. Note that calling "user#ClearTree" is fast, it doesn't walk the tree, so it's ok to call fairly often. For example, it's commonly called on every module. 3. Parameters can be passed between the visitors in close to the "normal" function caller to callee way. This is the second "vup" parameter of type "AstNUser" that is ignored on most of the visitor functions. V3Width does this, but it proved more messy than the above and is deprecated. (V3Width was nearly the first module written. Someday this scheme may be removed, as it slows the program down to have to pass vup everywhere.) Iterators "AstNode" provides a set of iterators to facilitate walking over the tree. Each takes two arguments, a visitor, "v", of type "AstNVisitor" and an optional pointer user data, "vup", of type "AstNUser*". The second is one of the ways to pass parameters to visitors described in "Visitor Functions", but its use is now deprecated and should *not* be used for new visitor classes. "iterate()" This just applies the "accept" method of the "AstNode" to the visitor function. "iterateAndNextIgnoreEdit" Applies the "accept" method of each "AstNode" in a list (i.e. connected by "nextp" and "backp" pointers). "iterateAndNext" Applies the "accept" method of each "AstNode" in a list. If a node is edited by the call to "accept", apply "accept" again, until the node does not change. "iterateListBackwards" Applies the "accept" method of each "AstNode" in a list, starting with the last one. "iterateChildren" Apply the "iterateAndNext" method on each child "op1p" through "op4p" in turn. "iterateChildrenBackwards" Apply the "iterateListBackwards" method on each child "op1p" through "op4p" in turn. Caution on Using Iterators When Child Changes Visitors often replace one node with another node; V3Width and V3Const are major examples. A visitor which is the parent of such a replacement needs to be aware that calling iteration may cause the children to change. For example: // nodep->lhsp() is 0x1234000 nodep->lhsp()->iterateAndNext(...); // and under covers nodep->lhsp() changes // nodep->lhsp() is 0x5678400 nodep->lhsp()->iterateAndNext(...); Will work fine, as even if the first iterate causes a new node to take the place of the lhsp(), that edit will update nodep->lhsp() and the second call will correctly see the change. Alternatively: lp = nodep->lhsp(); // nodep->lhsp() is 0x1234000, lp is 0x1234000 lp->iterateAndNext(...); **lhsp=NULL;** // and under covers nodep->lhsp() changes // nodep->lhsp() is 0x5678400, lp is 0x1234000 lp->iterateAndNext(...); This will cause bugs or a core dump, as lp is a dangling pointer. Thus it is advisable to set lhsp=NULL shown in the *'s above to make sure these dangles are avoided. Another alternative used in special cases mostly in V3Width is to use acceptSubtreeReturnEdits, which operates on a single node and returns the new pointer if any. Note acceptSubtreeReturnEdits does not follow nextp() links. lp = lp->acceptSubtreeReturnEdits() Identifying derived classes A common requirement is to identify the specific "AstNode" class we are dealing with. For example a visitor might not implement separate "visit" methods for "AstIf" and "AstGenIf", but just a single method for the base class: void visit (AstNodeIf* nodep, AstNUser* vup) However that method might want to specify additional code if it is called for "AstGenIf". Verilator does this by providing a "castSOMETYPE()" method for each possible node type, using C++ "dynamic_cast". This either returns a pointer to the object cast to that type (if it is of class "SOMETYPE", or a derived class of "SOMETYPE") or else NULL. So our "visit" method could use: if (nodep->castAstGenIf()) { } A common test is for "AstNetlist", which is the node at the root of the AST. TESTING For an overview of how to write a test see the BUGS section of the Verilator primary manual. It is important to add tests for failures as well as success (for example to check that an error message is correctly triggered). Tests that fail should by convention have the suffix "_bad" in their name, and include "fails => 1" in either their "compile" or "execute" step as appropriate. Preparing to Run Tests For all tests to pass you must install the following packages: * SystemC to compile the SystemC outputs, see http://systemc.org * Parallel::Forker from CPAN to run tests in parallel, you can install this with e.g. "sudo cpan install Parallel::Forker". * vcddiff to find differences in VCD outputs. See the readme at https://github.com/veripool/vcddiff Controlling the Test Driver Test drivers are written in PERL. All invoke the main test driver script, which can provide detailed help on all the features available when writing a test driver. test_regress/t/driver.pl --help For convenience, a summary of the most commonly used features is provided here. All drivers require a call to "compile" subroutine to compile the test. For run-time tests, this is followed by a call to the "execute" subroutine. Both of these functions can optionally be provided with a hash table as argument specifying additional options. The test driver assumes by default that the source Verilog file name matches the PERL driver name. So a test whose driver is "t/t_mytest.pl" will expect a Verilog source file "t/t_mytest.v". This can be changed using the "top_filename" subroutine, for example top_filename("t/t_myothertest.v"); By default all tests will run with major simulators (Icarus Verilog, NC, VCS, ModelSim) as well as Verilator, to allow results to be compared. However if you wish a test only to be used with Verilator, you can use the following: $Self->{vlt} or $Self->skip("Verilator only test"); Of the many options that can be set through arguments to "compiler" and "execute", the following are particularly useful: "verilator_flags2" A list of flags to be passed to verilator when compiling. "fails" Set to 1 to indicate that the compilation or execution is intended to fail. For example the following would specify that compilation requires two defines and is expected to fail. compile ( verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"], fails => 1, ); Regression Testing for Developers Developers will also want to call ./configure with two extra flags: --enable-ccwarn Causes the build to stop on warnings as well as errors. A good way to ensure no sloppy code gets added, however it can be painful when it comes to testing, since third party code used in the tests (e.g. SystemC) may not be warning free. --enable-longtests In addition to the standard C, SystemC tests also run the tests in the "test_verilated" and "test_regress" directories when using *make test*. This is disabled by default as SystemC installation problems would otherwise falsely indicate a Verilator problem. When enabling the long tests, some additional PERL modules are needed, which you can install using cpan. cpan install Unix::Processors There are some traps to avoid when running regression tests * When checking the MANIFEST, the test will barf on unexpected code in the Verilator tree. So make sure to keep any such code outside the tree. * Not all Linux systems install Perldoc by default. This is needed for the *--help* option to Verilator, and also for regression testing. This can be installed using cpan: cpan install Pod::Perldoc Many Linux systems also offer a standard package for this. Red Hat/Fedora/Centos offer *perl-Pod-Perldoc*, while Debian/Ubuntu/Linux Mint offer *perl-doc*. * Running regression may exhaust resources on some Linux systems, particularly file handles and user processes. Increase these to respectively 16,384 and 4,096. The method of doing this is system dependent, but on Fedora Linux it would require editing the "/etc/security/limits.conf" file as root. DEBUGGING --debug When you run with --debug there are two primary output file types placed into the obj_dir, .tree and .dot files. .dot output Dot files are dumps of internal graphs in Graphviz dot format. When a dot file is dumped, Verilator will also print a line on stdout that can be used to format the output, for example: dot -Tps -o ~/a.ps obj_dir/Vtop_foo.dot You can then print a.ps. You may prefer gif format, which doesn't get scaled so can be more useful with large graphs. For dynamic graph viewing consider ZGRViewer . If you know of better viewers let us know; ZGRViewer isn't great for large graphs. .tree output Tree files are dumps of the AST Tree and are produced between every major algorithmic stage. An example: NETLIST 0x90fb00 {a0} 1: MODULE 0x912b20 {a8} top L2 [P] *1:2: VAR 0x91a780 {a22} @dt=0xa2e640(w32) out_wide [O] WIRE 1:2:1: BASICDTYPE 0xa2e640 {e24} @dt=this(sw32) integer kwd=integer range=[31:0] The following summarizes the above example dump, with more detail on each field in the section below. "1:2:" indicates the hierarchy of the "VAR" is the "op2p" pointer under the "MODULE", which in turn is the "op1p" pointer under the "NETLIST" "VAR" is the AstNodeType. "0x91a780" is the address of this node. "" means the 74th edit to the netlist was the last modification to this node. "{a22}" indicates this node is related to line 22 in the source filename "a", where "a" is the first file read, "z" the 26th, and "aa" the 27th. "@dt=0x..." indicates the address of the data type this node contains. "w32" indicates the width is 32 bits. "out_wide" is the name of the node, in this case the name of the variable. "[O]" are flags which vary with the type of node, in this case it means the variable is an output. In more detail the following fields are dumped common to all nodes. They are produced by the "AstNode::dump()" method: Tree Hierarchy The dump lines begin with numbers and colons to indicate the child node hierarchy. As noted above in "Key Classes Used in the Verilator Flow", "AstNode" has lists of items at the same level in the AST, connected by the "nextp()" and "prevp()" pointers. These appear as nodes at the same level. For example after inlining: NETLIST 0x929c1c8 {a0} w0 1: MODULE 0x92bac80 {e14} w0 TOP_t L1 [P] 1:1: CELLINLINE 0x92bab18 {e14} w0 v -> t 1:1: CELLINLINE 0x92bc1d8 {e24} w0 v__DOT__i_test_gen -> test_gen ... 1: MODULE 0x92b9bb0 {e47} w0 test_gen L3 ... AstNode type The textual name of this node AST type (always in capitals). Many of these correspond directly to Verilog entities (for example "MODULE" and "TASK"), but others are internal to Verialtor (for example "NETLIST" and "BASICDTYPE"). Address of the node A hexadecimal address of the node in memory. Useful for examining with the debugger. Last edit number Of the form "" or "" , where "nnnn" is the number of the last edit to modify this node. The trailing "#" indicates the node has been edited since the last tree dump (which typically means in the last refinement or optimization pass). GDB can watch for this, see "Debugging with GDB". Source file and line Of the form "{xxnnnn}", where C{xx} is the filename letter (or letters) and "nnnn" is the line number within that file. The first file is "a", the 26th is "z", the 27th is "aa" and so on. User pointers Shows the value of the node's user1p...user5p, if non-NULL. Data type Many nodes have an explicit data type. "@dt=0x..." indicates the address of the data type (AstNodeDType) this node uses. If a data type is present and is numeric, it then prints the width of the item. This field is a sequence of flag characters and width data as follows: "s" if the node is signed. "d" if the node is a double (i.e a floating point entity). "w" always present, indicating this is the width field. "u" if the node is unsized. "/nnnn" if the node is unsized, where "nnnn" is the minimum width. Name of the entity represented by the node if it exists For example for a "VAR" it is the name of the variable. Many nodes follow these fields with additional node specific information. Thus the "VARREF" node will print either "[LV]" or "[RV]" to indicate a left value or right value, followed by the node of the variable being referred to. For example: 1:2:1:1: VARREF 0x92c2598 {e24} w0 clk [RV] <- VAR 0x92a2e90 {e18} w0 clk [I] INPUT In general, examine the "dump()" method in "V3AstNodes.cpp" of the node type in question to determine additional fields that may be printed. The "MODULE" has a list of "CELLINLINE" nodes referred to by its "op1p()" pointer, connected by "nextp()" and "prevp()" pointers. Similarly the "NETLIST" has a list of modules referred to by its "op1p()" pointer. Debugging with GDB The test_regress/driver.pl script accepts --debug --gdb to start Verilator under gdb and break when an error is hit or the program is about to exit. You can also use --debug --gdbbt to just backtrace and then exit gdb. To debug the Verilated executable, use --gdbsim. If you wish to start Verilator under GDB (or another debugger), then you can use --debug and look at the underlying invocation of verilator_dgb. For example t/t_alw_dly.pl --debug shows it invokes the command: ../verilator_bin_dbg --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v Start GDB, then "start" with the remaining arguments. gdb ../verilator_bin_dbg ... (gdb) start --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v > obj_dir/t_alw_dly/vlt_compile.log ... Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc) at ../Verilator.cpp:615 615 ios::sync_with_stdio(); (gdb) You can then continue execution with breakpoints as required. To break at a specific edit number which changed a node (presumably to find what made a line in the tree dumps): watch AstNode::s_editCntGbl==#### To print a node: pn nodep # or: call nodep->dumpGdb() # aliased to "pn" in src/.gdbinit pnt nodep # or: call nodep->dumpTreeGdb() # aliased to "pnt" in src/.gdbinit When GDB halts, it is useful to understand that the backtrace will commonly show the iterator functions between each invocation of "visit" in the backtrace. You will typically see a frame sequence something like ... visit() iterateChildren() iterateAndNext() accept() visit() ... ADDING A NEW FEATURE Generally what would you do to add a new feature? 1. File a bug (if there isn't already) so others know what you're working on. 2. Make a testcase in the test_regress/t/t_EXAMPLE format, see TESTING. 3. If grammar changes are needed, look at the git version of VerilogPerl's src/VParseGrammar.y, as this grammar supports the full SystemVerilog language and has a lot of back-and-forth with Verilator's grammar. Copy the appropriate rules to src/verilog.y and modify the productions. 4. If a new Ast type is needed, add it to V3AstNodes.h. Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree file which you can examine to see if the parsing worked. See also the sections above on debugging. Modify the later visitor functions to process the new feature as needed. Adding a new pass For more substantial changes you may need to add a new pass. The simplest way to do this is to copy the ".cpp" and ".h" files from an existing pass. You'll need to add a call into your pass from the "process()" function in "src/verilator.cpp". To get your pass to build you'll need to add its binary filename to the list in "src/Makefile_obj.in" and reconfigure. DISTRIBUTION The latest version is available from . Copyright 2008-2015 by Wilson Snyder. Verilator 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. verilator-3.874/configure0000775000177100017500000050526212534631142015445 0ustar wsnyderwsnyder#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for Verilator 3.874 2015-06-06. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Verilator' PACKAGE_TARNAME='verilator' PACKAGE_VERSION='3.874 2015-06-06' PACKAGE_STRING='Verilator 3.874 2015-06-06' PACKAGE_BUGREPORT='' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS LIBOBJS pkgconfigdir pkgdatadir CFG_CXXFLAGS_NO_UNUSED CFG_CXXFLAGS_PARSER CFG_CXXFLAGS_SRC EGREP GREP CXXCPP YACC LEX PERL INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM ac_ct_CXX CXXFLAGS CXX OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC CFG_WITH_LONGTESTS CFG_WITH_CCWARN CFG_WITH_DEFENV target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_defenv enable_ccwarn enable_longtests ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CXX CXXFLAGS CCC CXXCPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Verilator 3.874 2015-06-06 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/verilator] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Verilator 3.874 2015-06-06:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-defenv disable using some hardcoded data paths extracted from some default environment variables (the default is to use hardcoded paths) --enable-ccwarn enable showing and stopping on compilation warnings --enable-longtests enable running long developer tests Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Verilator configure 3.874 2015-06-06 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES # --------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_cxx_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_type # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_cxx_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Verilator $as_me 3.874 2015-06-06, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers src/config_build.h" ac_config_files="$ac_config_files Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc" { $as_echo "$as_me:${as_lineno-$LINENO}: result: configuring for $PACKAGE_STRING" >&5 $as_echo "configuring for $PACKAGE_STRING" >&6; } # Special Substitutions - CFG_WITH_DEFENV { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to disable hardcoded paths" >&5 $as_echo_n "checking whether to disable hardcoded paths... " >&6; } # Check whether --enable-defenv was given. if test "${enable_defenv+set}" = set; then : enableval=$enable_defenv; case "${enableval}" in yes) CFG_WITH_DEFENV=yes ;; no) CFG_WITH_DEFENV=no ;; *) as_fn_error $? "bad value ${enableval} for --disable-defenv" "$LINENO" 5 ;; esac else CFG_WITH_DEFENV=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CFG_WITH_DEFENV" >&5 $as_echo "$CFG_WITH_DEFENV" >&6; } # Special Substitutions - CFG_WITH_CCWARN { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to show and stop on compilation warnings" >&5 $as_echo_n "checking whether to show and stop on compilation warnings... " >&6; } # Check whether --enable-ccwarn was given. if test "${enable_ccwarn+set}" = set; then : enableval=$enable_ccwarn; case "${enableval}" in yes) CFG_WITH_CCWARN=yes ;; no) CFG_WITH_CCWARN=no ;; *) as_fn_error $? "bad value ${enableval} for --enable-ccwarn" "$LINENO" 5 ;; esac else case "x${VERILATOR_AUTHOR_SITE}" in x) CFG_WITH_CCWARN=no ;; *) CFG_WITH_CCWARN=yes ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CFG_WITH_CCWARN" >&5 $as_echo "$CFG_WITH_CCWARN" >&6; } # Special Substitutions - CFG_WITH_LONGTESTS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to run long tests" >&5 $as_echo_n "checking whether to run long tests... " >&6; } # Check whether --enable-longtests was given. if test "${enable_longtests+set}" = set; then : enableval=$enable_longtests; case "${enableval}" in yes) CFG_WITH_LONGTESTS=yes ;; no) CFG_WITH_LONGTESTS=no ;; *) as_fn_error $? "bad value ${enableval} for --enable-longtests" "$LINENO" 5 ;; esac else case "x${VERILATOR_AUTHOR_SITE}" in x) CFG_WITH_LONGTESTS=no ;; *) CFG_WITH_LONGTESTS=yes ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CFG_WITH_LONGTESTS" >&5 $as_echo "$CFG_WITH_LONGTESTS" >&6; } # Compiler flags CFLAGS=-I${includedir} CPPFLAGS=-I${includedir} CXXFLAGS=-I${includedir} LDFLAGS=-L${libdir} # Checks for programs. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking that C++ compiler can compile simple program" >&5 $as_echo_n "checking that C++ compiler can compile simple program... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() { return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; };as_fn_error $? "a working C++ compiler is required" "$LINENO" 5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$PERL" = "x" ; then as_fn_error $? "Cannot find \"perl\" in your PATH, please install it" "$LINENO" 5 fi # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LEX+:} false; then : $as_echo_n "(cached) " >&6 else case $LEX in [\\/]* | ?:[\\/]*) ac_cv_path_LEX="$LEX" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_LEX="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi LEX=$ac_cv_path_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$LEX" = "x" ; then as_fn_error $? "Cannot find \"flex\" in your PATH, please install it" "$LINENO" 5 fi # Extract the first word of "bison", so it can be a program name with args. set dummy bison; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_YACC+:} false; then : $as_echo_n "(cached) " >&6 else case $YACC in [\\/]* | ?:[\\/]*) ac_cv_path_YACC="$YACC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_YACC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi YACC=$ac_cv_path_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$YACC" = "x" ; then as_fn_error $? "Cannot find \"bison\" in your PATH, please install it" "$LINENO" 5 fi # Checks for libraries. # Checks for typedefs, structures ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # Checks for compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac # _MY_CXX_CHECK_OPT # Flags for compiling Verilator internals including parser # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-unused-parameter -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-unused-parameter" >&5 $as_echo_n "checking whether $CXX accepts -Wno-unused-parameter... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused-parameter" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -Wno-unused-parameter" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-char-subscripts -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-char-subscripts" >&5 $as_echo_n "checking whether $CXX accepts -Wno-char-subscripts... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-char-subscripts" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -Wno-char-subscripts" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Qunused-arguments -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Qunused-arguments" >&5 $as_echo_n "checking whether $CXX accepts -Qunused-arguments... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Qunused-arguments" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -Qunused-arguments" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # Flags for compiling Verilator parser # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-unused -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-unused" >&5 $as_echo_n "checking whether $CXX accepts -Wno-unused... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_PARSER="$CFG_CXXFLAGS_PARSER -Wno-unused" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-parentheses-equality -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-parentheses-equality" >&5 $as_echo_n "checking whether $CXX accepts -Wno-parentheses-equality... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-parentheses-equality" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_PARSER="$CFG_CXXFLAGS_PARSER -Wno-parentheses-equality" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-null-conversion -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-null-conversion" >&5 $as_echo_n "checking whether $CXX accepts -Wno-null-conversion... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-null-conversion" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_PARSER="$CFG_CXXFLAGS_PARSER -Wno-null-conversion" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # Flags for Verilated makefile # For example, -Wno-div-by-zero isn't in 4.1.2 # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-char-subscripts -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-char-subscripts" >&5 $as_echo_n "checking whether $CXX accepts -Wno-char-subscripts... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-char-subscripts" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-char-subscripts" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-parentheses-equality -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-parentheses-equality" >&5 $as_echo_n "checking whether $CXX accepts -Wno-parentheses-equality... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-parentheses-equality" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-parentheses-equality" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn # without this flag, even though there's a conditional to prevent the divide. # We still don't add no-div-by-zero as it throws message to stdout, though doesn't die. #_MY_CXX_CHECK_OPT(-Wno-div-by-zero) # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-sign-compare -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-sign-compare" >&5 $as_echo_n "checking whether $CXX accepts -Wno-sign-compare... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-sign-compare" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-sign-compare" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-uninitialized -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-uninitialized" >&5 $as_echo_n "checking whether $CXX accepts -Wno-uninitialized... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-uninitialized" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-uninitialized" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-unused-but-set-variable -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-unused-but-set-variable" >&5 $as_echo_n "checking whether $CXX accepts -Wno-unused-but-set-variable... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused-but-set-variable" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-unused-but-set-variable" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-unused-parameter -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-unused-parameter" >&5 $as_echo_n "checking whether $CXX accepts -Wno-unused-parameter... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused-parameter" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-unused-parameter" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Wno-unused-variable -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-unused-variable" >&5 $as_echo_n "checking whether $CXX accepts -Wno-unused-variable... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Wno-unused-variable" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-unused-variable" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -fbracket-depth=4096 -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -fbracket-depth=4096" >&5 $as_echo_n "checking whether $CXX accepts -fbracket-depth=4096... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-fbracket-depth=4096" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -fbracket-depth=4096" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options ACO_SAVE_CXXFLAGS="$CXXFLAGS" # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems CXXFLAGS="$CXXFLAGS -Qunused-arguments -Werror" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Qunused-arguments" >&5 $as_echo_n "checking whether $CXX accepts -Qunused-arguments... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : _my_result=yes if test -s conftest.err; then if grep -e "-Qunused-arguments" conftest.err >/dev/null; then _my_result=no fi fi else _my_result=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5 $as_echo "$_my_result" >&6; } if test "$_my_result" = "yes" ; then CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Qunused-arguments" fi CXXFLAGS="$ACO_SAVE_CXXFLAGS" # Checks for library functions. # Checks for system services # Other install directories pkgdatadir=${datadir}/verilator pkgconfigdir=${datadir}/pkgconfig cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Verilator $as_me 3.874 2015-06-06, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ Verilator config.status 3.874 2015-06-06 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/config_build.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config_build.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/Makefile_obj") CONFIG_FILES="$CONFIG_FILES src/Makefile_obj" ;; "include/verilated.mk") CONFIG_FILES="$CONFIG_FILES include/verilated.mk" ;; "include/verilated_config.h") CONFIG_FILES="$CONFIG_FILES include/verilated_config.h" ;; "verilator.pc") CONFIG_FILES="$CONFIG_FILES verilator.pc" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Now type 'make' (or sometimes 'gmake') to build Verilator." >&5 $as_echo "Now type 'make' (or sometimes 'gmake') to build Verilator." >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } verilator-3.874/include/0000775000177100017500000000000012534632370015153 5ustar wsnyderwsnyderverilator-3.874/include/verilated_vpi.cpp0000664000177100017500000002222212525171733020515 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //========================================================================= /// /// \file /// \brief Verilator: VPI implementation code /// /// This file must be compiled and linked against all objects /// created from Verilator or called by Verilator that use the VPI. /// /// Code available from: http://www.veripool.org/verilator /// //========================================================================= #include "verilated_vpi.h" //====================================================================== VerilatedVpi VerilatedVpi::s_s; // Singleton vluint8_t* VerilatedVpio::s_freeHead = NULL; //====================================================================== const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) { static const char *names[] = { "*undefined*", "vpiBinStrVal", "vpiOctStrVal", "vpiDecStrVal", "vpiHexStrVal", "vpiScalarVal", "vpiIntVal", "vpiRealVal", "vpiStringVal", "vpiVectorVal", "vpiStrengthVal", "vpiTimeVal", "vpiObjTypeVal", "vpiSuppressVal", "vpiShortIntVal", "vpiLongIntVal", "vpiShortRealVal", "vpiRawTwoStateVal", "vpiRawFourStateVal", }; if (vpiVal < 0) return names[0]; return names[(vpiVal<=vpiRawFourStateVal)?vpiVal:0]; } const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) { static const char *names[] = { "*undefined*", "vpiAlways", "vpiAssignStmt", "vpiAssignment", "vpiBegin", "vpiCase", "vpiCaseItem", "vpiConstant", "vpiContAssign", "vpiDeassign", "vpiDefParam", "vpiDelayControl", "vpiDisable", "vpiEventControl", "vpiEventStmt", "vpiFor", "vpiForce", "vpiForever", "vpiFork", "vpiFuncCall", "vpiFunction", "vpiGate", "vpiIf", "vpiIfElse", "vpiInitial", "vpiIntegerVar", "vpiInterModPath", "vpiIterator", "vpiIODecl", "vpiMemory", "vpiMemoryWord", "vpiModPath", "vpiModule", "vpiNamedBegin", "vpiNamedEvent", "vpiNamedFork", "vpiNet", "vpiNetBit", "vpiNullStmt", "vpiOperation", "vpiParamAssign", "vpiParameter", "vpiPartSelect", "vpiPathTerm", "vpiPort", "vpiPortBit", "vpiPrimTerm", "vpiRealVar", "vpiReg", "vpiRegBit", "vpiRelease", "vpiRepeat", "vpiRepeatControl", "vpiSchedEvent", "vpiSpecParam", "vpiSwitch", "vpiSysFuncCall", "vpiSysTaskCall", "vpiTableEntry", "vpiTask", "vpiTaskCall", "vpiTchk", "vpiTchkTerm", "vpiTimeVar", "vpiTimeQueue", "vpiUdp", "vpiUdpDefn", "vpiUserSystf", "vpiVarSelect", "vpiWait", "vpiWhile", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "vpiAttribute", "vpiBitSelect", "vpiCallback", "vpiDelayTerm", "vpiDelayDevice", "vpiFrame", "vpiGateArray", "vpiModuleArray", "vpiPrimitiveArray", "vpiNetArray", "vpiRange", "vpiRegArray", "vpiSwitchArray", "vpiUdpArray", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "*undefined*", "vpiContAssignBit", "vpiNamedEventArray", "vpiIndexedPartSelect", "*undefined*", "*undefined*", "vpiGenScopeArray", "vpiGenScope", "vpiGenVar" }; if (vpiVal < 0) return names[0]; return names[(vpiVal<=vpiGenVar)?vpiVal:0]; } const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) { static const char *names[] = { "vpiCondition", "vpiDelay", "vpiElseStmt", "vpiForIncStmt", "vpiForInitStmt", "vpiHighConn", "vpiLhs", "vpiIndex", "vpiLeftRange", "vpiLowConn", "vpiParent", "vpiRhs", "vpiRightRange", "vpiScope", "vpiSysTfCall", "vpiTchkDataTerm", "vpiTchkNotifier", "vpiTchkRefTerm", "vpiArgument", "vpiBit", "vpiDriver", "vpiInternalScope", "vpiLoad", "vpiModDataPathIn", "vpiModPathIn", "vpiModPathOut", "vpiOperand", "vpiPortInst", "vpiProcess", "vpiVariables", "vpiUse", "vpiExpr", "vpiPrimitive", "vpiStmt" }; if (vpiVal>vpiStmt || vpiVal $@ $(VM_PREFIX)__ALLsup.cpp: $(VK_SUPPORT_CPP) $(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@ else #Slow way of building... Each .cpp file by itself VK_OBJS += $(addsuffix .o, $(VM_CLASSES) $(VM_SUPPORT)) endif $(VM_PREFIX)__ALL.a: $(VK_OBJS) @echo " Archiving" $@ ... $(AR) r $@ $^ $(RANLIB) $@ ###################################################################### ### Compile rules #Default rule embedded in make: (Not defined so user makefiles can override it) #.cpp.o: # $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $< $(VM_PREFIX)__ALLsup.o: $(VM_PREFIX)__ALLsup.cpp $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $< $(VM_PREFIX)__ALLcls.o: $(VM_PREFIX)__ALLcls.cpp $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $< ###################################################################### ### Debugging debug-make:: @echo @echo VM_PREFIX: $(VM_PREFIX) @echo VM_CLASSES_FAST: $(VM_CLASSES_FAST) @echo VM_CLASSES_SLOW: $(VM_CLASSES_SLOW) @echo VM_SUPPORT_FAST: $(VM_SUPPORT_FAST) @echo VM_SUPPORT_SLOW: $(VM_SUPPORT_SLOW) @echo VM_GLOBAL_FAST: $(VM_GLOBAL_FAST) @echo VM_GLOBAL_SLOW: $(VM_GLOBAL_SLOW) @echo CPPFLAGS: $(CPPFLAGS) @echo ###################################################################### ### Detect out of date files and rebuild. DEPS := $(wildcard *.d) ifneq ($(DEPS),) include $(DEPS) endif verilator-3.874/include/verilated_cov_key.h0000664000177100017500000001561412525172076021033 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2015 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. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief Coverage item keys /// //============================================================================= #ifndef _VERILATED_COV_KEY_H_ #define _VERILATED_COV_KEY_H_ 1 #include "verilatedos.h" #include using namespace std; //============================================================================= // Data used to edit below file, using vlcovgen #define VLCOVGEN_ITEM(string_parsed_by_vlcovgen) VLCOVGEN_ITEM("name=>'col0_name', short=>'C0', group=>1, default=>undef, descr=>'The column title for the header line of this column'") VLCOVGEN_ITEM("name=>'col1_name', short=>'C1', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'col2_name', short=>'C2', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'col3_name', short=>'C3', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'column', short=>'n', group=>1, default=>0, descr=>'Column number for the item. Used to disambiguate multiple coverage points on the same line number'") VLCOVGEN_ITEM("name=>'filename', short=>'f', group=>1, default=>undef, descr=>'Filename of the item'") VLCOVGEN_ITEM("name=>'groupdesc', short=>'d', group=>1, default=>'', descr=>'Description of the covergroup this item belongs to'") VLCOVGEN_ITEM("name=>'groupname', short=>'g', group=>1, default=>'', descr=>'Group name of the covergroup this item belongs to'") VLCOVGEN_ITEM("name=>'groupcmt', short=>'O', group=>1, default=>'', ") VLCOVGEN_ITEM("name=>'per_instance',short=>'P', group=>1, default=>0, descr=>'True if every hierarchy is independently counted; otherwise all hierarchies will be combined into a single count'") VLCOVGEN_ITEM("name=>'row0_name', short=>'R0', group=>1, default=>undef, descr=>'The row title for the header line of this row'") VLCOVGEN_ITEM("name=>'row1_name', short=>'R1', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'row2_name', short=>'R2', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'row3_name', short=>'R3', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'table', short=>'T', group=>1, default=>undef, descr=>'The name of the table for automatically generated tables'") VLCOVGEN_ITEM("name=>'thresh', short=>'s', group=>1, default=>undef, ") VLCOVGEN_ITEM("name=>'type', short=>'t', group=>1, default=>'', descr=>'Type of coverage (block, line, fsm, etc)'") // Bin attributes VLCOVGEN_ITEM("name=>'col0', short=>'c0', group=>0, default=>undef, descr=>'The (enumeration) value name for this column in a table cross' ") VLCOVGEN_ITEM("name=>'col1', short=>'c1', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'col2', short=>'c2', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'col3', short=>'c3', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'comment', short=>'o', group=>0, default=>'', descr=>'Textual description for the item'") VLCOVGEN_ITEM("name=>'hier', short=>'h', group=>0, default=>'', descr=>'Hierarchy path name for the item'") VLCOVGEN_ITEM("name=>'limit', short=>'L', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'lineno', short=>'l', group=>0, default=>0, descr=>'Line number for the item'") VLCOVGEN_ITEM("name=>'row0', short=>'r0', group=>0, default=>undef, descr=>'The (enumeration) value name for this row in a table cross'") VLCOVGEN_ITEM("name=>'row1', short=>'r1', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'row2', short=>'r2', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'row3', short=>'r3', group=>0, default=>undef, ") VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr=>'For totaling items, weight of this item'") //============================================================================= // VerilatedCovKey /// Verilator coverage global class //// /// Global class with methods affecting all coverage data. // VLCOVGEN_CIK_AUTO_EDIT_BEGIN #define VL_CIK_COL0 "c0" #define VL_CIK_COL0_NAME "C0" #define VL_CIK_COL1 "c1" #define VL_CIK_COL1_NAME "C1" #define VL_CIK_COL2 "c2" #define VL_CIK_COL2_NAME "C2" #define VL_CIK_COL3 "c3" #define VL_CIK_COL3_NAME "C3" #define VL_CIK_COLUMN "n" #define VL_CIK_COMMENT "o" #define VL_CIK_FILENAME "f" #define VL_CIK_GROUPCMT "O" #define VL_CIK_GROUPDESC "d" #define VL_CIK_GROUPNAME "g" #define VL_CIK_HIER "h" #define VL_CIK_LIMIT "L" #define VL_CIK_LINENO "l" #define VL_CIK_PER_INSTANCE "P" #define VL_CIK_ROW0 "r0" #define VL_CIK_ROW0_NAME "R0" #define VL_CIK_ROW1 "r1" #define VL_CIK_ROW1_NAME "R1" #define VL_CIK_ROW2 "r2" #define VL_CIK_ROW2_NAME "R2" #define VL_CIK_ROW3 "r3" #define VL_CIK_ROW3_NAME "R3" #define VL_CIK_TABLE "T" #define VL_CIK_THRESH "s" #define VL_CIK_TYPE "t" #define VL_CIK_WEIGHT "w" // VLCOVGEN_CIK_AUTO_EDIT_END class VerilatedCovKey { public: static string shortKey(const string& key) { // VLCOVGEN_SHORT_AUTO_EDIT_BEGIN if (key == "col0") return VL_CIK_COL0; if (key == "col0_name") return VL_CIK_COL0_NAME; if (key == "col1") return VL_CIK_COL1; if (key == "col1_name") return VL_CIK_COL1_NAME; if (key == "col2") return VL_CIK_COL2; if (key == "col2_name") return VL_CIK_COL2_NAME; if (key == "col3") return VL_CIK_COL3; if (key == "col3_name") return VL_CIK_COL3_NAME; if (key == "column") return VL_CIK_COLUMN; if (key == "comment") return VL_CIK_COMMENT; if (key == "filename") return VL_CIK_FILENAME; if (key == "groupcmt") return VL_CIK_GROUPCMT; if (key == "groupdesc") return VL_CIK_GROUPDESC; if (key == "groupname") return VL_CIK_GROUPNAME; if (key == "hier") return VL_CIK_HIER; if (key == "limit") return VL_CIK_LIMIT; if (key == "lineno") return VL_CIK_LINENO; if (key == "per_instance") return VL_CIK_PER_INSTANCE; if (key == "row0") return VL_CIK_ROW0; if (key == "row0_name") return VL_CIK_ROW0_NAME; if (key == "row1") return VL_CIK_ROW1; if (key == "row1_name") return VL_CIK_ROW1_NAME; if (key == "row2") return VL_CIK_ROW2; if (key == "row2_name") return VL_CIK_ROW2_NAME; if (key == "row3") return VL_CIK_ROW3; if (key == "row3_name") return VL_CIK_ROW3_NAME; if (key == "table") return VL_CIK_TABLE; if (key == "thresh") return VL_CIK_THRESH; if (key == "type") return VL_CIK_TYPE; if (key == "weight") return VL_CIK_WEIGHT; // VLCOVGEN_SHORT_AUTO_EDIT_END return key; } }; #endif // guard verilator-3.874/include/.gitignore0000664000177100017500000000004012436222044017127 0ustar wsnyderwsnyderverilated.mk verilated_config.h verilator-3.874/include/verilated.v0000664000177100017500000000217612525171733017330 0ustar wsnyderwsnyder//************************************************************************* // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2015 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. // // This is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //========================================================================= // // DESCRIPTION: Verilator: Include in verilog files to hide verilator defines `ifdef _VERILATED_V_ `else `define _VERILATED_V_ 1 // Hide verilator pragmas from other tools `ifdef VERILATOR `else `define coverage_block_off `endif // Hide file descriptor difference - deprecated - for older versions `define verilator_file_descriptor integer `endif // guard verilator-3.874/include/verilated.cpp0000664000177100017500000012364312525171733017650 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //========================================================================= /// /// \file /// \brief Verilator: Linked against all applications using Verilated source. /// /// This file must be compiled and linked against all objects /// created from Verilator. /// /// Code available from: http://www.veripool.org/verilator /// //========================================================================= #define _VERILATED_CPP_ #include "verilated_imp.h" #include #define VL_VALUE_STRING_MAX_WIDTH 8192 ///< Max static char array for VL_VALUE_STRING //=========================================================================== // Global variables // Slow path variables VerilatedVoidCb Verilated::s_flushCb = NULL; // Keep below together in one cache line Verilated::Serialized Verilated::s_s; VL_THREAD const VerilatedScope* Verilated::t_dpiScopep = NULL; VL_THREAD const char* Verilated::t_dpiFilename = ""; VL_THREAD int Verilated::t_dpiLineno = 0; struct Verilated::CommandArgValues Verilated::s_args = {0, NULL}; VerilatedImp VerilatedImp::s_s; //=========================================================================== // User definable functions #ifndef VL_USER_FINISH // Define this to override this function void vl_finish (const char* filename, int linenum, const char* hier) { if (0 && hier) {} VL_PRINTF("- %s:%d: Verilog $finish\n", filename, linenum); if (Verilated::gotFinish()) { VL_PRINTF("- %s:%d: Second verilog $finish, exiting\n", filename, linenum); Verilated::flushCall(); exit(0); } Verilated::gotFinish(true); } #endif #ifndef VL_USER_STOP // Define this to override this function void vl_stop (const char* filename, int linenum, const char* hier) { Verilated::gotFinish(true); Verilated::flushCall(); vl_fatal (filename,linenum,hier,"Verilog $stop"); } #endif #ifndef VL_USER_FATAL // Define this to override this function void vl_fatal (const char* filename, int linenum, const char* hier, const char* msg) { if (0 && hier) {} Verilated::gotFinish(true); VL_PRINTF("%%Error: %s:%d: %s\n", filename, linenum, msg); Verilated::flushCall(); VL_PRINTF("Aborting...\n"); Verilated::flushCall(); // Second flush in case VL_PRINTF does something needing a flush abort(); } #endif //=========================================================================== // Overall class init Verilated::Serialized::Serialized() { s_randReset = 0; s_debug = 0; s_calcUnusedSigs = false; s_gotFinish = false; s_assertOn = true; s_fatalOnVpiError = true; // retains old default behaviour } //=========================================================================== // Random reset -- Only called at init time, so don't inline. IData VL_RAND32() { #if defined(_WIN32) && !defined(__CYGWIN__) // Windows doesn't have lrand48(), although Cygwin does. return (rand()<<16) ^ rand(); #else return (lrand48()<<16) ^ lrand48(); #endif } IData VL_RANDOM_I(int obits) { return VL_RAND32() & VL_MASK_I(obits); } QData VL_RANDOM_Q(int obits) { QData data = ((QData)VL_RAND32()<=0; i--) { VL_PRINTF("%08x ",iwp[i]); } VL_PRINTF("\n"); } //=========================================================================== // Slow math WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool is_modulus) { // See Knuth Algorithm D. Computes u/v = q.r // This isn't massively tuned, as wide division is rare // for debug see V3Number version // Requires clean input int words = VL_WORDS_I(lbits); for (int i=0; i= 0; j--) { vluint64_t unw64 = ((k<> 32 won't mask the value for (int i = vw-1; i>0; i--) { vn[i] = (rwp[i] << s) | (shift_mask & (rwp[i-1] >> (32-s))); } vn[0] = rwp[0] << s; // Copy and shift dividend by same amount; may set new upper word if (s) un[uw] = lwp[uw-1] >> (32-s); else un[uw] = 0; for (int i=uw-1; i>0; i--) { un[i] = (lwp[i] << s) | (shift_mask & (lwp[i-1] >> (32-s))); } un[0] = lwp[0] << s; // Main loop for (int j = uw - vw; j >= 0; j--) { // Estimate vluint64_t unw64 = ((vluint64_t)(un[j+vw])<= VL_ULL(0x100000000) || ((qhat*vn[vw-2]) > ((rhat<> VL_ULL(32)) - (t >> VL_ULL(32)); } t = un[j+vw] - k; un[j+vw] = t; owp[j] = qhat; // Save quotient digit if (t < 0) { // Over subtracted; correct by adding back owp[j]--; k = 0; for (int i=0; i> VL_ULL(32); } un[j+vw] = un[j+vw] + k; } } if (is_modulus) { // modulus // Need to reverse normalization on copy to output for (int i=0; i> s) | (shift_mask & (un[i+1] << (32-s))); } for (int i=vw; i=0; lsb--) { lsb = (lsb / 8) * 8; // Next digit IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff; output += (charval==0)?' ':charval; } break; case 'd': { // Signed decimal int digits=sprintf(tmp,"%" VL_PRI64 "d",(vlsint64_t)(VL_EXTENDS_QQ(lbits,lbits,ld))); int needmore = width-digits; if (needmore>0) { if (pctp && pctp[0] && pctp[1]=='0') { //%0 output.append(needmore,'0'); // Pre-pad zero } else { output.append(needmore,' '); // Pre-pad spaces } } output += tmp; break; } case 'u': { // Unsigned decimal int digits=sprintf(tmp,"%" VL_PRI64 "u",ld); int needmore = width-digits; if (needmore>0) { if (pctp && pctp[0] && pctp[1]=='0') { //%0 output.append(needmore,'0'); // Pre-pad zero } else { output.append(needmore,' '); // Pre-pad spaces } } output += tmp; break; } case 't': { // Time int digits; if (VL_TIME_MULTIPLIER==1) { digits=sprintf(tmp,"%" VL_PRI64 "u",ld); } else if (VL_TIME_MULTIPLIER==1000) { digits=sprintf(tmp,"%" VL_PRI64 "u.%03" VL_PRI64 "u", (QData)(ld/VL_TIME_MULTIPLIER), (QData)(ld%VL_TIME_MULTIPLIER)); } else { vl_fatal(__FILE__,__LINE__,"","Unsupported VL_TIME_MULTIPLIER"); } int needmore = width-digits; if (needmore>0) output.append(needmore,' '); // Pre-pad spaces output += tmp; break; } case 'b': for (; lsb>=0; lsb--) { output += ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0'; } break; case 'o': for (; lsb>=0; lsb--) { lsb = (lsb / 3) * 3; // Next digit // Octal numbers may span more than one wide word, // so we need to grab each bit separately and check for overrun // Octal is rare, so we'll do it a slow simple way output += ('0' + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+0)) ? 1 : 0) + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+1)) ? 2 : 0) + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+2)) ? 4 : 0)); } break; case 'x': for (; lsb>=0; lsb--) { lsb = (lsb / 4) * 4; // Next digit IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xf; output += "0123456789abcdef"[charval]; } break; default: string msg = string("Unknown _vl_vsformat code: ")+pos[0]; vl_fatal(__FILE__,__LINE__,"",msg.c_str()); break; } // switch } } // switch } } } static inline bool _vl_vsss_eof(FILE* fp, int& floc) { if (fp) return feof(fp) ? 1 : 0; // 1:0 to prevent MSVC++ warning else return (floc<0); } static inline void _vl_vsss_advance(FILE* fp, int& floc) { if (fp) fgetc(fp); else floc -= 8; } static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const string& fstr) { // Get a character without advancing if (fp) { int data = fgetc(fp); if (data == EOF) return EOF; ungetc(data,fp); return data; } else { if (floc < 0) return EOF; floc = floc & ~7; // Align to closest character if (fromp == NULL) { return fstr[fstr.length()-1 - (floc>>3)]; } else { return (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff; } } } static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp, const string& fstr) { while (1) { int c = _vl_vsss_peek(fp, floc, fromp, fstr); if (c==EOF || !isspace(c)) return; _vl_vsss_advance(fp, floc); } } static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const string& fstr, char* tmpp, const char* acceptp) { // Read into tmp, consisting of characters from acceptp list char* cp = tmpp; while (1) { int c = _vl_vsss_peek(fp, floc, fromp, fstr); if (c==EOF || isspace(c)) break; if (acceptp!=NULL // String - allow anything && NULL==strchr(acceptp, c)) break; if (acceptp!=NULL) c = tolower(c); // Non-strings we'll simplify *cp++ = c; _vl_vsss_advance(fp, floc); } *cp++ = '\0'; //VL_PRINTF("\t_read got='%s'\n", tmpp); } static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits, IData ld) { for (; nbits && lsb>=1) { VL_ASSIGNBIT_WI(0, lsb, owp, ld & 1); } } static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp, int posstart, int posend) { // Read in base "2^^baseLog2" digits from strp[posstart..posend-1] into owp of size obits. int lsb = 0; for (int i=0, pos=posend-1; i=posstart; pos--) { switch (tolower (strp[pos])) { case 'x': case 'z': case '?': //FALLTHRU case '0': lsb += baseLog2; break; case '1': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 1); lsb+=baseLog2; break; case '2': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 2); lsb+=baseLog2; break; case '3': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 3); lsb+=baseLog2; break; case '4': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 4); lsb+=baseLog2; break; case '5': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 5); lsb+=baseLog2; break; case '6': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 6); lsb+=baseLog2; break; case '7': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 7); lsb+=baseLog2; break; case '8': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 8); lsb+=baseLog2; break; case '9': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 9); lsb+=baseLog2; break; case 'a': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 10); lsb+=baseLog2; break; case 'b': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 11); lsb+=baseLog2; break; case 'c': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 12); lsb+=baseLog2; break; case 'd': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 13); lsb+=baseLog2; break; case 'e': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 14); lsb+=baseLog2; break; case 'f': _vl_vsss_setbit(owp,obits,lsb, baseLog2, 15); lsb+=baseLog2; break; case '_': break; } } } IData _vl_vsscanf(FILE* fp, // If a fscanf int fbits, WDataInP fromp, // Else if a sscanf const string& fstr, // if a sscanf to string const char* formatp, va_list ap) { // Read a Verilog $sscanf/$fscanf style format into the output list // The format must be pre-processed (and lower cased) by Verilator // Arguments are in "width, arg-value (or WDataIn* if wide)" form static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH]; int floc = fbits - 1; IData got = 0; bool inPct = false; const char* pos = formatp; for (; *pos && !_vl_vsss_eof(fp,floc); ++pos) { //VL_PRINTF("_vlscan fmt='%c' floc=%d file='%c'\n", pos[0], floc, _vl_vsss_peek(fp,floc,fromp,fstr)); if (!inPct && pos[0]=='%') { inPct = true; } else if (!inPct && isspace(pos[0])) { // Format spaces while (isspace(pos[1])) pos++; _vl_vsss_skipspace(fp,floc,fromp,fstr); } else if (!inPct) { // Expected Format _vl_vsss_skipspace(fp,floc,fromp,fstr); int c = _vl_vsss_peek(fp,floc,fromp,fstr); if (c != pos[0]) goto done; else _vl_vsss_advance(fp,floc); } else { // Format character // Skip loading spaces inPct = false; char fmt = pos[0]; switch (fmt) { case '%': { int c = _vl_vsss_peek(fp,floc,fromp,fstr); if (c != '%') goto done; else _vl_vsss_advance(fp,floc); break; } default: { // Deal with all read-and-scan somethings // Note LSBs are preserved if there's an overflow const int obits = va_arg(ap, int); WData qowp[2]; WDataOutP owp = qowp; if (obits > VL_QUADSIZE) { owp = va_arg(ap,WDataOutP); } for (int i=0; i=0; pos--) { _vl_vsss_setbit(owp,obits,lsb, 8, tmp[pos]); lsb+=8; } break; } case 'd': { // Signed decimal _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789+-xXzZ?_"); if (!tmp[0]) goto done; vlsint64_t ld; sscanf(tmp,"%30" VL_PRI64 "d",&ld); VL_SET_WQ(owp,ld); break; } case 'f': case 'e': case 'g': { // Real number _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "+-.0123456789eE"); if (!tmp[0]) goto done; union { double r; vlsint64_t ld; } u; u.r = strtod(tmp, NULL); VL_SET_WQ(owp,u.ld); break; } case 't': // FALLTHRU // Time case 'u': { // Unsigned decimal _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789+-xXzZ?_"); if (!tmp[0]) goto done; QData ld; sscanf(tmp,"%30" VL_PRI64 "u",&ld); VL_SET_WQ(owp,ld); break; } case 'b': { _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "01xXzZ?_"); if (!tmp[0]) goto done; _vl_vsss_based(owp,obits, 1, tmp, 0, (int)strlen(tmp)); break; } case 'o': { _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "01234567xXzZ?_"); if (!tmp[0]) goto done; _vl_vsss_based(owp,obits, 3, tmp, 0, (int)strlen(tmp)); break; } case 'x': { _vl_vsss_skipspace(fp,floc,fromp,fstr); _vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789abcdefABCDEFxXzZ?_"); if (!tmp[0]) goto done; _vl_vsss_based(owp,obits, 4, tmp, 0, (int)strlen(tmp)); break; } default: string msg = string("Unknown _vl_vsscanf code: ")+pos[0]; vl_fatal(__FILE__,__LINE__,"",msg.c_str()); break; } // switch got++; // Reload data if non-wide (if wide, we put it in the right place directly) if (obits <= VL_BYTESIZE) { CData* p = va_arg(ap,CData*); *p = owp[0]; } else if (obits <= VL_SHORTSIZE) { SData* p = va_arg(ap,SData*); *p = owp[0]; } else if (obits <= VL_WORDSIZE) { IData* p = va_arg(ap,IData*); *p = owp[0]; } else if (obits <= VL_QUADSIZE) { QData* p = va_arg(ap,QData*); *p = VL_SET_QW(owp); } } } // switch } } done: return got; } //=========================================================================== // File I/O FILE* VL_CVT_I_FP(IData lhs) { return VerilatedImp::fdToFp(lhs); } void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) { // See also VL_DATA_TO_STRING_NW int lsb=obits-1; bool start=true; char* destp = destoutp; for (; lsb>=0; lsb--) { lsb = (lsb / 8) * 8; // Next digit IData charval = (sourcep[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff; if (!start || charval) { *destp++ = (charval==0)?' ':charval; start = false; // Drop leading 0s } } *destp++ = '\0'; // Terminate while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces } void _VL_STRING_TO_VINT(int obits, void* destp, int srclen, const char* srcp) { // Convert C string to Verilog format int bytes = VL_BYTES_I(obits); char* op = ((char*)(destp)); if (srclen > bytes) srclen = bytes; // Don't overflow destination int i; for (i=0; i VL_TO_STRING_MAX_WORDS*VL_WORDSIZE)) { vl_fatal(__FILE__,__LINE__,"","Internal: fgets buffer overrun"); } // We don't use fgets, as we must read \0s. IData got = 0; char* cp = buffer; while (got < bytes) { int c = getc(fp); if (c==EOF) break; *cp++ = c; got++; if (c=='\n') break; } _VL_STRING_TO_VINT(obits, destp, got, buffer); return got; } IData VL_FOPEN_QI(QData filename, IData mode) { IData fnw[2]; VL_SET_WQ(fnw, filename); return VL_FOPEN_WI(2, fnw, mode); } IData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) { char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1]; _VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, filenamez, filenamep); char modez[5]; _VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode); return VL_FOPEN_S(filenamez,modez); } IData VL_FOPEN_S(const char* filenamep, const char* modep) { return VerilatedImp::fdNew(fopen(filenamep,modep)); } void VL_FCLOSE_I(IData fdi) { FILE* fp = VL_CVT_I_FP(fdi); if (VL_UNLIKELY(!fp)) return; fclose(fp); VerilatedImp::fdDelete(fdi); } void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) { VL_STATIC_OR_THREAD string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); _VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str()); } void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) { VL_STATIC_OR_THREAD string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); _VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str()); } void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) { VL_STATIC_OR_THREAD string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); _VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str()); } void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) { VL_STATIC_OR_THREAD string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); _VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str()); } void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) { VL_STATIC_OR_THREAD string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); _VL_STRING_TO_VINT(obits, destp, (int)output.length(), output.c_str()); } void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...) { if (obits_ignored) {} output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); } string VL_SFORMATF_NX(const char* formatp, ...) { VL_STATIC_OR_THREAD string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); return output; } void VL_WRITEF(const char* formatp, ...) { VL_STATIC_OR_THREAD string output; // static only for speed output = ""; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); // Users can redefine VL_PRINTF if they wish. VL_PRINTF("%s", output.c_str()); } void VL_FWRITEF(IData fpi, const char* formatp, ...) { VL_STATIC_OR_THREAD string output; // static only for speed output = ""; FILE* fp = VL_CVT_I_FP(fpi); if (VL_UNLIKELY(!fp)) return; va_list ap; va_start(ap,formatp); _vl_vsformat(output, formatp, ap); va_end(ap); fputs(output.c_str(), fp); } IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) { FILE* fp = VL_CVT_I_FP(fpi); if (VL_UNLIKELY(!fp)) return 0; va_list ap; va_start(ap,formatp); IData got = _vl_vsscanf(fp, 0, NULL, "", formatp, ap); va_end(ap); return got; } IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) { IData fnw[2]; VL_SET_WI(fnw, ld); va_list ap; va_start(ap,formatp); IData got = _vl_vsscanf(NULL, lbits, fnw, "", formatp, ap); va_end(ap); return got; } IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) { IData fnw[2]; VL_SET_WQ(fnw, ld); va_list ap; va_start(ap,formatp); IData got = _vl_vsscanf(NULL, lbits, fnw, "", formatp, ap); va_end(ap); return got; } IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...) { va_list ap; va_start(ap,formatp); IData got = _vl_vsscanf(NULL, lbits, lwp, "", formatp, ap); va_end(ap); return got; } IData VL_SSCANF_INX(int, const string& ld, const char* formatp, ...) { va_list ap; va_start(ap,formatp); IData got = _vl_vsscanf(NULL, ld.length()*8, NULL, ld, formatp, ap); va_end(ap); return got; } void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int, QData ofilename, void* memp, IData start, IData end) { IData fnw[2]; VL_SET_WQ(fnw, ofilename); return VL_READMEM_W(hex,width,depth,array_lsb,2, fnw,memp,start,end); } void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords, WDataInP ofilenamep, void* memp, IData start, IData end) { char ofilenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1]; _VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, ofilenamez, ofilenamep); FILE* fp = fopen(ofilenamez, "r"); if (VL_UNLIKELY(!fp)) { // We don't report the Verilog source filename as it slow to have to pass it down vl_fatal (ofilenamez, 0, "", "$readmem file not found"); return; } // Prep for reading IData addr = start; int linenum = 1; bool innum = false; bool ignore_to_eol = false; bool ignore_to_cmt = false; bool needinc = false; bool reading_addr = false; int lastc = ' '; // Read the data // We process a character at a time, as then we don't need to deal // with changing buffer sizes dynamically, etc. while (1) { int c = fgetc(fp); if (VL_UNLIKELY(c==EOF)) break; //printf("%d: Got '%c' Addr%x IN%d IgE%d IgC%d ninc%d\n", linenum, c, addr, innum, ignore_to_eol, ignore_to_cmt, needinc); if (c=='\n') { linenum++; ignore_to_eol=false; if (innum) reading_addr=false; innum=false; } else if (c=='\t' || c==' ' || c=='\r' || c=='\f') { if (innum) reading_addr=false; innum=false; } // Skip // comments and detect /* comments else if (ignore_to_cmt && lastc=='*' && c=='/') { ignore_to_cmt = false; if (innum) reading_addr=false; innum=false; } else if (!ignore_to_eol && !ignore_to_cmt) { if (lastc=='/' && c=='*') { ignore_to_cmt = true; } else if (lastc=='/' && c=='/') { ignore_to_eol = true; } else if (c=='/') {} // Part of /* or // else if (c=='_') {} else if (c=='@') { reading_addr = true; innum=false; needinc=false; } // Check for hex or binary digits as file format requests else if (isxdigit(c)) { c = tolower(c); int value = (c >= 'a' ? (c-'a'+10) : (c-'0')); if (!innum) { // Prep for next number if (needinc) { addr++; needinc=false; } } if (reading_addr) { // Decode @ addresses if (!innum) addr=0; addr = (addr<<4) + value; } else { needinc = true; //printf(" Value width=%d @%x = %c\n", width, addr, c); if (VL_UNLIKELY(addr >= (IData)(depth+array_lsb) || addr < (IData)(array_lsb))) { vl_fatal (ofilenamez, linenum, "", "$readmem file address beyond bounds of array"); } else { int entry = addr - array_lsb; QData shift = hex ? VL_ULL(4) : VL_ULL(1); // Shift value in if (width<=8) { CData* datap = &((CData*)(memp))[entry]; if (!innum) { *datap = 0; } *datap = ((*datap << shift) + value) & VL_MASK_I(width); } else if (width<=16) { SData* datap = &((SData*)(memp))[entry]; if (!innum) { *datap = 0; } *datap = ((*datap << shift) + value) & VL_MASK_I(width); } else if (width<=VL_WORDSIZE) { IData* datap = &((IData*)(memp))[entry]; if (!innum) { *datap = 0; } *datap = ((*datap << shift) + value) & VL_MASK_I(width); } else if (width<=VL_QUADSIZE) { QData* datap = &((QData*)(memp))[entry]; if (!innum) { *datap = 0; } *datap = ((*datap << (QData)(shift)) + (QData)(value)) & VL_MASK_Q(width); } else { WDataOutP datap = &((WDataOutP)(memp))[ entry*VL_WORDS_I(width) ]; if (!innum) { VL_ZERO_RESET_W(width, datap); } _VL_SHIFTL_INPLACE_W(width, datap, (IData)shift); datap[0] |= value; } if (VL_UNLIKELY(value>=(1<> 8; // Want exit status } IData VL_TESTPLUSARGS_I(const char* formatp) { const string& match = VerilatedImp::argPlusMatch(formatp); if (match == "") return 0; else return 1; } IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp) { const string& match = VerilatedImp::argPlusMatch(prefixp); const char* dp = match.c_str() + 1 /*leading + */ + strlen(prefixp); if (match == "") return 0; VL_ZERO_RESET_W(rbits, rwp); switch (tolower(fmt)) { case '%': break; case 'd': vlsint64_t ld; sscanf(dp,"%30" VL_PRI64 "d",&ld); VL_SET_WQ(rwp,ld); break; case 'b': _vl_vsss_based(rwp,rbits, 1, dp, 0, (int)strlen(dp)); break; case 'o': _vl_vsss_based(rwp,rbits, 3, dp, 0, (int)strlen(dp)); break; case 'h': //FALLTHRU case 'x': _vl_vsss_based(rwp,rbits, 4, dp, 0, (int)strlen(dp)); break; case 's': for (int i=0, lsb=0, pos=((int)strlen(dp))-1; i=0; pos--) { _vl_vsss_setbit(rwp,rbits,lsb, 8, dp[pos]); lsb+=8; } break; default: // Compile time should have found all errors before this vl_fatal (__FILE__, __LINE__, "", "$value$plusargs format error"); break; } _VL_CLEAN_INPLACE_W(rbits,rwp); return 1; } const char* vl_mc_scan_plusargs(const char* prefixp) { const string& match = VerilatedImp::argPlusMatch(prefixp); static VL_THREAD char outstr[VL_VALUE_STRING_MAX_WIDTH]; if (match == "") return NULL; strncpy(outstr, match.c_str()+strlen(prefixp)+1, // +1 to skip the "+" VL_VALUE_STRING_MAX_WIDTH); outstr[VL_VALUE_STRING_MAX_WIDTH-1] = '\0'; return outstr; } //=========================================================================== // Heavy functions string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) { // See also _VL_VINT_TO_STRING char destout[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1]; int obits = lwords * VL_WORDSIZE; int lsb=obits-1; bool start=true; char* destp = destout; int len = 0; for (; lsb>=0; lsb--) { lsb = (lsb / 8) * 8; // Next digit IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff; if (!start || charval) { *destp++ = (charval==0)?' ':charval; len++; start = false; // Drop leading 0s } } return string(destout, len); } //=========================================================================== // Verilated:: Methods const char* Verilated::catName(const char* n1, const char* n2) { // Returns new'ed data // Used by symbol table creation to make module names static char* strp = NULL; static size_t len = 0; size_t newlen = strlen(n1)+strlen(n2)+2; if (newlen > len) { if (strp) delete [] strp; strp = new char[newlen]; len = newlen; } strcpy(strp,n1); if (*n1) strcat(strp,"."); strcat(strp,n2); return strp; } void Verilated::flushCb(VerilatedVoidCb cb) { if (s_flushCb == cb) {} // Ok - don't duplicate else if (!s_flushCb) { s_flushCb=cb; } else { // Someday we may allow multiple callbacks ala atexit(), but until then vl_fatal("unknown",0,"", "Verilated::flushCb called twice with different callbacks"); } } void Verilated::commandArgs(int argc, const char** argv) { s_args.argc = argc; s_args.argv = argv; VerilatedImp::commandArgs(argc,argv); } const char* Verilated::commandArgsPlusMatch(const char* prefixp) { return VerilatedImp::argPlusMatch(prefixp).c_str(); } void Verilated::internalsDump() { VerilatedImp::internalsDump(); } void Verilated::scopesDump() { VerilatedImp::scopesDump(); } const VerilatedScope* Verilated::scopeFind(const char* namep) { return VerilatedImp::scopeFind(namep); } int Verilated::exportFuncNum(const char* namep) { return VerilatedImp::exportFind(namep); } //=========================================================================== // VerilatedModule:: Methods VerilatedModule::VerilatedModule(const char* namep) : m_namep(strdup(namep)) { } VerilatedModule::~VerilatedModule() { if (m_namep) free((void*)m_namep); m_namep=NULL; } //====================================================================== // VerilatedVar:: Methods // cppcheck-suppress unusedFunction // Used by applications vluint32_t VerilatedVar::entSize() const { vluint32_t size = 1; switch (vltype()) { case VLVT_PTR: size=sizeof(void*); break; case VLVT_UINT8: size=sizeof(CData); break; case VLVT_UINT16: size=sizeof(SData); break; case VLVT_UINT32: size=sizeof(IData); break; case VLVT_UINT64: size=sizeof(QData); break; case VLVT_WDATA: size=VL_WORDS_I(range().elements())*sizeof(IData); break; default: size=0; break; } return size; } //====================================================================== // VerilatedScope:: Methods VerilatedScope::VerilatedScope() { m_callbacksp = NULL; m_namep = NULL; m_funcnumMax = 0; m_symsp = NULL; m_varsp = NULL; } VerilatedScope::~VerilatedScope() { VerilatedImp::scopeErase(this); if (m_namep) { delete [] m_namep; m_namep = NULL; } if (m_callbacksp) { delete [] m_callbacksp; m_callbacksp = NULL; } if (m_varsp) { delete m_varsp; m_varsp = NULL; } m_funcnumMax = 0; // Force callback table to empty } void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp) { // Slowpath - called once/scope at construction // We don't want the space and reference-count access overhead of strings. m_symsp = symsp; char* namep = new char[strlen(prefixp)+strlen(suffixp)+2]; strcpy(namep, prefixp); if (*prefixp && *suffixp) strcat(namep,"."); strcat(namep, suffixp); m_namep = namep; VerilatedImp::scopeInsert(this); } void VerilatedScope::exportInsert(int finalize, const char* namep, void* cb) { // Slowpath - called once/scope*export at construction // Insert a exported function into scope table int funcnum = VerilatedImp::exportInsert(namep); if (!finalize) { // Need two passes so we know array size to create // Alternative is to dynamically stretch the array, which is more code, and slower. if (funcnum >= m_funcnumMax) { m_funcnumMax = funcnum+1; } } else { if (VL_UNLIKELY(funcnum >= m_funcnumMax)) { vl_fatal(__FILE__,__LINE__,"","Internal: Bad funcnum vs. pre-finalize maximum"); } if (VL_UNLIKELY(!m_callbacksp)) { // First allocation m_callbacksp = new void* [m_funcnumMax]; memset(m_callbacksp, 0, m_funcnumMax*sizeof(void*)); } m_callbacksp[funcnum] = cb; } } void VerilatedScope::varInsert(int finalize, const char* namep, void* datap, VerilatedVarType vltype, int vlflags, int dims, ...) { // Grab dimensions // In the future we may just create a large table at emit time and statically construct from that. if (!finalize) return; if (!m_varsp) m_varsp = new VerilatedVarNameMap(); VerilatedVar var (namep, datap, vltype, (VerilatedVarFlags)vlflags, dims); va_list ap; va_start(ap,dims); for (int i=0; iinsert(make_pair(namep,var)); } // cppcheck-suppress unusedFunction // Used by applications VerilatedVar* VerilatedScope::varFind(const char* namep) const { if (VL_LIKELY(m_varsp)) { VerilatedVarNameMap::iterator it = m_varsp->find(namep); if (VL_LIKELY(it != m_varsp->end())) { return &(it->second); } } return NULL; } void* VerilatedScope::exportFindNullError(int funcnum) const { // Slowpath - Called only when find has failed string msg = (string("Testbench C called '") +VerilatedImp::exportName(funcnum) +"' but scope wasn't set, perhaps due to dpi import call without 'context'"); vl_fatal("unknown",0,"", msg.c_str()); return NULL; } void* VerilatedScope::exportFindError(int funcnum) const { // Slowpath - Called only when find has failed string msg = (string("Testbench C called '") +VerilatedImp::exportName(funcnum) +"' but this DPI export function exists only in other scopes, not scope '" +name()+"'"); vl_fatal("unknown",0,"", msg.c_str()); return NULL; } void VerilatedScope::scopeDump() const { VL_PRINTF(" SCOPE %p: %s\n", this, name()); for (int i=0; ivarsp()) { for (VerilatedVarNameMap::const_iterator it = varsp->begin(); it != varsp->end(); ++it) { VL_PRINTF(" VAR %p: %s\n", &(it->second), it->first); } } } //=========================================================================== verilator-3.874/include/verilated_dpi.h0000664000177100017500000000473212525171733020146 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* /// /// \file /// \brief Verilator: Common include for all Verilated C files that use DPI /// /// This file is included automatically by Verilator at the top of /// all C++ files it generates where DPI is used. It contains /// DPI interface functions required by the Verilated code. /// /// Code available from: http://www.veripool.org/verilator /// //************************************************************************* #ifndef _VERILATED_DPI_H_ #define _VERILATED_DPI_H_ 1 ///< Header Guard #include "verilated.h" // Presumed done by caller #include "svdpi.h" //=================================================================== // SETTING OPERATORS /// Return svBitVecVal from WData static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, svBitVecVal* lwp) { int words = VL_WORDS_I(obits); for (int i=0; i #include #include //============================================================================= // VerilatedCovImpBase /// Implementation base class for constants struct VerilatedCovImpBase { // TYPES enum { MAX_KEYS = 33 }; /// Maximum user arguments + filename+lineno enum { KEY_UNDEF = 0 }; /// Magic key # for unspecified values }; //============================================================================= // VerilatedCovImpItem /// Implementation class for a VerilatedCov item class VerilatedCovImpItem : VerilatedCovImpBase { public: // But only local to this file // MEMBERS int m_keys[MAX_KEYS]; ///< Key int m_vals[MAX_KEYS]; ///< Value for specified key // CONSTRUCTORS // Derived classes should call zero() in their constructor VerilatedCovImpItem() { for (int i=0; i class VerilatedCoverItemSpec : public VerilatedCovImpItem { private: // MEMBERS T* m_countp; ///< Count value public: // METHODS virtual vluint64_t count() const { return *m_countp; } virtual void zero() const { *m_countp = 0; } // CONSTRUCTORS VerilatedCoverItemSpec(T* countp) : m_countp(countp) { zero(); } virtual ~VerilatedCoverItemSpec() {} }; //============================================================================= // VerilatedCovImp /// Implementation class for VerilatedCov. See that class for public method information. /// All value and keys are indexed into a unique number. Thus we can greatly reduce /// the storage requirements for otherwise identical keys. class VerilatedCovImp : VerilatedCovImpBase { private: // TYPES typedef map ValueIndexMap; typedef map IndexValueMap; typedef deque ItemList; private: // MEMBERS ValueIndexMap m_valueIndexes; ///< For each key/value a unique arbitrary index value IndexValueMap m_indexValues; ///< For each key/value a unique arbitrary index value ItemList m_items; ///< List of all items VerilatedCovImpItem* m_insertp; ///< Item about to insert const char* m_insertFilenamep; ///< Filename about to insert int m_insertLineno; ///< Line number about to insert // CONSTRUCTORS VerilatedCovImp() { m_insertp = NULL; m_insertFilenamep = NULL; m_insertLineno = 0; } public: ~VerilatedCovImp() { clear(); } static VerilatedCovImp& imp() { static VerilatedCovImp s_singleton; return s_singleton; } private: // PRIVATE METHODS int valueIndex(const string& value) { static int nextIndex = KEY_UNDEF+1; ValueIndexMap::iterator iter = m_valueIndexes.find(value); if (iter != m_valueIndexes.end()) return iter->second; nextIndex++; assert(nextIndex>0); m_valueIndexes.insert(make_pair(value, nextIndex)); m_indexValues.insert(make_pair(nextIndex, value)); return nextIndex; } string dequote(const string& text) { // Quote any special characters string rtn; for (const char* pos = text.c_str(); *pos; pos++) { if (!isprint(*pos) || *pos=='%' || *pos=='"') { char hex[10]; sprintf(hex,"%%%02X",pos[0]); rtn += hex; } else { rtn += *pos; } } return rtn; } bool legalKey(const string& key) { // Because we compress long keys to a single letter, and // don't want applications to either get confused if they use // a letter differently, nor want them to rely on our compression... // (Considered using numeric keys, but will remain back compatible.) if (key.length()<2) return false; if (key.length()==2 && isdigit(key[1])) return false; return true; } string keyValueFormatter (const string& key, const string& value) { string name; if (key.length()==1 && isalpha(key[0])) { name += string("\001")+key; } else { name += string("\001")+dequote(key); } name += string("\002")+dequote(value); return name; } string combineHier (const string& old, const string& add) { // (foo.a.x, foo.b.x) => foo.*.x // (foo.a.x, foo.b.y) => foo.* // (foo.a.x, foo.b) => foo.* if (old == add) return add; if (old == "") return add; if (add == "") return old; const char* a = old.c_str(); const char* b = add.c_str(); // Scan forward to first mismatch const char* apre = a; const char* bpre = b; while (*apre == *bpre) { apre++; bpre++; } // We used to backup and split on only .'s but it seems better to be verbose // and not assume . is the separator string prefix = string(a,apre-a); // Scan backward to last mismatch const char* apost = a+strlen(a)-1; const char* bpost = b+strlen(b)-1; while (*apost == *bpost && apost>apre && bpost>bpre) { apost--; bpost--; } // Forward to . so we have a whole word string suffix = *bpost ? string(bpost+1) : ""; string out = prefix+"*"+suffix; //cout << "\nch pre="<zero(); } } // We assume there's always call to i/f/p in that order void inserti (VerilatedCovImpItem* itemp) { assert(!m_insertp); m_insertp = itemp; } void insertf (const char* filenamep, int lineno) { m_insertFilenamep = filenamep; m_insertLineno = lineno; } void insertp (const char* ckeyps[MAX_KEYS], const char* valps[MAX_KEYS]) { assert(m_insertp); // First two key/vals are filename ckeyps[0]="filename"; valps[0]=m_insertFilenamep; VlCovCvtToCStr linestrp (m_insertLineno); ckeyps[1]="lineno"; valps[1]=linestrp; // Default page if not specified const char* fnstartp = m_insertFilenamep; while (const char* foundp = strchr(fnstartp,'/')) fnstartp=foundp+1; const char* fnendp = fnstartp; while (*fnendp && *fnendp!='.') fnendp++; string page_default = "sp_user/"+string(fnstartp,fnendp-fnstartp); ckeyps[2]="page"; valps[2]=page_default.c_str(); // Keys -> strings string keys[MAX_KEYS]; for (int i=0; i > EventMap; EventMap eventCounts; for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) { VerilatedCovImpItem* itemp = *(it); string name; string hier; bool per_instance = false; for (int i=0; im_keys[i] != KEY_UNDEF) { string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]); string val = m_indexValues[itemp->m_vals[i]]; if (key == VL_CIK_PER_INSTANCE) { if (val != "0") per_instance = true; } if (key == VL_CIK_HIER) { hier = val; } else { // Print it name += keyValueFormatter(key,val); } } } if (per_instance) { // Not collapsing hierarchies name += keyValueFormatter(VL_CIK_HIER,hier); hier = ""; } // Group versus point labels don't matter here, downstream // deals with it. Seems bad for sizing though and doesn't // allow easy addition of new group codes (would be // inefficient) // Find or insert the named event EventMap::iterator cit = eventCounts.find(name); if (cit != eventCounts.end()) { const string& oldhier = cit->second.first; cit->second.second += itemp->count(); cit->second.first = combineHier(oldhier, hier); } else { eventCounts.insert(make_pair(name, make_pair(hier,itemp->count()))); } } // Output body for (EventMap::iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) { os<<"C '"<first; if (it->second.first != "") os<second.first); os<<"' "<second.second; os<(itemp)); } void VerilatedCov::_inserti (vluint64_t* itemp) { VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec(itemp)); } void VerilatedCov::_insertf (const char* filename, int lineno) { VerilatedCovImp::imp().insertf(filename,lineno); } #define K(n) const char* key ## n #define A(n) const char* key ## n, const char* val ## n // Argument list #define C(n) key ## n, val ## n // Calling argument list #define N(n) "","" // Null argument list void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9), A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19), A(20),A(21),A(22),A(23),A(24),A(25),A(26),A(27),A(28),A(29)) { const char* keyps[VerilatedCovImpBase::MAX_KEYS] = {NULL,NULL,NULL, // filename,lineno,page key0,key1,key2,key3,key4,key5,key6,key7,key8,key9, key10,key11,key12,key13,key14,key15,key16,key17,key18,key19, key20,key21,key22,key23,key24,key25,key26,key27,key28,key29}; const char* valps[VerilatedCovImpBase::MAX_KEYS] = {NULL,NULL,NULL, // filename,lineno,page val0,val1,val2,val3,val4,val5,val6,val7,val8,val9, val10,val11,val12,val13,val14,val15,val16,val17,val18,val19, val20,val21,val22,val23,val24,val25,val26,val27,val28,val29}; VerilatedCovImp::imp().insertp(keyps, valps); } // And versions with fewer arguments (oh for a language with named parameters!) void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) { _insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9), N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19), N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29)); } void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9), A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) { _insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9), C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19), N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29)); } // Backward compatibility for Verilator void VerilatedCov::_insertp (A(0), A(1), K(2),int val2, K(3),int val3, K(4),const string& val4, A(5),A(6)) { _insertp(C(0),C(1), key2,VlCovCvtToCStr(val2), key3,VlCovCvtToCStr(val3), key4, val4.c_str(), C(5),C(6),N(7),N(8),N(9), N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19), N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29)); } #undef A #undef C #undef N #undef K verilator-3.874/include/verilated_save.cpp0000664000177100017500000001627512525172076020671 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2015 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. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief C++ Tracing in VCD Format /// //============================================================================= #include "verilatedos.h" #include "verilated.h" #include "verilated_save.h" #include #include #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) # include #else # include #endif #ifndef O_LARGEFILE // For example on WIN32 # define O_LARGEFILE 0 #endif #ifndef O_NONBLOCK # define O_NONBLOCK 0 #endif // CONSTANTS static const char* VLTSAVE_HEADER_STR = "verilatorsave01\n"; ///< Value of first bytes of each file static const char* VLTSAVE_TRAILER_STR = "vltsaved"; ///< Value of last bytes of each file //============================================================================= //============================================================================= //============================================================================= // Searalization bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t size) { bufferCheck(); const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap; vluint8_t miss = 0; while (size--) { miss |= (*dp++ ^ *m_cp++); } return (miss!=0); } VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) { if (VL_UNLIKELY(readDiffers(datap,size))) { string fn = filename(); string msg = (string)"Can't deserialize save-restore file as was made from different model"; vl_fatal(fn.c_str(), 0, "", msg.c_str()); close(); } return *this; // For function chaining } void VerilatedSerialize::header() { VerilatedSerialize& os = *this; // So can cut and paste standard << code below assert((strlen(VLTSAVE_HEADER_STR) & 7) == 0); // Keep aligned os.write(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)); // Verilated doesn't do it itself, as if we're not using save/restore // it doesn't need to compile this stuff in os.write(Verilated::serializedPtr(), Verilated::serializedSize()); } void VerilatedDeserialize::header() { VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) { string fn = filename(); string msg = (string)"Can't deserialize; file has wrong header signature"; vl_fatal(fn.c_str(), 0, "", msg.c_str()); close(); } os.read(Verilated::serializedPtr(), Verilated::serializedSize()); } void VerilatedSerialize::trailer() { VerilatedSerialize& os = *this; // So can cut and paste standard << code below assert((strlen(VLTSAVE_TRAILER_STR) & 7) == 0); // Keep aligned os.write(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)); } void VerilatedDeserialize::trailer() { VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) { string fn = filename(); string msg = (string)"Can't deserialize; file has wrong end-of-file signature"; vl_fatal(fn.c_str(), 0, "", msg.c_str()); close(); } } //============================================================================= //============================================================================= //============================================================================= // Opening/Closing void VerilatedSave::open (const char* filenamep) { if (isOpen()) return; VL_DEBUG_IF(VL_PRINTF("-vltSave: opening save file %s\n",filenamep);); if (filenamep[0]=='|') { assert(0); // Not supported yet. } else { // cppcheck-suppress duplicateExpression m_fd = ::open (filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK , 0666); if (m_fd<0) { // User code can check isOpen() m_isOpen = false; return; } } m_isOpen = true; m_filename = filenamep; m_cp = m_bufp; header(); } void VerilatedRestore::open (const char* filenamep) { if (isOpen()) return; VL_DEBUG_IF(VL_PRINTF("-vltRestore: opening restore file %s\n",filenamep);); if (filenamep[0]=='|') { assert(0); // Not supported yet. } else { // cppcheck-suppress duplicateExpression m_fd = ::open (filenamep, O_CREAT|O_RDONLY|O_LARGEFILE , 0666); if (m_fd<0) { // User code can check isOpen() m_isOpen = false; return; } } m_isOpen = true; m_filename = filenamep; m_cp = m_bufp; m_endp = m_bufp; header(); } void VerilatedSave::close () { if (!isOpen()) return; trailer(); flush(); m_isOpen = false; ::close(m_fd); // May get error, just ignore it } void VerilatedRestore::close () { if (!isOpen()) return; trailer(); flush(); m_isOpen = false; ::close(m_fd); // May get error, just ignore it } //============================================================================= // Buffer management void VerilatedSave::flush() { if (VL_UNLIKELY(!isOpen())) return; vluint8_t* wp = m_bufp; while (1) { ssize_t remaining = (m_cp - wp); if (remaining==0) break; errno = 0; ssize_t got = ::write (m_fd, wp, remaining); if (got>0) { wp += got; } else if (got < 0) { if (errno != EAGAIN && errno != EINTR) { // write failed, presume error (perhaps out of disk space) string msg = string(__FUNCTION__)+": "+strerror(errno); vl_fatal("",0,"",msg.c_str()); close(); break; } } } m_cp = m_bufp; // Reset buffer } void VerilatedRestore::fill() { if (VL_UNLIKELY(!isOpen())) return; // Move remaining characters down to start of buffer. (No memcpy, overlaps allowed) vluint8_t* rp = m_bufp; for (vluint8_t* sp=m_cp; rp < m_endp;) *rp++ = *sp++; // Overlaps m_endp = m_bufp + (m_endp - m_cp); m_cp = m_bufp; // Reset buffer // Read into buffer starting at m_endp while (1) { ssize_t remaining = (m_bufp+bufferSize() - m_endp); if (remaining==0) break; errno = 0; ssize_t got = ::read (m_fd, m_endp, remaining); if (got>0) { m_endp += got; } else if (got < 0) { if (errno != EAGAIN && errno != EINTR) { // write failed, presume error (perhaps out of disk space) string msg = string(__FUNCTION__)+": "+strerror(errno); vl_fatal("",0,"",msg.c_str()); close(); break; } } else { // got==0, EOF // Fill buffer from here to end with NULLs so reader's don't need to check eof each character. while (m_endp < m_bufp+bufferSize()) *m_endp++ = '\0'; break; } } } //============================================================================= // Serialization of types verilator-3.874/include/verilated_cov.h0000664000177100017500000001303212525172076020153 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2015 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. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief Coverage analysis support /// //============================================================================= #ifndef _VERILATED_COV_H_ #define _VERILATED_COV_H_ 1 #include "verilatedos.h" #include #include #include using namespace std; //============================================================================= /// Conditionally compile coverage code #ifdef VM_COVERAGE # define VL_IF_COVER(stmts) do { stmts ; } while(0) #else # define VL_IF_COVER(stmts) do { if(0) { stmts ; } } while(0) #endif //============================================================================= /// Insert a item for coverage analysis. /// The first argument is a pointer to the count to be dumped. /// The remaining arguments occur in pairs: A string key, and a value. /// The value may be a string, or another type which will be auto-converted to a string. /// /// Some typical keys: /// filename File the recording occurs in. Defaults to __FILE__ /// lineno Line number the recording occurs in. Defaults to __LINE__ /// column Column number (or occurrence# for dup file/lines). Defaults to undef. /// hier Hierarchical name. Defaults to name() /// type Type of coverage. Defaults to "user" /// Other types are 'block', 'fsm', 'toggle'. /// comment Description of the coverage event. Should be set by the user. /// Comments for type==block: 'if', 'else', 'elsif', 'case' /// thresh Threshold to consider fully covered. /// If unspecified, downstream tools will determine it. /// /// Examples: /// /// vluint32_t m_cases[10]; /// constructor { /// for (int i=0; i<10; i++) { m_cases[i]=0; } /// } /// for (int i=0; i<10; i++) { /// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i)); /// } #define VL_COVER_INSERT(countp,args...) \ VL_IF_COVER(VerilatedCov::_inserti(countp); \ VerilatedCov::_insertf(__FILE__,__LINE__); \ VerilatedCov::_insertp("hier", name(), args)) //============================================================================= /// Convert VL_COVER_INSERT value arguments to strings template< class T> std::string vlCovCvtToStr (const T& t) { ostringstream os; os< VlCovCvtToCStr (const T& t) { ostringstream os; os<name(); } svScope svGetScopeFromName(const char* scopeName) { return (svScope)VerilatedImp::scopeFind(scopeName); } int svPutUserData(const svScope scope, void *userKey, void* userData) { VerilatedImp::userInsert(scope,userKey,userData); return 0; } void* svGetUserData(const svScope scope, void* userKey) { return VerilatedImp::userFind(scope,userKey); } int svGetCallerInfo(const char** fileNamepp, int *lineNumberp) { if (VL_UNLIKELY(!Verilated::dpiInContext())) { _VL_SVDPI_CONTEXT_WARN(); return false; } if (VL_LIKELY(fileNamepp)) *fileNamepp = Verilated::dpiFilenamep(); // thread local if (VL_LIKELY(lineNumberp)) *lineNumberp = Verilated::dpiLineno(); // thread local return true; } //====================================================================== // Disables int svIsDisabledState() { return 0; // Disables not implemented } void svAckDisabledState() { // Disables not implemented } verilator-3.874/include/verilated_sc.h0000664000177100017500000000360512525171733017775 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* /// /// \file /// \brief Verilator: Common include for all Verilated SystemC files /// /// This file is included automatically by Verilator at the top of /// all SystemC files it generates. /// /// Code available from: http://www.veripool.org/verilator /// //************************************************************************* #ifndef _VERILATED_SC_H_ #define _VERILATED_SC_H_ 1 ///< Header Guard #include "verilatedos.h" #include "systemc.h" //============================================================================= // VL_SC_BV_DATAP // We want to get a pointer to m_data in the sc_bv_base class, // but it is protected. So make an exposing class, then use // cast magic to get at it. Saves patching get_datap in SystemC. #define VL_SC_BV_DATAP(bv) (VlScBvExposer::sp_datap(bv)) class VlScBvExposer : public sc_bv_base { public: static vluint32_t* sp_datap(const sc_bv_base& base) { return static_cast(&base)->sp_datatp(); } vluint32_t* sp_datatp() const { return (vluint32_t*)(m_data); } // Above reads this protected element in sc_bv_base: // sc_digit* m_data; // data array }; //========================================================================= #endif // guard verilator-3.874/include/verilatedos.h0000664000177100017500000002637312534317670017663 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* /// /// \file /// \brief Verilator: Common include for OS portability (verilated & verilator) /// /// This header is used by both the Verilator source code (run on the /// build and host system), and the Verilated output (run on the target /// system). Code needed by only the host system goes into /// config_build.h.in, code needed by Verilated code only goes into /// verilated.h, and code needed by both goes here (verilatedos.h). /// /// Code available from: http://www.veripool.org/verilator /// //************************************************************************* #ifndef _VERILATEDOS_H_ #define _VERILATEDOS_H_ 1 ///< Header Guard //========================================================================= // Compiler pragma abstraction #ifdef __GNUC__ # define VL_ATTR_ALIGNED(alignment) __attribute__ ((aligned (alignment))) # define VL_ATTR_ALWINLINE __attribute__ ((always_inline)) # define VL_ATTR_NORETURN __attribute__ ((noreturn)) # ifdef _WIN32 # define VL_ATTR_PRINTF(fmtArgNum) // GCC with MS runtime will fool the print arg checker # else # define VL_ATTR_PRINTF(fmtArgNum) __attribute__ ((format (printf, fmtArgNum, fmtArgNum+1))) # endif # define VL_ATTR_UNUSED __attribute__ ((unused)) # define VL_FUNC __func__ # define VL_LIKELY(x) __builtin_expect(!!(x), 1) # define VL_UNLIKELY(x) __builtin_expect(!!(x), 0) # define VL_PREFETCH_RD(p) __builtin_prefetch((p),0) # define VL_PREFETCH_RW(p) __builtin_prefetch((p),1) #elif defined(_MSC_VER) # define VL_ATTR_ALIGNED(alignment) # define VL_ATTR_ALWINLINE # define VL_ATTR_NORETURN # define VL_ATTR_PRINTF(fmtArgNum) # define VL_ATTR_UNUSED # define VL_FUNC __FUNCTION__ # define VL_LIKELY(x) (!!(x)) # define VL_UNLIKELY(x) (!!(x)) # define VL_PREFETCH_RD(p) # define VL_PREFETCH_RW(p) #else # define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment # define VL_ATTR_ALWINLINE ///< Inline, even when not optimizing # define VL_ATTR_NORETURN ///< Function does not ever return # define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking # define VL_ATTR_UNUSED ///< Function that may be never used # define VL_FUNC "__func__" ///< Name of current function for error macros # define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false # define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true # define VL_PREFETCH_RD(p) ///< Prefetch data with read intent # define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent #endif #ifdef VL_THREADED # ifdef __GNUC__ # define VL_THREAD __thread ///< Storage class for thread-local storage # else # error "Unsupported compiler for VL_THREADED: No thread-local declarator" # endif # define VL_STATIC_OR_THREAD ///< Static if unthreaded, as some strings can be faster // ///< if non-dynamic and can't do "static VL_THREAD string" #else # define VL_THREAD ///< Storage class for thread-local storage # define VL_STATIC_OR_THREAD static ///< Static if unthreaded, as some strings can be faster // ///< if non-dynamic and can't do "static VL_THREAD string" #endif #ifdef _MSC_VER # define VL_ULL(c) (c##ui64) ///< Add appropriate suffix to 64-bit constant #else # define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant #endif // This is not necessarily the same as #UL, depending on what the IData typedef is. #define VL_UL(c) ((IData)(c##UL)) ///< Add appropriate suffix to 32-bit constant //========================================================================= // C++-2011 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) # define VL_HAS_UNIQUE_PTR # define VL_UNIQUE_PTR unique_ptr #else # define VL_UNIQUE_PTR auto_ptr #endif //========================================================================= // Optimization #ifndef VL_INLINE_OPT # define VL_INLINE_OPT ///< "inline" if compiling all objects in single compiler run #endif //========================================================================= // Warning disabled #ifndef VL_WARNINGS # ifdef _MSC_VER # pragma warning(disable:4099) // C4099: type name first seen using 'class' now seen using 'struct' (V3AstNode) # pragma warning(disable:4100) // C4100: unreferenced formal parameter (L4) # pragma warning(disable:4127) // C4127: conditional expression is constant (L4) # pragma warning(disable:4146) // C4146: unary minus operator applied to unsigned type, result still unsigned # pragma warning(disable:4189) // C4189: local variable is initialized but not referenced (L4) # pragma warning(disable:4244) // C4244: conversion from 'uint64_t' to 'uint_32_t', possible loss of data # pragma warning(disable:4245) // C4245: conversion from 'int' to 'unsigned', signed/unsigned mismatch # pragma warning(disable:4996) // C4996: sscanf/fopen/etc may be unsafe # endif #endif //========================================================================= // Basic integer types #ifdef VL_UINTS_DEFINED #elif defined(__CYGWIN__) # include typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility) typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility) typedef unsigned char vluint8_t; ///< 8-bit unsigned type typedef unsigned short int vluint16_t; ///< 16-bit unsigned type # if defined(__uint32_t_defined) || defined(___int32_t_defined) // Newer Cygwin uint32_t in stdint.h as an unsigned int typedef int32_t vlsint32_t; ///< 32-bit signed type typedef uint32_t vluint32_t; ///< 32-bit unsigned type # else // Older Cygwin has long==uint32_t typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility) typedef long vlsint32_t; ///< 32-bit signed type typedef unsigned long vluint32_t; ///< 32-bit unsigned type # endif # if defined(__WORDSIZE) && (__WORDSIZE == 64) typedef long vlsint64_t; ///< 64-bit signed type typedef unsigned long vluint64_t; ///< 64-bit unsigned type # else typedef long long vlsint64_t; ///< 64-bit signed type typedef unsigned long long vluint64_t; ///< 64-bit unsigned type # endif #elif defined(_WIN32) && defined(_MSC_VER) typedef unsigned __int8 uint8_t; ///< 8-bit unsigned type (backward compatibility) typedef unsigned __int16 uint16_t; ///< 16-bit unsigned type (backward compatibility) typedef unsigned __int32 uint32_t; ///< 32-bit unsigned type (backward compatibility) typedef unsigned __int8 vluint8_t; ///< 8-bit unsigned type typedef unsigned __int16 vluint16_t; ///< 16-bit unsigned type typedef signed __int32 vlsint32_t; ///< 32-bit signed type typedef unsigned __int32 vluint32_t; ///< 32-bit unsigned type typedef signed __int64 vlsint64_t; ///< 64-bit signed type typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type # ifndef _SSIZE_T_DEFINED # ifdef _WIN64 typedef signed __int64 ssize_t; ///< signed size_t; returned from read() # else typedef signed __int32 ssize_t; ///< signed size_t; returned from read() # endif # endif #else // Linux or compliant Unix flavors, -m64 # include // Linux and most flavors # include // Linux ssize_t # include // Solaris typedef uint8_t vluint8_t; ///< 32-bit unsigned type typedef uint16_t vluint16_t; ///< 32-bit unsigned type typedef int vlsint32_t; ///< 32-bit signed type typedef uint32_t vluint32_t; ///< 32-bit signed type # if defined(__WORDSIZE) && (__WORDSIZE == 64) typedef long vlsint64_t; ///< 64-bit signed type typedef unsigned long vluint64_t; ///< 64-bit unsigned type # else typedef long long vlsint64_t; ///< 64-bit signed type typedef unsigned long long vluint64_t; ///< 64-bit unsigned type # endif #endif //========================================================================= // Printing printf/scanf formats // Alas cinttypes isn't that standard yet #ifdef _WIN32 # define VL_PRI64 "I64" #else // Linux or compliant Unix flavors # if defined(__WORDSIZE) && (__WORDSIZE == 64) # define VL_PRI64 "l" # else # define VL_PRI64 "ll" # endif #endif #ifdef _WIN32 # define VL_VSNPRINTF vl_vsnprintf inline int vl_vsnprintf(char* str, size_t size, const char* format, va_list ap) { int count = -1; if (size != 0) { count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); } if (count == -1) { count = _vscprintf(format, ap); } return count; } #else # define VL_VSNPRINTF vsnprintf #endif //========================================================================= // File system functions #ifdef _WIN32 # define VL_DEV_NULL "nul" #else // Linux or compliant Unix flavors # define VL_DEV_NULL "/dev/null" #endif //========================================================================= // Integer size macros #define VL_BYTESIZE 8 ///< Bits in a byte #define VL_SHORTSIZE 16 ///< Bits in a short #define VL_WORDSIZE 32 ///< Bits in a word #define VL_QUADSIZE 64 ///< Bits in a quadword #define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE) /// Bytes this number of bits needs (1 bit=1 byte) #define VL_BYTES_I(nbits) (((nbits)+(VL_BYTESIZE-1))/VL_BYTESIZE) /// Words this number of bits needs (1 bit=1 word) #define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE) //========================================================================= // Verilated function size macros #define VL_MULS_MAX_WORDS 16 ///< Max size in words of MULS operation #define VL_TO_STRING_MAX_WORDS 64 ///< Max size in words of String conversion operation //========================================================================= // Base macros #define VL_SIZEBITS_I (VL_WORDSIZE-1) ///< Bit mask for bits in a word #define VL_SIZEBITS_Q (VL_QUADSIZE-1) ///< Bit mask for bits in a quad /// Mask for words with 1's where relevant bits are (0=all bits) #define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) \ ? ((1U << ((nbits) & VL_SIZEBITS_I) )-1) : ~0) /// Mask for quads with 1's where relevant bits are (0=all bits) #define VL_MASK_Q(nbits) (((nbits) & VL_SIZEBITS_Q) \ ? ((VL_ULL(1) << ((nbits) & VL_SIZEBITS_Q) )-VL_ULL(1)) : VL_ULL(~0)) #define VL_BITWORD_I(bit) ((bit)/VL_WORDSIZE) ///< Word number for a wide quantity #define VL_BITBIT_I(bit) ((bit)&VL_SIZEBITS_I) ///< Bit number for a bit in a long #define VL_BITBIT_Q(bit) ((bit)&VL_SIZEBITS_Q) ///< Bit number for a bit in a quad //========================================================================= // Floating point // #defines, to avoid requiring math.h on all compile runs #ifdef _MSC_VER # define VL_TRUNC(n) (((n)<0) ? ceil((n)) : floor((n))) # define VL_ROUND(n) (((n)<0) ? ceil((n)-0.5) : floor((n)+0.5)) #else # define VL_TRUNC(n) trunc(n) # define VL_ROUND(n) round(n) #endif //========================================================================= #endif /*guard*/ verilator-3.874/include/verilated_syms.h0000664000177100017500000000667512525171733020375 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* /// /// \file /// \brief Verilator: Include to allow symbol inspection /// /// This file is for inclusion by files that need to inspect /// the symbol table. It is not included in verilated.h /// as it requires some heavyweight C++ classes. /// /// Code available from: http://www.veripool.org/verilator /// //************************************************************************* #ifndef _VERILATED_SYMS_H_ #define _VERILATED_SYMS_H_ 1 ///< Header Guard #include "verilated_heavy.h" #include //====================================================================== // Types struct VerilatedCStrCmp { /// Ordering maps keyed by const char*'s bool operator() (const char *a, const char *b) const { return std::strcmp(a, b) < 0; } }; //=========================================================================== /// Verilator range // See also V3Ast::VNumRange class VerilatedRange { int m_left; int m_right; protected: friend class VerilatedVar; friend class VerilatedScope; VerilatedRange() : m_left(0), m_right(0) {} void sets(int left, int right) { m_left=left; m_right=right; } public: ~VerilatedRange() {} int left() const { return m_left; } int right() const { return m_right; } int elements() const { return (VL_LIKELY(m_left>=m_right)?(m_left-m_right+1):(m_right-m_left+1)); } }; //=========================================================================== /// Verilator variable class VerilatedVar { void* m_datap; // Location of data VerilatedVarType m_vltype; // Data type VerilatedVarFlags m_vlflags; // Direction VerilatedRange m_range; // First range VerilatedRange m_array; // Array int m_dims; // Dimensions const char* m_namep; // Name - slowpath protected: friend class VerilatedScope; VerilatedVar(const char* namep, void* datap, VerilatedVarType vltype, VerilatedVarFlags vlflags, int dims) : m_datap(datap), m_vltype(vltype), m_vlflags(vlflags), m_dims(dims), m_namep(namep) {} public: ~VerilatedVar() {} void* datap() const { return m_datap; } VerilatedVarType vltype() const { return m_vltype; } VerilatedVarFlags vldir() const { return (VerilatedVarFlags)((int)m_vlflags & VLVF_MASK_DIR); } vluint32_t entSize() const; bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); } const VerilatedRange& range() const { return m_range; } const VerilatedRange& array() const { return m_array; } const char* name() const { return m_namep; } int dims() const { return m_dims; } }; //====================================================================== /// Types class VerilatedVarNameMap : public map { public: VerilatedVarNameMap() {} ~VerilatedVarNameMap() {} }; #endif // Guard verilator-3.874/include/verilated_vcd_c.h0000664000177100017500000004154012525172076020447 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2015 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. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief C++ Tracing in VCD Format /// //============================================================================= // SPDIFF_OFF #ifndef _VERILATED_VCD_C_H_ #define _VERILATED_VCD_C_H_ 1 #include "verilatedos.h" #include #include #include using namespace std; class VerilatedVcd; class VerilatedVcdCallInfo; // SPDIFF_ON //============================================================================= // VerilatedFile /// File handling routines, which can be overrode for e.g. socket I/O class VerilatedVcdFile { private: int m_fd; ///< File descriptor we're writing to public: // METHODS VerilatedVcdFile() : m_fd(0) {} virtual ~VerilatedVcdFile() {} virtual bool open(const string& name); virtual void close(); virtual ssize_t write(const char* bufp, ssize_t len); }; //============================================================================= // VerilatedVcdSig /// Internal data on one signal being traced. class VerilatedVcdSig { protected: friend class VerilatedVcd; vluint32_t m_code; ///< VCD file code number int m_bits; ///< Size of value in bits VerilatedVcdSig (vluint32_t code, int bits) : m_code(code), m_bits(bits) {} public: ~VerilatedVcdSig() {} }; //============================================================================= typedef void (*VerilatedVcdCallback_t)(VerilatedVcd* vcdp, void* userthis, vluint32_t code); //============================================================================= // VerilatedVcd /// Base class to create a Verilator VCD dump /// This is an internally used class - see VerilatedVcdC for what to call from applications class VerilatedVcd { private: VerilatedVcdFile* m_filep; ///< File we're writing to bool m_fileNewed; ///< m_filep needs destruction bool m_isOpen; ///< True indicates open file bool m_evcd; ///< True for evcd format string m_filename; ///< Filename we're writing to (if open) vluint64_t m_rolloverMB; ///< MB of file size to rollover at char m_scopeEscape; ///< Character to separate scope components int m_modDepth; ///< Depth of module hierarchy bool m_fullDump; ///< True indicates dump ignoring if changed vluint32_t m_nextCode; ///< Next code number to assign string m_modName; ///< Module name being traced now double m_timeRes; ///< Time resolution (ns/ms etc) double m_timeUnit; ///< Time units (ns/ms etc) vluint64_t m_timeLastDump; ///< Last time we did a dump char* m_wrBufp; ///< Output buffer char* m_wrFlushp; ///< Output buffer flush trigger location char* m_writep; ///< Write pointer into output buffer vluint64_t m_wrChunkSize; ///< Output buffer size vluint64_t m_wroteBytes; ///< Number of bytes written to this file vluint32_t* m_sigs_oldvalp; ///< Pointer to old signal values vector m_sigs; ///< Pointer to signal information vector m_callbacks; ///< Routines to perform dumping typedef map NameMap; NameMap* m_namemapp; ///< List of names for the header static vector s_vcdVecp; ///< List of all created traces void bufferResize(vluint64_t minsize); void bufferFlush(); inline void bufferCheck() { // Flush the write buffer if there's not enough space left for new information // We only call this once per vector, so we need enough slop for a very wide "b###" line if (VL_UNLIKELY(m_writep > m_wrFlushp)) { bufferFlush(); } } void closePrev(); void closeErr(); void openNext(); void makeNameMap(); void deleteNameMap(); void printIndent (int levelchange); void printStr (const char* str); void printQuad (vluint64_t n); void printTime (vluint64_t timeui); void declare (vluint32_t code, const char* name, const char* wirep, int arraynum, bool tri, bool bussed, int msb, int lsb); void dumpHeader(); void dumpPrep (vluint64_t timeui); void dumpFull (vluint64_t timeui); // cppcheck-suppress functionConst void dumpDone (); inline void printCode (vluint32_t code) { if (code>=(94*94*94)) *m_writep++ = ((char)((code/94/94/94)%94+33)); if (code>=(94*94)) *m_writep++ = ((char)((code/94/94)%94+33)); if (code>=(94)) *m_writep++ = ((char)((code/94)%94+33)); *m_writep++ = ((char)((code)%94+33)); } static string stringCode (vluint32_t code) { string out; if (code>=(94*94*94)) out += ((char)((code/94/94/94)%94+33)); if (code>=(94*94)) out += ((char)((code/94/94)%94+33)); if (code>=(94)) out += ((char)((code/94)%94+33)); return out + ((char)((code)%94+33)); } protected: // METHODS void evcd(bool flag) { m_evcd = flag; } public: // CREATORS VerilatedVcd(VerilatedVcdFile* filep=NULL); ~VerilatedVcd(); // ACCESSORS /// Inside dumping routines, return next VCD signal code vluint32_t nextCode() const {return m_nextCode;} /// Set size in megabytes after which new file should be created void rolloverMB(vluint64_t rolloverMB) { m_rolloverMB=rolloverMB; }; /// Is file open? bool isOpen() const { return m_isOpen; } /// Change character that splits scopes. Note whitespace are ALWAYS escapes. void scopeEscape(char flag) { m_scopeEscape = flag; } /// Is this an escape? inline bool isScopeEscape(char c) { return isspace(c) || c==m_scopeEscape; } // METHODS void open (const char* filename); ///< Open the file; call isOpen() to see if errors void openNext (bool incFilename); ///< Open next data-only file void flush() { bufferFlush(); } ///< Flush any remaining data static void flush_all(); ///< Flush any remaining data from all files void close (); ///< Close the file void set_time_unit (const char* unit); ///< Set time units (s/ms, defaults to ns) void set_time_unit (const string& unit) { set_time_unit(unit.c_str()); } void set_time_resolution (const char* unit); ///< Set time resolution (s/ms, defaults to ns) void set_time_resolution (const string& unit) { set_time_resolution(unit.c_str()); } double timescaleToDouble (const char* unitp); string doubleToTimescale (double value); /// Inside dumping routines, called each cycle to make the dump void dump (vluint64_t timeui); /// Call dump with a absolute unscaled time in seconds void dumpSeconds (double secs) { dump((vluint64_t)(secs * m_timeRes)); } /// Inside dumping routines, declare callbacks for tracings void addCallback (VerilatedVcdCallback_t init, VerilatedVcdCallback_t full, VerilatedVcdCallback_t change, void* userthis); /// Inside dumping routines, declare a module void module (const string& name); /// Inside dumping routines, declare a signal void declBit (vluint32_t code, const char* name, int arraynum); void declBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb); void declQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb); void declArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb); void declTriBit (vluint32_t code, const char* name, int arraynum); void declTriBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb); void declTriQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb); void declTriArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb); void declDouble (vluint32_t code, const char* name, int arraynum); void declFloat (vluint32_t code, const char* name, int arraynum); // ... other module_start for submodules (based on cell name) /// Inside dumping routines, dump one signal void fullBit (vluint32_t code, const vluint32_t newval) { // Note the &1, so we don't require clean input -- makes more common no change case faster m_sigs_oldvalp[code] = newval; *m_writep++=('0'+(char)(newval&1)); printCode(code); *m_writep++='\n'; bufferCheck(); } void fullBus (vluint32_t code, const vluint32_t newval, int bits) { m_sigs_oldvalp[code] = newval; *m_writep++='b'; for (int bit=bits-1; bit>=0; --bit) { *m_writep++=((newval&(1L<=0; --bit) { *m_writep++=((newval&(1ULL<=0; --bit) { *m_writep++=((newval[(bit/32)]&(1L<<(bit&0x1f)))?'1':'0'); } *m_writep++=' '; printCode(code); *m_writep++='\n'; bufferCheck(); } void fullTriBit (vluint32_t code, const vluint32_t newval, const vluint32_t newtri) { m_sigs_oldvalp[code] = newval; m_sigs_oldvalp[code+1] = newtri; *m_writep++ = "01zz"[m_sigs_oldvalp[code] | (m_sigs_oldvalp[code+1]<<1)]; printCode(code); *m_writep++='\n'; bufferCheck(); } void fullTriBus (vluint32_t code, const vluint32_t newval, const vluint32_t newtri, int bits) { m_sigs_oldvalp[code] = newval; m_sigs_oldvalp[code+1] = newtri; *m_writep++='b'; for (int bit=bits-1; bit>=0; --bit) { *m_writep++ = "01zz"[((newval >> bit)&1) | (((newtri >> bit)&1)<<1)]; } *m_writep++=' '; printCode(code); *m_writep++='\n'; bufferCheck(); } void fullTriQuad (vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits) { (*((vluint64_t*)&m_sigs_oldvalp[code])) = newval; (*((vluint64_t*)&m_sigs_oldvalp[code+1])) = newtri; *m_writep++='b'; for (int bit=bits-1; bit>=0; --bit) { *m_writep++ = "01zz"[((newval >> bit)&1ULL) | (((newtri >> bit)&1ULL)<<1ULL)]; } *m_writep++=' '; printCode(code); *m_writep++='\n'; bufferCheck(); } void fullTriArray (vluint32_t code, const vluint32_t* newvalp, const vluint32_t* newtrip, int bits) { for (int word=0; word<(((bits-1)/32)+1); ++word) { m_sigs_oldvalp[code+word*2] = newvalp[word]; m_sigs_oldvalp[code+word*2+1] = newtrip[word]; } *m_writep++='b'; for (int bit=bits-1; bit>=0; --bit) { vluint32_t valbit = (newvalp[(bit/32)]>>(bit&0x1f)) & 1; vluint32_t tribit = (newtrip[(bit/32)]>>(bit&0x1f)) & 1; *m_writep++ = "01zz"[valbit | (tribit<<1)]; } *m_writep++=' '; printCode(code); *m_writep++='\n'; bufferCheck(); } void fullDouble (vluint32_t code, const double newval); void fullFloat (vluint32_t code, const float newval); /// Inside dumping routines, dump one signal as unknowns /// Presently this code doesn't change the oldval vector. /// Thus this is for special standalone applications that after calling /// fullBitX, must when then value goes non-X call fullBit. inline void fullBitX (vluint32_t code) { *m_writep++='x'; printCode(code); *m_writep++='\n'; bufferCheck(); } inline void fullBusX (vluint32_t code, int bits) { *m_writep++='b'; for (int bit=bits-1; bit>=0; --bit) { *m_writep++='x'; } *m_writep++=' '; printCode(code); *m_writep++='\n'; bufferCheck(); } inline void fullQuadX (vluint32_t code, int bits) { fullBusX (code, bits); } inline void fullArrayX (vluint32_t code, int bits) { fullBusX (code, bits); } /// Inside dumping routines, dump one signal if it has changed inline void chgBit (vluint32_t code, const vluint32_t newval) { vluint32_t diff = m_sigs_oldvalp[code] ^ newval; if (VL_UNLIKELY(diff)) { // Verilator 3.510 and newer provide clean input, so the below is only for back compatibility if (VL_UNLIKELY(diff & 1)) { // Change after clean? fullBit (code, newval); } } } inline void chgBus (vluint32_t code, const vluint32_t newval, int bits) { vluint32_t diff = m_sigs_oldvalp[code] ^ newval; if (VL_UNLIKELY(diff)) { if (VL_UNLIKELY(bits==32 || (diff & ((1U< #elif defined(__APPLE__) #include #elif defined(__linux) || (defined(__APPLE__) && defined(__MACH__)) #include #else #include #endif /* Use to import a symbol into dll */ #ifndef DPI_DLLISPEC #if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)) #define DPI_DLLISPEC __declspec(dllimport) #else #define DPI_DLLISPEC #endif #endif /* Use to export a symbol from dll */ #ifndef DPI_DLLESPEC #if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)) #define DPI_DLLESPEC __declspec(dllexport) #else #define DPI_DLLESPEC #endif #endif /* Use to mark a function as external */ #ifndef DPI_EXTERN #define DPI_EXTERN #endif #ifndef DPI_PROTOTYPES #define DPI_PROTOTYPES /* object is defined imported by the application */ #define XXTERN DPI_EXTERN DPI_DLLISPEC /* object is exported by the application */ #define EETERN DPI_EXTERN DPI_DLLESPEC #endif /* canonical representation */ #define sv_0 0 #define sv_1 1 #define sv_z 2 #define sv_x 3 /* common type for 'bit' and 'logic' scalars. */ typedef uint8_t svScalar; typedef svScalar svBit; /* scalar */ typedef svScalar svLogic; /* scalar */ /* * DPI representation of packed arrays. * 2-state and 4-state vectors, exactly the same as PLI's avalue/bvalue. */ #ifndef VPI_VECVAL #define VPI_VECVAL typedef struct t_vpi_vecval { uint32_t aval; uint32_t bval; } s_vpi_vecval, *p_vpi_vecval; #endif /* (a chunk of) packed logic array */ typedef s_vpi_vecval svLogicVecVal; /* (a chunk of) packed bit array */ typedef uint32_t svBitVecVal; /* Number of chunks required to represent the given width packed array */ #define SV_PACKED_DATA_NELEMS(WIDTH) (((WIDTH) + 31) >> 5) /* * Because the contents of the unused bits is undetermined, * the following macros can be handy. */ #define SV_MASK(N) (~(-1 << (N))) #define SV_GET_UNSIGNED_BITS(VALUE, N) \ ((N) == 32 ? (VALUE) : ((VALUE) & SV_MASK(N))) #define SV_GET_SIGNED_BITS(VALUE, N) \ ((N) == 32 ? (VALUE) : \ (((VALUE) & (1 << (N))) ? ((VALUE) | ~SV_MASK(N)) : ((VALUE) & SV_MASK(N)))) /* * Implementation-dependent representation. */ /* * Return implementation version information string ("1800-2005" or "SV3.1a"). */ XXTERN const char* svDpiVersion(); /* a handle to a scope (an instance of a module or interface) */ XXTERN typedef void* svScope; /* a handle to a generic object (actually, unsized array) */ XXTERN typedef void* svOpenArrayHandle; /* * Bit-select utility functions. * * Packed arrays are assumed to be indexed n-1:0, * where 0 is the index of LSB */ /* s=source, i=bit-index */ XXTERN svBit svGetBitselBit(const svBitVecVal* s, int i); XXTERN svLogic svGetBitselLogic(const svLogicVecVal* s, int i); /* d=destination, i=bit-index, s=scalar */ XXTERN void svPutBitselBit(svBitVecVal* d, int i, svBit s); XXTERN void svPutBitselLogic(svLogicVecVal* d, int i, svLogic s); /* * Part-select utility functions. * * A narrow (<=32 bits) part-select is extracted from the * source representation and written into the destination word. * * Normalized ranges and indexing [n-1:0] are used for both arrays. * * s=source, d=destination, i=starting bit index, w=width * like for variable part-selects; limitations: w <= 32 */ XXTERN void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w); XXTERN void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w); XXTERN void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w); XXTERN void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w); /* * Open array querying functions * These functions are modeled upon the SystemVerilog array * querying functions and use the same semantics. * * If the dimension is 0, then the query refers to the * packed part of an array (which is one-dimensional). * Dimensions > 0 refer to the unpacked part of an array. */ /* h= handle to open array, d=dimension */ XXTERN int svLeft(const svOpenArrayHandle h, int d); XXTERN int svRight(const svOpenArrayHandle h, int d); XXTERN int svLow(const svOpenArrayHandle h, int d); XXTERN int svHigh(const svOpenArrayHandle h, int d); XXTERN int svIncrement(const svOpenArrayHandle h, int d); XXTERN int svSize(const svOpenArrayHandle h, int d); XXTERN int svDimensions(const svOpenArrayHandle h); /* * Pointer to the actual representation of the whole array of any type * NULL if not in C layout */ XXTERN void *svGetArrayPtr(const svOpenArrayHandle); /* total size in bytes or 0 if not in C layout */ XXTERN int svSizeOfArray(const svOpenArrayHandle); /* * Return a pointer to an element of the array * or NULL if index outside the range or null pointer */ XXTERN void *svGetArrElemPtr(const svOpenArrayHandle, int indx1, ...); /* specialized versions for 1-, 2- and 3-dimensional arrays: */ XXTERN void *svGetArrElemPtr1(const svOpenArrayHandle, int indx1); XXTERN void *svGetArrElemPtr2(const svOpenArrayHandle, int indx1, int indx2); XXTERN void *svGetArrElemPtr3(const svOpenArrayHandle, int indx1, int indx2, int indx3); /* * Functions for copying between simulator storage and user space. * These functions copy the whole packed array in either direction. * The user is responsible for allocating an array to hold the * canonical representation. */ /* s=source, d=destination */ /* From user space into simulator storage */ XXTERN void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, ...); XXTERN void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1); XXTERN void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2); XXTERN void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2, int indx3); XXTERN void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, ...); XXTERN void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1); XXTERN void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, int indx2); XXTERN void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, int indx2, int indx3); /* From simulator storage into user space */ XXTERN void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, ...); XXTERN void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1); XXTERN void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2); XXTERN void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, ...); XXTERN void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1); XXTERN void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2); XXTERN void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...); XXTERN svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1); XXTERN svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2); XXTERN svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...); XXTERN svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1); XXTERN svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2); XXTERN svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...); XXTERN void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1); XXTERN void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2); XXTERN void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2, int indx3); XXTERN void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...); XXTERN void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1); XXTERN void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1, int indx2); XXTERN void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1, int indx2, int indx3); /* Functions for working with DPI context */ /* * Retrieve the active instance scope currently associated with the executing * imported function. Unless a prior call to svSetScope has occurred, this * is the scope of the function's declaration site, not call site. * Returns NULL if called from C code that is *not* an imported function. */ XXTERN svScope svGetScope(); /* * Set context for subsequent export function execution. * This function must be called before calling an export function, unless * the export function is called while executing an import function. In that * case the export function shall inherit the scope of the surrounding import * function. This is known as the "default scope". * The return is the previous active scope (per svGetScope) */ XXTERN svScope svSetScope(const svScope scope); /* Gets the fully qualified name of a scope handle */ XXTERN const char* svGetNameFromScope(const svScope); /* * Retrieve svScope to instance scope of an arbitrary function declaration. * (can be either module, program, interface, or generate scope) * The return value shall be NULL for unrecognized scope names. */ XXTERN svScope svGetScopeFromName(const char* scopeName); /* * Store an arbitrary user data pointer for later retrieval by svGetUserData() * The userKey is generated by the user. It must be guaranteed by the user to * be unique from all other userKey's for all unique data storage requirements * It is recommended that the address of static functions or variables in the * user's C code be used as the userKey. * It is illegal to pass in NULL values for either the scope or userData * arguments. It is also an error to call svPutUserData() with an invalid * svScope. This function returns -1 for all error cases, 0 upon success. It is * suggested that userData values of 0 (NULL) not be used as otherwise it can * be impossible to discern error status returns when calling svGetUserData() */ XXTERN int svPutUserData(const svScope scope, void *userKey, void* userData); /* * Retrieve an arbitrary user data pointer that was previously * stored by a call to svPutUserData(). See the comment above * svPutUserData() for an explanation of userKey, as well as * restrictions on NULL and illegal svScope and userKey values. * This function returns NULL for all error cases, 0 upon success. * This function also returns NULL in the event that a prior call * to svPutUserData() was never made. */ XXTERN void* svGetUserData(const svScope scope, void* userKey); /* * Returns the file and line number in the SV code from which the import call * was made. If this information available, returns TRUE and updates fileName * and lineNumber to the appropriate values. Behavior is unpredictable if * fileName or lineNumber are not appropriate pointers. If this information is * not available return FALSE and contents of fileName and lineNumber not * modified. Whether this information is available or not is implementation- * specific. Note that the string provided (if any) is owned by the SV * implementation and is valid only until the next call to any SV function. * Applications must not modify this string or free it */ XXTERN int svGetCallerInfo(const char** fileName, int *lineNumber); /* * Returns 1 if the current execution thread is in the disabled state. * Disable protocol must be adhered to if in the disabled state. */ XXTERN int svIsDisabledState(); /* * Imported functions call this API function during disable processing to * acknowledge that they are correctly participating in the DPI disable protocol. * This function must be called before returning from an imported function that is * in the disabled state. */ XXTERN void svAckDisabledState(); /* ********************************************************** * DEPRECATED PORTION OF FILE STARTS FROM HERE. * IEEE-1800-compliant tools may not provide * support for the following functionality. ********************************************************** */ /* * Canonical representation of packed arrays * 2-state and 4-state vectors, modeled upon PLI's avalue/bvalue */ #define SV_CANONICAL_SIZE(WIDTH) (((WIDTH)+31)>>5) typedef unsigned int svBitVec32;/* (a chunk of) packed bit array */ typedef struct { unsigned int c; unsigned int d;} svLogicVec32; /* (a chunk of) packed logic array */ /* reference to a standalone packed array */ typedef void* svBitPackedArrRef; typedef void* svLogicPackedArrRef; /* * total size in bytes of the simulator's representation of a packed array * width in bits */ XXTERN int svSizeOfBitPackedArr(int width); XXTERN int svSizeOfLogicPackedArr(int width); /* Translation between the actual representation and the canonical representation */ /* s=source, d=destination, w=width */ /* actual <-- canonical */ XXTERN void svPutBitVec32(svBitPackedArrRef d, const svBitVec32* s, int w); XXTERN void svPutLogicVec32(svLogicPackedArrRef d, const svLogicVec32* s, int w); /* canonical <-- actual */ XXTERN void svGetBitVec32(svBitVec32* d, const svBitPackedArrRef s, int w); XXTERN void svGetLogicVec32(svLogicVec32* d, const svLogicPackedArrRef s, int w); /* * Bit-select functions * Packed arrays are assumed to be indexed n-1:0, * where 0 is the index of LSB */ /* s=source, i=bit-index */ XXTERN svBit svGetSelectBit(const svBitPackedArrRef s, int i); XXTERN svLogic svGetSelectLogic(const svLogicPackedArrRef s, int i); /* d=destination, i=bit-index, s=scalar */ XXTERN void svPutSelectBit(svBitPackedArrRef d, int i, svBit s); XXTERN void svPutSelectLogic(svLogicPackedArrRef d, int i, svLogic s); /* * functions for part-select * * a narrow (<=32 bits) part-select is copied between * the implementation representation and a single chunk of * canonical representation * Normalized ranges and indexing [n-1:0] are used for both arrays: * the array in the implementation representation and the canonical array. * * s=source, d=destination, i=starting bit index, w=width * like for variable part-selects; limitations: w <= 32 */ /* canonical <-- actual */ XXTERN void svGetPartSelectBit(svBitVec32* d, const svBitPackedArrRef s, int i, int w); XXTERN svBitVec32 svGetBits(const svBitPackedArrRef s, int i, int w); XXTERN svBitVec32 svGet32Bits(const svBitPackedArrRef s, int i); /* 32-bits */ XXTERN uint64_t svGet64Bits(const svBitPackedArrRef s, int i); /* 64-bits */ XXTERN void svGetPartSelectLogic(svLogicVec32* d, const svLogicPackedArrRef s, int i, int w); /* actual <-- canonical */ XXTERN void svPutPartSelectBit(svBitPackedArrRef d, const svBitVec32 s, int i, int w); XXTERN void svPutPartSelectLogic(svLogicPackedArrRef d, const svLogicVec32* s, int i, int w); /* * Functions for open array translation between simulator and canonical * representations. These functions copy the whole packed array in either * direction. The user is responsible for allocating an array in the * canonical representation. */ /* s=source, d=destination */ /* actual <-- canonical */ XXTERN void svPutBitArrElemVec32(const svOpenArrayHandle d, const svBitVec32* s, int indx1, ...); XXTERN void svPutBitArrElem1Vec32(const svOpenArrayHandle d, const svBitVec32* s, int indx1); XXTERN void svPutBitArrElem2Vec32(const svOpenArrayHandle d, const svBitVec32* s, int indx1, int indx2); XXTERN void svPutBitArrElem3Vec32(const svOpenArrayHandle d, const svBitVec32* s, int indx1, int indx2, int indx3); XXTERN void svPutLogicArrElemVec32(const svOpenArrayHandle d, const svLogicVec32* s, int indx1, ...); XXTERN void svPutLogicArrElem1Vec32(const svOpenArrayHandle d, const svLogicVec32* s, int indx1); XXTERN void svPutLogicArrElem2Vec32(const svOpenArrayHandle d, const svLogicVec32* s, int indx1, int indx2); XXTERN void svPutLogicArrElem3Vec32(const svOpenArrayHandle d, const svLogicVec32* s, int indx1, int indx2, int indx3); /* canonical <-- actual */ XXTERN void svGetBitArrElemVec32(svBitVec32* d, const svOpenArrayHandle s, int indx1, ...); XXTERN void svGetBitArrElem1Vec32(svBitVec32* d, const svOpenArrayHandle s, int indx1); XXTERN void svGetBitArrElem2Vec32(svBitVec32* d, const svOpenArrayHandle s, int indx1, int indx2); XXTERN void svGetBitArrElem3Vec32(svBitVec32* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3); XXTERN void svGetLogicArrElemVec32(svLogicVec32* d, const svOpenArrayHandle s, int indx1, ...); XXTERN void svGetLogicArrElem1Vec32(svLogicVec32* d, const svOpenArrayHandle s, int indx1); XXTERN void svGetLogicArrElem2Vec32(svLogicVec32* d, const svOpenArrayHandle s, int indx1, int indx2); XXTERN void svGetLogicArrElem3Vec32(svLogicVec32* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3); /* ********************************************************** * DEPRECATED PORTION OF FILE ENDS HERE. ********************************************************** */ #undef DPI_EXTERN #ifdef DPI_PROTOTYPES #undef DPI_PROTOTYPES #undef XXTERN #undef EETERN #endif #ifdef __cplusplus } #endif #endif verilator-3.874/include/vltstd/vpi_user.h0000664000177100017500000013066612436231574020516 0ustar wsnyderwsnyder/******************************************************************************* * vpi_user.h * * IEEE Std 1800-2012 Programming Language Interface (PLI) * * This file contains the constant definitions, structure definitions, and * routine declarations used by the SystemVerilog Verification Procedural * Interface (VPI) access routines. * ******************************************************************************/ /******************************************************************************* * NOTE: the constant values 1 through 299 are reserved for use in this * vpi_user.h file. ******************************************************************************/ #ifndef VPI_USER_H #define VPI_USER_H #include #ifdef __cplusplus extern "C" { #endif /*----------------------------------------------------------------------------*/ /*----------------------------- Portability Help -----------------------------*/ /*----------------------------------------------------------------------------*/ /* Define size-critical types on all OS platforms. */ #if defined (_MSC_VER) typedef unsigned __int64 uint64_t; typedef unsigned __int32 uint32_t; typedef unsigned __int8 uint8_t; typedef signed __int64 int64_t; typedef signed __int32 int32_t; typedef signed __int8 int8_t; #elif defined(__MINGW32__) #include #elif defined(__linux) || (defined(__APPLE__) && defined(__MACH__)) #include #else #include #endif /* Sized variables */ #ifndef SVPI_TYPES #define SVPI_TYPES typedef int64_t PLI_INT64; typedef uint64_t PLI_UINT64; #endif #ifndef PLI_TYPES #define PLI_TYPES typedef int PLI_INT32; typedef unsigned int PLI_UINT32; typedef short PLI_INT16; typedef unsigned short PLI_UINT16; typedef char PLI_BYTE8; typedef unsigned char PLI_UBYTE8; #endif /* Use to import a symbol */ #if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)) #ifndef PLI_DLLISPEC #define PLI_DLLISPEC __declspec(dllimport) #define VPI_USER_DEFINED_DLLISPEC 1 #endif #else #ifndef PLI_DLLISPEC #define PLI_DLLISPEC #endif #endif /* Use to export a symbol */ #if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)) #ifndef PLI_DLLESPEC #define PLI_DLLESPEC __declspec(dllexport) #define VPI_USER_DEFINED_DLLESPEC 1 #endif #else #ifndef PLI_DLLESPEC #define PLI_DLLESPEC #endif #endif /* Use to mark a function as external */ #ifndef PLI_EXTERN #define PLI_EXTERN #endif /* Use to mark a variable as external */ #ifndef PLI_VEXTERN #define PLI_VEXTERN extern #endif #ifndef PLI_PROTOTYPES #define PLI_PROTOTYPES #define PROTO_PARAMS(params) params /* object is defined imported by the application */ #define XXTERN PLI_EXTERN PLI_DLLISPEC /* object is exported by the application */ #define EETERN PLI_EXTERN PLI_DLLESPEC #endif /********************************** TYPEDEFS **********************************/ typedef PLI_UINT32 *vpiHandle; /******************************** OBJECT TYPES ********************************/ #define vpiAlways 1 /* always procedure */ #define vpiAssignStmt 2 /* quasi-continuous assignment */ #define vpiAssignment 3 /* procedural assignment */ #define vpiBegin 4 /* block statement */ #define vpiCase 5 /* case statement */ #define vpiCaseItem 6 /* case statement item */ #define vpiConstant 7 /* numerical constant or string literal */ #define vpiContAssign 8 /* continuous assignment */ #define vpiDeassign 9 /* deassignment statement */ #define vpiDefParam 10 /* defparam */ #define vpiDelayControl 11 /* delay statement (e.g., #10) */ #define vpiDisable 12 /* named block disable statement */ #define vpiEventControl 13 /* wait on event, e.g., @e */ #define vpiEventStmt 14 /* event trigger, e.g., ->e */ #define vpiFor 15 /* for statement */ #define vpiForce 16 /* force statement */ #define vpiForever 17 /* forever statement */ #define vpiFork 18 /* fork-join block */ #define vpiFuncCall 19 /* function call */ #define vpiFunction 20 /* function */ #define vpiGate 21 /* primitive gate */ #define vpiIf 22 /* if statement */ #define vpiIfElse 23 /* if-else statement */ #define vpiInitial 24 /* initial procedure */ #define vpiIntegerVar 25 /* integer variable */ #define vpiInterModPath 26 /* intermodule wire delay */ #define vpiIterator 27 /* iterator */ #define vpiIODecl 28 /* input/output declaration */ #define vpiMemory 29 /* behavioral memory */ #define vpiMemoryWord 30 /* single word of memory */ #define vpiModPath 31 /* module path for path delays */ #define vpiModule 32 /* module instance */ #define vpiNamedBegin 33 /* named block statement */ #define vpiNamedEvent 34 /* event variable */ #define vpiNamedFork 35 /* named fork-join block */ #define vpiNet 36 /* scalar or vector net */ #define vpiNetBit 37 /* bit of vector net */ #define vpiNullStmt 38 /* a semicolon. Ie. #10 ; */ #define vpiOperation 39 /* behavioral operation */ #define vpiParamAssign 40 /* module parameter assignment */ #define vpiParameter 41 /* module parameter */ #define vpiPartSelect 42 /* part-select */ #define vpiPathTerm 43 /* terminal of module path */ #define vpiPort 44 /* module port */ #define vpiPortBit 45 /* bit of vector module port */ #define vpiPrimTerm 46 /* primitive terminal */ #define vpiRealVar 47 /* real variable */ #define vpiReg 48 /* scalar or vector reg */ #define vpiRegBit 49 /* bit of vector reg */ #define vpiRelease 50 /* release statement */ #define vpiRepeat 51 /* repeat statement */ #define vpiRepeatControl 52 /* repeat control in an assign stmt */ #define vpiSchedEvent 53 /* vpi_put_value() event */ #define vpiSpecParam 54 /* specparam */ #define vpiSwitch 55 /* transistor switch */ #define vpiSysFuncCall 56 /* system function call */ #define vpiSysTaskCall 57 /* system task call */ #define vpiTableEntry 58 /* UDP state table entry */ #define vpiTask 59 /* task */ #define vpiTaskCall 60 /* task call */ #define vpiTchk 61 /* timing check */ #define vpiTchkTerm 62 /* terminal of timing check */ #define vpiTimeVar 63 /* time variable */ #define vpiTimeQueue 64 /* simulation event queue */ #define vpiUdp 65 /* user-defined primitive */ #define vpiUdpDefn 66 /* UDP definition */ #define vpiUserSystf 67 /* user-defined system task/function */ #define vpiVarSelect 68 /* variable array selection */ #define vpiWait 69 /* wait statement */ #define vpiWhile 70 /* while statement */ /********************** object types added with 1364-2001 *********************/ #define vpiAttribute 105 /* attribute of an object */ #define vpiBitSelect 106 /* Bit-select of parameter, var select */ #define vpiCallback 107 /* callback object */ #define vpiDelayTerm 108 /* Delay term which is a load or driver */ #define vpiDelayDevice 109 /* Delay object within a net */ #define vpiFrame 110 /* reentrant task/func frame */ #define vpiGateArray 111 /* gate instance array */ #define vpiModuleArray 112 /* module instance array */ #define vpiPrimitiveArray 113 /* vpiprimitiveArray type */ #define vpiNetArray 114 /* multidimensional net */ #define vpiRange 115 /* range declaration */ #define vpiRegArray 116 /* multidimensional reg */ #define vpiSwitchArray 117 /* switch instance array */ #define vpiUdpArray 118 /* UDP instance array */ #define vpiContAssignBit 128 /* Bit of a vector continuous assignment */ #define vpiNamedEventArray 129 /* multidimensional named event */ /********************** object types added with 1364-2005 *********************/ #define vpiIndexedPartSelect 130 /* Indexed part-select object */ #define vpiGenScopeArray 133 /* array of generated scopes */ #define vpiGenScope 134 /* A generated scope */ #define vpiGenVar 135 /* Object used to instantiate gen scopes */ /*********************************** METHODS **********************************/ /**************** methods used to traverse 1 to 1 relationships ***************/ #define vpiCondition 71 /* condition expression */ #define vpiDelay 72 /* net or gate delay */ #define vpiElseStmt 73 /* else statement */ #define vpiForIncStmt 74 /* increment statement in for loop */ #define vpiForInitStmt 75 /* initialization statement in for loop */ #define vpiHighConn 76 /* higher connection to port */ #define vpiLhs 77 /* left-hand side of assignment */ #define vpiIndex 78 /* index of var select, bit-select, etc. */ #define vpiLeftRange 79 /* left range of vector or part-select */ #define vpiLowConn 80 /* lower connection to port */ #define vpiParent 81 /* parent object */ #define vpiRhs 82 /* right-hand side of assignment */ #define vpiRightRange 83 /* right range of vector or part-select */ #define vpiScope 84 /* containing scope object */ #define vpiSysTfCall 85 /* task function call */ #define vpiTchkDataTerm 86 /* timing check data term */ #define vpiTchkNotifier 87 /* timing check notifier */ #define vpiTchkRefTerm 88 /* timing check reference term */ /************* methods used to traverse 1 to many relationships ***************/ #define vpiArgument 89 /* argument to (system) task/function */ #define vpiBit 90 /* bit of vector net or port */ #define vpiDriver 91 /* driver for a net */ #define vpiInternalScope 92 /* internal scope in module */ #define vpiLoad 93 /* load on net or reg */ #define vpiModDataPathIn 94 /* data terminal of a module path */ #define vpiModPathIn 95 /* Input terminal of a module path */ #define vpiModPathOut 96 /* output terminal of a module path */ #define vpiOperand 97 /* operand of expression */ #define vpiPortInst 98 /* connected port instance */ #define vpiProcess 99 /* process in module */ #define vpiVariables 100 /* variables in module */ #define vpiUse 101 /* usage */ /******** methods which can traverse 1 to 1, or 1 to many relationships *******/ #define vpiExpr 102 /* connected expression */ #define vpiPrimitive 103 /* primitive (gate, switch, UDP) */ #define vpiStmt 104 /* statement in process or task */ /************************ methods added with 1364-2001 ************************/ #define vpiActiveTimeFormat 119 /* active $timeformat() system task */ #define vpiInTerm 120 /* To get to a delay device's drivers. */ #define vpiInstanceArray 121 /* vpiInstance arrays */ #define vpiLocalDriver 122 /* local drivers (within a module */ #define vpiLocalLoad 123 /* local loads (within a module */ #define vpiOutTerm 124 /* To get to a delay device's loads. */ #define vpiPorts 125 /* Module port */ #define vpiSimNet 126 /* simulated net after collapsing */ #define vpiTaskFunc 127 /* task/function */ /************************ methods added with 1364-2005 ************************/ #define vpiBaseExpr 131 /* Indexed part-select's base expression */ #define vpiWidthExpr 132 /* Indexed part-select's width expression */ /************************ methods added with 1800-2009 ************************/ #define vpiAutomatics 136 /* Automatic variables of a frame */ /********************************* PROPERTIES *********************************/ /************************** generic object properties *************************/ #define vpiUndefined -1 /* undefined property */ #define vpiType 1 /* type of object */ #define vpiName 2 /* local name of object */ #define vpiFullName 3 /* full hierarchical name */ #define vpiSize 4 /* size of gate, net, port, etc. */ #define vpiFile 5 /* File name in which the object is used*/ #define vpiLineNo 6 /* line number where the object is used */ /***************************** module properties ******************************/ #define vpiTopModule 7 /* top-level module (Boolean) */ #define vpiCellInstance 8 /* cell (Boolean) */ #define vpiDefName 9 /* module definition name */ #define vpiProtected 10 /* source protected module (Boolean) */ #define vpiTimeUnit 11 /* module time unit */ #define vpiTimePrecision 12 /* module time precision */ #define vpiDefNetType 13 /* default net type */ #define vpiUnconnDrive 14 /* unconnected port drive strength */ #define vpiHighZ 1 /* No default drive given */ #define vpiPull1 2 /* default pull1 drive */ #define vpiPull0 3 /* default pull0 drive */ #define vpiDefFile 15 /* File name where the module is defined*/ #define vpiDefLineNo 16 /* line number for module definition */ #define vpiDefDelayMode 47 /* Default delay mode for a module */ #define vpiDelayModeNone 1 /* no delay mode specified */ #define vpiDelayModePath 2 /* path delay mode */ #define vpiDelayModeDistrib 3 /* distributed delay mode */ #define vpiDelayModeUnit 4 /* unit delay mode */ #define vpiDelayModeZero 5 /* zero delay mode */ #define vpiDelayModeMTM 6 /* min:typ:max delay mode */ #define vpiDefDecayTime 48 /* Default decay time for a module */ /*************************** port and net properties **************************/ #define vpiScalar 17 /* scalar (Boolean) */ #define vpiVector 18 /* vector (Boolean) */ #define vpiExplicitName 19 /* port is explicitly named */ #define vpiDirection 20 /* direction of port: */ #define vpiInput 1 /* input */ #define vpiOutput 2 /* output */ #define vpiInout 3 /* inout */ #define vpiMixedIO 4 /* mixed input-output */ #define vpiNoDirection 5 /* no direction */ #define vpiConnByName 21 /* connected by name (Boolean) */ #define vpiNetType 22 /* net subtypes: */ #define vpiWire 1 /* wire net */ #define vpiWand 2 /* wire-and net */ #define vpiWor 3 /* wire-or net */ #define vpiTri 4 /* tri net */ #define vpiTri0 5 /* pull-down net */ #define vpiTri1 6 /* pull-up net */ #define vpiTriReg 7 /* three-state reg net */ #define vpiTriAnd 8 /* three-state wire-and net */ #define vpiTriOr 9 /* three-state wire-or net */ #define vpiSupply1 10 /* supply-1 net */ #define vpiSupply0 11 /* supply-0 net */ #define vpiNone 12 /* no default net type (1364-2001) */ #define vpiUwire 13 /* unresolved wire net (1364-2005) */ #define vpiExplicitScalared 23 /* explicitly scalared (Boolean) */ #define vpiExplicitVectored 24 /* explicitly vectored (Boolean) */ #define vpiExpanded 25 /* expanded vector net (Boolean) */ #define vpiImplicitDecl 26 /* implicitly declared net (Boolean) */ #define vpiChargeStrength 27 /* charge decay strength of net */ /* Defined as part of strengths section. #define vpiLargeCharge 0x10 #define vpiMediumCharge 0x04 #define vpiSmallCharge 0x02 */ #define vpiArray 28 /* variable array (Boolean) */ #define vpiPortIndex 29 /* Port index */ /************************ gate and terminal properties ************************/ #define vpiTermIndex 30 /* Index of a primitive terminal */ #define vpiStrength0 31 /* 0-strength of net or gate */ #define vpiStrength1 32 /* 1-strength of net or gate */ #define vpiPrimType 33 /* primitive subtypes: */ #define vpiAndPrim 1 /* and gate */ #define vpiNandPrim 2 /* nand gate */ #define vpiNorPrim 3 /* nor gate */ #define vpiOrPrim 4 /* or gate */ #define vpiXorPrim 5 /* xor gate */ #define vpiXnorPrim 6 /* xnor gate */ #define vpiBufPrim 7 /* buffer */ #define vpiNotPrim 8 /* not gate */ #define vpiBufif0Prim 9 /* zero-enabled buffer */ #define vpiBufif1Prim 10 /* one-enabled buffer */ #define vpiNotif0Prim 11 /* zero-enabled not gate */ #define vpiNotif1Prim 12 /* one-enabled not gate */ #define vpiNmosPrim 13 /* nmos switch */ #define vpiPmosPrim 14 /* pmos switch */ #define vpiCmosPrim 15 /* cmos switch */ #define vpiRnmosPrim 16 /* resistive nmos switch */ #define vpiRpmosPrim 17 /* resistive pmos switch */ #define vpiRcmosPrim 18 /* resistive cmos switch */ #define vpiRtranPrim 19 /* resistive bidirectional */ #define vpiRtranif0Prim 20 /* zero-enable resistive bidirectional */ #define vpiRtranif1Prim 21 /* one-enable resistive bidirectional */ #define vpiTranPrim 22 /* bidirectional */ #define vpiTranif0Prim 23 /* zero-enabled bidirectional */ #define vpiTranif1Prim 24 /* one-enabled bidirectional */ #define vpiPullupPrim 25 /* pullup */ #define vpiPulldownPrim 26 /* pulldown */ #define vpiSeqPrim 27 /* sequential UDP */ #define vpiCombPrim 28 /* combinational UDP */ /**************** path, path terminal, timing check properties ****************/ #define vpiPolarity 34 /* polarity of module path... */ #define vpiDataPolarity 35 /* ...or data path: */ #define vpiPositive 1 /* positive */ #define vpiNegative 2 /* negative */ #define vpiUnknown 3 /* unknown (unspecified) */ #define vpiEdge 36 /* edge type of module path: */ #define vpiNoEdge 0x00 /* no edge */ #define vpiEdge01 0x01 /* 0 -> 1 */ #define vpiEdge10 0x02 /* 1 -> 0 */ #define vpiEdge0x 0x04 /* 0 -> x */ #define vpiEdgex1 0x08 /* x -> 1 */ #define vpiEdge1x 0x10 /* 1 -> x */ #define vpiEdgex0 0x20 /* x -> 0 */ #define vpiPosedge (vpiEdgex1 | vpiEdge01 | vpiEdge0x) #define vpiNegedge (vpiEdgex0 | vpiEdge10 | vpiEdge1x) #define vpiAnyEdge (vpiPosedge | vpiNegedge) #define vpiPathType 37 /* path delay connection subtypes: */ #define vpiPathFull 1 /* ( a *> b ) */ #define vpiPathParallel 2 /* ( a => b ) */ #define vpiTchkType 38 /* timing check subtypes: */ #define vpiSetup 1 /* $setup */ #define vpiHold 2 /* $hold */ #define vpiPeriod 3 /* $period */ #define vpiWidth 4 /* $width */ #define vpiSkew 5 /* $skew */ #define vpiRecovery 6 /* $recovery */ #define vpiNoChange 7 /* $nochange */ #define vpiSetupHold 8 /* $setuphold */ #define vpiFullskew 9 /* $fullskew -- added for 1364-2001 */ #define vpiRecrem 10 /* $recrem -- added for 1364-2001 */ #define vpiRemoval 11 /* $removal -- added for 1364-2001 */ #define vpiTimeskew 12 /* $timeskew -- added for 1364-2001 */ /**************************** expression properties ***************************/ #define vpiOpType 39 /* operation subtypes: */ #define vpiMinusOp 1 /* unary minus */ #define vpiPlusOp 2 /* unary plus */ #define vpiNotOp 3 /* unary not */ #define vpiBitNegOp 4 /* bitwise negation */ #define vpiUnaryAndOp 5 /* bitwise reduction AND */ #define vpiUnaryNandOp 6 /* bitwise reduction NAND */ #define vpiUnaryOrOp 7 /* bitwise reduction OR */ #define vpiUnaryNorOp 8 /* bitwise reduction NOR */ #define vpiUnaryXorOp 9 /* bitwise reduction XOR */ #define vpiUnaryXNorOp 10 /* bitwise reduction XNOR */ #define vpiSubOp 11 /* binary subtraction */ #define vpiDivOp 12 /* binary division */ #define vpiModOp 13 /* binary modulus */ #define vpiEqOp 14 /* binary equality */ #define vpiNeqOp 15 /* binary inequality */ #define vpiCaseEqOp 16 /* case (x and z) equality */ #define vpiCaseNeqOp 17 /* case inequality */ #define vpiGtOp 18 /* binary greater than */ #define vpiGeOp 19 /* binary greater than or equal */ #define vpiLtOp 20 /* binary less than */ #define vpiLeOp 21 /* binary less than or equal */ #define vpiLShiftOp 22 /* binary left shift */ #define vpiRShiftOp 23 /* binary right shift */ #define vpiAddOp 24 /* binary addition */ #define vpiMultOp 25 /* binary multiplication */ #define vpiLogAndOp 26 /* binary logical AND */ #define vpiLogOrOp 27 /* binary logical OR */ #define vpiBitAndOp 28 /* binary bitwise AND */ #define vpiBitOrOp 29 /* binary bitwise OR */ #define vpiBitXorOp 30 /* binary bitwise XOR */ #define vpiBitXNorOp 31 /* binary bitwise XNOR */ #define vpiBitXnorOp vpiBitXNorOp /* added with 1364-2001 */ #define vpiConditionOp 32 /* ternary conditional */ #define vpiConcatOp 33 /* n-ary concatenation */ #define vpiMultiConcatOp 34 /* repeated concatenation */ #define vpiEventOrOp 35 /* event OR */ #define vpiNullOp 36 /* null operation */ #define vpiListOp 37 /* list of expressions */ #define vpiMinTypMaxOp 38 /* min:typ:max: delay expression */ #define vpiPosedgeOp 39 /* posedge */ #define vpiNegedgeOp 40 /* negedge */ #define vpiArithLShiftOp 41 /* arithmetic left shift (1364-2001) */ #define vpiArithRShiftOp 42 /* arithmetic right shift (1364-2001) */ #define vpiPowerOp 43 /* arithmetic power op (1364-2001) */ #define vpiConstType 40 /* constant subtypes: */ #define vpiDecConst 1 /* decimal integer */ #define vpiRealConst 2 /* real */ #define vpiBinaryConst 3 /* binary integer */ #define vpiOctConst 4 /* octal integer */ #define vpiHexConst 5 /* hexadecimal integer */ #define vpiStringConst 6 /* string literal */ #define vpiIntConst 7 /* integer constant (1364-2001) */ #define vpiTimeConst 8 /* time constant */ #define vpiBlocking 41 /* blocking assignment (Boolean) */ #define vpiCaseType 42 /* case statement subtypes: */ #define vpiCaseExact 1 /* exact match */ #define vpiCaseX 2 /* ignore X's */ #define vpiCaseZ 3 /* ignore Z's */ #define vpiNetDeclAssign 43 /* assign part of decl (Boolean) */ /************************** task/function properties **************************/ #define vpiFuncType 44 /* function & system function type */ #define vpiIntFunc 1 /* returns integer */ #define vpiRealFunc 2 /* returns real */ #define vpiTimeFunc 3 /* returns time */ #define vpiSizedFunc 4 /* returns an arbitrary size */ #define vpiSizedSignedFunc 5 /* returns sized signed value */ /** alias 1364-1995 system function subtypes to 1364-2001 function subtypes ***/ #define vpiSysFuncType vpiFuncType #define vpiSysFuncInt vpiIntFunc #define vpiSysFuncReal vpiRealFunc #define vpiSysFuncTime vpiTimeFunc #define vpiSysFuncSized vpiSizedFunc #define vpiUserDefn 45 /*user-defined system task/func(Boolean)*/ #define vpiScheduled 46 /* object still scheduled (Boolean) */ /*********************** properties added with 1364-2001 **********************/ #define vpiActive 49 /* reentrant task/func frame is active */ #define vpiAutomatic 50 /* task/func obj is automatic */ #define vpiCell 51 /* configuration cell */ #define vpiConfig 52 /* configuration config file */ #define vpiConstantSelect 53 /* (Boolean) bit-select or part-select indices are constant expressions */ #define vpiDecompile 54 /* decompile the object */ #define vpiDefAttribute 55 /* Attribute defined for the obj */ #define vpiDelayType 56 /* delay subtype */ #define vpiModPathDelay 1 /* module path delay */ #define vpiInterModPathDelay 2 /* intermodule path delay */ #define vpiMIPDelay 3 /* module input port delay */ #define vpiIteratorType 57 /* object type of an iterator */ #define vpiLibrary 58 /* configuration library */ #define vpiOffset 60 /* offset from LSB */ #define vpiResolvedNetType 61 /* net subtype after resolution, returns same subtypes as vpiNetType */ #define vpiSaveRestartID 62 /* unique ID for save/restart data */ #define vpiSaveRestartLocation 63 /* name of save/restart data file */ /* vpiValid,vpiValidTrue,vpiValidFalse were deprecated in 1800-2009 */ #define vpiValid 64 /* reentrant task/func frame or automatic variable is valid */ #define vpiValidFalse 0 #define vpiValidTrue 1 #define vpiSigned 65 /* TRUE for vpiIODecl and any object in the expression class if the object has the signed attribute */ #define vpiLocalParam 70 /* TRUE when a param is declared as a localparam */ #define vpiModPathHasIfNone 71 /* Mod path has an ifnone statement */ /*********************** properties added with 1364-2005 **********************/ #define vpiIndexedPartSelectType 72 /* Indexed part-select type */ #define vpiPosIndexed 1 /* +: */ #define vpiNegIndexed 2 /* -: */ #define vpiIsMemory 73 /* TRUE for a one-dimensional reg array */ #define vpiIsProtected 74 /* TRUE for protected design information */ /*************** vpi_control() constants (added with 1364-2001) ***************/ #define vpiStop 66 /* execute simulator's $stop */ #define vpiFinish 67 /* execute simulator's $finish */ #define vpiReset 68 /* execute simulator's $reset */ #define vpiSetInteractiveScope 69 /* set simulator's interactive scope */ /**************************** I/O related defines *****************************/ #define VPI_MCD_STDOUT 0x00000001 /*************************** STRUCTURE DEFINITIONS ****************************/ /******************************* time structure *******************************/ typedef struct t_vpi_time { PLI_INT32 type; /* [vpiScaledRealTime, vpiSimTime, vpiSuppressTime] */ PLI_UINT32 high, low; /* for vpiSimTime */ double real; /* for vpiScaledRealTime */ } s_vpi_time, *p_vpi_time; /* time types */ #define vpiScaledRealTime 1 #define vpiSimTime 2 #define vpiSuppressTime 3 /****************************** delay structures ******************************/ typedef struct t_vpi_delay { struct t_vpi_time *da; /* pointer to application-allocated array of delay values */ PLI_INT32 no_of_delays; /* number of delays */ PLI_INT32 time_type; /* [vpiScaledRealTime, vpiSimTime, vpiSuppressTime] */ PLI_INT32 mtm_flag; /* true for mtm values */ PLI_INT32 append_flag; /* true for append */ PLI_INT32 pulsere_flag; /* true for pulsere values */ } s_vpi_delay, *p_vpi_delay; /***************************** value structures *******************************/ /* vector value */ #ifndef VPI_VECVAL /* added in 1364-2005 */ #define VPI_VECVAL typedef struct t_vpi_vecval { /* following fields are repeated enough times to contain vector */ PLI_UINT32 aval, bval; /* bit encoding: ab: 00=0, 10=1, 11=X, 01=Z */ } s_vpi_vecval, *p_vpi_vecval; #endif /* strength (scalar) value */ typedef struct t_vpi_strengthval { PLI_INT32 logic; /* vpi[0,1,X,Z] */ PLI_INT32 s0, s1; /* refer to strength coding below */ } s_vpi_strengthval, *p_vpi_strengthval; /* strength values */ #define vpiSupplyDrive 0x80 #define vpiStrongDrive 0x40 #define vpiPullDrive 0x20 #define vpiWeakDrive 0x08 #define vpiLargeCharge 0x10 #define vpiMediumCharge 0x04 #define vpiSmallCharge 0x02 #define vpiHiZ 0x01 /* generic value */ typedef struct t_vpi_value { PLI_INT32 format; /* vpi[[Bin,Oct,Dec,Hex]Str,Scalar,Int,Real,String, Vector,Strength,Suppress,Time,ObjType]Val */ union { PLI_BYTE8 *str; /* string value */ PLI_INT32 scalar; /* vpi[0,1,X,Z] */ PLI_INT32 integer; /* integer value */ double real; /* real value */ struct t_vpi_time *time; /* time value */ struct t_vpi_vecval *vector; /* vector value */ struct t_vpi_strengthval *strength; /* strength value */ PLI_BYTE8 *misc; /* ...other */ } value; } s_vpi_value, *p_vpi_value; typedef struct t_vpi_arrayvalue { PLI_UINT32 format; /* vpi[Int,Real,Time,ShortInt,LongInt,ShortReal, RawTwoState,RawFourState]Val */ PLI_UINT32 flags; /* array bit flags- vpiUserAllocFlag */ union { PLI_INT32 *integers; /* integer values */ PLI_INT16 *shortints; /* short integer values */ PLI_INT64 *longints; /* long integer values */ PLI_BYTE8 *rawvals; /* 2/4-state vector elements */ struct t_vpi_vecval *vectors; /* 4-state vector elements */ struct t_vpi_time *times; /* time values */ double *reals; /* real values */ float *shortreals; /* short real values */ } value; } s_vpi_arrayvalue, *p_vpi_arrayvalue; /* value formats */ #define vpiBinStrVal 1 #define vpiOctStrVal 2 #define vpiDecStrVal 3 #define vpiHexStrVal 4 #define vpiScalarVal 5 #define vpiIntVal 6 #define vpiRealVal 7 #define vpiStringVal 8 #define vpiVectorVal 9 #define vpiStrengthVal 10 #define vpiTimeVal 11 #define vpiObjTypeVal 12 #define vpiSuppressVal 13 #define vpiShortIntVal 14 #define vpiLongIntVal 15 #define vpiShortRealVal 16 #define vpiRawTwoStateVal 17 #define vpiRawFourStateVal 18 /* delay modes */ #define vpiNoDelay 1 #define vpiInertialDelay 2 #define vpiTransportDelay 3 #define vpiPureTransportDelay 4 /* force and release flags */ #define vpiForceFlag 5 #define vpiReleaseFlag 6 /* scheduled event cancel flag */ #define vpiCancelEvent 7 /* bit mask for the flags argument to vpi_put_value() */ #define vpiReturnEvent 0x1000 /* bit flags for vpi_get_value_array flags field */ #define vpiUserAllocFlag 0x2000 /* bit flags for vpi_put_value_array flags field */ #define vpiOneValue 0x4000 #define vpiPropagateOff 0x8000 /* scalar values */ #define vpi0 0 #define vpi1 1 #define vpiZ 2 #define vpiX 3 #define vpiH 4 #define vpiL 5 #define vpiDontCare 6 /* #define vpiNoChange 7 Defined under vpiTchkType, but can be used here. */ /*********************** system task/function structure ***********************/ typedef struct t_vpi_systf_data { PLI_INT32 type; /* vpiSysTask, vpiSysFunc */ PLI_INT32 sysfunctype; /* vpiSysTask, vpi[Int,Real,Time,Sized, SizedSigned]Func */ PLI_BYTE8 *tfname; /* first character must be '$' */ PLI_INT32 (*calltf)(PLI_BYTE8 *); PLI_INT32 (*compiletf)(PLI_BYTE8 *); PLI_INT32 (*sizetf)(PLI_BYTE8 *); /* for sized function callbacks only */ PLI_BYTE8 *user_data; } s_vpi_systf_data, *p_vpi_systf_data; #define vpiSysTask 1 #define vpiSysFunc 2 /* the subtypes are defined under the vpiFuncType property */ /**************** SystemVerilog execution information structure ***************/ typedef struct t_vpi_vlog_info { PLI_INT32 argc; PLI_BYTE8 **argv; PLI_BYTE8 *product; PLI_BYTE8 *version; } s_vpi_vlog_info, *p_vpi_vlog_info; /*********************** PLI error information structure **********************/ typedef struct t_vpi_error_info { PLI_INT32 state; /* vpi[Compile,PLI,Run] */ PLI_INT32 level; /* vpi[Notice,Warning,Error,System,Internal] */ PLI_BYTE8 *message; PLI_BYTE8 *product; PLI_BYTE8 *code; PLI_BYTE8 *file; PLI_INT32 line; } s_vpi_error_info, *p_vpi_error_info; /* state when error occurred */ #define vpiCompile 1 #define vpiPLI 2 #define vpiRun 3 /* error severity levels */ #define vpiNotice 1 #define vpiWarning 2 #define vpiError 3 #define vpiSystem 4 #define vpiInternal 5 /**************************** callback structures *****************************/ /* normal callback structure */ typedef struct t_cb_data { PLI_INT32 reason; /* callback reason */ PLI_INT32 (*cb_rtn)(struct t_cb_data *); /* call routine */ vpiHandle obj; /* trigger object */ p_vpi_time time; /* callback time */ p_vpi_value value; /* trigger object value */ PLI_INT32 index; /* index of the memory word or var select that changed */ PLI_BYTE8 *user_data; } s_cb_data, *p_cb_data; /****************************** CALLBACK REASONS ******************************/ /***************************** Simulation related *****************************/ #define cbValueChange 1 #define cbStmt 2 #define cbForce 3 #define cbRelease 4 /******************************** Time related ********************************/ #define cbAtStartOfSimTime 5 #define cbReadWriteSynch 6 #define cbReadOnlySynch 7 #define cbNextSimTime 8 #define cbAfterDelay 9 /******************************* Action related *******************************/ #define cbEndOfCompile 10 #define cbStartOfSimulation 11 #define cbEndOfSimulation 12 #define cbError 13 #define cbTchkViolation 14 #define cbStartOfSave 15 #define cbEndOfSave 16 #define cbStartOfRestart 17 #define cbEndOfRestart 18 #define cbStartOfReset 19 #define cbEndOfReset 20 #define cbEnterInteractive 21 #define cbExitInteractive 22 #define cbInteractiveScopeChange 23 #define cbUnresolvedSystf 24 /**************************** Added with 1364-2001 ****************************/ #define cbAssign 25 #define cbDeassign 26 #define cbDisable 27 #define cbPLIError 28 #define cbSignal 29 /**************************** Added with 1364-2005 ****************************/ #define cbNBASynch 30 #define cbAtEndOfSimTime 31 /**************************** FUNCTION DECLARATIONS ***************************/ /* Include compatibility mode macro definitions. */ //#include "vpi_compatibility.h" /* callback related */ XXTERN vpiHandle vpi_register_cb PROTO_PARAMS((p_cb_data cb_data_p)); XXTERN PLI_INT32 vpi_remove_cb PROTO_PARAMS((vpiHandle cb_obj)); XXTERN void vpi_get_cb_info PROTO_PARAMS((vpiHandle object, p_cb_data cb_data_p)); XXTERN vpiHandle vpi_register_systf PROTO_PARAMS((p_vpi_systf_data systf_data_p)); XXTERN void vpi_get_systf_info PROTO_PARAMS((vpiHandle object, p_vpi_systf_data systf_data_p)); /* for obtaining handles */ XXTERN vpiHandle vpi_handle_by_name PROTO_PARAMS((PLI_BYTE8 *name, vpiHandle scope)); XXTERN vpiHandle vpi_handle_by_index PROTO_PARAMS((vpiHandle object, PLI_INT32 indx)); /* for traversing relationships */ XXTERN vpiHandle vpi_handle PROTO_PARAMS((PLI_INT32 type, vpiHandle refHandle)); XXTERN vpiHandle vpi_handle_multi PROTO_PARAMS((PLI_INT32 type, vpiHandle refHandle1, vpiHandle refHandle2, ... )); XXTERN vpiHandle vpi_iterate PROTO_PARAMS((PLI_INT32 type, vpiHandle refHandle)); XXTERN vpiHandle vpi_scan PROTO_PARAMS((vpiHandle iterator)); /* for processing properties */ XXTERN PLI_INT32 vpi_get PROTO_PARAMS((PLI_INT32 property, vpiHandle object)); XXTERN PLI_INT64 vpi_get64 PROTO_PARAMS((PLI_INT32 property, vpiHandle object)); XXTERN PLI_BYTE8 *vpi_get_str PROTO_PARAMS((PLI_INT32 property, vpiHandle object)); /* delay processing */ XXTERN void vpi_get_delays PROTO_PARAMS((vpiHandle object, p_vpi_delay delay_p)); XXTERN void vpi_put_delays PROTO_PARAMS((vpiHandle object, p_vpi_delay delay_p)); /* value processing */ XXTERN void vpi_get_value PROTO_PARAMS((vpiHandle expr, p_vpi_value value_p)); XXTERN vpiHandle vpi_put_value PROTO_PARAMS((vpiHandle object, p_vpi_value value_p, p_vpi_time time_p, PLI_INT32 flags)); XXTERN void vpi_get_value_array PROTO_PARAMS((vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_INT32 *index_p, PLI_UINT32 num)); XXTERN void vpi_put_value_array PROTO_PARAMS((vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_INT32 *index_p, PLI_UINT32 num)); /* time processing */ XXTERN void vpi_get_time PROTO_PARAMS((vpiHandle object, p_vpi_time time_p)); /* I/O routines */ XXTERN PLI_UINT32 vpi_mcd_open PROTO_PARAMS((PLI_BYTE8 *fileName)); XXTERN PLI_UINT32 vpi_mcd_close PROTO_PARAMS((PLI_UINT32 mcd)); XXTERN PLI_BYTE8 *vpi_mcd_name PROTO_PARAMS((PLI_UINT32 cd)); XXTERN PLI_INT32 vpi_mcd_printf PROTO_PARAMS((PLI_UINT32 mcd, PLI_BYTE8 *format, ...)); XXTERN PLI_INT32 vpi_printf PROTO_PARAMS((PLI_BYTE8 *format, ...)); /* utility routines */ XXTERN PLI_INT32 vpi_compare_objects PROTO_PARAMS((vpiHandle object1, vpiHandle object2)); XXTERN PLI_INT32 vpi_chk_error PROTO_PARAMS((p_vpi_error_info error_info_p)); /* vpi_free_object() was deprecated in 1800-2009 */ XXTERN PLI_INT32 vpi_free_object PROTO_PARAMS((vpiHandle object)); XXTERN PLI_INT32 vpi_release_handle PROTO_PARAMS((vpiHandle object)); XXTERN PLI_INT32 vpi_get_vlog_info PROTO_PARAMS((p_vpi_vlog_info vlog_info_p)); /* routines added with 1364-2001 */ XXTERN PLI_INT32 vpi_get_data PROTO_PARAMS((PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes)); XXTERN PLI_INT32 vpi_put_data PROTO_PARAMS((PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes)); XXTERN void *vpi_get_userdata PROTO_PARAMS((vpiHandle obj)); XXTERN PLI_INT32 vpi_put_userdata PROTO_PARAMS((vpiHandle obj, void *userdata)); XXTERN PLI_INT32 vpi_vprintf PROTO_PARAMS((PLI_BYTE8 *format, va_list ap)); XXTERN PLI_INT32 vpi_mcd_vprintf PROTO_PARAMS((PLI_UINT32 mcd, PLI_BYTE8 *format, va_list ap)); XXTERN PLI_INT32 vpi_flush PROTO_PARAMS((void)); XXTERN PLI_INT32 vpi_mcd_flush PROTO_PARAMS((PLI_UINT32 mcd)); XXTERN PLI_INT32 vpi_control PROTO_PARAMS((PLI_INT32 operation, ...)); XXTERN vpiHandle vpi_handle_by_multi_index PROTO_PARAMS((vpiHandle obj, PLI_INT32 num_index, PLI_INT32 *index_array)); /****************************** GLOBAL VARIABLES ******************************/ PLI_VEXTERN PLI_DLLESPEC void (*vlog_startup_routines[])(); /* array of function pointers, last pointer should be null */ #undef PLI_EXTERN #undef PLI_VEXTERN #ifdef VPI_USER_DEFINED_DLLISPEC # undef VPI_USER_DEFINED_DLLISPEC # undef PLI_DLLISPEC #endif #ifdef VPI_USER_DEFINED_DLLESPEC # undef VPI_USER_DEFINED_DLLESPEC # undef PLI_DLLESPEC #endif #ifdef PLI_PROTOTYPES # undef PLI_PROTOTYPES # undef PROTO_PARAMS # undef XXTERN # undef EETERN #endif #ifdef __cplusplus } #endif #endif /* VPI_USER_H */ verilator-3.874/include/verilated_vcd_c.cpp0000664000177100017500000006004112525172076020777 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2015 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. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief C++ Tracing in VCD Format /// //============================================================================= // SPDIFF_OFF #include "verilatedos.h" #include "verilated.h" #include "verilated_vcd_c.h" #include #include #include #include #include #include #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) # include #else # include #endif // SPDIFF_ON #ifndef O_LARGEFILE // For example on WIN32 # define O_LARGEFILE 0 #endif #ifndef O_NONBLOCK # define O_NONBLOCK 0 #endif //============================================================================= // Global vector VerilatedVcd::s_vcdVecp; ///< List of all created traces //============================================================================= // VerilatedVcdCallInfo /// Internal callback routines for each module being traced. //// /// Each module that wishes to be traced registers a set of /// callbacks stored in this class. When the trace file is being /// constructed, this class provides the callback routines to be executed. class VerilatedVcdCallInfo { protected: friend class VerilatedVcd; VerilatedVcdCallback_t m_initcb; ///< Initialization Callback function VerilatedVcdCallback_t m_fullcb; ///< Full Dumping Callback function VerilatedVcdCallback_t m_changecb; ///< Incremental Dumping Callback function void* m_userthis; ///< Fake "this" for caller vluint32_t m_code; ///< Starting code number // CREATORS VerilatedVcdCallInfo (VerilatedVcdCallback_t icb, VerilatedVcdCallback_t fcb, VerilatedVcdCallback_t changecb, void* ut, vluint32_t code) : m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {}; }; //============================================================================= //============================================================================= //============================================================================= // VerilatedVcdFile bool VerilatedVcdFile::open(const string& name) { m_fd = ::open(name.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK, 0666); return (m_fd>=0); } void VerilatedVcdFile::close() { ::close(m_fd); } ssize_t VerilatedVcdFile::write(const char* bufp, ssize_t len) { return ::write(m_fd, bufp, len); } //============================================================================= //============================================================================= //============================================================================= // Opening/Closing VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep) : m_isOpen(false), m_rolloverMB(0), m_modDepth(0), m_nextCode(1) { // Not in header to avoid link issue if header is included without this .cpp file m_fileNewed = (filep == NULL); m_filep = m_fileNewed ? new VerilatedVcdFile : filep; m_namemapp = NULL; m_timeRes = m_timeUnit = 1e-9; m_timeLastDump = 0; m_sigs_oldvalp = NULL; m_evcd = false; m_scopeEscape = '.'; // Backward compatibility m_fullDump = true; m_wrChunkSize = 8*1024; m_wrBufp = new char [m_wrChunkSize*8]; m_wrFlushp = m_wrBufp + m_wrChunkSize * 6; m_writep = m_wrBufp; m_wroteBytes = 0; } void VerilatedVcd::open (const char* filename) { if (isOpen()) return; // Set member variables m_filename = filename; s_vcdVecp.push_back(this); // SPDIFF_OFF // Set callback so an early exit will flush us Verilated::flushCb(&flush_all); // SPDIFF_ON openNext (m_rolloverMB!=0); if (!isOpen()) return; dumpHeader(); // Allocate space now we know the number of codes if (!m_sigs_oldvalp) { m_sigs_oldvalp = new vluint32_t [m_nextCode+10]; } if (m_rolloverMB) { openNext(true); if (!isOpen()) return; } } void VerilatedVcd::openNext (bool incFilename) { // Open next filename in concat sequence, mangle filename if // incFilename is true. closePrev(); // Close existing if (incFilename) { // Find _0000.{ext} in filename string name = m_filename; size_t pos=name.rfind("."); if (pos>8 && 0==strncmp("_cat",name.c_str()+pos-8,4) && isdigit(name.c_str()[pos-4]) && isdigit(name.c_str()[pos-3]) && isdigit(name.c_str()[pos-2]) && isdigit(name.c_str()[pos-1])) { // Increment code. if ((++(name[pos-1])) > '9') { name[pos-1] = '0'; if ((++(name[pos-2])) > '9') { name[pos-2] = '0'; if ((++(name[pos-3])) > '9') { name[pos-3] = '0'; if ((++(name[pos-4])) > '9') { name[pos-4] = '0'; }}}} } else { // Append _cat0000 name.insert(pos,"_cat0000"); } m_filename = name; } if (m_filename[0]=='|') { assert(0); // Not supported yet. } else { // cppcheck-suppress duplicateExpression if (!m_filep->open(m_filename)) { // User code can check isOpen() m_isOpen = false; return; } } m_isOpen = true; m_fullDump = true; // First dump must be full m_wroteBytes = 0; } void VerilatedVcd::makeNameMap() { // Take signal information from each module and build m_namemapp deleteNameMap(); m_nextCode = 1; m_namemapp = new NameMap; for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) { VerilatedVcdCallInfo *cip = m_callbacks[ent]; cip->m_code = nextCode(); (cip->m_initcb) (this, cip->m_userthis, cip->m_code); } // Though not speced, it's illegal to generate a vcd with signals // not under any module - it crashes at least two viewers. // If no scope was specified, prefix everything with a "top" // This comes from user instantiations with no name - IE Vtop(""). bool nullScope = false; for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) { const string& hiername = it->first; if (hiername.size() >= 1 && hiername[0] == '\t') nullScope=true; } if (nullScope) { NameMap* newmapp = new NameMap; for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) { const string& hiername = it->first; const string& decl = it->second; string newname = string("top"); if (hiername[0] != '\t') newname += ' '; newname += hiername; newmapp->insert(make_pair(newname,decl)); } deleteNameMap(); m_namemapp = newmapp; } } void VerilatedVcd::deleteNameMap() { if (m_namemapp) { delete m_namemapp; m_namemapp=NULL; } } VerilatedVcd::~VerilatedVcd() { close(); if (m_wrBufp) { delete[] m_wrBufp; m_wrBufp=NULL; } if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; } deleteNameMap(); if (m_filep && m_fileNewed) { delete m_filep; m_filep = NULL; } // Remove from list of traces vector::iterator pos = find(s_vcdVecp.begin(), s_vcdVecp.end(), this); if (pos != s_vcdVecp.end()) { s_vcdVecp.erase(pos); } } void VerilatedVcd::closePrev () { if (!isOpen()) return; bufferFlush(); m_isOpen = false; m_filep->close(); } void VerilatedVcd::closeErr () { // Close due to an error. We might abort before even getting here, // depending on the definition of vl_fatal. if (!isOpen()) return; // No buffer flush, just fclose m_isOpen = false; m_filep->close(); // May get error, just ignore it } void VerilatedVcd::close() { if (!isOpen()) return; if (m_evcd) { printStr("$vcdclose "); printTime(m_timeLastDump); printStr(" $end\n"); } closePrev(); } void VerilatedVcd::printStr (const char* str) { // Not fast... while (*str) { *m_writep++ = *str++; bufferCheck(); } } void VerilatedVcd::printQuad (vluint64_t n) { char buf [100]; sprintf(buf,"%" VL_PRI64 "u", n); printStr(buf); } void VerilatedVcd::printTime (vluint64_t timeui) { // VCD file format specification does not allow non-integers for timestamps // Dinotrace doesn't mind, but Cadence vvision seems to choke if (VL_UNLIKELY(timeui < m_timeLastDump)) { timeui = m_timeLastDump; static bool backTime = false; if (!backTime) { backTime = true; VL_PRINTF("VCD time is moving backwards, wave file may be incorrect.\n"); } } m_timeLastDump = timeui; printQuad(timeui); } void VerilatedVcd::bufferResize(vluint64_t minsize) { // minsize is size of largest write. We buffer at least 8 times as much data, // writing when we are 3/4 full (with thus 2*minsize remaining free) if (VL_UNLIKELY(minsize > m_wrChunkSize)) { char* oldbufp = m_wrBufp; m_wrChunkSize = minsize*2; m_wrBufp = new char [m_wrChunkSize * 8]; memcpy(m_wrBufp, oldbufp, m_writep - oldbufp); m_writep = m_wrBufp + (m_writep - oldbufp); m_wrFlushp = m_wrBufp + m_wrChunkSize * 6; delete oldbufp; oldbufp=NULL; } } void VerilatedVcd::bufferFlush () { // We add output data to m_writep. // When it gets nearly full we dump it using this routine which calls write() // This is much faster than using buffered I/O if (VL_UNLIKELY(!isOpen())) return; char* wp = m_wrBufp; while (1) { ssize_t remaining = (m_writep - wp); if (remaining==0) break; errno = 0; ssize_t got = m_filep->write(wp, remaining); if (got>0) { wp += got; m_wroteBytes += got; } else if (got < 0) { if (errno != EAGAIN && errno != EINTR) { // write failed, presume error (perhaps out of disk space) string msg = (string)"VerilatedVcd::bufferFlush: "+strerror(errno); vl_fatal("",0,"",msg.c_str()); closeErr(); break; } } } // Reset buffer m_writep = m_wrBufp; } //============================================================================= // Simple methods void VerilatedVcd::set_time_unit (const char* unitp) { //cout<<" set_time_unit ("<=1e0) { suffixp="s"; value *= 1e0; } else if (value>=1e-3 ) { suffixp="ms"; value *= 1e3; } else if (value>=1e-6 ) { suffixp="us"; value *= 1e6; } else if (value>=1e-9 ) { suffixp="ns"; value *= 1e9; } else if (value>=1e-12) { suffixp="ps"; value *= 1e12; } else if (value>=1e-15) { suffixp="fs"; value *= 1e15; } else if (value>=1e-18) { suffixp="as"; value *= 1e18; } char valuestr[100]; sprintf(valuestr,"%d%s",(int)(value), suffixp); return valuestr; // Gets converted to string, so no ref to stack } //============================================================================= // Definitions void VerilatedVcd::printIndent (int level_change) { if (level_change<0) m_modDepth += level_change; assert(m_modDepth>=0); for (int i=0; i0) m_modDepth += level_change; } void VerilatedVcd::dumpHeader () { printStr("$version Generated by VerilatedVcd $end\n"); time_t time_str = time(NULL); printStr("$date "); printStr(ctime(&time_str)); printStr(" $end\n"); printStr("$timescale "); const string& timeResStr = doubleToTimescale(m_timeRes); printStr(timeResStr.c_str()); printStr(" $end\n"); makeNameMap(); // Signal header assert (m_modDepth==0); printIndent(1); printStr("\n"); // We detect the spaces in module names to determine hierarchy. This // allows signals to be declared without fixed ordering, which is // required as Verilog signals might be separately declared from // "SP_TRACE" signals. // Print the signal names const char* lastName = ""; for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) { const string& hiernamestr = it->first; const string& decl = it->second; // Determine difference between the old and new names const char* hiername = hiernamestr.c_str(); const char* lp = lastName; const char* np = hiername; lastName = hiername; // Skip common prefix, it must break at a space or tab for (; *np && (*np == *lp); np++, lp++) {} while (np!=hiername && *np && *np!=' ' && *np!='\t') { np--; lp--; } //printf("hier %s\n lp=%s\n np=%s\n",hiername,lp,np); // Any extra spaces in last name are scope ups we need to do bool first = true; for (; *lp; lp++) { if (*lp==' ' || (first && *lp!='\t')) { printIndent(-1); printStr("$upscope $end\n"); } first = false; } // Any new spaces are scope downs we need to do while (*np) { if (*np==' ') np++; if (*np=='\t') break; // tab means signal name starts printIndent(1); printStr("$scope module "); for (; *np && *np!=' ' && *np!='\t'; np++) { if (*np=='[') printStr("("); else if (*np==']') printStr(")"); else *m_writep++=*np; } printStr(" $end\n"); } printIndent(0); printStr(decl.c_str()); } while (m_modDepth>1) { printIndent(-1); printStr("$upscope $end\n"); } printIndent(-1); printStr("$enddefinitions $end\n\n\n"); assert (m_modDepth==0); // Reclaim storage deleteNameMap(); } void VerilatedVcd::module (const string& name) { m_modName = name; } void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep, int arraynum, bool tri, bool bussed, int msb, int lsb) { if (!code) { vl_fatal(__FILE__,__LINE__,"","Internal: internal trace problem, code 0 is illegal"); } int bits = ((msb>lsb)?(msb-lsb):(lsb-msb))+1; int codesNeeded = 1+int(bits/32); if (tri) codesNeeded *= 2; // Space in change array for __en signals // Make sure array is large enough m_nextCode = max(nextCode(), code+codesNeeded); if (m_sigs.capacity() <= m_nextCode) { m_sigs.reserve(m_nextCode*2); // Power-of-2 allocation speeds things up } // Make sure write buffer is large enough (one character per bit), plus header bufferResize(bits+1024); // Save declaration info VerilatedVcdSig sig = VerilatedVcdSig(code, bits); m_sigs.push_back(sig); // Split name into basename // Spaces and tabs aren't legal in VCD signal names, so: // Space separates each level of scope // Tab separates final scope from signal name // Tab sorts before spaces, so signals nicely will print before scopes // Note the hiername may be nothing, if so we'll add "\t{name}" string nameasstr = name; if (m_modName!="") { nameasstr = m_modName+m_scopeEscape+nameasstr; } // Optional ->module prefix string hiername; string basename; for (const char* cp=nameasstr.c_str(); *cp; cp++) { if (isScopeEscape(*cp)) { // Ahh, we've just read a scope, not a basename if (hiername!="") hiername += " "; hiername += basename; basename = ""; } else { basename += *cp; } } hiername += "\t"+basename; // Print reference string decl = "$var "; if (m_evcd) decl += "port"; else decl += wirep; // usually "wire" char buf [1000]; sprintf(buf, " %2d ", bits); decl += buf; if (m_evcd) { sprintf(buf, "<%d", code); decl += buf; } else { decl += stringCode(code); } decl += " "; decl += basename; if (arraynum>=0) { sprintf(buf, "(%d)", arraynum); decl += buf; hiername += buf; } if (bussed) { sprintf(buf, " [%d:%d]", msb, lsb); decl += buf; } decl += " $end\n"; m_namemapp->insert(make_pair(hiername,decl)); } void VerilatedVcd::declBit (vluint32_t code, const char* name, int arraynum) { declare (code, name, "wire", arraynum, false, false, 0, 0); } void VerilatedVcd::declBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb) { declare (code, name, "wire", arraynum, false, true, msb, lsb); } void VerilatedVcd::declQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb) { declare (code, name, "wire", arraynum, false, true, msb, lsb); } void VerilatedVcd::declArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb) { declare (code, name, "wire", arraynum, false, true, msb, lsb); } void VerilatedVcd::declTriBit (vluint32_t code, const char* name, int arraynum) { declare (code, name, "wire", arraynum, true, false, 0, 0); } void VerilatedVcd::declTriBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb) { declare (code, name, "wire", arraynum, true, true, msb, lsb); } void VerilatedVcd::declTriQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb) { declare (code, name, "wire", arraynum, true, true, msb, lsb); } void VerilatedVcd::declTriArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb) { declare (code, name, "wire", arraynum, true, true, msb, lsb); } void VerilatedVcd::declFloat (vluint32_t code, const char* name, int arraynum) { declare (code, name, "real", arraynum, false, false, 31, 0); } void VerilatedVcd::declDouble (vluint32_t code, const char* name, int arraynum) { declare (code, name, "real", arraynum, false, false, 63, 0); } //============================================================================= void VerilatedVcd::fullDouble (vluint32_t code, const double newval) { (*((double*)&m_sigs_oldvalp[code])) = newval; // Buffer can't overflow before sprintf; we sized during declaration sprintf(m_writep, "r%.16g", newval); m_writep += strlen(m_writep); *m_writep++=' '; printCode(code); *m_writep++='\n'; bufferCheck(); } void VerilatedVcd::fullFloat (vluint32_t code, const float newval) { (*((float*)&m_sigs_oldvalp[code])) = newval; // Buffer can't overflow before sprintf; we sized during declaration sprintf(m_writep, "r%.16g", (double)newval); m_writep += strlen(m_writep); *m_writep++=' '; printCode(code); *m_writep++='\n'; bufferCheck(); } //============================================================================= // Callbacks void VerilatedVcd::addCallback ( VerilatedVcdCallback_t initcb, VerilatedVcdCallback_t fullcb, VerilatedVcdCallback_t changecb, void* userthis) { if (VL_UNLIKELY(isOpen())) { string msg = (string)"Internal: "+__FILE__+"::"+__FUNCTION__+" called with already open file"; vl_fatal(__FILE__,__LINE__,"",msg.c_str()); } VerilatedVcdCallInfo* vci = new VerilatedVcdCallInfo(initcb, fullcb, changecb, userthis, nextCode()); m_callbacks.push_back(vci); } //============================================================================= // Dumping void VerilatedVcd::dumpFull (vluint64_t timeui) { dumpPrep (timeui); for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) { VerilatedVcdCallInfo *cip = m_callbacks[ent]; (cip->m_fullcb) (this, cip->m_userthis, cip->m_code); } dumpDone (); } void VerilatedVcd::dump (vluint64_t timeui) { if (!isOpen()) return; if (VL_UNLIKELY(m_fullDump)) { m_fullDump = false; // No need for more full dumps dumpFull(timeui); return; } if (VL_UNLIKELY(m_rolloverMB && m_wroteBytes > this->m_rolloverMB)) { openNext(true); if (!isOpen()) return; } dumpPrep (timeui); for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) { VerilatedVcdCallInfo *cip = m_callbacks[ent]; (cip->m_changecb) (this, cip->m_userthis, cip->m_code); } dumpDone(); } void VerilatedVcd::dumpPrep (vluint64_t timeui) { printStr("#"); printTime(timeui); printStr("\n"); } void VerilatedVcd::dumpDone () { } //====================================================================== // Static members void VerilatedVcd::flush_all() { for (vluint32_t ent = 0; ent< s_vcdVecp.size(); ent++) { VerilatedVcd* vcdp = s_vcdVecp[ent]; vcdp->flush(); } } //====================================================================== //====================================================================== //====================================================================== #ifdef VERILATED_VCD_TEST vluint32_t v1, v2, s1, s2[3]; vluint32_t tri96[3]; vluint32_t tri96__tri[3]; vluint8_t ch; vluint64_t timestamp = 1; double doub = 0; void vcdInit (VerilatedVcd* vcdp, void* userthis, vluint32_t code) { vcdp->scopeEscape('.'); vcdp->module ("top"); vcdp->declBus (0x2, "v1",-1,5,1); vcdp->declBus (0x3, "v2",-1,6,0); vcdp->module ("top.sub1"); vcdp->declBit (0x4, "s1",-1); vcdp->declBit (0x5, "ch",-1); vcdp->module ("top.sub2"); vcdp->declArray (0x6, "s2",-1, 40,3); // Note need to add 3 for next code. vcdp->module ("top2"); vcdp->declBus (0x2, "t2v1",-1,4,1); vcdp->declTriBit (0x10, "io1", -1); vcdp->declTriBus (0x12, "io5", -1,4,0); vcdp->declTriArray (0x16, "io96",-1,95,0); // Note need to add 6 for next code. vcdp->declDouble (0x1c, "doub",-1); // Note need to add 2 for next code. } void vcdFull (VerilatedVcd* vcdp, void* userthis, vluint32_t code) { vcdp->fullBus (0x2, v1,5); vcdp->fullBus (0x3, v2,7); vcdp->fullBit (0x4, s1); vcdp->fullBus (0x5, ch,2); vcdp->fullArray(0x6, &s2[0], 38); vcdp->fullTriBit (0x10, tri96[0]&1, tri96__tri[0]&1); vcdp->fullTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5); vcdp->fullTriArray (0x16, tri96, tri96__tri, 96); vcdp->fullDouble(0x1c, doub); } void vcdChange (VerilatedVcd* vcdp, void* userthis, vluint32_t code) { vcdp->chgBus (0x2, v1,5); vcdp->chgBus (0x3, v2,7); vcdp->chgBit (0x4, s1); vcdp->chgBus (0x5, ch,2); vcdp->chgArray(0x6, &s2[0], 38); vcdp->chgTriBit (0x10, tri96[0]&1, tri96__tri[0]&1); vcdp->chgTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5); vcdp->chgTriArray (0x16, tri96, tri96__tri, 96); vcdp->chgDouble (0x1c, doub); } main() { cout<<"test: O_LARGEFILE="<spTrace()->addCallback (&vcdInit, &vcdFull, &vcdChange, 0); vcdp->open ("test.vcd"); // Dumping vcdp->dump(timestamp++); v1 = 0xfff; tri96[2] = 4; tri96[1] = 2; tri96[0] = 1; tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = ~0; // Still tri doub = 1.5; vcdp->dump(timestamp++); v2 = 0x1; s2[1] = 2; tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = 0; // enable w/o data change doub = -1.66e13; vcdp->dump(timestamp++); ch = 2; tri96[2] = ~4; tri96[1] = ~2; tri96[0] = ~1; doub = -3.33e-13; vcdp->dump(timestamp++); vcdp->dump(timestamp++); # ifdef VERILATED_VCD_TEST_64BIT vluint64_t bytesPerDump = 15ULL; for (vluint64_t i=0; i<((1ULL<<32) / bytesPerDump); i++) { v1 = i; vcdp->dump(timestamp++); } # endif vcdp->close(); } } #endif //******************************************************************** // Local Variables: // compile-command: "mkdir -p ../test_dir && cd ../test_dir && c++ -DVERILATED_VCD_TEST ../src/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd" // End: verilator-3.874/include/verilated_imp.h0000664000177100017500000002271712525171733020162 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //========================================================================= /// /// \file /// \brief Verilator: Implementation Header, only for verilated.cpp internals. /// /// Code available from: http://www.veripool.org/verilator /// //========================================================================= #ifndef _VERILATED_IMP_H_ #define _VERILATED_IMP_H_ 1 ///< Header Guard #if !defined(_VERILATED_CPP_) && !defined(_VERILATED_DPI_CPP_) # error "verilated_imp.h only to be included by verilated*.cpp internals" #endif #include "verilatedos.h" #include "verilated.h" #include "verilated_heavy.h" #include "verilated_syms.h" #include #include #include #include class VerilatedScope; //====================================================================== // Types class VerilatedImp { // Whole class is internal use only - Global information shared between verilated*.cpp files. // TYPES typedef vector ArgVec; typedef map,void*> UserMap; typedef map ScopeNameMap; typedef map ExportNameMap; // MEMBERS static VerilatedImp s_s; ///< Static Singleton; One and only static this // Nothing here is save-restored; users expected to re-register appropriately ArgVec m_argVec; ///< Argument list (NOT save-restored, may want different results) bool m_argVecLoaded; ///< Ever loaded argument list UserMap m_userMap; ///< Map of <(scope,userkey), userData> ScopeNameMap m_nameMap; ///< Map of // Slow - somewhat static: ExportNameMap m_exportMap; ///< Map of int m_exportNext; ///< Next export funcnum // File I/O vector m_fdps; ///< File descriptors deque m_fdFree; ///< List of free descriptors (SLOW - FOPEN/CLOSE only) public: // But only for verilated*.cpp // CONSTRUCTORS VerilatedImp() : m_argVecLoaded(false), m_exportNext(0) { m_fdps.resize(3); m_fdps[0] = stdin; m_fdps[1] = stdout; m_fdps[2] = stderr; } ~VerilatedImp() {} static void internalsDump() { VL_PRINTF("internalsDump:\n"); VL_PRINTF(" Argv:"); for (ArgVec::iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) { VL_PRINTF(" %s",it->c_str()); } VL_PRINTF("\n"); VL_PRINTF(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion()); scopesDump(); exportsDump(); userDump(); } // METHODS - arguments static void commandArgs(int argc, const char** argv) { s_s.m_argVec.clear(); for (int i=0; ic_str()+1, len)) return *it; } } return ""; } // METHODS - user scope tracking // We implement this as a single large map instead of one map per scope // There's often many more scopes than userdata's and thus having a ~48byte // per map overhead * N scopes would take much more space and cache thrashing. static inline void userInsert(const void* scopep, void* userKey, void* userData) { UserMap::iterator it=s_s.m_userMap.find(make_pair(scopep,userKey)); if (it != s_s.m_userMap.end()) it->second = userData; // When we support VL_THREADs, we need a lock around this insert, as it's runtime else s_s.m_userMap.insert(it, make_pair(make_pair(scopep,userKey),userData)); } static inline void* userFind(const void* scopep, void* userKey) { UserMap::iterator it=s_s.m_userMap.find(make_pair(scopep,userKey)); if (VL_LIKELY(it != s_s.m_userMap.end())) return it->second; else return NULL; } private: /// Symbol table destruction cleans up the entries for each scope. static void userEraseScope(const VerilatedScope* scopep) { // Slow ok - called once/scope on destruction, so we simply iterate. for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ) { if (it->first.first == scopep) { s_s.m_userMap.erase(it++); } else { ++it; } } } static void userDump() { bool first = true; for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) { if (first) { VL_PRINTF(" userDump:\n"); first=false; } VL_PRINTF(" DPI_USER_DATA scope %p key %p: %p\n", it->first.first, it->first.second, it->second); } } public: // But only for verilated*.cpp // METHODS - scope name static void scopeInsert(const VerilatedScope* scopep) { // Slow ok - called once/scope at construction ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name()); if (it == s_s.m_nameMap.end()) { s_s.m_nameMap.insert(it, make_pair(scopep->name(),scopep)); } } static inline const VerilatedScope* scopeFind(const char* namep) { ScopeNameMap::iterator it=s_s.m_nameMap.find(namep); if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second; else return NULL; } static void scopeErase(const VerilatedScope* scopep) { // Slow ok - called once/scope at destruction userEraseScope(scopep); ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name()); if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it); } static void scopesDump() { VL_PRINTF(" scopesDump:\n"); for (ScopeNameMap::iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) { const VerilatedScope* scopep = it->second; scopep->scopeDump(); } VL_PRINTF("\n"); } public: // But only for verilated*.cpp // METHODS - export names // Each function prototype is converted to a function number which we // then use to index a 2D table also indexed by scope number, because we // can't know at Verilation time what scopes will exist in other modules // in the design that also happen to have our same callback function. // Rather than a 2D map, the integer scheme saves 500ish ns on a likely // miss at the cost of a multiply, and all lookups move to slowpath. static int exportInsert(const char* namep) { // Slow ok - called once/function at creation ExportNameMap::iterator it=s_s.m_exportMap.find(namep); if (it == s_s.m_exportMap.end()) { s_s.m_exportMap.insert(it, make_pair(namep, s_s.m_exportNext++)); return s_s.m_exportNext++; } else { return it->second; } } static int exportFind(const char* namep) { ExportNameMap::iterator it=s_s.m_exportMap.find(namep); if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second; string msg = (string("%Error: Testbench C called ")+namep +" but no such DPI export function name exists in ANY model"); vl_fatal("unknown",0,"", msg.c_str()); return -1; } static const char* exportName(int funcnum) { // Slowpath; find name for given export; errors only so no map to reverse-map it for (ExportNameMap::iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) { if (it->second == funcnum) return it->first; } return "*UNKNOWN*"; } static void exportsDump() { bool first = true; for (ExportNameMap::iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) { if (first) { VL_PRINTF(" exportDump:\n"); first=false; } VL_PRINTF(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first); } } // We don't free up m_exportMap until the end, because we can't be sure // what other models are using the assigned funcnum's. public: // But only for verilated*.cpp // METHODS - file IO static IData fdNew(FILE* fp) { if (VL_UNLIKELY(!fp)) return 0; // Bit 31 indicates it's a descriptor not a MCD if (s_s.m_fdFree.empty()) { // Need to create more space in m_fdps and m_fdFree size_t start = s_s.m_fdps.size(); s_s.m_fdps.resize(start*2); for (size_t i=start; i= s_s.m_fdps.size())) return; if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free s_s.m_fdps[idx] = NULL; s_s.m_fdFree.push_back(idx); } static inline FILE* fdToFp(IData fdi) { IData idx = VL_MASK_I(31) & fdi; if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return NULL; return s_s.m_fdps[idx]; } }; #endif // Guard verilator-3.874/include/verilated_vpi.h0000664000177100017500000015416012534317670020173 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //========================================================================= /// /// \file /// \brief Verilator: VPI implementation code /// /// This file must be compiled and linked against all objects /// created from Verilator or called by Verilator that use the VPI. /// /// Code available from: http://www.veripool.org/verilator /// //========================================================================= #ifndef CHPI_VERILATED_VPI_H #define CHPI_VERILATED_VPI_H 1 #include "verilated.h" #include "verilated_syms.h" //====================================================================== // From IEEE 1800-2009 annex K #include "vltstd/vpi_user.h" //====================================================================== // Internal macros #define _VL_VPI_INTERNAL VerilatedVpi::error_info()->setMessage(vpiInternal)->setMessage #define _VL_VPI_SYSTEM VerilatedVpi::error_info()->setMessage(vpiSystem )->setMessage #define _VL_VPI_ERROR VerilatedVpi::error_info()->setMessage(vpiError )->setMessage #define _VL_VPI_WARNING VerilatedVpi::error_info()->setMessage(vpiWarning )->setMessage #define _VL_VPI_NOTICE VerilatedVpi::error_info()->setMessage(vpiNotice )->setMessage #define _VL_VPI_ERROR_RESET VerilatedVpi::error_info()->resetError // Not supported yet #define _VL_VPI_UNIMP() \ _VL_VPI_ERROR(__FILE__,__LINE__,Verilated::catName("Unsupported VPI function: ",VL_FUNC)); //====================================================================== // Implementation #include #include #include #define VL_DEBUG_IF_PLI VL_DEBUG_IF #define VL_VPI_LINE_SIZE 8192 // Base VPI handled object class VerilatedVpio { // MEM MANGLEMENT static vluint8_t* s_freeHead; public: // CONSTRUCTORS VerilatedVpio() {} virtual ~VerilatedVpio() {} inline static void* operator new(size_t size) { // We new and delete tons of vpi structures, so keep them around // To simplify our free list, we use a size large enough for all derived types // We reserve word zero for the next pointer, as that's safer in case a // dangling reference to the original remains around. static size_t chunk = 96; if (VL_UNLIKELY(size>chunk)) vl_fatal(__FILE__,__LINE__,"", "increase chunk"); if (VL_LIKELY(s_freeHead)) { vluint8_t* newp = s_freeHead; s_freeHead = *((vluint8_t**)newp); return newp+8; } else { // +8: 8 bytes for next vluint8_t* newp = (vluint8_t*)(::operator new(chunk+8)); return newp+8; } } inline static void operator delete(void* obj, size_t size) { vluint8_t* oldp = ((vluint8_t*)obj)-8; *((void**)oldp) = s_freeHead; s_freeHead = oldp; } // MEMBERS static inline VerilatedVpio* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } inline vpiHandle castVpiHandle() { return (vpiHandle)(this); } // ACCESSORS virtual const char* name() { return ""; } virtual const char* fullname() { return ""; } virtual const char* defname() { return ""; } virtual const vluint32_t type() { return 0; } virtual const vluint32_t size() const { return 0; } virtual const VerilatedRange* rangep() const { return NULL; } virtual vpiHandle dovpi_scan() { return 0; } }; typedef PLI_INT32 (*VerilatedPliCb)(struct t_cb_data *); class VerilatedVpioCb : public VerilatedVpio { t_cb_data m_cbData; s_vpi_value m_value; QData m_time; public: // cppcheck-suppress uninitVar // m_value VerilatedVpioCb(const t_cb_data* cbDatap, QData time) : m_cbData(*cbDatap), m_time(time) { m_value.format = cbDatap->value ? cbDatap->value->format : vpiSuppressVal; m_cbData.value = &m_value; } virtual ~VerilatedVpioCb() {} static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual const vluint32_t type() { return vpiCallback; } vluint32_t reason() const { return m_cbData.reason; } VerilatedPliCb cb_rtnp() const { return m_cbData.cb_rtn; } t_cb_data* cb_datap() { return &(m_cbData); } QData time() const { return m_time; } }; class VerilatedVpioConst : public VerilatedVpio { vlsint32_t m_num; public: VerilatedVpioConst(vlsint32_t num) : m_num(num) {} virtual ~VerilatedVpioConst() {} static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual const vluint32_t type() { return vpiUndefined; } vlsint32_t num() const { return m_num; } }; class VerilatedVpioRange : public VerilatedVpio { const VerilatedRange* m_range; vlsint32_t m_iteration; public: VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {} virtual ~VerilatedVpioRange() {} static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual const vluint32_t type() { return vpiRange; } virtual const vluint32_t size() const { return m_range->elements(); } virtual const VerilatedRange* rangep() const { return m_range; } int iteration() const { return m_iteration; } void iterationInc() { ++m_iteration; } virtual vpiHandle dovpi_scan() { if (!iteration()) { VerilatedVpioRange* nextp = new VerilatedVpioRange(*this); nextp->iterationInc(); return ((nextp)->castVpiHandle()); } else { return 0; // End of list - only one deep } } }; class VerilatedVpioScope : public VerilatedVpio { const VerilatedScope* m_scopep; public: VerilatedVpioScope(const VerilatedScope* scopep) : m_scopep(scopep) {} virtual ~VerilatedVpioScope() {} static inline VerilatedVpioScope* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual const vluint32_t type() { return vpiScope; } const VerilatedScope* scopep() const { return m_scopep; } virtual const char* name() { return m_scopep->name(); } virtual const char* fullname() { return m_scopep->name(); } }; class VerilatedVpioVar : public VerilatedVpio { const VerilatedVar* m_varp; const VerilatedScope* m_scopep; vluint8_t* m_prevDatap; // Previous value of data, for cbValueChange union { vluint8_t u8[4]; vluint32_t u32; } m_mask; // memoized variable mask vluint32_t m_entSize; // memoized variable size protected: void* m_varDatap; // varp()->datap() adjusted for array entries vlsint32_t m_index; const VerilatedRange& get_range() const { // Determine number of dimensions and return outermost return (m_varp->dims()>1) ? m_varp->array() : m_varp->range(); } public: VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep) : m_varp(varp), m_scopep(scopep), m_index(0) { m_prevDatap = NULL; m_mask.u32 = VL_MASK_I(varp->range().elements()); m_entSize = varp->entSize(); m_varDatap = varp->datap(); } virtual ~VerilatedVpioVar() { if (m_prevDatap) { delete [] m_prevDatap; m_prevDatap = NULL; } } static inline VerilatedVpioVar* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } const VerilatedVar* varp() const { return m_varp; } const VerilatedScope* scopep() const { return m_scopep; } vluint32_t mask() const { return m_mask.u32; } vluint8_t mask_byte(int idx) { return m_mask.u8[idx & 3]; } vluint32_t entSize() const { return m_entSize; } const vluint32_t index() { return m_index; } virtual const vluint32_t type() { if (varp()->vldir() != vpiNoDirection) return vpiPort; return (varp()->dims()>1) ? vpiMemory : vpiReg; /* but might be wire, logic */ } virtual const vluint32_t size() const { return get_range().elements(); } virtual const VerilatedRange* rangep() const { return &get_range(); } virtual const char* name() { return m_varp->name(); } virtual const char* fullname() { VL_STATIC_OR_THREAD string out; out = string(m_scopep->name())+"."+name(); return out.c_str(); } void* prevDatap() const { return m_prevDatap; } void* varDatap() const { return m_varDatap; } void createPrevDatap() { if (VL_UNLIKELY(!m_prevDatap)) { m_prevDatap = new vluint8_t [entSize()]; memcpy(prevDatap(), varp()->datap(), entSize()); } } }; class VerilatedVpioMemoryWord : public VerilatedVpioVar { public: VerilatedVpioMemoryWord(const VerilatedVar* varp, const VerilatedScope* scopep, vlsint32_t index, int offset) : VerilatedVpioVar(varp, scopep) { m_index = index; m_varDatap = ((vluint8_t*)varp->datap()) + entSize()*offset; } virtual ~VerilatedVpioMemoryWord() {} static inline VerilatedVpioMemoryWord* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual const vluint32_t type() { return vpiMemoryWord; } virtual const vluint32_t size() const { return varp()->range().elements(); } virtual const VerilatedRange* rangep() const { return &(varp()->range()); } virtual const char* fullname() { VL_STATIC_OR_THREAD string out; char num[20]; sprintf(num,"%d",m_index); out = string(scopep()->name())+"."+name()+"["+num+"]"; return out.c_str(); } }; class VerilatedVpioVarIter : public VerilatedVpio { const VerilatedScope* m_scopep; VerilatedVarNameMap::iterator m_it; bool m_started; public: VerilatedVpioVarIter(const VerilatedScope* scopep) : m_scopep(scopep), m_started(false) { } virtual ~VerilatedVpioVarIter() {} static inline VerilatedVpioVarIter* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual const vluint32_t type() { return vpiIterator; } virtual vpiHandle dovpi_scan() { if (VL_LIKELY(m_scopep->varsp())) { VerilatedVarNameMap* varsp = m_scopep->varsp(); if (VL_UNLIKELY(!m_started)) { m_it = varsp->begin(); m_started=true; } else if (VL_UNLIKELY(m_it == varsp->end())) return 0; else ++m_it; if (m_it == varsp->end()) return 0; return ((new VerilatedVpioVar(&(m_it->second), m_scopep)) ->castVpiHandle()); } else { return 0; // End of list - only one deep } } }; class VerilatedVpioMemoryWordIter : public VerilatedVpio { const vpiHandle m_handle; const VerilatedVar* m_varp; vlsint32_t m_iteration; vlsint32_t m_direction; bool m_done; public: VerilatedVpioMemoryWordIter(const vpiHandle handle, const VerilatedVar* varp) : m_handle(handle), m_varp(varp), m_iteration(varp->array().right()), m_direction(VL_LIKELY(varp->array().left()>varp->array().right())?1:-1), m_done(false) { } virtual ~VerilatedVpioMemoryWordIter() {} static inline VerilatedVpioMemoryWordIter* castp(vpiHandle h) { return dynamic_cast((VerilatedVpio*)h); } virtual const vluint32_t type() { return vpiIterator; } void iterationInc() { if (!(m_done = (m_iteration == m_varp->array().left()))) m_iteration+=m_direction; } virtual vpiHandle dovpi_scan() { vpiHandle result; if (m_done) return 0; result = vpi_handle_by_index(m_handle, m_iteration); iterationInc(); return result; } }; //====================================================================== struct VerilatedVpiTimedCbsCmp { /// Ordering sets keyed by time, then callback descriptor bool operator() (const pair& a, const pair& b) const { if (a.first < b.first) return 1; if (a.first > b.first) return 0; return a.second < b.second; } }; class VerilatedVpiError; class VerilatedVpi { enum { CB_ENUM_MAX_VALUE = cbAtEndOfSimTime+1 }; // Maxium callback reason typedef list VpioCbList; typedef set,VerilatedVpiTimedCbsCmp > VpioTimedCbs; struct product_info { PLI_BYTE8* product; PLI_BYTE8* version; }; VpioCbList m_cbObjLists[CB_ENUM_MAX_VALUE]; // Callbacks for each supported reason VpioTimedCbs m_timedCbs; // Time based callbacks VerilatedVpiError* m_errorInfop; // Container for vpi error info static VerilatedVpi s_s; // Singleton public: VerilatedVpi() { m_errorInfop=NULL; } ~VerilatedVpi() {} static void cbReasonAdd(VerilatedVpioCb* vop) { if (vop->reason() == cbValueChange) { if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) { varop->createPrevDatap(); } } if (VL_UNLIKELY(vop->reason() >= CB_ENUM_MAX_VALUE)) vl_fatal(__FILE__,__LINE__,"", "vpi bb reason too large"); s_s.m_cbObjLists[vop->reason()].push_back(vop); } static void cbTimedAdd(VerilatedVpioCb* vop) { s_s.m_timedCbs.insert(make_pair(vop->time(), vop)); } static void cbReasonRemove(VerilatedVpioCb* cbp) { VpioCbList& cbObjList = s_s.m_cbObjLists[cbp->reason()]; // We do not remove it now as we may be iterating the list, // instead set to NULL and will cleanup later for (VpioCbList::iterator it=cbObjList.begin(); it!=cbObjList.end(); ++it) { if (*it == cbp) *it = NULL; } } static void cbTimedRemove(VerilatedVpioCb* cbp) { VpioTimedCbs::iterator it=s_s.m_timedCbs.find(make_pair(cbp->time(),cbp)); if (VL_LIKELY(it != s_s.m_timedCbs.end())) { s_s.m_timedCbs.erase(it); } } static void callTimedCbs() { QData time = VL_TIME_Q(); for (VpioTimedCbs::iterator it=s_s.m_timedCbs.begin(); it!=s_s.m_timedCbs.end(); ) { if (VL_UNLIKELY(it->first <= time)) { VerilatedVpioCb* vop = it->second; ++it; // iterator may be deleted by callback VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: timed_callback %p\n",vop);); (vop->cb_rtnp()) (vop->cb_datap()); } else { ++it; } } } static QData cbNextDeadline() { VpioTimedCbs::iterator it=s_s.m_timedCbs.begin(); if (VL_LIKELY(it!=s_s.m_timedCbs.end())) { return it->first; } else { return ~VL_ULL(0); // maxquad } } static void callCbs(vluint32_t reason) { VpioCbList& cbObjList = s_s.m_cbObjLists[reason]; for (VpioCbList::iterator it=cbObjList.begin(); it!=cbObjList.end();) { if (VL_UNLIKELY(!*it)) { // Deleted earlier, cleanup it = cbObjList.erase(it); continue; } VerilatedVpioCb* vop = *it++; VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: reason_callback %d %p\n",reason,vop);); (vop->cb_rtnp()) (vop->cb_datap()); } } static void callValueCbs() { VpioCbList& cbObjList = s_s.m_cbObjLists[cbValueChange]; set update; // set of objects to update after callbacks for (VpioCbList::iterator it=cbObjList.begin(); it!=cbObjList.end();) { if (VL_UNLIKELY(!*it)) { // Deleted earlier, cleanup it = cbObjList.erase(it); continue; } VerilatedVpioCb* vop = *it++; if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) { void* newDatap = varop->varDatap(); void* prevDatap = varop->prevDatap(); // Was malloced when we added the callback VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_test %s v[0]=%d/%d %p %p\n", varop->fullname(), *((CData*)newDatap), *((CData*)prevDatap), newDatap, prevDatap);); if (memcmp(prevDatap, newDatap, varop->entSize())) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_callback %p %s v[0]=%d\n", vop,varop->fullname(), *((CData*)newDatap));); update.insert(varop); vpi_get_value(vop->cb_datap()->obj, vop->cb_datap()->value); (vop->cb_rtnp()) (vop->cb_datap()); } } } for (set::iterator it=update.begin(); it!=update.end(); ++it) { memcpy((*it)->prevDatap(), (*it)->varDatap(), (*it)->entSize()); } } static VerilatedVpiError* error_info(); // getter for vpi error info }; #define _VL_VPI_ERROR_SET \ do { \ va_list args; \ va_start(args, message); \ VL_VSNPRINTF(m_buff, sizeof(m_buff), message.c_str(), args); \ va_end(args); \ } while (0) class VerilatedVpiError { //// Container for vpi error info t_vpi_error_info m_errorInfo; bool m_flag; char m_buff[VL_VPI_LINE_SIZE]; void setError(PLI_BYTE8 *message, PLI_BYTE8 *code, PLI_BYTE8 *file, PLI_INT32 line) { m_errorInfo.message = message; m_errorInfo.file = file; m_errorInfo.line = line; m_errorInfo.code = code; do_callbacks(); } void do_callbacks() { if (getError()->level >= vpiError && Verilated::fatalOnVpiError()) { // Stop on vpi error/unsupported vpi_unsupported(); } // We need to run above code first because in the case that the callback executes further vpi // functions we will loose the error as it will be overwritten. VerilatedVpi::callCbs(cbPLIError); } public: VerilatedVpiError() : m_flag(false) { m_buff[0] = '\0'; m_errorInfo.product = (PLI_BYTE8*)Verilated::productName(); } ~VerilatedVpiError() {} VerilatedVpiError* setMessage(PLI_INT32 level) { m_flag=true; m_errorInfo.level = level; return this; } void setMessage(string file, PLI_INT32 line, string message, ...) { static VL_THREAD string filehold; _VL_VPI_ERROR_SET; m_errorInfo.state = vpiPLI; filehold = file; setError((PLI_BYTE8*)m_buff, NULL, (PLI_BYTE8*)filehold.c_str(), line); } p_vpi_error_info getError() { if (m_flag) return &m_errorInfo; return NULL; } void resetError() { m_flag=false; } static void vpi_unsupported() { // Not supported yet p_vpi_error_info error_info_p = VerilatedVpi::error_info()->getError(); if (error_info_p) { vl_fatal(error_info_p->file, error_info_p->line, "", error_info_p->message); return; } vl_fatal(__FILE__, __LINE__, "", "vpi_unsupported called without error info set"); } static const char* strFromVpiVal(PLI_INT32 vpiVal); static const char* strFromVpiObjType(PLI_INT32 vpiVal); static const char* strFromVpiMethod(PLI_INT32 vpiVal); static const char* strFromVpiCallbackReason(PLI_INT32 vpiVal); static const char* strFromVpiProp(PLI_INT32 vpiVal); }; VerilatedVpiError* VerilatedVpi::error_info() { if (s_s.m_errorInfop == NULL) { s_s.m_errorInfop = new VerilatedVpiError(); } return s_s.m_errorInfop; } // callback related vpiHandle vpi_register_cb(p_cb_data cb_data_p) { _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!cb_data_p)) { _VL_VPI_WARNING(__FILE__, __LINE__, "%s : callback data pointer is null", VL_FUNC); return NULL; } switch (cb_data_p->reason) { case cbAfterDelay: { QData time = 0; if (cb_data_p->time) time = _VL_SET_QII(cb_data_p->time->high, cb_data_p->time->low); VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, VL_TIME_Q()+time); VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_register_cb %d %p delay=%" VL_PRI64 "d\n",cb_data_p->reason,vop,time);); VerilatedVpi::cbTimedAdd(vop); return vop->castVpiHandle(); } case cbReadWriteSynch: // FALLTHRU // Supported via vlt_main.cpp case cbReadOnlySynch: // FALLTHRU // Supported via vlt_main.cpp case cbNextSimTime: // FALLTHRU // Supported via vlt_main.cpp case cbStartOfSimulation: // FALLTHRU // Supported via vlt_main.cpp case cbEndOfSimulation: // FALLTHRU // Supported via vlt_main.cpp case cbValueChange: // FALLTHRU // Supported via vlt_main.cpp case cbPLIError: // FALLTHRU // NOP, but need to return handle, so make object case cbEnterInteractive: // FALLTHRU // NOP, but need to return handle, so make object case cbExitInteractive: // FALLTHRU // NOP, but need to return handle, so make object case cbInteractiveScopeChange: { // FALLTHRU // NOP, but need to return handle, so make object VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, 0); VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_register_cb %d %p\n",cb_data_p->reason,vop);); VerilatedVpi::cbReasonAdd(vop); return vop->castVpiHandle(); } default: _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported callback type %s", VL_FUNC, VerilatedVpiError::strFromVpiCallbackReason(cb_data_p->reason)); return NULL; }; } PLI_INT32 vpi_remove_cb(vpiHandle object) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_remove_cb %p\n",object);); VerilatedVpioCb* vop = VerilatedVpioCb::castp(object); _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!vop)) return 0; if (vop->cb_datap()->reason == cbAfterDelay) { VerilatedVpi::cbTimedRemove(vop); } else { VerilatedVpi::cbReasonRemove(vop); } return 1; } void vpi_get_cb_info(vpiHandle object, p_cb_data cb_data_p) { _VL_VPI_UNIMP(); return; } vpiHandle vpi_register_systf(p_vpi_systf_data systf_data_p) { _VL_VPI_UNIMP(); return 0; } void vpi_get_systf_info(vpiHandle object, p_vpi_systf_data systf_data_p) { _VL_VPI_UNIMP(); return; } // for obtaining handles vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) { _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!namep)) return NULL; VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_handle_by_name %s %p\n",namep,scope);); VerilatedVpioScope* voScopep = VerilatedVpioScope::castp(scope); const VerilatedVar* varp; const VerilatedScope* scopep; string scopeAndName = namep; if (voScopep) { scopeAndName = string(voScopep->fullname()) + "." + namep; namep = (PLI_BYTE8*)scopeAndName.c_str(); } { // This doesn't yet follow the hierarchy in the proper way scopep = Verilated::scopeFind(namep); if (scopep) { // Whole thing found as a scope return (new VerilatedVpioScope(scopep))->castVpiHandle(); } const char* baseNamep = scopeAndName.c_str(); string scopename; const char* dotp = strrchr(namep, '.'); if (VL_LIKELY(dotp)) { baseNamep = dotp+1; scopename = string(namep,dotp-namep); } scopep = Verilated::scopeFind(scopename.c_str()); if (!scopep) return NULL; varp = scopep->varFind(baseNamep); } if (!varp) return NULL; return (new VerilatedVpioVar(varp, scopep))->castVpiHandle(); } vpiHandle vpi_handle_by_index(vpiHandle object, PLI_INT32 indx) { // Used to get array entries VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_handle_by_index %p %d\n",object, indx);); VerilatedVpioVar* varop = VerilatedVpioVar::castp(object); _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_LIKELY(varop)) { if (varop->varp()->dims()<2) return 0; if (VL_LIKELY(varop->varp()->array().left() >= varop->varp()->array().right())) { if (VL_UNLIKELY(indx > varop->varp()->array().left() || indx < varop->varp()->array().right())) return 0; return (new VerilatedVpioMemoryWord(varop->varp(), varop->scopep(), indx, indx - varop->varp()->array().right())) ->castVpiHandle(); } else { if (VL_UNLIKELY(indx < varop->varp()->array().left() || indx > varop->varp()->array().right())) return 0; return (new VerilatedVpioMemoryWord(varop->varp(), varop->scopep(), indx, indx - varop->varp()->array().left())) ->castVpiHandle(); } } else { _VL_VPI_INTERNAL(__FILE__, __LINE__, "%s : can't resolve handle", VL_FUNC); return 0; } } // for traversing relationships vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_handle %d %p\n",type,object);); _VL_VPI_ERROR_RESET(); // reset vpi error status switch (type) { case vpiLeftRange: { VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; if (VL_UNLIKELY(!vop->rangep())) return 0; return (new VerilatedVpioConst(vop->rangep()->left()))->castVpiHandle(); } case vpiRightRange: { VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; if (VL_UNLIKELY(!vop->rangep())) return 0; return (new VerilatedVpioConst(vop->rangep()->right()))->castVpiHandle(); } case vpiIndex: { VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; return (new VerilatedVpioConst(vop->index()))->castVpiHandle(); } case vpiScope: { VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; return (new VerilatedVpioScope(vop->scopep()))->castVpiHandle(); } case vpiParent: { VerilatedVpioMemoryWord* vop = VerilatedVpioMemoryWord::castp(object); if (VL_UNLIKELY(!vop)) return 0; return (new VerilatedVpioVar(vop->varp(), vop->scopep()))->castVpiHandle(); } default: _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, nothing will be returned", VL_FUNC, VerilatedVpiError::strFromVpiMethod(type)); return 0; } } vpiHandle vpi_handle_multi(PLI_INT32 type, vpiHandle refHandle1, vpiHandle refHandle2, ... ) { _VL_VPI_UNIMP(); return 0; } vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_iterate %d %p\n",type,object);); _VL_VPI_ERROR_RESET(); // reset vpi error status switch (type) { case vpiMemoryWord: { VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; if (vop->varp()->dims() < 2) return 0; if (vop->varp()->dims() > 2) { _VL_VPI_WARNING(__FILE__, __LINE__, "%s: %s, object %s has unsupported number of indices (%d)", VL_FUNC, VerilatedVpiError::strFromVpiMethod(type), vop->fullname() , vop->varp()->dims()); } return (new VerilatedVpioMemoryWordIter(object, vop->varp()))->castVpiHandle(); } case vpiRange: { VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; if (vop->varp()->dims() < 2) return 0; // Unsupported is multidim list if (vop->varp()->dims() > 2) { _VL_VPI_WARNING(__FILE__, __LINE__, "%s: %s, object %s has unsupported number of indices (%d)", VL_FUNC, VerilatedVpiError::strFromVpiMethod(type), vop->fullname() , vop->varp()->dims()); } return ((new VerilatedVpioRange(vop->rangep()))->castVpiHandle()); } case vpiReg: { VerilatedVpioScope* vop = VerilatedVpioScope::castp(object); if (VL_UNLIKELY(!vop)) return 0; return ((new VerilatedVpioVarIter(vop->scopep())) ->castVpiHandle()); } default: _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, nothing will be returned", VL_FUNC, VerilatedVpiError::strFromVpiObjType(type)); return 0; } } vpiHandle vpi_scan(vpiHandle object) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_scan %p\n",object);); _VL_VPI_ERROR_RESET(); // reset vpi error status VerilatedVpio* vop = VerilatedVpio::castp(object); if (VL_UNLIKELY(!vop)) return NULL; return vop->dovpi_scan(); } // for processing properties PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) { // Leave this in the header file - in many cases the compiler can constant propagate "object" VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get %d %p\n",property,object);); _VL_VPI_ERROR_RESET(); // reset vpi error status switch (property) { case vpiTimePrecision: { return VL_TIME_PRECISION; } case vpiType: { VerilatedVpio* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; return vop->type(); } case vpiDirection: { // By forthought, the directions already are vpi enumerated VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; return vop->varp()->vldir(); } case vpiScalar: // FALLTHRU case vpiVector: { VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; return (property==vpiVector)^(vop->varp()->dims()==0); } case vpiSize: { VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); if (VL_UNLIKELY(!vop)) return 0; return vop->size(); } default: _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, nothing will be returned", VL_FUNC, VerilatedVpiError::strFromVpiProp(property)); return 0; } } PLI_INT64 vpi_get64(PLI_INT32 property, vpiHandle object) { _VL_VPI_UNIMP(); return 0; } PLI_BYTE8 *vpi_get_str(PLI_INT32 property, vpiHandle object) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get_str %d %p\n",property,object);); VerilatedVpio* vop = VerilatedVpio::castp(object); _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!vop)) return NULL; switch (property) { case vpiName: { return (PLI_BYTE8*)vop->name(); } case vpiFullName: { return (PLI_BYTE8*)vop->fullname(); } case vpiDefName: { return (PLI_BYTE8*)vop->defname(); } default: _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, nothing will be returned", VL_FUNC, VerilatedVpiError::strFromVpiProp(property)); return 0; } } // delay processing void vpi_get_delays(vpiHandle object, p_vpi_delay delay_p) { _VL_VPI_UNIMP(); return; } void vpi_put_delays(vpiHandle object, p_vpi_delay delay_p) { _VL_VPI_UNIMP(); return; } // value processing void vpi_get_value(vpiHandle object, p_vpi_value value_p) { static VL_THREAD char outStr[1+VL_MULS_MAX_WORDS*32]; // Maximum required size is for binary string, one byte per bit plus null termination // cppcheck-suppress variableScope static VL_THREAD int outStrSz = sizeof(outStr)-1; VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get_value %p\n",object);); _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!value_p)) return; if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) { // We used to presume vpiValue.format = vpiIntVal or if single bit vpiScalarVal // This may cause backward compatability issues with older code. if (value_p->format == vpiVectorVal) { // Vector pointer must come from our memory pool // It only needs to persist until the next vpi_get_value static VL_THREAD t_vpi_vecval out[VL_MULS_MAX_WORDS*2]; value_p->value.vector = out; switch (vop->varp()->vltype()) { case VLVT_UINT8: out[0].aval = *((CData*)(vop->varDatap())); out[0].bval = 0; return; case VLVT_UINT16: out[0].aval = *((SData*)(vop->varDatap())); out[0].bval = 0; return; case VLVT_UINT32: out[0].aval = *((IData*)(vop->varDatap())); out[0].bval = 0; return; case VLVT_WDATA: { int words = VL_WORDS_I(vop->varp()->range().elements()); if (VL_UNLIKELY(words >= VL_MULS_MAX_WORDS)) { vl_fatal(__FILE__,__LINE__,"", "vpi_get_value with more than VL_MULS_MAX_WORDS; increase and recompile"); } WDataInP datap = ((IData*)(vop->varDatap())); for (int i=0; ivarDatap())); out[1].aval = (IData)(data>>VL_ULL(32)); out[1].bval = 0; out[0].aval = (IData)(data); out[0].bval = 0; return; } default: { _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return; } } } else if (value_p->format == vpiBinStrVal) { value_p->value.str = outStr; switch (vop->varp()->vltype()) { case VLVT_UINT8 : case VLVT_UINT16: case VLVT_UINT32: case VLVT_UINT64: case VLVT_WDATA: { int bits = vop->varp()->range().elements(); CData* datap = ((CData*)(vop->varDatap())); int i; if (bits > outStrSz) { // limit maximum size of output to size of buffer to prevent overrun. bits = outStrSz; _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, bits); } for (i=0; i>3]>>(i&7))&1; outStr[bits-i-1] = val?'1':'0'; } outStr[i]=0; // NULL terminate return; } default: _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return; } } else if (value_p->format == vpiOctStrVal) { value_p->value.str = outStr; switch (vop->varp()->vltype()) { case VLVT_UINT8 : case VLVT_UINT16: case VLVT_UINT32: case VLVT_UINT64: case VLVT_WDATA: { int chars = (vop->varp()->range().elements()+2)/3; int bytes = VL_BYTES_I(vop->varp()->range().elements()); CData* datap = ((CData*)(vop->varDatap())); int i; if (chars > outStrSz) { // limit maximum size of output to size of buffer to prevent overrun. _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars); chars = outStrSz; } for (i=0; i>= idx.rem; if (i==(chars-1)) { // most signifcant char, mask off non existant bits when vector // size is not a multiple of 3 unsigned int rem = vop->varp()->range().elements() % 3; if (rem) { // generate bit mask & zero non existant bits val &= (1<format), vop->fullname()); return; } } else if (value_p->format == vpiDecStrVal) { value_p->value.str = outStr; switch (vop->varp()->vltype()) { // outStrSz does not include NULL termination so add one case VLVT_UINT8 : snprintf(outStr, outStrSz+1, "%hhu", (unsigned char )*((CData*)(vop->varDatap()))); return; case VLVT_UINT16: snprintf(outStr, outStrSz+1, "%hu", (unsigned short)*((SData*)(vop->varDatap()))); return; case VLVT_UINT32: snprintf(outStr, outStrSz+1, "%u", (unsigned int )*((IData*)(vop->varDatap()))); return; case VLVT_UINT64: snprintf(outStr, outStrSz+1, "%llu", (unsigned long long)*((QData*)(vop->varDatap()))); return; default: strcpy(outStr, "-1"); _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s, maximum limit is 64 bits", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return; } } else if (value_p->format == vpiHexStrVal) { value_p->value.str = outStr; switch (vop->varp()->vltype()) { case VLVT_UINT8 : case VLVT_UINT16: case VLVT_UINT32: case VLVT_UINT64: case VLVT_WDATA: { int chars = (vop->varp()->range().elements()+3)>>2; CData* datap = ((CData*)(vop->varDatap())); int i; if (chars > outStrSz) { // limit maximum size of output to size of buffer to prevent overrun. _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars); chars = outStrSz; } for (i=0; i>1]>>((i&1)<<2))&15; static char hex[] = "0123456789abcdef"; if (i==(chars-1)) { // most signifcant char, mask off non existant bits when vector // size is not a multiple of 4 unsigned int rem = vop->varp()->range().elements() & 3; if (rem) { // generate bit mask & zero non existant bits val &= (1<(val)]; } outStr[i]=0; // NULL terminate return; } default: _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return; } } else if (value_p->format == vpiStringVal) { value_p->value.str = outStr; switch (vop->varp()->vltype()) { case VLVT_UINT8 : case VLVT_UINT16: case VLVT_UINT32: case VLVT_UINT64: case VLVT_WDATA: { int bytes = VL_BYTES_I(vop->varp()->range().elements()); CData* datap = ((CData*)(vop->varDatap())); int i; if (bytes > outStrSz) { // limit maximum size of output to size of buffer to prevent overrun. _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, bytes); bytes = outStrSz; } for (i=0; iformat), vop->fullname()); return; } } else if (value_p->format == vpiIntVal) { switch (vop->varp()->vltype()) { case VLVT_UINT8: value_p->value.integer = *((CData*)(vop->varDatap())); return; case VLVT_UINT16: value_p->value.integer = *((SData*)(vop->varDatap())); return; case VLVT_UINT32: value_p->value.integer = *((IData*)(vop->varDatap())); return; case VLVT_WDATA: case VLVT_UINT64: // Not legal value_p->value.integer = 0; default: _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return; } } else if (value_p->format == vpiSuppressVal) { return; } _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) as requested for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return; } else if (VerilatedVpioConst* vop = VerilatedVpioConst::castp(object)) { if (value_p->format == vpiIntVal) { value_p->value.integer = vop->num(); return; } _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return; } _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format)); } vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time time_p, PLI_INT32 flags) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_put_value %p %p\n",object, value_p);); _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!value_p)) { _VL_VPI_WARNING(__FILE__, __LINE__, "Ignoring vpi_put_value with NULL value pointer"); return 0; } if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_put_value name=%s fmt=%d vali=%d\n", vop->fullname(), value_p->format, value_p->value.integer); VL_PRINTF("-vltVpi: varp=%p putatp=%p\n", vop->varp()->datap(), vop->varDatap());); if (VL_UNLIKELY(!vop->varp()->isPublicRW())) { _VL_VPI_WARNING(__FILE__, __LINE__, "Ignoring vpi_put_value to signal marked read-only, use public_flat_rw instead: ", vop->fullname()); return 0; } if (value_p->format == vpiVectorVal) { if (VL_UNLIKELY(!value_p->value.vector)) return NULL; switch (vop->varp()->vltype()) { case VLVT_UINT8: *((CData*)(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask(); return object; case VLVT_UINT16: *((SData*)(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask(); return object; case VLVT_UINT32: *((IData*)(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask(); return object; case VLVT_WDATA: { int words = VL_WORDS_I(vop->varp()->range().elements()); WDataOutP datap = ((IData*)(vop->varDatap())); for (int i=0; ivalue.vector[i].aval; if (i==(words-1)) { datap[i] &= vop->mask(); } } return object; } case VLVT_UINT64: { *((QData*)(vop->varDatap())) = _VL_SET_QII( value_p->value.vector[1].aval & vop->mask(), value_p->value.vector[0].aval); return object; } default: { _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return NULL; } } } else if (value_p->format == vpiBinStrVal) { switch (vop->varp()->vltype()) { case VLVT_UINT8 : case VLVT_UINT16: case VLVT_UINT32: case VLVT_UINT64: case VLVT_WDATA: { int bits = vop->varp()->range().elements(); int len = strlen(value_p->value.str); CData* datap = ((CData*)(vop->varDatap())); for (int i=0; ivalue.str[len-i-1]=='1'):0; // zero bits 7:1 of byte when assigning to bit 0, else // or in 1 if bit set if (i&7) { datap[i>>3] |= set<<(i&7); } else { datap[i>>3] = set; } } return object; } default: _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return 0; } } else if (value_p->format == vpiOctStrVal) { switch (vop->varp()->vltype()) { case VLVT_UINT8 : case VLVT_UINT16: case VLVT_UINT32: case VLVT_UINT64: case VLVT_WDATA: { int chars = (vop->varp()->range().elements()+2)/3; int bytes = VL_BYTES_I(vop->varp()->range().elements()); int len = strlen(value_p->value.str); CData* datap = ((CData*)(vop->varDatap())); div_t idx; datap[0] = 0; // reset zero'th byte for (int i=0; ivalue.str[len-i-1]; if (digit >= '0' && digit <= '7') { val.half = digit-'0'; } else { _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Non octal character '%c' in '%s' as value %s for %s", VL_FUNC, digit, value_p->value.str, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); val.half = 0; } } else { val.half = 0; } // align octal character to position within vector, note that // the three bits may straddle a byte bounday so two byte wide // assignments are made to adjacent bytes - but not if the least // signifcant byte of the aligned value is the most significant // byte of the destination. val.half <<= idx.rem; datap[idx.quot] |= val.byte[0]; // or in value if ((idx.quot+1) < bytes) { datap[idx.quot+1] = val.byte[1]; // this also resets all bits to 0 prior to or'ing above } } // mask off non existant bits in the most significant byte if (idx.quot == (bytes-1)) { datap[idx.quot] &= vop->mask_byte(idx.quot); } else if (idx.quot+1 == (bytes-1)) { datap[idx.quot+1] &= vop->mask_byte(idx.quot+1); } // zero off remaining top bytes for (int i=idx.quot+2; iformat), vop->fullname()); return 0; } } else if (value_p->format == vpiDecStrVal) { char remainder[16]; unsigned long long val; int success = sscanf(value_p->value.str, "%30llu%15s", &val, remainder); if (success < 1) { _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Parsing failed for '%s' as value %s for %s", VL_FUNC, value_p->value.str, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return 0; } if (success > 1) { _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Trailing garbage '%s' in '%s' as value %s for %s", VL_FUNC, remainder, value_p->value.str, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); } switch (vop->varp()->vltype()) { case VLVT_UINT8 : *((CData*)(vop->varDatap())) = val & vop->mask(); break; case VLVT_UINT16: *((SData*)(vop->varDatap())) = val & vop->mask(); break; case VLVT_UINT32: *((IData*)(vop->varDatap())) = val & vop->mask(); break; case VLVT_UINT64: *((QData*)(vop->varDatap())) = val; ((IData*)(vop->varDatap()))[1] &= vop->mask(); break; case VLVT_WDATA: default: _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s, maximum limit is 64 bits", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return 0; } return object; } else if (value_p->format == vpiHexStrVal) { switch (vop->varp()->vltype()) { case VLVT_UINT8 : case VLVT_UINT16: case VLVT_UINT32: case VLVT_UINT64: case VLVT_WDATA: { int chars = (vop->varp()->range().elements()+3)>>2; CData* datap = ((CData*)(vop->varDatap())); char* val = value_p->value.str; // skip hex ident if one is detected at the start of the string if (val[0] == '0' && (val[1] == 'x' || val[1] == 'X')) { val += 2; } int len = strlen(val); for (int i=0; i= '0' && digit <= '9') hex = digit - '0'; else if (digit >= 'a' && digit <= 'f') hex = digit - 'a' + 10; else if (digit >= 'A' && digit <= 'F') hex = digit - 'A' + 10; else { _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Non hex character '%c' in '%s' as value %s for %s", VL_FUNC, digit, value_p->value.str, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); hex = 0; } } else { hex = 0; } // assign hex digit value to destination if (i&1) { datap[i>>1] |= hex<<4; } else { datap[i>>1] = hex; // this also resets all bits to 0 prior to or'ing above of the msb } } // apply bit mask to most significant byte datap[(chars-1)>>1] &= vop->mask_byte((chars-1)>>1); return object; } default: _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return 0; } } else if (value_p->format == vpiStringVal) { switch (vop->varp()->vltype()) { case VLVT_UINT8 : case VLVT_UINT16: case VLVT_UINT32: case VLVT_UINT64: case VLVT_WDATA: { int bytes = VL_BYTES_I(vop->varp()->range().elements()); int len = strlen(value_p->value.str); CData* datap = ((CData*)(vop->varDatap())); for (int i=0; ivalue.str[len-i-1]:0; // prepend with 0 values before placing string the least signifcant bytes } return object; } default: _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return 0; } } else if (value_p->format == vpiIntVal) { switch (vop->varp()->vltype()) { case VLVT_UINT8: *((CData*)(vop->varDatap())) = vop->mask() & value_p->value.integer; return object; case VLVT_UINT16: *((SData*)(vop->varDatap())) = vop->mask() & value_p->value.integer; return object; case VLVT_UINT32: *((IData*)(vop->varDatap())) = vop->mask() & value_p->value.integer; return object; case VLVT_WDATA: // FALLTHRU case VLVT_UINT64: // FALLTHRU default: _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return 0; } } _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) as requested for %s", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return NULL; } _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for ??", VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format)); return NULL; } void vpi_get_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_INT32 *index_p, PLI_UINT32 num) { _VL_VPI_UNIMP(); return; } void vpi_put_value_array(vpiHandle object, p_vpi_arrayvalue arrayvalue_p, PLI_INT32 *index_p, PLI_UINT32 num) { _VL_VPI_UNIMP(); return; } // time processing void vpi_get_time(vpiHandle object, p_vpi_time time_p) { if (VL_UNLIKELY(!time_p)) { _VL_VPI_WARNING(__FILE__, __LINE__, "Ignoring vpi_get_time with NULL value pointer"); return; } if (time_p->type == vpiSimTime) { QData qtime = VL_TIME_Q(); IData itime[2]; VL_SET_WQ(itime, qtime); time_p->low = itime[0]; time_p->high = itime[1]; return; } _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported type (%d)", VL_FUNC, time_p->type); return; } // I/O routines PLI_UINT32 vpi_mcd_open(PLI_BYTE8 *filenamep) { _VL_VPI_ERROR_RESET(); // reset vpi error status return VL_FOPEN_S(filenamep,"wb"); } PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) { _VL_VPI_ERROR_RESET(); // reset vpi error status VL_FCLOSE_I(mcd); return 0; } PLI_BYTE8 *vpi_mcd_name(PLI_UINT32 mcd) { _VL_VPI_UNIMP(); return 0; } PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, PLI_BYTE8 *formatp, ...) { _VL_VPI_ERROR_RESET(); // reset vpi error status va_list ap; va_start(ap,formatp); int chars = vpi_mcd_vprintf(mcd, formatp, ap); va_end(ap); return chars; } PLI_INT32 vpi_printf(PLI_BYTE8 *formatp, ...) { _VL_VPI_ERROR_RESET(); // reset vpi error status va_list ap; va_start(ap,formatp); int chars = vpi_vprintf(formatp, ap); va_end(ap); return chars; } PLI_INT32 vpi_vprintf(PLI_BYTE8* formatp, va_list ap) { _VL_VPI_ERROR_RESET(); // reset vpi error status return VL_VPRINTF(formatp, ap); } PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, PLI_BYTE8 *format, va_list ap) { FILE* fp = VL_CVT_I_FP(mcd); _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!fp)) return 0; int chars = vfprintf(fp, format, ap); return chars; } PLI_INT32 vpi_flush(void) { _VL_VPI_ERROR_RESET(); // reset vpi error status Verilated::flushCall(); return 0; } PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) { FILE* fp = VL_CVT_I_FP(mcd); _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!fp)) return 1; fflush(fp); return 0; } // utility routines PLI_INT32 vpi_compare_objects(vpiHandle object1, vpiHandle object2) { _VL_VPI_UNIMP(); return 0; } PLI_INT32 vpi_chk_error(p_vpi_error_info error_info_p) { // executing vpi_chk_error does not reset error // error_info_p can be NULL, so only return level in that case p_vpi_error_info _error_info_p = VerilatedVpi::error_info()->getError(); if (error_info_p && _error_info_p) { *error_info_p = *_error_info_p; } if (!_error_info_p) return 0; // no error occured return _error_info_p->level; // return error severity level }; PLI_INT32 vpi_free_object(vpiHandle object) { _VL_VPI_ERROR_RESET(); // reset vpi error status return vpi_release_handle(object); // Deprecated } PLI_INT32 vpi_release_handle (vpiHandle object) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_release_handle %p\n",object);); VerilatedVpio* vop = VerilatedVpio::castp(object); _VL_VPI_ERROR_RESET(); // reset vpi error status if (VL_UNLIKELY(!vop)) return 0; vpi_remove_cb(object); // May not be a callback, but that's ok delete vop; return 1; } PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p) { _VL_VPI_ERROR_RESET(); // reset vpi error status vlog_info_p->argc = Verilated::getCommandArgs()->argc; vlog_info_p->argv = (PLI_BYTE8**)Verilated::getCommandArgs()->argv; vlog_info_p->product = (PLI_BYTE8*)Verilated::productName(); vlog_info_p->version = (PLI_BYTE8*)Verilated::productVersion(); return 1; } // routines added with 1364-2001 PLI_INT32 vpi_get_data(PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes) { _VL_VPI_UNIMP(); return 0; } PLI_INT32 vpi_put_data(PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes) { _VL_VPI_UNIMP(); return 0; } void *vpi_get_userdata(vpiHandle obj) { _VL_VPI_UNIMP(); return 0; } PLI_INT32 vpi_put_userdata(vpiHandle obj, void *userdata) { _VL_VPI_UNIMP(); return 0; } PLI_INT32 vpi_control(PLI_INT32 operation, ...) { VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_control %d\n",operation);); _VL_VPI_ERROR_RESET(); // reset vpi error status switch (operation) { case vpiFinish: { vl_finish(__FILE__,__LINE__,"*VPI*"); return 1; } case vpiStop: { vl_stop(__FILE__,__LINE__,"*VPI*"); return 1; } } _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, ignoring", VL_FUNC, VerilatedVpiError::strFromVpiProp(operation)); return 0; } vpiHandle vpi_handle_by_multi_index(vpiHandle obj, PLI_INT32 num_index, PLI_INT32 *index_array) { _VL_VPI_UNIMP(); return 0; } //====================================================================== #endif // Guard verilator-3.874/include/verilated.h0000664000177100017500000022574412525172076017323 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2003-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* /// /// \file /// \brief Verilator: Common include for all Verilated C files /// /// This file is included automatically by Verilator at the top of /// all C++ files it generates. It contains standard macros and /// classes required by the Verilated code. /// /// Code available from: http://www.veripool.org/verilator /// //************************************************************************* #ifndef _VERILATED_H_ #define _VERILATED_H_ 1 ///< Header Guard #include "verilated_config.h" #include "verilatedos.h" #include #include #include #include #include #include // avoided to reduce compile time // avoided and instead in verilated_heavy.h to reduce compile time using namespace std; //============================================================================= // Switches #if VM_TRACE // Verilator tracing requested # define WAVES 1 // Set backward compatibility flag as in systemperl.h #endif //========================================================================= // Basic types // P // Packed data of bit type (C/S/I/Q/W) typedef vluint8_t CData; ///< Verilated pack data, 1-8 bits typedef vluint16_t SData; ///< Verilated pack data, 9-16 bits typedef vluint32_t IData; ///< Verilated pack data, 17-32 bits typedef vluint64_t QData; ///< Verilated pack data, 33-64 bits typedef vluint32_t WData; ///< Verilated pack data, >64 bits, as an array // float F // No typedef needed; Verilator uses float // double D // No typedef needed; Verilator uses double // string N // No typedef needed; Verilator uses string typedef const WData* WDataInP; ///< Array input to a function typedef WData* WDataOutP; ///< Array output from a function typedef void (*VerilatedVoidCb)(void); class SpTraceVcd; class SpTraceVcdCFile; class VerilatedVar; class VerilatedVarNameMap; class VerilatedVcd; class VerilatedVcdC; enum VerilatedVarType { VLVT_UNKNOWN=0, VLVT_PTR, // Pointer to something VLVT_UINT8, // AKA CData VLVT_UINT16, // AKA SData VLVT_UINT32, // AKA IData VLVT_UINT64, // AKA QData VLVT_WDATA, // AKA WData VLVT_STRING // C++ string }; enum VerilatedVarFlags { VLVD_IN=1, // == vpiInput VLVD_OUT=2, // == vpiOutput VLVD_INOUT=3, // == vpiInOut VLVD_NODIR=5, // == vpiNoDirection VLVF_MASK_DIR=7, // Bit mask for above directions // Flags VLVF_PUB_RD=(1<<8), // Public readable VLVF_PUB_RW=(1<<9) // Public writable }; //========================================================================= /// Base class for all Verilated module classes class VerilatedModule { private: const char* m_namep; ///< Module name VerilatedModule(); ///< N/A, always use named constructor below VerilatedModule(const VerilatedModule& ); ///< N/A, no copying modules public: VerilatedModule(const char* namep); ///< Create module with given hierarchy name ~VerilatedModule(); const char* name() const { return m_namep; } ///< Return name of module }; //========================================================================= // Declare nets #ifndef VL_ST_SIG # define VL_ST_SIG8(name, msb,lsb) CData name ///< Declare signal, 1-8 bits # define VL_ST_SIG16(name, msb,lsb) SData name ///< Declare signal, 9-16 bits # define VL_ST_SIG64(name, msb,lsb) QData name ///< Declare signal, 33-64 bits # define VL_ST_SIG(name, msb,lsb) IData name ///< Declare signal, 17-32 bits # define VL_ST_SIGW(name,msb,lsb,words) WData name[words] ///< Declare signal, 65+ bits #endif #ifndef VL_SIG # define VL_SIG8(name, msb,lsb) CData name ///< Declare signal, 1-8 bits # define VL_SIG16(name, msb,lsb) SData name ///< Declare signal, 9-16 bits # define VL_SIG64(name, msb,lsb) QData name ///< Declare signal, 33-64 bits # define VL_SIG(name, msb,lsb) IData name ///< Declare signal, 17-32 bits # define VL_SIGW(name, msb,lsb, words) WData name[words] ///< Declare signal, 65+ bits # define VL_IN8(name, msb,lsb) CData name ///< Declare input signal, 1-8 bits # define VL_IN16(name, msb,lsb) SData name ///< Declare input signal, 9-16 bits # define VL_IN64(name, msb,lsb) QData name ///< Declare input signal, 33-64 bits # define VL_IN(name, msb,lsb) IData name ///< Declare input signal, 17-32 bits # define VL_INW(name, msb,lsb, words) WData name[words] ///< Declare input signal, 65+ bits # define VL_INOUT8(name, msb,lsb) CData name ///< Declare bidir signal, 1-8 bits # define VL_INOUT16(name, msb,lsb) SData name ///< Declare bidir signal, 9-16 bits # define VL_INOUT64(name, msb,lsb) QData name ///< Declare bidir signal, 33-64 bits # define VL_INOUT(name, msb,lsb) IData name ///< Declare bidir signal, 17-32 bits # define VL_INOUTW(name, msb,lsb, words) WData name[words] ///< Declare bidir signal, 65+ bits # define VL_OUT8(name, msb,lsb) CData name ///< Declare output signal, 1-8 bits # define VL_OUT16(name, msb,lsb) SData name ///< Declare output signal, 9-16 bits # define VL_OUT64(name, msb,lsb) QData name ///< Declare output signal, 33-64bits # define VL_OUT(name, msb,lsb) IData name ///< Declare output signal, 17-32 bits # define VL_OUTW(name, msb,lsb, words) WData name[words] ///< Declare output signal, 65+ bits # define VL_PIN_NOP(instname,pin,port) ///< Connect a pin, ala SP_PIN # define VL_CELL(instname,type) ///< Declare a cell, ala SP_CELL /// Declare a module, ala SC_MODULE # define VL_MODULE(modname) class modname : public VerilatedModule /// Constructor, ala SC_CTOR # define VL_CTOR(modname) modname(const char* __VCname="") /// Constructor declaration for C++, ala SP_CTOR_IMPL # define VL_CTOR_IMP(modname) modname::modname(const char* __VCname) : VerilatedModule(__VCname) /// Constructor declaration for SystemC, ala SP_CTOR_IMPL # define VL_SC_CTOR_IMP(modname) modname::modname(sc_module_name) #endif //========================================================================= // Functions overridable by user defines #ifndef VL_PRINTF # define VL_PRINTF printf ///< Print ala printf; may redefine if desired #endif #ifndef VL_VPRINTF # define VL_VPRINTF vprintf ///< Print ala vprintf; may redefine if desired #endif //=========================================================================== /// Verilator symbol table base class class VerilatedSyms { // VerilatedSyms base class exists just so symbol tables have a common pointer type }; //=========================================================================== /// Verilator global static information class class VerilatedScope { // Fastpath: VerilatedSyms* m_symsp; ///< Symbol table void** m_callbacksp; ///< Callback table pointer (Fastpath) int m_funcnumMax; ///< Maxium function number stored (Fastpath) // 4 bytes padding (on -m64), for rent. VerilatedVarNameMap* m_varsp; ///< Variable map const char* m_namep; ///< Scope name (Slowpath) public: // But internals only - called from VerilatedModule's VerilatedScope(); ~VerilatedScope(); void configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp); void exportInsert(int finalize, const char* namep, void* cb); void varInsert(int finalize, const char* namep, void* datap, VerilatedVarType vltype, int vlflags, int dims, ...); // ACCESSORS const char* name() const { return m_namep; } inline VerilatedSyms* symsp() const { return m_symsp; } VerilatedVar* varFind(const char* namep) const; VerilatedVarNameMap* varsp() const { return m_varsp; } void* exportFindError(int funcnum) const; void* exportFindNullError(int funcnum) const; void scopeDump() const; inline void* exportFind(int funcnum) const { if (VL_UNLIKELY(!this)) return exportFindNullError(funcnum); if (VL_LIKELY(funcnum < m_funcnumMax)) { // m_callbacksp must be declared, as Max'es are > 0 return m_callbacksp[funcnum]; } else { return exportFindError(funcnum); } } }; //=========================================================================== /// Verilator global static information class class Verilated { // MEMBERS // Slow path variables static VerilatedVoidCb s_flushCb; ///< Flush callback function static struct Serialized { // All these members serialized/deserialized // Slow path int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random // Fast path int s_debug; ///< See accessors... only when VL_DEBUG set bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated bool s_gotFinish; ///< A $finish statement executed bool s_assertOn; ///< Assertions are enabled bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported Serialized(); } s_s; static VL_THREAD const VerilatedScope* t_dpiScopep; ///< DPI context scope static VL_THREAD const char* t_dpiFilename; ///< DPI context filename static VL_THREAD int t_dpiLineno; ///< DPI context line number // no need to be save-restored (serialized) the // assumption is that the restore is allowed to pass different arguments static struct CommandArgValues { int argc; const char** argv; } s_args; public: // METHODS - User called /// Select initial value of otherwise uninitialized signals. //// /// 0 = Set to zeros /// 1 = Set all bits to one /// 2 = Randomize all bits static void randReset(int val) { s_s.s_randReset=val; } static int randReset() { return s_s.s_randReset; } ///< Return randReset value /// Enable debug of internal verilated code static inline void debug(int level) { s_s.s_debug = level; } #ifdef VL_DEBUG static inline int debug() { return s_s.s_debug; } ///< Return debug value #else static inline int debug() { return 0; } ///< Constant 0 debug, so C++'s optimizer rips up #endif /// Enable calculation of unused signals static void calcUnusedSigs(bool flag) { s_s.s_calcUnusedSigs=flag; } static bool calcUnusedSigs() { return s_s.s_calcUnusedSigs; } ///< Return calcUnusedSigs value /// Did the simulation $finish? static void gotFinish(bool flag) { s_s.s_gotFinish=flag; } static bool gotFinish() { return s_s.s_gotFinish; } ///< Return if got a $finish /// Allow traces to at some point be enabled (disables some optimizations) static void traceEverOn(bool flag) { if (flag) { calcUnusedSigs(flag); } } /// Enable/disable assertions static void assertOn(bool flag) { s_s.s_assertOn=flag; } static bool assertOn() { return s_s.s_assertOn; } /// Enable/disable vpi fatal static void fatalOnVpiError(bool flag) { s_s.s_fatalOnVpiError=flag; } static bool fatalOnVpiError() { return s_s.s_fatalOnVpiError; } /// Flush callback for VCD waves static void flushCb(VerilatedVoidCb cb); static void flushCall() { if (s_flushCb) (*s_flushCb)(); } /// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs static void commandArgs(int argc, const char** argv); static void commandArgs(int argc, char** argv) { commandArgs(argc,(const char**)argv); } static CommandArgValues* getCommandArgs() {return &s_args;} static const char* commandArgsPlusMatch(const char* prefixp); /// Produce name & version for (at least) VPI static const char* productName() { return VERILATOR_PRODUCT; } static const char* productVersion() { return VERILATOR_VERSION; } /// For debugging, print much of the Verilator internal state. /// The output of this function may change in future /// releases - contact the authors before production use. static void internalsDump(); /// For debugging, print text list of all scope names with /// dpiImport/Export context. This function may change in future /// releases - contact the authors before production use. static void scopesDump(); // METHODS - INTERNAL USE ONLY // Internal: Create a new module name by concatenating two strings static const char* catName(const char* n1, const char* n2); // Returns new'ed data // Internal: Find scope static const VerilatedScope* scopeFind(const char* namep); // Internal: Get and set DPI context static const VerilatedScope* dpiScope() { return t_dpiScopep; } static void dpiScope(const VerilatedScope* scopep) { t_dpiScopep=scopep; } static void dpiContext(const VerilatedScope* scopep, const char* filenamep, int lineno) { t_dpiScopep=scopep; t_dpiFilename=filenamep; t_dpiLineno=lineno; } static void dpiClearContext() { t_dpiScopep = NULL; } static bool dpiInContext() { return t_dpiScopep != NULL; } static const char* dpiFilenamep() { return t_dpiFilename; } static int dpiLineno() { return t_dpiLineno; } static int exportFuncNum(const char* namep); static size_t serializedSize() { return sizeof(s_s); } static void* serializedPtr() { return &s_s; } }; //========================================================================= // Extern functions -- User may override -- See verilated.cpp /// Routine to call for $finish extern void vl_finish (const char* filename, int linenum, const char* hier); /// Routine to call for $stop extern void vl_stop (const char* filename, int linenum, const char* hier); /// Routine to call for a couple of fatal messages extern void vl_fatal (const char* filename, int linenum, const char* hier, const char* msg); //========================================================================= // Extern functions -- Slow path extern IData VL_RANDOM_I(int obits); ///< Randomize a signal extern QData VL_RANDOM_Q(int obits); ///< Randomize a signal extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp); ///< Randomize a signal /// Init time only, so slow is fine extern IData VL_RAND_RESET_I(int obits); ///< Random reset a signal extern QData VL_RAND_RESET_Q(int obits); ///< Random reset a signal extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp); ///< Random reset a signal extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp); ///< Zero reset a signal /// Math extern WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool is_modulus); /// File I/O extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi); extern IData VL_FOPEN_S(const char* filenamep, const char* mode); extern IData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode); extern IData VL_FOPEN_QI(QData ofilename, IData mode); inline IData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); } extern void VL_FCLOSE_I(IData fdi); extern void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords, WDataInP ofilename, void* memp, IData start, IData end); extern void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int fnwords, QData ofilename, void* memp, IData start, IData end); inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwords, IData ofilename, void* memp, IData start, IData end) { VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); } extern void VL_WRITEF(const char* formatp, ...); extern void VL_FWRITEF(IData fpi, const char* formatp, ...); extern IData VL_FSCANF_IX(IData fpi, const char* formatp, ...); extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...); extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...); extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...); extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...); extern IData VL_SYSTEM_IW(int lhsnwords, WDataInP lhs); extern IData VL_SYSTEM_IQ(QData lhs); inline IData VL_SYSTEM_II(IData lhs) { return VL_SYSTEM_IQ(lhs); } extern IData VL_TESTPLUSARGS_I(const char* formatp); extern IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp); extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish //========================================================================= // Base macros /// Return true if data[bit] set #define VL_BITISSET_I(data,bit) (data & (VL_UL(1)<>VL_WORDSIZE); } #define VL_SET_WI(owp,data) { owp[0]=(IData)(data); owp[1]=0; } #define VL_SET_QW(lwp) ( ((QData)(lwp[0])) | ((QData)(lwp[1])<<((QData)(VL_WORDSIZE)) )) #define _VL_SET_QII(ld,rd) ( ((QData)(ld)<> VL_BITBIT_I((nbits) - VL_UL(1))) #define VL_SIGN_Q(nbits,lhs) ((lhs) >> VL_BITBIT_Q((nbits) - VL_ULL(1))) #define VL_SIGNONES_I(nbits,lhs) (-(VL_SIGN_I(nbits,lhs))) // Sign bit extended up to MSB, doesn't include unsigned portion // Optimization bug in GCC 3.3 returns different bitmasks to later states for static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(VL_UL(1)<<(lbits-1)))); } static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); } // Debugging prints void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp); //========================================================================= // Pli macros #ifndef VL_TIME_PRECISION # define VL_TIME_PRECISION -12 ///< Timescale units only for for VPI return - picoseconds #endif #ifndef VL_TIME_MULTIPLIER # define VL_TIME_MULTIPLIER 1 #endif /// Return current simulation time #if defined(SYSTEMC_VERSION) && (SYSTEMC_VERSION>20011000) # define VL_TIME_I() ((IData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER)) # define VL_TIME_Q() ((QData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER)) # define VL_TIME_D() ((double)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER)) #else # define VL_TIME_I() ((IData)(sc_time_stamp()*VL_TIME_MULTIPLIER)) # define VL_TIME_Q() ((QData)(sc_time_stamp()*VL_TIME_MULTIPLIER)) # define VL_TIME_D() ((double)(sc_time_stamp()*VL_TIME_MULTIPLIER)) extern double sc_time_stamp(); #endif /// Evaluate expression if debug enabled #ifdef VL_DEBUG # define VL_DEBUG_IF(text) {if (VL_UNLIKELY(Verilated::debug())) {text}} #else # define VL_DEBUG_IF(text) #endif /// Collect coverage analysis for this line #ifndef SP_AUTO_COVER3 # define SP_AUTO_COVER3(what,file,line) #endif //========================================================================= // Functional macros/routines // These all take the form // VL_func_IW(bits,bits,op,op) // VL_func_WW(bits,bits,out,op,op) // The I/W indicates if it's a integer or wide for the output and each operand. // The bits indicate the bit width of the output and each operand. // If wide output, a temporary storage location is specified. //=================================================================== // SETTING OPERATORS // Output clean // EMIT_RULE: VL_CLEAN: oclean=clean; obits=lbits; #define VL_CLEAN_II(obits,lbits,lhs) ((lhs) & VL_MASK_I(obits)) #define VL_CLEAN_QQ(obits,lbits,lhs) ((lhs) & VL_MASK_Q(obits)) // EMIT_RULE: VL_ASSIGNCLEAN: oclean=clean; obits==lbits; #define VL_ASSIGNCLEAN_W(obits,owp,lwp) VL_CLEAN_WW(obits,obits,owp,lwp) static inline WDataOutP _VL_CLEAN_INPLACE_W(int obits, WDataOutP owp) { int words = VL_WORDS_I(obits); owp[words-1] &= VL_MASK_I(obits); return(owp); } static inline WDataOutP VL_CLEAN_WW(int obits, int, WDataOutP owp, WDataInP lwp){ int words = VL_WORDS_I(obits); for (int i=0; (i < (words-1)); i++) owp[i] = lwp[i]; owp[words-1] = lwp[words-1] & VL_MASK_I(obits); return(owp); } // EMIT_RULE: VL_ASSIGN: oclean=rclean; obits==lbits; // For now, we always have a clean rhs. // Note: If a ASSIGN isn't clean, use VL_ASSIGNCLEAN instead to do the same thing. static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp,WDataInP lwp){ int words = VL_WORDS_I(obits); for (int i=0; i < words; i++) owp[i] = lwp[i]; return(owp); } // EMIT_RULE: VL_ASSIGNBIT: rclean=clean; static inline void VL_ASSIGNBIT_II(int, int bit, CData& lhsr, IData rhs) { lhsr = ((lhsr & ~(VL_UL(1)< _butemp = (svar).read(); \ for (int i=0; i < words; i++) { \ int msb = ((i+1)*VL_WORDSIZE) - 1; \ msb = (msb >= obits) ? (obits-1) : msb; \ owp[i] = _butemp.range(msb,i*VL_WORDSIZE).to_uint(); \ } \ owp[words-1] &= VL_MASK_I(obits); \ } // Copying verilog format from systemc integers and bit vectors. // Set a SystemC variable #define VL_ASSIGN_SII(obits,svar,vvar) { (svar).write(vvar); } #define VL_ASSIGN_SQQ(obits,svar,vvar) { (svar).write(vvar); } #define VL_ASSIGN_SWI(obits,svar,rd) { \ sc_bv _bvtemp; \ _bvtemp.set_word(0,(rd)); \ svar.write(_bvtemp); \ } #define VL_ASSIGN_SWQ(obits,svar,rd) { \ sc_bv _bvtemp; \ _bvtemp.set_word(0,(IData)(rd)); \ _bvtemp.set_word(1,(IData)((rd)>>VL_WORDSIZE)); \ svar.write(_bvtemp); \ } #define VL_ASSIGN_SWW(obits,svar,rwp) { \ sc_bv _bvtemp; \ for (int i=0; i < VL_WORDS_I(obits); i++) _bvtemp.set_word(i,rwp[i]); \ svar.write(_bvtemp); \ } #define VL_ASSIGN_SUI(obits,svar,rd) { (svar).write(rd); } #define VL_ASSIGN_SUQ(obits,svar,rd) { (svar).write(rd); } #define VL_ASSIGN_SBI(obits,svar,rd) { (svar).write(rd); } #define VL_ASSIGN_SBQ(obits,svar,rd) { (svar).write(rd); } #define VL_ASSIGN_SBW(obits,svar,rwp) { \ sc_biguint _butemp; \ for (int i=0; i < VL_WORDS_I(obits); i++) { \ int msb = ((i+1)*VL_WORDSIZE) - 1; \ msb = (msb >= obits) ? (obits-1) : msb; \ _butemp.range(msb,i*VL_WORDSIZE) = rwp[i]; \ } \ svar.write(_butemp); \ } //=================================================================== // Extending sizes // CAREFUL, we're width changing, so obits!=lbits // Right must be clean because otherwise size increase would pick up bad bits // EMIT_RULE: VL_EXTEND: oclean=clean; rclean==clean; #define VL_EXTEND_II(obits,lbits,lhs) ((lhs)) #define VL_EXTEND_QI(obits,lbits,lhs) ((QData)(lhs)) #define VL_EXTEND_QQ(obits,lbits,lhs) ((lhs)) static inline WDataOutP VL_EXTEND_WI(int obits, int, WDataOutP owp, IData ld) { // Note for extracts that obits != lbits owp[0] = ld; for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = 0; return(owp); } static inline WDataOutP VL_EXTEND_WQ(int obits, int, WDataOutP owp, QData ld) { VL_SET_WQ(owp,ld); for (int i=2; i < VL_WORDS_I(obits); i++) owp[i] = 0; return(owp); } static inline WDataOutP VL_EXTEND_WW(int obits, int lbits, WDataOutP owp, WDataInP lwp) { for (int i=0; i < VL_WORDS_I(lbits); i++) owp[i] = lwp[i]; for (int i=VL_WORDS_I(lbits); i < VL_WORDS_I(obits); i++) owp[i] = 0; return(owp); } // EMIT_RULE: VL_EXTENDS: oclean=*dirty*; obits=lbits; // Sign extension; output dirty static inline IData VL_EXTENDS_II(int, int lbits, IData lhs) { return VL_EXTENDSIGN_I(lbits,lhs) | lhs; } static inline QData VL_EXTENDS_QI(int, int lbits, QData lhs/*Q_as_need_extended*/) { return VL_EXTENDSIGN_Q(lbits,lhs) | lhs; } static inline QData VL_EXTENDS_QQ(int, int lbits, QData lhs) { return VL_EXTENDSIGN_Q(lbits,lhs) | lhs; } static inline WDataOutP VL_EXTENDS_WI(int obits, int lbits, WDataOutP owp, IData ld) { IData sign = VL_SIGNONES_I(lbits,ld); owp[0] = ld | (sign & ~VL_MASK_I(lbits)); for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = sign; return(owp); } static inline WDataOutP VL_EXTENDS_WQ(int obits, int lbits, WDataOutP owp, QData ld) { VL_SET_WQ(owp,ld); IData sign = VL_SIGNONES_I(lbits,owp[1]); owp[1] |= sign & ~VL_MASK_I(lbits); for (int i=2; i < VL_WORDS_I(obits); i++) owp[i] = sign; return(owp); } static inline WDataOutP VL_EXTENDS_WW(int obits, int lbits, WDataOutP owp, WDataInP lwp) { for (int i=0; i < VL_WORDS_I(lbits)-1; i++) owp[i] = lwp[i]; int lmsw=VL_WORDS_I(lbits)-1; IData sign = VL_SIGNONES_I(lbits,lwp[lmsw]); owp[lmsw] = lwp[lmsw] | (sign & ~VL_MASK_I(lbits)); for (int i=VL_WORDS_I(lbits); i < VL_WORDS_I(obits); i++) owp[i] = sign; return(owp); } //=================================================================== // REDUCTION OPERATORS // EMIT_RULE: VL_REDAND: oclean=clean; lclean==clean; obits=1; #define VL_REDAND_II(obits,lbits,lhs) (lhs == VL_MASK_I(lbits)) #define VL_REDAND_IQ(obits,lbits,lhs) (lhs == VL_MASK_Q(lbits)) static inline IData VL_REDAND_IW(int, int lbits, WDataInP lwp) { int words = VL_WORDS_I(lbits); IData combine=lwp[0]; for (int i=1; i < words-1; i++) combine &= lwp[i]; combine &= ~VL_MASK_I(lbits) | lwp[words-1]; return ((~combine)==0); } // EMIT_RULE: VL_REDOR: oclean=clean; lclean==clean; obits=1; #define VL_REDOR_I(lhs) (lhs!=0) #define VL_REDOR_Q(lhs) (lhs!=0) static inline IData VL_REDOR_W(int words, WDataInP lwp) { IData equal=0; for (int i=0; i < words; i++) equal |= lwp[i]; return(equal!=0); } // EMIT_RULE: VL_REDXOR: oclean=dirty; obits=1; static inline IData VL_REDXOR_2(IData r) { // Experiments show VL_REDXOR_2 is faster than __builtin_parityl r=(r^(r>>1)); return r; } static inline IData VL_REDXOR_4(IData r) { #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS) return __builtin_parityl(r); #else r=(r^(r>>1)); r=(r^(r>>2)); return r; #endif } static inline IData VL_REDXOR_8(IData r) { #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS) return __builtin_parityl(r); #else r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); return r; #endif } static inline IData VL_REDXOR_16(IData r) { #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS) return __builtin_parityl(r); #else r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); return r; #endif } static inline IData VL_REDXOR_32(IData r) { #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS) return __builtin_parityl(r); #else r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>16)); return r; #endif } static inline IData VL_REDXOR_64(QData r) { #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS) return __builtin_parityll(r); #else r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>16)); r=(r^(r>>32)); return (IData)r; #endif } static inline IData VL_REDXOR_W(int words, WDataInP lwp) { IData r = lwp[0]; for (int i=1; i < words; i++) r ^= lwp[i]; return VL_REDXOR_32(r); } // EMIT_RULE: VL_COUNTONES_II: oclean = false; lhs clean static inline IData VL_COUNTONES_I(IData lhs) { // This is faster than __builtin_popcountl IData r = lhs - ((lhs >> 1) & 033333333333) - ((lhs >> 2) & 011111111111); r = (r + (r>>3)) & 030707070707; r = (r + (r>>6)); r = (r + (r>>12) + (r>>24)) & 077; return r; } static inline IData VL_COUNTONES_Q(QData lhs) { return VL_COUNTONES_I((IData)lhs) + VL_COUNTONES_I((IData)(lhs>>32)); } static inline IData VL_COUNTONES_W(int words, WDataInP lwp) { IData r = 0; for (int i=0; (i < words); i++) r+=VL_COUNTONES_I(lwp[i]); return r; } static inline IData VL_ONEHOT_I(IData lhs) { return (((lhs & (lhs-1))==0) & (lhs!=0)); } static inline IData VL_ONEHOT_Q(QData lhs) { return (((lhs & (lhs-1))==0) & (lhs!=0)); } static inline IData VL_ONEHOT_W(int words, WDataInP lwp) { IData one=0; for (int i=0; (i < words); i++) { if (lwp[i]) { if (one) return 0; one = 1; if (lwp[i] & (lwp[i]-1)) return 0; } } return one; } static inline IData VL_ONEHOT0_I(IData lhs) { return ((lhs & (lhs-1))==0); } static inline IData VL_ONEHOT0_Q(QData lhs) { return ((lhs & (lhs-1))==0); } static inline IData VL_ONEHOT0_W(int words, WDataInP lwp) { bool one=false; for (int i=0; (i < words); i++) { if (lwp[i]) { if (one) return 0; one = true; if (lwp[i] & (lwp[i]-1)) return 0; } } return 1; } static inline IData VL_CLOG2_I(IData lhs) { // There are faster algorithms, or fls GCC4 builtins, but rarely used if (VL_UNLIKELY(!lhs)) return 0; lhs--; int shifts=0; for (; lhs!=0; shifts++) lhs = lhs >> 1; return shifts; } static inline IData VL_CLOG2_Q(QData lhs) { if (VL_UNLIKELY(!lhs)) return 0; lhs--; int shifts=0; for (; lhs!=0; shifts++) lhs = lhs >> VL_ULL(1); return shifts; } static inline IData VL_CLOG2_W(int words, WDataInP lwp) { IData adjust = (VL_COUNTONES_W(words,lwp)==1) ? 0 : 1; for (int i=words-1; i>=0; i--) { if (VL_UNLIKELY(lwp[i])) { // Shorter worst case if predict not taken for (int bit=31; bit>=0; bit--) { if (VL_UNLIKELY(VL_BITISSET_I(lwp[i],bit))) { return i*VL_WORDSIZE + bit + adjust; } } // Can't get here - one bit must be set } } return 0; } static inline IData VL_MOSTSETBITP1_W(int words, WDataInP lwp) { // MSB set bit plus one; similar to FLS. 0=value is zero for (int i=words-1; i>=0; i--) { if (VL_UNLIKELY(lwp[i])) { // Shorter worst case if predict not taken for (int bit=31; bit>=0; bit--) { if (VL_UNLIKELY(VL_BITISSET_I(lwp[i],bit))) { return i*VL_WORDSIZE + bit + 1; } } // Can't get here - one bit must be set } } return 0; } //=================================================================== // SIMPLE LOGICAL OPERATORS // EMIT_RULE: VL_AND: oclean=lclean||rclean; obits=lbits; lbits==rbits; static inline WDataOutP VL_AND_W(int words, WDataOutP owp,WDataInP lwp,WDataInP rwp){ for (int i=0; (i < words); i++) owp[i] = (lwp[i] & rwp[i]); return(owp); } // EMIT_RULE: VL_OR: oclean=lclean&&rclean; obits=lbits; lbits==rbits; static inline WDataOutP VL_OR_W(int words, WDataOutP owp,WDataInP lwp,WDataInP rwp){ for (int i=0; (i < words); i++) owp[i] = (lwp[i] | rwp[i]); return(owp); } // EMIT_RULE: VL_CHANGEXOR: oclean=1; obits=32; lbits==rbits; static inline IData VL_CHANGEXOR_W(int words, WDataInP lwp,WDataInP rwp){ IData od = 0; for (int i=0; (i < words); i++) od |= (lwp[i] ^ rwp[i]); return(od); } // EMIT_RULE: VL_XOR: oclean=lclean&&rclean; obits=lbits; lbits==rbits; static inline WDataOutP VL_XOR_W(int words, WDataOutP owp,WDataInP lwp,WDataInP rwp){ for (int i=0; (i < words); i++) owp[i] = (lwp[i] ^ rwp[i]); return(owp); } // EMIT_RULE: VL_XNOR: oclean=dirty; obits=lbits; lbits==rbits; static inline WDataOutP VL_XNOR_W(int words, WDataOutP owp,WDataInP lwp,WDataInP rwp){ for (int i=0; (i < words); i++) owp[i] = (lwp[i] ^ ~rwp[i]); return(owp); } // EMIT_RULE: VL_NOT: oclean=dirty; obits=lbits; static inline WDataOutP VL_NOT_W(int words, WDataOutP owp,WDataInP lwp) { for (int i=0; i < words; i++) owp[i] = ~(lwp[i]); return(owp); } //========================================================================= // Logical comparisons // EMIT_RULE: VL_EQ: oclean=clean; lclean==clean; rclean==clean; obits=1; lbits==rbits; // EMIT_RULE: VL_NEQ: oclean=clean; lclean==clean; rclean==clean; obits=1; lbits==rbits; // EMIT_RULE: VL_LT: oclean=clean; lclean==clean; rclean==clean; obits=1; lbits==rbits; // EMIT_RULE: VL_GT: oclean=clean; lclean==clean; rclean==clean; obits=1; lbits==rbits; // EMIT_RULE: VL_GTE: oclean=clean; lclean==clean; rclean==clean; obits=1; lbits==rbits; // EMIT_RULE: VL_LTE: oclean=clean; lclean==clean; rclean==clean; obits=1; lbits==rbits; #define VL_NEQ_W(words,lwp,rwp) (!VL_EQ_W(words,lwp,rwp)) #define VL_LT_W(words,lwp,rwp) (_VL_CMP_W(words,lwp,rwp)<0) #define VL_LTE_W(words,lwp,rwp) (_VL_CMP_W(words,lwp,rwp)<=0) #define VL_GT_W(words,lwp,rwp) (_VL_CMP_W(words,lwp,rwp)>0) #define VL_GTE_W(words,lwp,rwp) (_VL_CMP_W(words,lwp,rwp)>=0) // Output clean, AND MUST BE CLEAN static inline IData VL_EQ_W(int words, WDataInP lwp, WDataInP rwp) { int nequal=0; for (int i=0; (i < words); i++) nequal |= (lwp[i] ^ rwp[i]); return(nequal==0); } // Internal usage static inline int _VL_CMP_W(int words, WDataInP lwp, WDataInP rwp) { for (int i=words-1; i>=0; --i) { if (lwp[i] > rwp[i]) return 1; if (lwp[i] < rwp[i]) return -1; } return(0); // == } #define VL_LTS_IWW(obits,lbits,rbbits,lwp,rwp) (_VL_CMPS_W(lbits,lwp,rwp)<0) #define VL_LTES_IWW(obits,lbits,rbits,lwp,rwp) (_VL_CMPS_W(lbits,lwp,rwp)<=0) #define VL_GTS_IWW(obits,lbits,rbits,lwp,rwp) (_VL_CMPS_W(lbits,lwp,rwp)>0) #define VL_GTES_IWW(obits,lbits,rbits,lwp,rwp) (_VL_CMPS_W(lbits,lwp,rwp)>=0) static inline IData VL_GTS_III(int, int lbits, int, IData lhs, IData rhs) { // For lbits==32, this becomes just a single instruction, otherwise ~5. // GCC 3.3.4 sign extension bugs on AMD64 architecture force us to use quad logic vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); //Q for gcc vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); //Q for gcc return lhs_signed > rhs_signed; } static inline IData VL_GTS_IQQ(int, int lbits, int, QData lhs, QData rhs) { vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); return lhs_signed > rhs_signed; } static inline IData VL_GTES_III(int, int lbits, int, IData lhs, IData rhs) { vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); //Q for gcc vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); //Q for gcc return lhs_signed >= rhs_signed; } static inline IData VL_GTES_IQQ(int, int lbits, int, QData lhs, QData rhs) { vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); return lhs_signed >= rhs_signed; } static inline IData VL_LTS_III(int, int lbits, int, IData lhs, IData rhs) { vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); //Q for gcc vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); //Q for gcc return lhs_signed < rhs_signed; } static inline IData VL_LTS_IQQ(int, int lbits, int, QData lhs, QData rhs) { vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); return lhs_signed < rhs_signed; } static inline IData VL_LTES_III(int, int lbits, int, IData lhs, IData rhs) { vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); //Q for gcc vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); //Q for gcc return lhs_signed <= rhs_signed; } static inline IData VL_LTES_IQQ(int, int lbits, int, QData lhs, QData rhs) { vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); return lhs_signed <= rhs_signed; } static inline int _VL_CMPS_W(int lbits, WDataInP lwp, WDataInP rwp) { int words = VL_WORDS_I(lbits); int i=words-1; // We need to flip sense if negative comparison IData lsign = VL_SIGN_I(lbits,lwp[i]); IData rsign = VL_SIGN_I(lbits,rwp[i]); if (!lsign && rsign) return 1; // + > - if (lsign && !rsign) return -1; // - < + for (; i>=0; --i) { if (lwp[i] > rwp[i]) return 1; if (lwp[i] < rwp[i]) return -1; } return(0); // == } //========================================================================= // Math // EMIT_RULE: VL_MUL: oclean=dirty; lclean==clean; rclean==clean; // EMIT_RULE: VL_DIV: oclean=dirty; lclean==clean; rclean==clean; // EMIT_RULE: VL_MODDIV: oclean=dirty; lclean==clean; rclean==clean; #define VL_DIV_III(lbits,lhs,rhs) (((rhs)==0)?0:(lhs)/(rhs)) #define VL_DIV_QQQ(lbits,lhs,rhs) (((rhs)==0)?0:(lhs)/(rhs)) #define VL_DIV_WWW(lbits,owp,lwp,rwp) (_vl_moddiv_w(lbits,owp,lwp,rwp,0)) #define VL_MODDIV_III(lbits,lhs,rhs) (((rhs)==0)?0:(lhs)%(rhs)) #define VL_MODDIV_QQQ(lbits,lhs,rhs) (((rhs)==0)?0:(lhs)%(rhs)) #define VL_MODDIV_WWW(lbits,owp,lwp,rwp) (_vl_moddiv_w(lbits,owp,lwp,rwp,1)) static inline WDataOutP VL_ADD_W(int words, WDataOutP owp,WDataInP lwp,WDataInP rwp){ QData carry = 0; for (int i=0; i> VL_ULL(32)) & VL_ULL(0xffffffff); } return(owp); } static inline WDataOutP VL_SUB_W(int words, WDataOutP owp,WDataInP lwp,WDataInP rwp){ QData carry = 0; for (int i=0; i> VL_ULL(32)) & VL_ULL(0xffffffff); } return(owp); } // Optimization bug in GCC 2.96 and presumably all-pre GCC 3 versions need this workaround, // we can't just //# define VL_NEGATE_I(data) (-(data)) static inline IData VL_NEGATE_I(IData data) { return -data; } static inline QData VL_NEGATE_Q(QData data) { return -data; } static inline WDataOutP VL_NEGATE_W(int words, WDataOutP owp,WDataInP lwp){ QData carry = 0; for (int i=0; i> VL_ULL(32)) & VL_ULL(0xffffffff); } return(owp); } static inline WDataOutP VL_MUL_W(int words, WDataOutP owp,WDataInP lwp,WDataInP rwp){ for (int i=0; i> VL_ULL(32)) & VL_ULL(0xffffffff); } } } // Last output word is dirty return(owp); } static inline IData VL_MULS_III(int,int lbits,int, IData lhs,IData rhs) { vlsint32_t lhs_signed = VL_EXTENDS_II(32, lbits, lhs); vlsint32_t rhs_signed = VL_EXTENDS_II(32, lbits, rhs); return lhs_signed * rhs_signed; } static inline QData VL_MULS_QQQ(int,int lbits,int, QData lhs,QData rhs) { vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); return lhs_signed * rhs_signed; } static inline WDataOutP VL_MULS_WWW(int,int lbits,int, WDataOutP owp,WDataInP lwp,WDataInP rwp){ int words = VL_WORDS_I(lbits); IData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here IData rwstore[VL_MULS_MAX_WORDS]; WDataInP lwusp = lwp; WDataInP rwusp = rwp; IData lneg = VL_SIGN_I(lbits,lwp[words-1]); if (lneg) { // Negate lhs lwusp = lwstore; VL_NEGATE_W(words, lwstore, lwp); lwstore[words-1] &= VL_MASK_I(lbits); // Clean it } IData rneg = VL_SIGN_I(lbits,rwp[words-1]); if (rneg) { // Negate rhs rwusp = rwstore; VL_NEGATE_W(words, rwstore, rwp); rwstore[words-1] &= VL_MASK_I(lbits); // Clean it } VL_MUL_W(words,owp,lwusp,rwusp); owp[words-1] &= VL_MASK_I(lbits); // Clean. Note it's ok for the multiply to overflow into the sign bit if ((lneg ^ rneg) & 1) { // Negate output (not using NEGATE, as owp==lwp) QData carry = 0; for (int i=0; i> VL_ULL(32)) & VL_ULL(0xffffffff); } //Not needed: owp[words-1] |= 1<0) power = power*power; if (rhs & (VL_ULL(1)<0) power = power*power; if (rhs & (VL_ULL(1)<>nbitsonright) & hinsmask); } } } // INTERNAL: Stuff large LHS bit 0++ into OUTPUT at specified offset // lwp may be "dirty" static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int lbit) { int hoffset = hbit & VL_SIZEBITS_I; int loffset = lbit & VL_SIZEBITS_I; int lword = VL_BITWORD_I(lbit); int words = VL_WORDS_I(hbit-lbit+1); if (hoffset==VL_SIZEBITS_I && loffset==0) { // Fast and common case, word based insertion for (int i=0; i>nbitsonright; IData od = (d & ~linsmask) | (owp[oword] & linsmask); if (oword==hword) owp[oword] = (owp[oword] & ~hinsmask) | (od & hinsmask); else owp[oword] = od; } } } } } static inline void _VL_INSERT_WQ(int obits, WDataOutP owp, QData ld, int hbit, int lbit) { WData lwp[2]; VL_SET_WQ(lwp,ld); _VL_INSERT_WW(obits,owp,lwp,hbit,lbit); } // EMIT_RULE: VL_REPLICATE: oclean=clean>width32, dirty<=width32; lclean=clean; rclean==clean; // RHS MUST BE CLEAN CONSTANT. #define VL_REPLICATE_IOI(obits,lbits,rbits, ld, rep) (-(ld)) // Iff lbits==1 #define VL_REPLICATE_QOI(obits,lbits,rbits, ld, rep) (-((QData)ld)) // Iff lbits==1 static inline IData VL_REPLICATE_III(int, int lbits, int, IData ld, IData rep) { IData returndata = ld; for (unsigned i=1; i < rep; i++){ returndata = returndata << lbits; returndata |= ld; } return (returndata); } static inline QData VL_REPLICATE_QII(int, int lbits, int, IData ld, IData rep) { QData returndata = ld; for (unsigned i=1; i < rep; i++){ returndata = returndata << lbits; returndata |= (QData)ld; } return (returndata); } static inline WDataOutP VL_REPLICATE_WII(int obits, int lbits, int, WDataOutP owp, IData ld, IData rep) { owp[0] = ld; for (unsigned i=1; i < rep; i++){ _VL_INSERT_WI(obits,owp,ld,i*lbits+lbits-1,i*lbits); } return(owp); } static inline WDataOutP VL_REPLICATE_WQI(int obits, int lbits, int, WDataOutP owp, QData ld, IData rep) { VL_SET_WQ(owp,ld); for (unsigned i=1; i < rep; i++){ _VL_INSERT_WQ(obits,owp,ld,i*lbits+lbits-1,i*lbits); } return(owp); } static inline WDataOutP VL_REPLICATE_WWI(int obits, int lbits, int, WDataOutP owp, WDataInP lwp, IData rep) { for (int i=0; i < VL_WORDS_I(lbits); i++) owp[i] = lwp[i]; for (unsigned i=1; i < rep; i++){ _VL_INSERT_WW(obits,owp,lwp,i*lbits+lbits-1,i*lbits); } return(owp); } // Left stream operator. Output will always be clean. LHS and RHS must be clean. // Special "fast" versions for slice sizes that are a power of 2. These use // shifts and masks to execute faster than the slower for-loop approach where a // subset of bits is copied in during each iteration. static inline IData VL_STREAML_FAST_III(int, int lbits, int, IData ld, IData rd_log2) { // Pre-shift bits in most-significant slice: // // If lbits is not a multiple of the slice size (i.e., lbits % rd != 0), // then we end up with a "gap" in our reversed result. For example, if we // have a 5-bit Verlilog signal (lbits=5) in an 8-bit C data type: // // ld = ---43210 // // (where numbers are the Verilog signal bit numbers and '-' is an unused bit). // Executing the switch statement below with a slice size of two (rd=2, // rd_log2=1) produces: // // ret = 1032-400 // // Pre-shifting the bits in the most-significant slice allows us to avoid // this gap in the shuffled data: // // ld_adjusted = --4-3210 // ret = 10324--- IData ret = ld; if (rd_log2) { vluint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2); // max multiple of rd <= lbits vluint32_t lbitsRem = lbits - lbitsFloor; // number of bits in most-sig slice (MSS) IData msbMask = VL_MASK_I(lbitsRem) << lbitsFloor; // mask to sel only bits in MSS ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_UL(1) << rd_log2) - lbitsRem)); } switch (rd_log2) { case 0: ret = ((ret >> 1) & VL_UL(0x55555555)) | ((ret & VL_UL(0x55555555)) << 1); // FALLTHRU case 1: ret = ((ret >> 2) & VL_UL(0x33333333)) | ((ret & VL_UL(0x33333333)) << 2); // FALLTHRU case 2: ret = ((ret >> 4) & VL_UL(0x0f0f0f0f)) | ((ret & VL_UL(0x0f0f0f0f)) << 4); // FALLTHRU case 3: ret = ((ret >> 8) & VL_UL(0x00ff00ff)) | ((ret & VL_UL(0x00ff00ff)) << 8); // FALLTHRU case 4: ret = ((ret >> 16) | (ret << 16)); } return ret >> (VL_WORDSIZE - lbits); } static inline QData VL_STREAML_FAST_QQI(int, int lbits, int, QData ld, IData rd_log2) { // Pre-shift bits in most-significant slice (see comment in VL_STREAML_FAST_III) QData ret = ld; if (rd_log2) { vluint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2); vluint32_t lbitsRem = lbits - lbitsFloor; QData msbMask = VL_MASK_Q(lbitsRem) << lbitsFloor; ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_ULL(1) << rd_log2) - lbitsRem)); } switch (rd_log2) { case 0: ret = ((ret >> 1) & VL_ULL(0x5555555555555555)) | ((ret & VL_ULL(0x5555555555555555)) << 1); // FALLTHRU case 1: ret = ((ret >> 2) & VL_ULL(0x3333333333333333)) | ((ret & VL_ULL(0x3333333333333333)) << 2); // FALLTHRU case 2: ret = ((ret >> 4) & VL_ULL(0x0f0f0f0f0f0f0f0f)) | ((ret & VL_ULL(0x0f0f0f0f0f0f0f0f)) << 4); // FALLTHRU case 3: ret = ((ret >> 8) & VL_ULL(0x00ff00ff00ff00ff)) | ((ret & VL_ULL(0x00ff00ff00ff00ff)) << 8); // FALLTHRU case 4: ret = ((ret >> 16) & VL_ULL(0x0000ffff0000ffff)) | ((ret & VL_ULL(0x0000ffff0000ffff)) << 16); // FALLTHRU case 5: ret = ((ret >> 32) | (ret << 32)); } return ret >> (VL_QUADSIZE - lbits); } // Regular "slow" streaming operators static inline IData VL_STREAML_III(int, int lbits, int, IData ld, IData rd) { IData ret = 0; // Slice size should never exceed the lhs width IData mask = VL_MASK_I(rd); for (int istart=0; istart 0 ? ostart : 0; ret |= ((ld >> istart) & mask) << ostart; } return ret; } static inline QData VL_STREAML_QQI(int, int lbits, int, QData ld, IData rd) { QData ret = 0; // Slice size should never exceed the lhs width QData mask = VL_MASK_Q(rd); for (int istart=0; istart 0 ? ostart : 0; ret |= ((ld >> istart) & mask) << ostart; } return ret; } static inline WDataOutP VL_STREAML_WWI(int, int lbits, int, WDataOutP owp, WDataInP lwp, IData rd) { VL_ZERO_RESET_W(lbits, owp); // Slice size should never exceed the lhs width int ssize = (rd < (IData)lbits) ? rd : ((IData)lbits); for (int istart=0; istart 0 ? ostart : 0; for (int sbit=0; sbit> VL_BITBIT_I(istart+sbit)) & 1) << VL_BITBIT_I(ostart+sbit); owp[VL_BITWORD_I(ostart+sbit)] |= bit; } } return owp; } // Because concats are common and wide, it's valuable to always have a clean output. // Thus we specify inputs must be clean, so we don't need to clean the output. // Note the bit shifts are always constants, so the adds in these constify out. // Casts required, as args may be 8 bit entities, and need to shift to appropriate output size #define VL_CONCAT_III(obits,lbits,rbits,ld,rd) ((IData)(ld)<<(rbits) | (IData)(rd)) #define VL_CONCAT_QII(obits,lbits,rbits,ld,rd) ((QData)(ld)<<(rbits) | (QData)(rd)) #define VL_CONCAT_QIQ(obits,lbits,rbits,ld,rd) ((QData)(ld)<<(rbits) | (QData)(rd)) #define VL_CONCAT_QQI(obits,lbits,rbits,ld,rd) ((QData)(ld)<<(rbits) | (QData)(rd)) #define VL_CONCAT_QQQ(obits,lbits,rbits,ld,rd) ((QData)(ld)<<(rbits) | (QData)(rd)) static inline WDataOutP VL_CONCAT_WII(int obits,int lbits,int rbits,WDataOutP owp,IData ld,IData rd) { owp[0] = rd; for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WI(obits,owp,ld,rbits+lbits-1,rbits); return(owp); } static inline WDataOutP VL_CONCAT_WWI(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, IData rd) { owp[0] = rd; for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WW(obits,owp,lwp,rbits+lbits-1,rbits); return(owp); } static inline WDataOutP VL_CONCAT_WIW(int obits,int lbits,int rbits,WDataOutP owp,IData ld, WDataInP rwp) { for (int i=0; i < VL_WORDS_I(rbits); i++) owp[i] = rwp[i]; for (int i=VL_WORDS_I(rbits); i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WI(obits,owp,ld,rbits+lbits-1,rbits); return(owp); } static inline WDataOutP VL_CONCAT_WIQ(int obits,int lbits,int rbits,WDataOutP owp,IData ld,QData rd) { VL_SET_WQ(owp,rd); for (int i=2; i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WI(obits,owp,ld,rbits+lbits-1,rbits); return(owp); } static inline WDataOutP VL_CONCAT_WQI(int obits,int lbits,int rbits,WDataOutP owp,QData ld,IData rd) { owp[0] = rd; for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WQ(obits,owp,ld,rbits+lbits-1,rbits); return(owp); } static inline WDataOutP VL_CONCAT_WQQ(int obits,int lbits,int rbits,WDataOutP owp,QData ld,QData rd) { VL_SET_WQ(owp,rd); for (int i=2; i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WQ(obits,owp,ld,rbits+lbits-1,rbits); return(owp); } static inline WDataOutP VL_CONCAT_WWQ(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, QData rd) { VL_SET_WQ(owp,rd); for (int i=2; i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WW(obits,owp,lwp,rbits+lbits-1,rbits); return(owp); } static inline WDataOutP VL_CONCAT_WQW(int obits,int lbits,int rbits,WDataOutP owp,QData ld, WDataInP rwp) { for (int i=0; i < VL_WORDS_I(rbits); i++) owp[i] = rwp[i]; for (int i=VL_WORDS_I(rbits); i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WQ(obits,owp,ld,rbits+lbits-1,rbits); return(owp); } static inline WDataOutP VL_CONCAT_WWW(int obits,int lbits,int rbits,WDataOutP owp,WDataInP lwp, WDataInP rwp) { for (int i=0; i < VL_WORDS_I(rbits); i++) owp[i] = rwp[i]; for (int i=VL_WORDS_I(rbits); i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WW(obits,owp,lwp,rbits+lbits-1,rbits); return(owp); } //=================================================================== // Shifts // Static shift, used by internal functions // The output is the same as the input - it overlaps! static inline void _VL_SHIFTL_INPLACE_W(int obits,WDataOutP iowp,IData rd/*1 or 4*/) { int words = VL_WORDS_I(obits); IData linsmask = VL_MASK_I(rd); for (int i=words-1; i>=1; i--) { iowp[i] = ((iowp[i]<> (32-rd)) & linsmask); } iowp[0] = ((iowp[0]<= (IData)obits) { // rd may be huge with MSB set for (int i=0; i < VL_WORDS_I(obits); i++) owp[i] = 0; } else if (bit_shift==0) { // Aligned word shift (<<0,<<32,<<64 etc) for (int i=0; i < word_shift; i++) owp[i] = 0; for (int i=word_shift; i < VL_WORDS_I(obits); i++) owp[i] = lwp[i-word_shift]; } else { for (int i=0; i < VL_WORDS_I(obits); i++) owp[i] = 0; _VL_INSERT_WW(obits,owp,lwp,obits-1,rd); } return(owp); } // EMIT_RULE: VL_SHIFTR: oclean=lclean; rclean==clean; // Important: Unlike most other funcs, the shift might well be a computed // expression. Thus consider this when optimizing. (And perhaps have 2 funcs?) static inline WDataOutP VL_SHIFTR_WWI(int obits,int,int,WDataOutP owp,WDataInP lwp, IData rd) { int word_shift = VL_BITWORD_I(rd); // Maybe 0 int bit_shift = VL_BITBIT_I(rd); if (rd >= (IData)obits) { // rd may be huge with MSB set for (int i=0; i < VL_WORDS_I(obits); i++) owp[i] = 0; } else if (bit_shift==0) { // Aligned word shift (>>0,>>32,>>64 etc) int copy_words = (VL_WORDS_I(obits)-word_shift); for (int i=0; i < copy_words; i++) owp[i] = lwp[i+word_shift]; for (int i=copy_words; i < VL_WORDS_I(obits); i++) owp[i] = 0; } else { int loffset = rd & VL_SIZEBITS_I; int nbitsonright = 32-loffset; // bits that end up in lword (know loffset!=0) // Middle words int words = VL_WORDS_I(obits-rd); for (int i=0; i>loffset; int upperword = i+word_shift+1; if (upperword < VL_WORDS_I(obits)) { owp[i] |= lwp[upperword]<< nbitsonright; } } for (int i=words; i> operator as a arithmetic shift! // IEEE says signed if output signed, but bit position from lbits; // must use lbits for sign; lbits might != obits, // an EXTEND(SHIFTRS(...)) can became a SHIFTRS(...) within same 32/64 bit word length IData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative IData signext = ~(VL_MASK_I(lbits) >> rhs); // One with bits where we've shifted "past" return (lhs >> rhs) | (sign & VL_CLEAN_II(obits,obits,signext)); } static inline QData VL_SHIFTRS_QQI(int obits, int lbits, int, QData lhs, IData rhs) { QData sign = -(lhs >> (lbits-1)); QData signext = ~(VL_MASK_Q(lbits) >> rhs); return (lhs >> rhs) | (sign & VL_CLEAN_QQ(obits,obits,signext)); } static inline IData VL_SHIFTRS_IQI(int obits, int lbits, int rbits, QData lhs, IData rhs) { return (IData)(VL_SHIFTRS_QQI(obits, lbits, rbits, lhs, rhs)); } static inline WDataOutP VL_SHIFTRS_WWI(int obits,int lbits,int,WDataOutP owp,WDataInP lwp, IData rd) { int word_shift = VL_BITWORD_I(rd); int bit_shift = VL_BITBIT_I(rd); int lmsw = VL_WORDS_I(obits)-1; IData sign = VL_SIGNONES_I(lbits,lwp[lmsw]); if (rd >= (IData)obits) { // Shifting past end, sign in all of lbits for (int i=0; i <= lmsw; i++) owp[i] = sign; owp[lmsw] &= VL_MASK_I(lbits); } else if (bit_shift==0) { // Aligned word shift (>>0,>>32,>>64 etc) int copy_words = (VL_WORDS_I(obits)-word_shift); for (int i=0; i < copy_words; i++) owp[i] = lwp[i+word_shift]; if (copy_words>=0) owp[copy_words-1] |= ~VL_MASK_I(obits) & sign; for (int i=copy_words; i < VL_WORDS_I(obits); i++) owp[i] = sign; owp[lmsw] &= VL_MASK_I(lbits); } else { int loffset = rd & VL_SIZEBITS_I; int nbitsonright = 32-loffset; // bits that end up in lword (know loffset!=0) // Middle words int words = VL_WORDS_I(obits-rd); for (int i=0; i>loffset; int upperword = i+word_shift+1; if (upperword < VL_WORDS_I(obits)) { owp[i] |= lwp[upperword]<< nbitsonright; } } if (words) owp[words-1] |= sign & ~VL_MASK_I(obits-loffset); for (int i=words; i>(rhs)) #define VL_BITSEL_QIII(obits,lbits,rbits,zbits,lhs,rhs) ((lhs)>>(rhs)) #define VL_BITSEL_QQII(obits,lbits,rbits,zbits,lhs,rhs) ((lhs)>>(rhs)) #define VL_BITSEL_IQII(obits,lbits,rbits,zbits,lhs,rhs) ((IData)((lhs)>>(rhs))) static inline IData VL_BITSEL_IWII(int, int lbits, int, int, WDataInP lwp, IData rd) { int word = VL_BITWORD_I(rd); if (VL_UNLIKELY(rd>(IData)lbits)) { return ~0; // Spec says you can go outside the range of a array. Don't coredump if so. // We return all 1's as that's more likely to find bugs (?) than 0's. } else { return (lwp[word]>>VL_BITBIT_I(rd)); } } // EMIT_RULE: VL_RANGE: oclean=lclean; out=dirty // & MUST BE CLEAN (currently constant) #define VL_SEL_IIII(obits,lbits,rbits,tbits,lhs,lsb,width) ((lhs)>>(lsb)) #define VL_SEL_QQII(obits,lbits,rbits,tbits,lhs,lsb,width) ((lhs)>>(lsb)) #define VL_SEL_IQII(obits,lbits,rbits,tbits,lhs,lsb,width) ((IData)((lhs)>>(lsb))) static inline IData VL_SEL_IWII(int, int lbits, int, int, WDataInP lwp, IData lsb, IData width) { int msb = lsb+width-1; if (VL_UNLIKELY(msb>lbits)) { return ~0; // Spec says you can go outside the range of a array. Don't coredump if so. } else if (VL_BITWORD_I(msb)==VL_BITWORD_I((int)lsb)) { return (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)); } else { // 32 bit extraction may span two words int nbitsfromlow = 32-VL_BITBIT_I(lsb); // bits that come from low word return ((lwp[VL_BITWORD_I(msb)]<>VL_BITBIT_I(lsb))); } } static inline QData VL_SEL_QWII(int, int lbits, int, int, WDataInP lwp, IData lsb, IData width) { int msb = lsb+width-1; if (VL_UNLIKELY(msb>lbits)) { return ~0; // Spec says you can go outside the range of a array. Don't coredump if so. } else if (VL_BITWORD_I(msb)==VL_BITWORD_I((int)lsb)) { return (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)); } else if (VL_BITWORD_I(msb)==1+VL_BITWORD_I((int)lsb)) { int nbitsfromlow = 32-VL_BITBIT_I(lsb); QData hi = (lwp[VL_BITWORD_I(msb)]); QData lo = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)); return (hi<>VL_BITBIT_I(lsb)); return (hi<<(nbitsfromlow+32)) | (mid<lbits)) { // Outside bounds, for (int i=0; i>loffset; int upperword = i+word_shift+1; if (upperword <= (int)VL_BITWORD_I(msb)) { owp[i] |= lwp[upperword]<< nbitsfromlow; } } for (int i=words; i= rhs width static inline void VL_ASSIGNSEL_WIII(int obits, int lsb, WDataOutP owp, IData rhs) { _VL_INSERT_WI(obits, owp, rhs, lsb+obits-1, lsb); } static inline void VL_ASSIGNSEL_WIIQ(int obits, int lsb, WDataOutP owp, QData rhs) { _VL_INSERT_WQ(obits, owp, rhs, lsb+obits-1, lsb); } static inline void VL_ASSIGNSEL_WIIW(int obits, int lsb, WDataOutP owp, WDataInP rwp) { _VL_INSERT_WW(obits, owp, rwp, lsb+obits-1, lsb); } //====================================================================== // Triops static inline WDataOutP VL_COND_WIWW(int obits, int, int, int, WDataOutP owp, int cond, WDataInP w1p, WDataInP w2p) { int words = VL_WORDS_I(obits); for (int i=0; i < words; i++) owp[i] = cond ? w1p[i] : w2p[i]; return(owp); } //====================================================================== // System Functions inline IData VL_VALUEPLUSARGS_IQ(int rbits, const char* prefixp, char fmt, QData& ldr) { WData wd[2]; IData v=VL_VALUEPLUSARGS_IW(rbits,prefixp,fmt,wd); if (v) ldr=VL_SET_QW(wd); return v; } inline IData VL_VALUEPLUSARGS_II(int rbits, const char* prefixp, char fmt, CData& ldr) { QData qd; IData v=VL_VALUEPLUSARGS_IQ(rbits,prefixp,fmt,qd); if (v) ldr=(CData)qd; return v; } inline IData VL_VALUEPLUSARGS_II(int rbits, const char* prefixp, char fmt, SData& ldr) { QData qd; IData v=VL_VALUEPLUSARGS_IQ(rbits,prefixp,fmt,qd); if (v) ldr=(SData)qd; return v; } inline IData VL_VALUEPLUSARGS_II(int rbits, const char* prefixp, char fmt, IData& ldr) { QData qd; IData v=VL_VALUEPLUSARGS_IQ(rbits,prefixp,fmt,qd); if (v) ldr=(IData)qd; return v; } //====================================================================== // Constification // VL_CONST_W_#X(int obits, WDataOutP owp, IData data0, .... IData data(#-1)) // Sets wide vector words to specified constant words, zeros upper data. // If changing the number of functions here, also change EMITCINLINES_NUM_CONSTW #define _END(obits,wordsSet) \ for(int i=(wordsSet);i using namespace std; //============================================================================= // VerilatedSerialBase - internal base class for common code between VerilatedSerialize and VerilatedDeserialize class VerilatedSerialBase { protected: // MEMBERS // For speed, keep m_cp as the first member of this structure vluint8_t* m_cp; ///< Current pointer into m_bufp buffer vluint8_t* m_bufp; ///< Output buffer bool m_isOpen; ///< True indicates open file/stream string m_filename; inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation inline static size_t bufferInsertSize() { return 16*1024; } // CREATORS VerilatedSerialBase() { m_isOpen = false; m_bufp = new vluint8_t [bufferSize()]; m_cp = m_bufp; } public: // CREATORS virtual ~VerilatedSerialBase() { close(); if (m_bufp) { delete m_bufp; m_bufp=NULL; } } // METHODS bool isOpen() const { return m_isOpen; } string filename() const { return m_filename; } virtual void close() { flush(); } virtual void flush() {} }; //============================================================================= // VerilatedSerialize - convert structures to a stream representation class VerilatedSerialize : public VerilatedSerialBase { protected: virtual void close() { flush(); } virtual void flush() {} void header(); void trailer(); public: // CREATORS VerilatedSerialize() {} virtual ~VerilatedSerialize() { close(); } // METHODS VerilatedSerialize& bufferCheck() { // Flush the write buffer if there's not enough space left for new information // We only call this once per vector, so we need enough slop for a very wide "b###" line if (VL_UNLIKELY(m_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) { flush(); } return *this; // For function chaining } inline VerilatedSerialize& write (const void* __restrict datap, size_t size) { const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap; while (size) { bufferCheck(); size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize(); const vluint8_t* __restrict maxp = dp + blk; while (dp < maxp) *m_cp++ = *dp++; size -= blk; } return *this; // For function chaining } }; //============================================================================= // VerilatedDeserial - load structures from a stream representation class VerilatedDeserialize : public VerilatedSerialBase { protected: vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer virtual void fill() = 0; void header(); void trailer(); public: // CREATORS VerilatedDeserialize() { m_endp = NULL; } virtual ~VerilatedDeserialize() { close(); } // METHODS inline VerilatedDeserialize& read (void* __restrict datap, size_t size) { vluint8_t* __restrict dp = (vluint8_t* __restrict)datap; while (size) { bufferCheck(); size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize(); const vluint8_t* __restrict maxp = dp + blk; while (dp < maxp) *dp++ = *m_cp++; size -= blk; } return *this; // For function chaining } // Read a datum and compare with expected value bool readDiffers (const void* __restrict datap, size_t size); VerilatedDeserialize& readAssert (const void* __restrict datap, size_t size); VerilatedDeserialize& readAssert (vluint64_t data) { return readAssert(&data, sizeof(data)); } VerilatedDeserialize& bufferCheck() { // Flush the write buffer if there's not enough space left for new information // We only call this once per vector, so we need enough slop for a very wide "b###" line if (VL_UNLIKELY((m_cp+bufferInsertSize()) > m_endp)) { fill(); } return *this; // For function chaining } }; //============================================================================= // VerilatedSave - serialize to a file class VerilatedSave : public VerilatedSerialize { private: int m_fd; ///< File descriptor we're writing to public: // CREATORS VerilatedSave() { m_fd=-1; } virtual ~VerilatedSave() { close(); } // METHODS void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors void open(const string& filename) { open(filename.c_str()); } virtual void close(); virtual void flush(); }; //============================================================================= // VerilatedRestore - deserialize from a file class VerilatedRestore : public VerilatedDeserialize { private: int m_fd; ///< File descriptor we're writing to public: // CREATORS VerilatedRestore() { m_fd=-1; } virtual ~VerilatedRestore() { close(); } // METHODS void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors void open(const string& filename) { open(filename.c_str()); } virtual void close(); virtual void flush() {} virtual void fill(); }; //============================================================================= inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint64_t& rhs) { return os.write(&rhs, sizeof(rhs)); } inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint64_t& rhs){ return os.read(&rhs, sizeof(rhs)); } inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint32_t& rhs) { return os.write(&rhs, sizeof(rhs)); } inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint32_t& rhs) { return os.read(&rhs, sizeof(rhs)); } inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint16_t& rhs) { return os.write(&rhs, sizeof(rhs)); } inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint16_t& rhs) { return os.read(&rhs, sizeof(rhs)); } inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint8_t& rhs) { return os.write(&rhs, sizeof(rhs)); } inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint8_t& rhs) { return os.read(&rhs, sizeof(rhs)); } inline VerilatedSerialize& operator<<(VerilatedSerialize& os, bool& rhs) { return os.write(&rhs, sizeof(rhs)); } inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, bool& rhs) { return os.read(&rhs, sizeof(rhs)); } inline VerilatedSerialize& operator<<(VerilatedSerialize& os, double& rhs) { return os.write(&rhs, sizeof(rhs)); } inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, double& rhs) { return os.read(&rhs, sizeof(rhs)); } inline VerilatedSerialize& operator<<(VerilatedSerialize& os, float& rhs) { return os.write(&rhs, sizeof(rhs)); } inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) { return os.read(&rhs, sizeof(rhs)); } inline VerilatedSerialize& operator<<(VerilatedSerialize& os, string& rhs) { vluint32_t len=rhs.length(); os<>(VerilatedDeserialize& os, string& rhs) { vluint32_t len; os>>len; rhs.resize(len); return os.read((void*)rhs.data(), len); } #endif // guard verilator-3.874/include/verilated_vcd_sc.cpp0000664000177100017500000001331512525172076021164 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // // THIS MODULE IS PUBLICLY LICENSED // // Copyright 2001-2015 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. // // This is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // //============================================================================= /// /// \file /// \brief Verilator tracing in VCD Format /// //============================================================================= // SPDIFF_OFF #include "verilatedos.h" #include "verilated_vcd_sc.h" // SPDIFF_ON //====================================================================== //====================================================================== //-------------------------------------------------- #if (SYSTEMC_VERSION>=20050714) // SystemC 2.1.v1 void VerilatedVcdSc::write_comment (const std::string &) {} void VerilatedVcdSc::trace (const unsigned int &, const std::string &, const char **) {} # define DECL_TRACE_METHOD_A(tp) \ void VerilatedVcdSc::trace( const tp& object, const std::string& name ) {} # define DECL_TRACE_METHOD_B(tp) \ void VerilatedVcdSc::trace( const tp& object, const std::string& name, int width ) {} DECL_TRACE_METHOD_A( bool ) DECL_TRACE_METHOD_A( sc_dt::sc_bit ) DECL_TRACE_METHOD_A( sc_dt::sc_logic ) DECL_TRACE_METHOD_B( unsigned char ) DECL_TRACE_METHOD_B( unsigned short ) DECL_TRACE_METHOD_B( unsigned int ) DECL_TRACE_METHOD_B( unsigned long ) #ifdef SYSTEMC_64BIT_PATCHES DECL_TRACE_METHOD_B( unsigned long long) #endif DECL_TRACE_METHOD_B( char ) DECL_TRACE_METHOD_B( short ) DECL_TRACE_METHOD_B( int ) DECL_TRACE_METHOD_B( long ) DECL_TRACE_METHOD_B( sc_dt::int64 ) DECL_TRACE_METHOD_B( sc_dt::uint64 ) DECL_TRACE_METHOD_A( float ) DECL_TRACE_METHOD_A( double ) DECL_TRACE_METHOD_A( sc_dt::sc_int_base ) DECL_TRACE_METHOD_A( sc_dt::sc_uint_base ) DECL_TRACE_METHOD_A( sc_dt::sc_signed ) DECL_TRACE_METHOD_A( sc_dt::sc_unsigned ) DECL_TRACE_METHOD_A( sc_dt::sc_fxval ) DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast ) DECL_TRACE_METHOD_A( sc_dt::sc_fxnum ) DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast ) DECL_TRACE_METHOD_A( sc_dt::sc_bv_base ) DECL_TRACE_METHOD_A( sc_dt::sc_lv_base ) //-------------------------------------------------- #elif (SYSTEMC_VERSION>20011000) // SystemC 2.0.1 void VerilatedVcdSc::write_comment (const sc_string &) {} void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char **) {} #define DECL_TRACE_METHOD_A(tp) \ void VerilatedVcdSc::trace( const tp& object, const sc_string& name ) {} #define DECL_TRACE_METHOD_B(tp) \ void VerilatedVcdSc::trace( const tp& object, const sc_string& name, int width ) {} DECL_TRACE_METHOD_A( bool ) DECL_TRACE_METHOD_A( sc_bit ) DECL_TRACE_METHOD_A( sc_logic ) DECL_TRACE_METHOD_B( unsigned char ) DECL_TRACE_METHOD_B( unsigned short ) DECL_TRACE_METHOD_B( unsigned int ) DECL_TRACE_METHOD_B( unsigned long ) #ifdef SYSTEMC_64BIT_PATCHES DECL_TRACE_METHOD_B( unsigned long long) #endif #if (SYSTEMC_VERSION>20041000) DECL_TRACE_METHOD_B( unsigned long long) DECL_TRACE_METHOD_B( long long) #endif DECL_TRACE_METHOD_B( char ) DECL_TRACE_METHOD_B( short ) DECL_TRACE_METHOD_B( int ) DECL_TRACE_METHOD_B( long ) DECL_TRACE_METHOD_A( float ) DECL_TRACE_METHOD_A( double ) DECL_TRACE_METHOD_A( sc_int_base ) DECL_TRACE_METHOD_A( sc_uint_base ) DECL_TRACE_METHOD_A( sc_signed ) DECL_TRACE_METHOD_A( sc_unsigned ) DECL_TRACE_METHOD_A( sc_fxval ) DECL_TRACE_METHOD_A( sc_fxval_fast ) DECL_TRACE_METHOD_A( sc_fxnum ) DECL_TRACE_METHOD_A( sc_fxnum_fast ) DECL_TRACE_METHOD_A( sc_bv_base ) DECL_TRACE_METHOD_A( sc_lv_base ) //-------------------------------------------------- #else // SystemC 1.2.1beta void VerilatedVcdSc::write_comment (const sc_string &) {} void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char **) {} #define DECL_TRACE_METHOD_A(tp) \ void VerilatedVcdSc::trace( const tp& object, const sc_string& name ) {} #define DECL_TRACE_METHOD_B(tp) \ void VerilatedVcdSc::trace( const tp& object, const sc_string& name, int width ) {} DECL_TRACE_METHOD_A( bool ) DECL_TRACE_METHOD_B( unsigned char ) DECL_TRACE_METHOD_B( short unsigned int ) DECL_TRACE_METHOD_B( unsigned int ) DECL_TRACE_METHOD_B( long unsigned int ) DECL_TRACE_METHOD_B( char ) DECL_TRACE_METHOD_B( short int ) DECL_TRACE_METHOD_B( int ) DECL_TRACE_METHOD_B( long int ) DECL_TRACE_METHOD_A( float ) DECL_TRACE_METHOD_A( double ) DECL_TRACE_METHOD_A( sc_bit ) DECL_TRACE_METHOD_A( sc_logic ) DECL_TRACE_METHOD_A( sc_bool_vector ) DECL_TRACE_METHOD_A( sc_logic_vector ) DECL_TRACE_METHOD_A( sc_signal_bool_vector ) DECL_TRACE_METHOD_A( sc_signal_logic_vector ) DECL_TRACE_METHOD_A( sc_uint_base ) DECL_TRACE_METHOD_A( sc_int_base ) DECL_TRACE_METHOD_A( sc_unsigned ) DECL_TRACE_METHOD_A( sc_signed ) DECL_TRACE_METHOD_A( sc_signal_resolved ) DECL_TRACE_METHOD_A( sc_signal_resolved_vector ) DECL_TRACE_METHOD_A( sc_bv_ns::sc_bv_base ) DECL_TRACE_METHOD_A( sc_bv_ns::sc_lv_base ) #endif #undef DECL_TRACE_METHOD_A #undef DECL_TRACE_METHOD_B //******************************************************************** verilator-3.874/include/verilated_heavy.h0000664000177100017500000000464112525171733020505 0ustar wsnyderwsnyder// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2010-2015 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* /// /// \file /// \brief Verilator: String include for all Verilated C files /// /// This file is included automatically by Verilator at the top of /// all C++ files it generates. It is used when strings or other /// heavyweight types are required; these contents are not part of /// verilated.h to save compile time when such types aren't used. /// /// Code available from: http://www.veripool.org/verilator /// //************************************************************************* #ifndef _VERILATED_HEAVY_H_ #define _VERILATED_HEAVY_H_ 1 ///< Header Guard #include "verilated.h" #include //====================================================================== // Conversion functions extern string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp); inline string VL_CVT_PACK_STR_NQ(QData lhs) { IData lw[2]; VL_SET_WQ(lw, lhs); return VL_CVT_PACK_STR_NW(2, lw); } inline string VL_CVT_PACK_STR_NN(const string& lhs) { return lhs; } inline string VL_CVT_PACK_STR_NI(IData lhs) { IData lw[1]; lw[0] = lhs; return VL_CVT_PACK_STR_NW(1, lw); } inline string VL_CONCATN_NNN(const string& lhs, const string& rhs) { return lhs+rhs; } inline string VL_REPLICATEN_NNQ(int,int,int, const string& lhs, IData rep) { string out; out.reserve(lhs.length() * rep); for (unsigned times=0; timesadd_trace_file(this); # if (SYSTEMC_VERSION>=20060505) // We want to avoid a depreciated warning, but still be back compatible. // Turning off the message just for this still results in an annoying "to turn off" message. sc_time t1sec(1,SC_SEC); if (t1sec.to_default_time_units()!=0) { sc_time tunits(1.0/t1sec.to_default_time_units(),SC_SEC); spTrace()->set_time_unit(tunits.to_string()); } spTrace()->set_time_resolution(sc_get_time_resolution().to_string()); # elif (SYSTEMC_VERSION>20011000) // To confuse matters 2.1.beta returns a char* here, while 2.1.v1 returns a std::string // we allow both flavors with overloaded set_time_* functions. spTrace()->set_time_unit(sc_get_default_time_unit().to_string()); spTrace()->set_time_resolution(sc_get_time_resolution().to_string()); # endif } virtual ~VerilatedVcdSc() {} /// Called by SystemC simulate() virtual void cycle (bool delta_cycle) { # if (SYSTEMC_VERSION>20011000) if (!delta_cycle) { this->dump(sc_time_stamp().to_double()); } # else // VCD files must have integer timestamps, so we write all times in increments of time_resolution if (!delta_cycle) { this->dump(sc_time_stamp().to_double()); } # endif } private: /// Fake outs for linker #ifdef NC_SYSTEMC // Cadence Incisive has these as abstract functions so we must create them virtual void set_time_unit( int exponent10_seconds ) {} // deprecated #endif #if defined(NC_SYSTEMC) || (SYSTEMC_VERSION>=20111100) virtual void set_time_unit( double v, sc_time_unit tu ) {} #endif //-------------------------------------------------- # if (SYSTEMC_VERSION>=20050714) // SystemC 2.1.v1 # define DECL_TRACE_METHOD_A(tp) \ virtual void trace( const tp& object, const std::string& name ); # define DECL_TRACE_METHOD_B(tp) \ virtual void trace( const tp& object, const std::string& name, int width ); virtual void write_comment (const std::string &); virtual void trace (const unsigned int &, const std::string &, const char **); DECL_TRACE_METHOD_A( bool ) DECL_TRACE_METHOD_A( sc_dt::sc_bit ) DECL_TRACE_METHOD_A( sc_dt::sc_logic ) DECL_TRACE_METHOD_B( unsigned char ) DECL_TRACE_METHOD_B( unsigned short ) DECL_TRACE_METHOD_B( unsigned int ) DECL_TRACE_METHOD_B( unsigned long ) #ifdef SYSTEMC_64BIT_PATCHES DECL_TRACE_METHOD_B( unsigned long long) #endif DECL_TRACE_METHOD_B( char ) DECL_TRACE_METHOD_B( short ) DECL_TRACE_METHOD_B( int ) DECL_TRACE_METHOD_B( long ) DECL_TRACE_METHOD_B( sc_dt::int64 ) DECL_TRACE_METHOD_B( sc_dt::uint64 ) DECL_TRACE_METHOD_A( float ) DECL_TRACE_METHOD_A( double ) DECL_TRACE_METHOD_A( sc_dt::sc_int_base ) DECL_TRACE_METHOD_A( sc_dt::sc_uint_base ) DECL_TRACE_METHOD_A( sc_dt::sc_signed ) DECL_TRACE_METHOD_A( sc_dt::sc_unsigned ) DECL_TRACE_METHOD_A( sc_dt::sc_fxval ) DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast ) DECL_TRACE_METHOD_A( sc_dt::sc_fxnum ) DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast ) DECL_TRACE_METHOD_A( sc_dt::sc_bv_base ) DECL_TRACE_METHOD_A( sc_dt::sc_lv_base ) //-------------------------------------------------- # elif (SYSTEMC_VERSION>20011000) // SystemC 2.0.1 # define DECL_TRACE_METHOD_A(tp) \ virtual void trace( const tp& object, const sc_string& name ); # define DECL_TRACE_METHOD_B(tp) \ virtual void trace( const tp& object, const sc_string& name, int width ); virtual void write_comment (const sc_string &); virtual void trace (const unsigned int &, const sc_string &, const char **); virtual void delta_cycles (bool) {} virtual void space( int n ) {} DECL_TRACE_METHOD_A( bool ) DECL_TRACE_METHOD_A( sc_bit ) DECL_TRACE_METHOD_A( sc_logic ) DECL_TRACE_METHOD_B( unsigned char ) DECL_TRACE_METHOD_B( unsigned short ) DECL_TRACE_METHOD_B( unsigned int ) DECL_TRACE_METHOD_B( unsigned long ) #ifdef SYSTEMC_64BIT_PATCHES DECL_TRACE_METHOD_B( unsigned long long) #endif #if (SYSTEMC_VERSION>20041000) DECL_TRACE_METHOD_B( unsigned long long) DECL_TRACE_METHOD_B( long long) #endif DECL_TRACE_METHOD_B( char ) DECL_TRACE_METHOD_B( short ) DECL_TRACE_METHOD_B( int ) DECL_TRACE_METHOD_B( long ) DECL_TRACE_METHOD_A( float ) DECL_TRACE_METHOD_A( double ) DECL_TRACE_METHOD_A( sc_int_base ) DECL_TRACE_METHOD_A( sc_uint_base ) DECL_TRACE_METHOD_A( sc_signed ) DECL_TRACE_METHOD_A( sc_unsigned ) DECL_TRACE_METHOD_A( sc_fxval ) DECL_TRACE_METHOD_A( sc_fxval_fast ) DECL_TRACE_METHOD_A( sc_fxnum ) DECL_TRACE_METHOD_A( sc_fxnum_fast ) DECL_TRACE_METHOD_A( sc_bv_base ) DECL_TRACE_METHOD_A( sc_lv_base ) //-------------------------------------------------- # else // SystemC 1.2.1beta # define DECL_TRACE_METHOD_A(tp) \ virtual void trace( const tp& object, const sc_string& name ); # define DECL_TRACE_METHOD_B(tp) \ virtual void trace( const tp& object, const sc_string& name, int width ); virtual void write_comment (const sc_string &); virtual void trace (const unsigned int &, const sc_string &, const char **); DECL_TRACE_METHOD_A( bool ) DECL_TRACE_METHOD_B( unsigned char ) DECL_TRACE_METHOD_B( short unsigned int ) DECL_TRACE_METHOD_B( unsigned int ) DECL_TRACE_METHOD_B( long unsigned int ) DECL_TRACE_METHOD_B( char ) DECL_TRACE_METHOD_B( short int ) DECL_TRACE_METHOD_B( int ) DECL_TRACE_METHOD_B( long int ) DECL_TRACE_METHOD_A( float ) DECL_TRACE_METHOD_A( double ) DECL_TRACE_METHOD_A( sc_bit ) DECL_TRACE_METHOD_A( sc_logic ) DECL_TRACE_METHOD_A( sc_bool_vector ) DECL_TRACE_METHOD_A( sc_logic_vector ) DECL_TRACE_METHOD_A( sc_signal_bool_vector ) DECL_TRACE_METHOD_A( sc_signal_logic_vector ) DECL_TRACE_METHOD_A( sc_uint_base ) DECL_TRACE_METHOD_A( sc_int_base ) DECL_TRACE_METHOD_A( sc_unsigned ) DECL_TRACE_METHOD_A( sc_signed ) DECL_TRACE_METHOD_A( sc_signal_resolved ) DECL_TRACE_METHOD_A( sc_signal_resolved_vector ) DECL_TRACE_METHOD_A( sc_bv_ns::sc_bv_base ) DECL_TRACE_METHOD_A( sc_bv_ns::sc_lv_base ) # endif # undef DECL_TRACE_METHOD_A # undef DECL_TRACE_METHOD_B }; #endif // guard